@@ -3741,49 +3741,56 @@ static bool ContextualCheckDynaFedHeader(const CBlockHeader& block, BlockValidat
37413741 return state.Invalid (BlockValidationResult::BLOCK_CONSENSUS, " invalid-dyna-fed" , " dynamic block header's current parameters do not match expected" );
37423742 }
37433743
3744- // Lastly, enforce rules on proposals.
3745- const DynaFedParamEntry& proposed = dynafed_params.m_proposed ;
3746- if (!proposed.IsNull ()) {
3747-
3748- // signblockscript proposals *must* be segwit versions
3749- int block_version = 0 ;
3750- std::vector<unsigned char > block_program;
3751- if (!proposed.m_signblockscript .IsWitnessProgram (block_version, block_program)) {
3752- return state.Invalid (BlockValidationResult::BLOCK_CONSENSUS, " invalid-dyna-fed" , " proposed signblockscript must be native segwit scriptPubkey" );
3753- }
3754-
3755- int fedpeg_version = 0 ;
3756- std::vector<unsigned char > fedpeg_program;
3757- if (!proposed.m_fedpeg_program .IsWitnessProgram (fedpeg_version, fedpeg_program)) {
3758- return state.Invalid (BlockValidationResult::BLOCK_CONSENSUS, " invalid-dyna-fed" , " proposed fedpegs program must be native segwit scriptPubkey" );
3759- }
3760-
3761- // for v0, fedpegscript's scriptPubKey must match. v1+ is unencumbered.
3762- if (fedpeg_version == 0 ) {
3763- uint256 fedpeg_program;
3764- CSHA256 ().Write (proposed.m_fedpegscript .data (), proposed.m_fedpegscript .size ()).Finalize (fedpeg_program.begin ());
3765- CScript computed_program = CScript () << OP_0 << ToByteVector (fedpeg_program);
3766- if (computed_program != proposed.m_fedpeg_program ) {
3767- return state.Invalid (BlockValidationResult::BLOCK_CONSENSUS, " invalid-dyna-fed" , " proposed v0 segwit fedpegscript must match proposed fedpeg witness program" );
3744+ // Lastly, enforce rules on proposals if they make changes.
3745+ if (!dynafed_params.m_proposed .IsNull ()) {
3746+ // Compare the new proposed parameters with the current full parameters.
3747+ const DynaFedParamEntry current = ComputeNextBlockFullCurrentParameters (pindexPrev, params.GetConsensus ());
3748+ const DynaFedParamEntry& proposed = dynafed_params.m_proposed ;
3749+
3750+ if (proposed.m_signblockscript != current.m_signblockscript ) {
3751+ // signblockscript proposals *must* be segwit versions
3752+ int block_version = 0 ;
3753+ std::vector<unsigned char > block_program;
3754+ if (!proposed.m_signblockscript .IsWitnessProgram (block_version, block_program)) {
3755+ return state.Invalid (BlockValidationResult::BLOCK_CONSENSUS, " invalid-dyna-fed" , " proposed signblockscript must be native segwit scriptPubkey" );
37683756 }
3757+ }
37693758
3770- // fedpegscript proposals *must not* start with OP_DEPTH
3771- // This forbids the first Liquid watchman script which is a hack.
3772- // Use miniscript, which doesn't even have OP_DEPTH.
3773- // We don't encumber future segwit versions as opcodes may change.
3774- if (!proposed.m_fedpegscript .empty () &&
3775- proposed.m_fedpegscript .front () == OP_DEPTH) {
3776- return state.Invalid (BlockValidationResult::BLOCK_CONSENSUS, " invalid-dyna-fed" , " Proposed fedpegscript starts with OP_DEPTH, which is illegal" );
3759+ if (proposed.m_fedpeg_program != current.m_fedpeg_program || proposed.m_fedpegscript != current.m_fedpegscript ) {
3760+ int fedpeg_version = 0 ;
3761+ std::vector<unsigned char > fedpeg_program;
3762+ if (!proposed.m_fedpeg_program .IsWitnessProgram (fedpeg_version, fedpeg_program)) {
3763+ return state.Invalid (BlockValidationResult::BLOCK_CONSENSUS, " invalid-dyna-fed" , " proposed signblockscript must be native segwit scriptPubkey" );
3764+ }
3765+
3766+ // for v0, fedpegscript's scriptPubKey must match. v1+ is unencumbered.
3767+ if (fedpeg_version == 0 ) {
3768+ uint256 fedpeg_program;
3769+ CSHA256 ().Write (proposed.m_fedpegscript .data (), proposed.m_fedpegscript .size ()).Finalize (fedpeg_program.begin ());
3770+ CScript computed_program = CScript () << OP_0 << ToByteVector (fedpeg_program);
3771+ if (computed_program != proposed.m_fedpeg_program ) {
3772+ return state.Invalid (BlockValidationResult::BLOCK_CONSENSUS, " invalid-dyna-fed" , " proposed v0 segwit fedpegscript must match proposed fedpeg witness program" );
3773+ }
3774+
3775+ // fedpegscript proposals *must not* start with OP_DEPTH
3776+ // This forbids the first Liquid watchman script which is a hack.
3777+ // Use miniscript, which doesn't even have OP_DEPTH.
3778+ // We don't encumber future segwit versions as opcodes may change.
3779+ if (!proposed.m_fedpegscript .empty () && proposed.m_fedpegscript .front () == OP_DEPTH) {
3780+ return state.Invalid (BlockValidationResult::BLOCK_CONSENSUS, " invalid-dyna-fed" , " Proposed fedpegscript starts with OP_DEPTH, which is illegal" );
3781+ }
37773782 }
37783783 }
37793784
3780- // When enforcing PAK, extension_space must give non-empty PAK list when
3781- // the vector itself is non-empty. Otherwise this means there were "junk"
3782- // entries
3783- if (params.GetEnforcePak ()) {
3784- if (!proposed.m_extension_space .empty () &&
3785- CreatePAKListFromExtensionSpace (proposed.m_extension_space ).IsReject ()) {
3786- return state.Invalid (BlockValidationResult::BLOCK_CONSENSUS, " invalid-dyna-fed" , " Extension space is not list of valid PAK entries" );
3785+ if (proposed.m_extension_space != current.m_extension_space ) {
3786+ // When enforcing PAK, extension_space must give non-empty PAK list when
3787+ // the vector itself is non-empty. Otherwise this means there were "junk"
3788+ // entries
3789+ if (params.GetEnforcePak ()) {
3790+ if (!proposed.m_extension_space .empty () &&
3791+ CreatePAKListFromExtensionSpace (proposed.m_extension_space ).IsReject ()) {
3792+ return state.Invalid (BlockValidationResult::BLOCK_CONSENSUS, " invalid-dyna-fed" , " Extension space is not list of valid PAK entries" );
3793+ }
37873794 }
37883795 }
37893796 }
0 commit comments