@@ -70,26 +70,25 @@ var (
7070)
7171
7272var (
73- // SubnetEVMDefaultChainConfig is the default configuration
73+ // SubnetEVMDefaultConfig is the default configuration
74+ // without any network upgrades.
7475 SubnetEVMDefaultChainConfig = & ChainConfig {
7576 ChainID : SubnetEVMChainID ,
7677 FeeConfig : DefaultFeeConfig ,
7778 AllowFeeRecipients : false ,
7879
79- HomesteadBlock : big .NewInt (0 ),
80- EIP150Block : big .NewInt (0 ),
81- EIP150Hash : common .HexToHash ("0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0" ),
82- EIP155Block : big .NewInt (0 ),
83- EIP158Block : big .NewInt (0 ),
84- ByzantiumBlock : big .NewInt (0 ),
85- ConstantinopleBlock : big .NewInt (0 ),
86- PetersburgBlock : big .NewInt (0 ),
87- IstanbulBlock : big .NewInt (0 ),
88- MuirGlacierBlock : big .NewInt (0 ),
89- GenesisPrecompiles : Precompiles {},
90- NetworkUpgrades : NetworkUpgrades {
91- SubnetEVMTimestamp : big .NewInt (0 ),
92- },
80+ HomesteadBlock : big .NewInt (0 ),
81+ EIP150Block : big .NewInt (0 ),
82+ EIP150Hash : common .HexToHash ("0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0" ),
83+ EIP155Block : big .NewInt (0 ),
84+ EIP158Block : big .NewInt (0 ),
85+ ByzantiumBlock : big .NewInt (0 ),
86+ ConstantinopleBlock : big .NewInt (0 ),
87+ PetersburgBlock : big .NewInt (0 ),
88+ IstanbulBlock : big .NewInt (0 ),
89+ MuirGlacierBlock : big .NewInt (0 ),
90+ MandatoryNetworkUpgrades : MainnetNetworkUpgrades , // This can be changed to correct network (local, test) via VM.
91+ GenesisPrecompiles : Precompiles {},
9392 }
9493
9594 TestChainConfig = & ChainConfig {
@@ -107,14 +106,37 @@ var (
107106 PetersburgBlock : big .NewInt (0 ),
108107 IstanbulBlock : big .NewInt (0 ),
109108 MuirGlacierBlock : big .NewInt (0 ),
110- NetworkUpgrades : NetworkUpgrades {big .NewInt (0 )},
111- GenesisPrecompiles : Precompiles {},
112- UpgradeConfig : UpgradeConfig {},
109+ MandatoryNetworkUpgrades : MandatoryNetworkUpgrades {
110+ SubnetEVMTimestamp : big .NewInt (0 ),
111+ DUpgradeTimestamp : big .NewInt (0 ),
112+ },
113+ GenesisPrecompiles : Precompiles {},
114+ UpgradeConfig : UpgradeConfig {},
113115 }
114116
115117 TestPreSubnetEVMConfig = & ChainConfig {
118+ AvalancheContext : AvalancheContext {snow .DefaultContextTest ()},
119+ ChainID : big .NewInt (1 ),
120+ FeeConfig : DefaultFeeConfig ,
121+ AllowFeeRecipients : false ,
122+ HomesteadBlock : big .NewInt (0 ),
123+ EIP150Block : big .NewInt (0 ),
124+ EIP150Hash : common.Hash {},
125+ EIP155Block : big .NewInt (0 ),
126+ EIP158Block : big .NewInt (0 ),
127+ ByzantiumBlock : big .NewInt (0 ),
128+ ConstantinopleBlock : big .NewInt (0 ),
129+ PetersburgBlock : big .NewInt (0 ),
130+ IstanbulBlock : big .NewInt (0 ),
131+ MuirGlacierBlock : big .NewInt (0 ),
132+ MandatoryNetworkUpgrades : MandatoryNetworkUpgrades {},
133+ GenesisPrecompiles : Precompiles {},
134+ UpgradeConfig : UpgradeConfig {},
135+ }
136+
137+ SimulatedTestChainConfig = & ChainConfig {
116138 AvalancheContext : AvalancheContext {snow .DefaultContextTest ()},
117- ChainID : big .NewInt (1 ),
139+ ChainID : big .NewInt (1337 ),
118140 FeeConfig : DefaultFeeConfig ,
119141 AllowFeeRecipients : false ,
120142 HomesteadBlock : big .NewInt (0 ),
@@ -127,20 +149,23 @@ var (
127149 PetersburgBlock : big .NewInt (0 ),
128150 IstanbulBlock : big .NewInt (0 ),
129151 MuirGlacierBlock : big .NewInt (0 ),
130- NetworkUpgrades : NetworkUpgrades {},
131- GenesisPrecompiles : Precompiles {},
132- UpgradeConfig : UpgradeConfig {},
152+ MandatoryNetworkUpgrades : MandatoryNetworkUpgrades {
153+ SubnetEVMTimestamp : big .NewInt (0 ),
154+ DUpgradeTimestamp : big .NewInt (0 ),
155+ },
156+ GenesisPrecompiles : Precompiles {},
157+ UpgradeConfig : UpgradeConfig {},
133158 }
134159)
135160
136161// UpgradeConfig includes the following configs that may be specified in upgradeBytes:
137162// - Timestamps that enable avalanche network upgrades,
138163// - Enabling or disabling precompiles as network upgrades.
139164type UpgradeConfig struct {
140- // Config for blocks/ timestamps that enable network upgrades.
141- // Note: if NetworkUpgrades is specified in the JSON all previously activated
165+ // Config for optional timestamps that enable network upgrades.
166+ // Note: if OptionalUpgrades is specified in the JSON all previously activated
142167 // forks must be present or upgradeBytes will be rejected.
143- NetworkUpgrades * NetworkUpgrades `json:"networkUpgrades,omitempty"`
168+ OptionalNetworkUpgrades * OptionalNetworkUpgrades `json:"networkUpgrades,omitempty"`
144169
145170 // Config for modifying state as a network upgrade.
146171 StateUpgrades []StateUpgrade `json:"stateUpgrades,omitempty"`
@@ -181,9 +206,10 @@ type ChainConfig struct {
181206 IstanbulBlock * big.Int `json:"istanbulBlock,omitempty"` // Istanbul switch block (nil = no fork, 0 = already on istanbul)
182207 MuirGlacierBlock * big.Int `json:"muirGlacierBlock,omitempty"` // Eip-2384 (bomb delay) switch block (nil = no fork, 0 = already activated)
183208
184- NetworkUpgrades // Config for timestamps that enable avalanche network upgrades
185- GenesisPrecompiles Precompiles `json:"-"` // Config for enabling precompiles from genesis. JSON encode/decode will be handled by the custom marshaler/unmarshaler.
186- UpgradeConfig `json:"-"` // Config specified in upgradeBytes (avalanche network upgrades or enable/disabling precompiles). Skip encoding/decoding directly into ChainConfig.
209+ MandatoryNetworkUpgrades // Config for timestamps that enable mandatory network upgrades. Skip encoding/decoding directly into ChainConfig.
210+ OptionalNetworkUpgrades // Config for optional timestamps that enable network upgrades
211+ GenesisPrecompiles Precompiles `json:"-"` // Config for enabling precompiles from genesis. JSON encode/decode will be handled by the custom marshaler/unmarshaler.
212+ UpgradeConfig `json:"-"` // Config specified in upgradeBytes (avalanche network upgrades or enable/disabling precompiles). Skip encoding/decoding directly into ChainConfig.
187213}
188214
189215// UnmarshalJSON parses the JSON-encoded data and stores the result in the
@@ -241,9 +267,13 @@ func (c *ChainConfig) String() string {
241267 if err != nil {
242268 feeBytes = []byte ("cannot marshal FeeConfig" )
243269 }
244- networkUpgradesBytes , err := json .Marshal (c .NetworkUpgrades )
270+ networkUpgradesBytes , err := json .Marshal (c .MandatoryNetworkUpgrades )
271+ if err != nil {
272+ networkUpgradesBytes = []byte ("cannot marshal MandatoryNetworkUpgrades" )
273+ }
274+ optionalNetworkUpgradeBytes , err := json .Marshal (c .OptionalNetworkUpgrades )
245275 if err != nil {
246- networkUpgradesBytes = []byte ("cannot marshal NetworkUpgrades " )
276+ optionalNetworkUpgradeBytes = []byte ("cannot marshal OptionalNetworkUpgrades " )
247277 }
248278 precompileUpgradeBytes , err := json .Marshal (c .GenesisPrecompiles )
249279 if err != nil {
@@ -254,7 +284,7 @@ func (c *ChainConfig) String() string {
254284 upgradeConfigBytes = []byte ("cannot marshal UpgradeConfig" )
255285 }
256286
257- return fmt .Sprintf ("{ChainID: %v Homestead: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Petersburg: %v Istanbul: %v, Muir Glacier: %v, Subnet EVM: %v, FeeConfig: %v, AllowFeeRecipients: %v, NetworkUpgrades : %v, PrecompileUpgrade: %v, UpgradeConfig: %v, Engine: Dummy Consensus Engine}" ,
287+ return fmt .Sprintf ("{ChainID: %v Homestead: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Petersburg: %v Istanbul: %v, Muir Glacier: %v, Subnet EVM: %v, DUpgrade: %v, FeeConfig: %v, AllowFeeRecipients: %v, MandatoryNetworkUpgrades: %v, OptionalNetworkUprades : %v, PrecompileUpgrade: %v, UpgradeConfig: %v, Engine: Dummy Consensus Engine}" ,
258288 c .ChainID ,
259289 c .HomesteadBlock ,
260290 c .EIP150Block ,
@@ -266,9 +296,11 @@ func (c *ChainConfig) String() string {
266296 c .IstanbulBlock ,
267297 c .MuirGlacierBlock ,
268298 c .SubnetEVMTimestamp ,
299+ c .DUpgradeTimestamp ,
269300 string (feeBytes ),
270301 c .AllowFeeRecipients ,
271302 string (networkUpgradesBytes ),
303+ string (optionalNetworkUpgradeBytes ),
272304 string (precompileUpgradeBytes ),
273305 string (upgradeConfigBytes ),
274306 )
@@ -323,7 +355,7 @@ func (c *ChainConfig) IsIstanbul(num *big.Int) bool {
323355
324356// IsSubnetEVM returns whether [blockTimestamp] is either equal to the SubnetEVM fork block timestamp or greater.
325357func (c * ChainConfig ) IsSubnetEVM (blockTimestamp * big.Int ) bool {
326- return utils .IsForked (c .getNetworkUpgrades (). SubnetEVMTimestamp , blockTimestamp )
358+ return utils .IsForked (c .SubnetEVMTimestamp , blockTimestamp )
327359}
328360
329361func (r * Rules ) PredicatesExist () bool {
@@ -383,16 +415,16 @@ func (c *ChainConfig) Verify() error {
383415 return nil
384416}
385417
418+ type fork struct {
419+ name string
420+ block * big.Int
421+ optional bool // if true, the fork may be nil and next fork is still allowed
422+ }
423+
386424// CheckConfigForkOrder checks that we don't "skip" any forks, geth isn't pluggable enough
387425// to guarantee that forks can be implemented in a different order than on official networks
388426func (c * ChainConfig ) CheckConfigForkOrder () error {
389- type fork struct {
390- name string
391- block * big.Int
392- optional bool // if true, the fork may be nil and next fork is still allowed
393- }
394- var lastFork fork
395- for _ , cur := range []fork {
427+ ethForks := []fork {
396428 {name : "homesteadBlock" , block : c .HomesteadBlock },
397429 {name : "eip150Block" , block : c .EIP150Block },
398430 {name : "eip155Block" , block : c .EIP155Block },
@@ -402,27 +434,11 @@ func (c *ChainConfig) CheckConfigForkOrder() error {
402434 {name : "petersburgBlock" , block : c .PetersburgBlock },
403435 {name : "istanbulBlock" , block : c .IstanbulBlock },
404436 {name : "muirGlacierBlock" , block : c .MuirGlacierBlock , optional : true },
405- } {
406- if cur .block != nil && common .Big0 .Cmp (cur .block ) != 0 {
407- return errNonGenesisForkByHeight
408- }
409- if lastFork .name != "" {
410- // Next one must be higher number
411- if lastFork .block == nil && cur .block != nil {
412- return fmt .Errorf ("unsupported fork ordering: %v not enabled, but %v enabled at %v" ,
413- lastFork .name , cur .name , cur .block )
414- }
415- if lastFork .block != nil && cur .block != nil {
416- if lastFork .block .Cmp (cur .block ) > 0 {
417- return fmt .Errorf ("unsupported fork ordering: %v enabled at %v, but %v enabled at %v" ,
418- lastFork .name , lastFork .block , cur .name , cur .block )
419- }
420- }
421- }
422- // If it was optional and not set, then ignore it
423- if ! cur .optional || cur .block != nil {
424- lastFork = cur
425- }
437+ }
438+
439+ // Check that forks are enabled in order
440+ if err := checkForks (ethForks , true ); err != nil {
441+ return err
426442 }
427443
428444 // Note: In Avalanche, hard forks must take place via block timestamps instead
@@ -433,10 +449,24 @@ func (c *ChainConfig) CheckConfigForkOrder() error {
433449 // Note: we do not add the optional stateful precompile configs in here because they are optional
434450 // and independent, such that the ordering they are enabled does not impact the correctness of the
435451 // chain config.
436- lastFork = fork {}
437- for _ , cur := range []fork {
438- {name : "subnetEVMTimestamp" , block : c .SubnetEVMTimestamp },
439- } {
452+ if err := checkForks (c .mandatoryForkOrder (), false ); err != nil {
453+ return err
454+ }
455+
456+ // Check optional forks are enabled in order
457+ if err := checkForks (c .optionalForkOrder (), false ); err != nil {
458+ return err
459+ }
460+
461+ return nil
462+ }
463+
464+ func checkForks (forks []fork , heightFork bool ) error {
465+ lastFork := fork {}
466+ for _ , cur := range forks {
467+ if heightFork && cur .block != nil && common .Big0 .Cmp (cur .block ) != 0 {
468+ return errNonGenesisForkByHeight
469+ }
440470 if lastFork .name != "" {
441471 // Next one must be higher number
442472 if lastFork .block == nil && cur .block != nil {
@@ -497,15 +527,20 @@ func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, lastHeight *big.Int,
497527 return newCompatError ("Muir Glacier fork block" , c .MuirGlacierBlock , newcfg .MuirGlacierBlock )
498528 }
499529
530+ // Check avalanhe network upgrades
531+ if err := c .CheckMandatoryCompatible (& newcfg .MandatoryNetworkUpgrades , lastTimestamp ); err != nil {
532+ return err
533+ }
534+
500535 // Check subnet-evm specific activations
501- newNetworkUpgrades := newcfg .getNetworkUpgrades ()
502- if c .UpgradeConfig .NetworkUpgrades != nil && newcfg .UpgradeConfig .NetworkUpgrades == nil {
503- // Note: if the current NetworkUpgrades are set via UpgradeConfig, then a new config
504- // without NetworkUpgrades will be treated as having specified an empty set of network
536+ newOptionalNetworkUpgrades := newcfg .getOptionalNetworkUpgrades ()
537+ if c .UpgradeConfig .OptionalNetworkUpgrades != nil && newcfg .UpgradeConfig .OptionalNetworkUpgrades == nil {
538+ // Note: if the current OptionalNetworkUpgrades are set via UpgradeConfig, then a new config
539+ // without OptionalNetworkUpgrades will be treated as having specified an empty set of network
505540 // upgrades (ie., treated as the user intends to cancel scheduled forks)
506- newNetworkUpgrades = & NetworkUpgrades {}
541+ newOptionalNetworkUpgrades = & OptionalNetworkUpgrades {}
507542 }
508- if err := c .getNetworkUpgrades ().CheckCompatible ( newNetworkUpgrades , lastTimestamp ); err != nil {
543+ if err := c .getOptionalNetworkUpgrades ().CheckOptionalCompatible ( newOptionalNetworkUpgrades , lastTimestamp ); err != nil {
509544 return err
510545 }
511546
@@ -523,13 +558,13 @@ func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, lastHeight *big.Int,
523558 return nil
524559}
525560
526- // getNetworkUpgrades returns NetworkUpgrades from upgrade config if set there,
561+ // getOptionalNetworkUpgrades returns OptionalNetworkUpgrades from upgrade config if set there,
527562// otherwise it falls back to the genesis chain config.
528- func (c * ChainConfig ) getNetworkUpgrades () * NetworkUpgrades {
529- if upgradeConfigOverride := c .UpgradeConfig .NetworkUpgrades ; upgradeConfigOverride != nil {
563+ func (c * ChainConfig ) getOptionalNetworkUpgrades () * OptionalNetworkUpgrades {
564+ if upgradeConfigOverride := c .UpgradeConfig .OptionalNetworkUpgrades ; upgradeConfigOverride != nil {
530565 return upgradeConfigOverride
531566 }
532- return & c .NetworkUpgrades
567+ return & c .OptionalNetworkUpgrades
533568}
534569
535570// isForkIncompatible returns true if a fork scheduled at s1 cannot be rescheduled to
0 commit comments