-
Notifications
You must be signed in to change notification settings - Fork 276
state modifications as network upgrade #549
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 14 commits
d6d999a
f8edd2c
e18dec2
0c1eedd
6afe5fc
2a59979
5c617bc
d02102f
a97ee33
7ea5d94
3a1cf82
6e921be
c6bb954
62760ee
bc3a8c7
fd25109
ca2c889
fae7aa3
3db8adc
5624d17
9ef281e
a111d22
2351e24
0c6d8c3
f6e6c1b
7dc8742
0f3dedf
923ecf7
f03b40e
eca4551
0cb03a2
281d3f6
95bb290
c53b094
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -66,8 +66,7 @@ func (u *PrecompileUpgrade) MarshalJSON() ([]byte, error) { | |
| // verifyPrecompileUpgrades checks [c.PrecompileUpgrades] is well formed: | ||
| // - [upgrades] must specify exactly one key per PrecompileUpgrade | ||
| // - the specified blockTimestamps must monotonically increase | ||
| // - the specified blockTimestamps must be compatible with those | ||
| // specified in the chainConfig by genesis. | ||
| // - the specified blockTimestamps must be compatible with those specified in the chainConfig by genesis. | ||
| // - check a precompile is disabled before it is re-enabled | ||
| func (c *ChainConfig) verifyPrecompileUpgrades() error { | ||
| // Store this struct to keep track of the last upgrade for each precompile key. | ||
|
|
@@ -149,18 +148,33 @@ func (c *ChainConfig) verifyPrecompileUpgrades() error { | |
| return nil | ||
| } | ||
|
|
||
| // GetActivePrecompileConfig returns the most recent precompile config corresponding to [address]. | ||
| // verifyStateUpgrades checks [c.StateUpgrades] is well formed: | ||
| // - the specified blockTimestamps must monotonically increase | ||
| func (c *ChainConfig) verifyStateUpgrades() error { | ||
| var previousUpgradeTimestamp *big.Int | ||
| for i, upgrade := range c.StateUpgrades { | ||
| upgradeTimestamp := upgrade.BlockTimestamp | ||
| // Verify specified timestamps are strictly monotonically increasing. | ||
ceyonur marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| if previousUpgradeTimestamp != nil && upgradeTimestamp.Cmp(previousUpgradeTimestamp) <= 0 { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if we decided not to use state upgrades at genesis, should we check if timestamp != 0? cc @aaronbuchwald
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ya I think we should add this check since we are not allowing them in the genesis |
||
| return fmt.Errorf("StateUpgrade[%d]: config block timestamp (%v) <= previous timestamp (%v)", i, upgradeTimestamp, previousUpgradeTimestamp) | ||
| } | ||
| previousUpgradeTimestamp = upgradeTimestamp | ||
| } | ||
| return nil | ||
| } | ||
|
|
||
| // getActivePrecompileConfig returns the most recent precompile config corresponding to [address]. | ||
| // If none have occurred, returns nil. | ||
| func (c *ChainConfig) GetActivePrecompileConfig(address common.Address, blockTimestamp *big.Int) precompileconfig.Config { | ||
| func (c *ChainConfig) getActivePrecompileConfig(address common.Address, blockTimestamp *big.Int) precompileconfig.Config { | ||
| configs := c.GetActivatingPrecompileConfigs(address, nil, blockTimestamp, c.PrecompileUpgrades) | ||
| if len(configs) == 0 { | ||
| return nil | ||
| } | ||
| return configs[len(configs)-1] // return the most recent config | ||
| } | ||
|
|
||
| // GetActivatingPrecompileConfigs returns all upgrades configured to activate during the state transition from a block with timestamp [from] | ||
| // to a block with timestamp [to]. | ||
| // GetActivatingPrecompileConfigs returns all precompile upgrades configured to activate during the | ||
| // state transition from a block with timestamp [from] to a block with timestamp [to]. | ||
| func (c *ChainConfig) GetActivatingPrecompileConfigs(address common.Address, from *big.Int, to *big.Int, upgrades []PrecompileUpgrade) []precompileconfig.Config { | ||
| // Get key from address. | ||
| module, ok := modules.GetPrecompileModuleByAddress(address) | ||
|
|
@@ -188,6 +202,18 @@ func (c *ChainConfig) GetActivatingPrecompileConfigs(address common.Address, fro | |
| return configs | ||
| } | ||
|
|
||
| // GetActivatingStateUpgrades returns all state upgrades configured to activate during the | ||
| // state transition from a block with timestamp [from] to a block with timestamp [to]. | ||
| func (c *ChainConfig) GetActivatingStateUpgrades(from *big.Int, to *big.Int, upgrades []StateUpgrade) []StateUpgrade { | ||
| activating := make([]StateUpgrade, 0) | ||
| for _, upgrade := range upgrades { | ||
| if utils.IsForkTransition(upgrade.BlockTimestamp, from, to) { | ||
| activating = append(activating, upgrade) | ||
| } | ||
| } | ||
| return activating | ||
| } | ||
|
|
||
| // CheckPrecompilesCompatible checks if [precompileUpgrades] are compatible with [c] at [headTimestamp]. | ||
| // Returns a ConfigCompatError if upgrades already activated at [headTimestamp] are missing from | ||
| // [precompileUpgrades]. Upgrades not already activated may be modified or absent from [precompileUpgrades]. | ||
|
|
@@ -246,11 +272,49 @@ func (c *ChainConfig) checkPrecompileCompatible(address common.Address, precompi | |
| return nil | ||
| } | ||
|
|
||
| // CheckStateUpgradesCompatible checks if [stateUpgrades] are compatible with [c] at [headTimestamp]. | ||
| func (c *ChainConfig) CheckStateUpgradesCompatible(stateUpgrades []StateUpgrade, lastTimestamp *big.Int) *ConfigCompatError { | ||
| // All active upgrades (from nil to [lastTimestamp]) must match. | ||
| activeUpgrades := c.GetActivatingStateUpgrades(nil, lastTimestamp, c.StateUpgrades) | ||
| newUpgrades := c.GetActivatingStateUpgrades(nil, lastTimestamp, stateUpgrades) | ||
|
|
||
| // Check activated upgrades are still present. | ||
| for i, upgrade := range activeUpgrades { | ||
| if len(newUpgrades) <= i { | ||
| // missing upgrade | ||
| return newCompatError( | ||
| fmt.Sprintf("missing StateUpgrade[%d]", i), | ||
| upgrade.BlockTimestamp, | ||
| nil, | ||
| ) | ||
| } | ||
| // All upgrades that have activated must be identical. | ||
| if !upgrade.Equal(&newUpgrades[i]) { | ||
| return newCompatError( | ||
| fmt.Sprintf("StateUpgrade[%d]", i), | ||
| upgrade.BlockTimestamp, | ||
| newUpgrades[i].BlockTimestamp, | ||
| ) | ||
| } | ||
| } | ||
| // then, make sure newUpgrades does not have additional upgrades | ||
| // that are already activated. (cannot perform retroactive upgrade) | ||
| if len(newUpgrades) > len(activeUpgrades) { | ||
| return newCompatError( | ||
| fmt.Sprintf("cannot retroactively enable StateUpgrade[%d]", len(activeUpgrades)), | ||
| nil, | ||
| newUpgrades[len(activeUpgrades)].BlockTimestamp, // this indexes to the first element in newUpgrades after the end of activeUpgrades | ||
| ) | ||
| } | ||
|
|
||
| return nil | ||
| } | ||
|
|
||
| // EnabledStatefulPrecompiles returns current stateful precompile configs that are enabled at [blockTimestamp]. | ||
| func (c *ChainConfig) EnabledStatefulPrecompiles(blockTimestamp *big.Int) Precompiles { | ||
| statefulPrecompileConfigs := make(Precompiles) | ||
| for _, module := range modules.RegisteredModules() { | ||
| if config := c.GetActivePrecompileConfig(module.Address, blockTimestamp); config != nil && !config.IsDisabled() { | ||
| if config := c.getActivePrecompileConfig(module.Address, blockTimestamp); config != nil && !config.IsDisabled() { | ||
| statefulPrecompileConfigs[module.ConfigKey] = config | ||
| } | ||
| } | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.