|
43 | 43 |
|
44 | 44 | // ELEMENTS |
45 | 45 | #include <block_proof.h> // CheckChallenge, CheckProof |
| 46 | +#include <dynafed.h> |
46 | 47 |
|
47 | 48 | #include <future> |
48 | 49 | #include <sstream> |
@@ -3452,6 +3453,36 @@ std::vector<unsigned char> GenerateCoinbaseCommitment(CBlock& block, const CBloc |
3452 | 3453 | // ELEMENTS |
3453 | 3454 |
|
3454 | 3455 |
|
| 3456 | +static bool ContextualCheckDynaFedHeader(const CBlockHeader& block, CValidationState& state, const CChainParams& params, const CBlockIndex* pindexPrev) |
| 3457 | +{ |
| 3458 | + // When not active, it's a NOP |
| 3459 | + if (!IsDynaFedEnabled(pindexPrev, params.GetConsensus())) { |
| 3460 | + return true; |
| 3461 | + } |
| 3462 | + |
| 3463 | + const DynaFedParams& d_params = block.m_dyna_params; |
| 3464 | + |
| 3465 | + // Dynamic blocks must at least publish current signblockscript in full |
| 3466 | + if (d_params.m_current.IsNull()) { |
| 3467 | + return state.Invalid(false, REJECT_INVALID, "invalid-dyna-fed", "dynamic block headers must have non-empty current signblockscript field"); |
| 3468 | + } |
| 3469 | + |
| 3470 | + // Make sure extension bits aren't active, reserved for future HF |
| 3471 | + uint32_t reserved_mask = (1<<23) | (1<<24) | (1<<25) | (1<<26); |
| 3472 | + if ((block.nVersion & reserved_mask) != 0) { |
| 3473 | + return state.Invalid(false, REJECT_INVALID, "invalid-dyna-fed", "dynamic block header has unknown HF extension bits set"); |
| 3474 | + } |
| 3475 | + |
| 3476 | + const ConsensusParamEntry expected_current_params = ComputeNextBlockCurrentParameters(pindexPrev, params.GetConsensus()); |
| 3477 | + |
| 3478 | + if (expected_current_params != d_params.m_current) { |
| 3479 | + return state.Invalid(false, REJECT_INVALID, "invalid-dyna-fed", "dynamic block header's current parameters do not match expected"); |
| 3480 | + } |
| 3481 | + |
| 3482 | + return true; |
| 3483 | +} |
| 3484 | + |
| 3485 | + |
3455 | 3486 | /** Context-dependent validity checks. |
3456 | 3487 | * By "context", we mean only the previous block headers, but not the UTXO |
3457 | 3488 | * set; UTXO-related validity checks are done in ConnectBlock(). |
@@ -3502,6 +3533,12 @@ static bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationSta |
3502 | 3533 | return state.Invalid(false, REJECT_OBSOLETE, strprintf("bad-version(0x%08x)", block.nVersion), |
3503 | 3534 | strprintf("rejected nVersion=0x%08x block", block.nVersion)); |
3504 | 3535 |
|
| 3536 | + // check for dynamic federations activation, then ensuring block header version |
| 3537 | + // bits are set. These bits drive serialization of the header. |
| 3538 | + if (!ContextualCheckDynaFedHeader(block, state, params, pindexPrev)) { |
| 3539 | + return false; |
| 3540 | + } |
| 3541 | + |
3505 | 3542 | return true; |
3506 | 3543 | } |
3507 | 3544 |
|
|
0 commit comments