@@ -21,32 +21,6 @@ struct ChainspecEvolveConfig {
2121 /// Block height at which the custom contract size limit activates.
2222 #[ serde( default , rename = "contractSizeLimitActivationHeight" ) ]
2323 pub contract_size_limit_activation_height : Option < u64 > ,
24- /// Block height at which canonical block hash enforcement activates.
25- ///
26- /// # Background
27- ///
28- /// Early versions of ev-node passed block hashes from height H-1 instead of H
29- /// when communicating with ev-reth via the Engine API. This caused block hashes
30- /// to not match the canonical Ethereum block hash (keccak256 of RLP-encoded header),
31- /// resulting in block explorers like Blockscout incorrectly displaying every block
32- /// as a fork due to parent hash mismatches.
33- ///
34- /// # Migration Strategy
35- ///
36- /// For existing networks with historical blocks containing non-canonical hashes:
37- /// - Set this to a future block height where the fix will activate
38- /// - Before the activation height: hash mismatches are bypassed (legacy mode)
39- /// - At and after the activation height: canonical hash validation is enforced
40- ///
41- /// This allows nodes to sync from genesis on networks with historical hash
42- /// mismatches while ensuring new blocks use correct canonical hashes.
43- ///
44- /// # Default Behavior
45- ///
46- /// If not set, canonical hash validation is enforced from genesis (block 0).
47- /// This is the correct setting for new networks without legacy data.
48- #[ serde( default , rename = "canonicalHashActivationHeight" ) ]
49- pub canonical_hash_activation_height : Option < u64 > ,
5024}
5125
5226/// Configuration for the Evolve payload builder
@@ -70,32 +44,6 @@ pub struct EvolvePayloadBuilderConfig {
7044 /// Block height at which the custom contract size limit activates.
7145 #[ serde( default ) ]
7246 pub contract_size_limit_activation_height : Option < u64 > ,
73- /// Block height at which canonical block hash enforcement activates.
74- ///
75- /// # Background
76- ///
77- /// Early versions of ev-node passed block hashes from height H-1 instead of H
78- /// when communicating with ev-reth via the Engine API. This caused block hashes
79- /// to not match the canonical Ethereum block hash (keccak256 of RLP-encoded header),
80- /// resulting in block explorers like Blockscout incorrectly displaying every block
81- /// as a fork due to parent hash mismatches.
82- ///
83- /// # Migration Strategy
84- ///
85- /// For existing networks with historical blocks containing non-canonical hashes:
86- /// - Set this to a future block height where the fix will activate
87- /// - Before the activation height: hash mismatches are bypassed (legacy mode)
88- /// - At and after the activation height: canonical hash validation is enforced
89- ///
90- /// This allows nodes to sync from genesis on networks with historical hash
91- /// mismatches while ensuring new blocks use correct canonical hashes.
92- ///
93- /// # Default Behavior
94- ///
95- /// If not set, canonical hash validation is enforced from genesis (block 0).
96- /// This is the correct setting for new networks without legacy data.
97- #[ serde( default ) ]
98- pub canonical_hash_activation_height : Option < u64 > ,
9947}
10048
10149impl EvolvePayloadBuilderConfig {
@@ -108,7 +56,6 @@ impl EvolvePayloadBuilderConfig {
10856 mint_precompile_activation_height : None ,
10957 contract_size_limit : None ,
11058 contract_size_limit_activation_height : None ,
111- canonical_hash_activation_height : None ,
11259 }
11360 }
11461
@@ -143,7 +90,6 @@ impl EvolvePayloadBuilderConfig {
14390 config. contract_size_limit = extras. contract_size_limit ;
14491 config. contract_size_limit_activation_height =
14592 extras. contract_size_limit_activation_height ;
146- config. canonical_hash_activation_height = extras. canonical_hash_activation_height ;
14793 }
14894 Ok ( config)
14995 }
@@ -197,29 +143,6 @@ impl EvolvePayloadBuilderConfig {
197143 self . base_fee_redirect_settings ( )
198144 . and_then ( |( sink, activation) | ( block_number >= activation) . then_some ( sink) )
199145 }
200-
201- /// Returns true if canonical block hash validation should be enforced for the given block.
202- ///
203- /// This method controls whether the validator should reject blocks with hash mismatches
204- /// or bypass the check for legacy compatibility.
205- ///
206- /// # Returns
207- ///
208- /// - `true`: Enforce canonical hash validation (reject mismatches)
209- /// - `false`: Bypass hash validation (legacy mode for historical blocks)
210- ///
211- /// # Logic
212- ///
213- /// - If `canonical_hash_activation_height` is `None`: Always enforce (new networks)
214- /// - If `canonical_hash_activation_height` is `Some(N)`:
215- /// - `block_number < N`: Don't enforce (legacy mode)
216- /// - `block_number >= N`: Enforce (canonical mode)
217- pub const fn is_canonical_hash_enforced ( & self , block_number : u64 ) -> bool {
218- match self . canonical_hash_activation_height {
219- Some ( activation) => block_number >= activation,
220- None => true , // Default: enforce canonical hashes from genesis
221- }
222- }
223146}
224147
225148/// Errors that can occur during configuration validation
@@ -409,7 +332,6 @@ mod tests {
409332 mint_precompile_activation_height : Some ( 0 ) ,
410333 contract_size_limit : None ,
411334 contract_size_limit_activation_height : None ,
412- canonical_hash_activation_height : None ,
413335 } ;
414336 assert ! ( config_with_sink. validate( ) . is_ok( ) ) ;
415337 }
@@ -424,7 +346,6 @@ mod tests {
424346 mint_precompile_activation_height : None ,
425347 contract_size_limit : None ,
426348 contract_size_limit_activation_height : None ,
427- canonical_hash_activation_height : None ,
428349 } ;
429350
430351 assert_eq ! ( config. base_fee_sink_for_block( 4 ) , None ) ;
@@ -555,29 +476,4 @@ mod tests {
555476 ) ;
556477 }
557478
558- #[ test]
559- fn test_canonical_hash_activation_from_chainspec ( ) {
560- let extras = json ! ( {
561- "canonicalHashActivationHeight" : 500
562- } ) ;
563-
564- let chainspec = create_test_chainspec_with_extras ( Some ( extras) ) ;
565- let config = EvolvePayloadBuilderConfig :: from_chain_spec ( & chainspec) . unwrap ( ) ;
566-
567- assert_eq ! ( config. canonical_hash_activation_height, Some ( 500 ) ) ;
568- // Before activation: legacy mode (not enforced)
569- assert ! ( !config. is_canonical_hash_enforced( 499 ) ) ;
570- // At and after activation: canonical mode (enforced)
571- assert ! ( config. is_canonical_hash_enforced( 500 ) ) ;
572- assert ! ( config. is_canonical_hash_enforced( 600 ) ) ;
573- }
574-
575- #[ test]
576- fn test_canonical_hash_default_enforces_from_genesis ( ) {
577- // When not configured, canonical hashes should be enforced from genesis
578- let config = EvolvePayloadBuilderConfig :: new ( ) ;
579- assert_eq ! ( config. canonical_hash_activation_height, None ) ;
580- assert ! ( config. is_canonical_hash_enforced( 0 ) ) ;
581- assert ! ( config. is_canonical_hash_enforced( 1000 ) ) ;
582- }
583479}
0 commit comments