@@ -461,6 +461,23 @@ impl NetworkConfigs {
461461 false
462462 }
463463
464+ /// Coerces `hardfork` into this network's family.
465+ ///
466+ /// Execution and fee rules apply the same lossy `From` conversions, so a cross-namespace
467+ /// override such as `--hardfork prague` on a Tempo node runs as a Tempo hardfork. Callers that
468+ /// need to describe what actually executed, like trace decoding, go through here rather than
469+ /// carrying the configured value.
470+ pub fn executed_hardfork ( & self , hardfork : FoundryHardfork ) -> FoundryHardfork {
471+ if self . is_tempo ( ) {
472+ return TempoHardfork :: from ( hardfork) . into ( ) ;
473+ }
474+ #[ cfg( feature = "monad" ) ]
475+ if self . is_monad ( ) {
476+ return MonadHardfork :: from ( hardfork) . into ( ) ;
477+ }
478+ hardfork
479+ }
480+
464481 /// Returns additional cheatcode contract addresses for the active network.
465482 pub const fn extra_cheatcode_addresses ( & self ) -> & ' static [ Address ] {
466483 #[ cfg( feature = "monad" ) ]
@@ -1789,4 +1806,16 @@ mod tests {
17891806 assert ! ( cfg_optimism. is_optimism( ) ) ;
17901807 }
17911808 }
1809+
1810+ #[ test]
1811+ fn executed_hardfork_follows_the_network_family ( ) {
1812+ // A cross-namespace override runs as the configured network's hardfork, so the value used
1813+ // to describe execution has to be coerced the same way.
1814+ let prague = FoundryHardfork :: Ethereum ( EthereumHardfork :: Prague ) ;
1815+ assert_eq ! ( NetworkConfigs :: default ( ) . executed_hardfork( prague) , prague) ;
1816+ assert_eq ! (
1817+ NetworkConfigs :: with_tempo( ) . executed_hardfork( prague) ,
1818+ FoundryHardfork :: Tempo ( TempoHardfork :: from( prague) )
1819+ ) ;
1820+ }
17921821}
0 commit comments