Commit 284913be authored by Vinod Damle's avatar Vinod Damle Committed by GitHub

Config: Add support for Isthmus (#12847)

* Config: Enable Isthmus

* Contracts: Add isthmus

* set the isthmus time offset in genesis

* rollup.Config implements types.BlockType interface

---------
Co-authored-by: default avatarVinod Damle <5338861+vdamle@users.noreply.github.com>
parent 49fcee02
......@@ -24,7 +24,7 @@ parser.add_argument('--allocs', help='Only create the allocs and exit', type=boo
log = logging.getLogger()
# Global constants
FORKS = ["delta", "ecotone", "fjord", "granite", "holocene"]
FORKS = ["delta", "ecotone", "fjord", "granite", "holocene", "isthmus"]
# Global environment variables
DEVNET_NO_BUILD = os.getenv('DEVNET_NO_BUILD') == "true"
......
......@@ -345,6 +345,9 @@ type UpgradeScheduleDeployConfig struct {
// L2GenesisHoloceneTimeOffset is the number of seconds after genesis block that the Holocene hard fork activates.
// Set it to 0 to activate at genesis. Nil to disable Holocene.
L2GenesisHoloceneTimeOffset *hexutil.Uint64 `json:"l2GenesisHoloceneTimeOffset,omitempty"`
// L2GenesisIsthmusTimeOffset is the number of seconds after genesis block that the Isthmus hard fork activates.
// Set it to 0 to activate at genesis. Nil to disable Isthmus.
L2GenesisIsthmusTimeOffset *hexutil.Uint64 `json:"l2GenesisIsthmusTimeOffset,omitempty"`
// L2GenesisInteropTimeOffset is the number of seconds after genesis block that the Interop hard fork activates.
// Set it to 0 to activate at genesis. Nil to disable Interop.
L2GenesisInteropTimeOffset *hexutil.Uint64 `json:"l2GenesisInteropTimeOffset,omitempty"`
......@@ -385,6 +388,8 @@ func (d *UpgradeScheduleDeployConfig) ForkTimeOffset(fork rollup.ForkName) *uint
return (*uint64)(d.L2GenesisGraniteTimeOffset)
case rollup.Holocene:
return (*uint64)(d.L2GenesisHoloceneTimeOffset)
case rollup.Isthmus:
return (*uint64)(d.L2GenesisIsthmusTimeOffset)
case rollup.Interop:
return (*uint64)(d.L2GenesisInteropTimeOffset)
default:
......@@ -408,6 +413,8 @@ func (d *UpgradeScheduleDeployConfig) SetForkTimeOffset(fork rollup.ForkName, of
d.L2GenesisGraniteTimeOffset = (*hexutil.Uint64)(offset)
case rollup.Holocene:
d.L2GenesisHoloceneTimeOffset = (*hexutil.Uint64)(offset)
case rollup.Isthmus:
d.L2GenesisIsthmusTimeOffset = (*hexutil.Uint64)(offset)
case rollup.Interop:
d.L2GenesisInteropTimeOffset = (*hexutil.Uint64)(offset)
default:
......@@ -472,6 +479,10 @@ func (d *UpgradeScheduleDeployConfig) HoloceneTime(genesisTime uint64) *uint64 {
return offsetToUpgradeTime(d.L2GenesisHoloceneTimeOffset, genesisTime)
}
func (d *UpgradeScheduleDeployConfig) IsthmusTime(genesisTime uint64) *uint64 {
return offsetToUpgradeTime(d.L2GenesisIsthmusTimeOffset, genesisTime)
}
func (d *UpgradeScheduleDeployConfig) InteropTime(genesisTime uint64) *uint64 {
return offsetToUpgradeTime(d.L2GenesisInteropTimeOffset, genesisTime)
}
......@@ -504,6 +515,7 @@ func (d *UpgradeScheduleDeployConfig) forks() []Fork {
{L2GenesisTimeOffset: d.L2GenesisFjordTimeOffset, Name: string(L2AllocsFjord)},
{L2GenesisTimeOffset: d.L2GenesisGraniteTimeOffset, Name: string(L2AllocsGranite)},
{L2GenesisTimeOffset: d.L2GenesisHoloceneTimeOffset, Name: string(L2AllocsHolocene)},
{L2GenesisTimeOffset: d.L2GenesisIsthmusTimeOffset, Name: string(L2AllocsIsthmus)},
}
}
......@@ -1008,6 +1020,7 @@ func (d *DeployConfig) RollupConfig(l1StartBlock *types.Header, l2GenesisBlockHa
FjordTime: d.FjordTime(l1StartTime),
GraniteTime: d.GraniteTime(l1StartTime),
HoloceneTime: d.HoloceneTime(l1StartTime),
IsthmusTime: d.IsthmusTime(l1StartTime),
InteropTime: d.InteropTime(l1StartTime),
ProtocolVersionsAddress: d.ProtocolVersionsProxy,
AltDAConfig: altDA,
......
......@@ -70,6 +70,7 @@ func NewL2Genesis(config *DeployConfig, l1StartHeader *types.Header) (*core.Gene
FjordTime: config.FjordTime(l1StartTime),
GraniteTime: config.GraniteTime(l1StartTime),
HoloceneTime: config.HoloceneTime(l1StartTime),
IsthmusTime: config.IsthmusTime(l1StartTime),
InteropTime: config.InteropTime(l1StartTime),
Optimism: &params.OptimismConfig{
EIP1559Denominator: eip1559Denom,
......
......@@ -27,6 +27,7 @@ const (
L2AllocsFjord L2AllocsMode = "fjord"
L2AllocsGranite L2AllocsMode = "granite"
L2AllocsHolocene L2AllocsMode = "holocene"
L2AllocsIsthmus L2AllocsMode = "isthmus"
)
var (
......
......@@ -41,6 +41,7 @@ const (
Fjord ForkName = "fjord"
Granite ForkName = "granite"
Holocene ForkName = "holocene"
Isthmus ForkName = "isthmus"
Interop ForkName = "interop"
// ADD NEW FORKS TO AllForks BELOW!
None ForkName = "none"
......@@ -55,6 +56,7 @@ var AllForks = []ForkName{
Fjord,
Granite,
Holocene,
Isthmus,
Interop,
// ADD NEW FORKS HERE!
}
......@@ -114,6 +116,11 @@ func (s *ChainSpec) IsHolocene(t uint64) bool {
return s.config.IsHolocene(t)
}
// IsIsthmus returns true if t >= isthmus_time
func (s *ChainSpec) IsIsthmus(t uint64) bool {
return s.config.IsIsthmus(t)
}
// MaxChannelBankSize returns the maximum number of bytes the can allocated inside the channel bank
// before pruning occurs at the given timestamp.
func (s *ChainSpec) MaxChannelBankSize(t uint64) uint64 {
......@@ -185,6 +192,9 @@ func (s *ChainSpec) CheckForkActivation(log log.Logger, block eth.L2BlockRef) {
if s.config.IsHolocene(block.Time) {
s.currentFork = Holocene
}
if s.config.IsIsthmus(block.Time) {
s.currentFork = Isthmus
}
if s.config.IsInterop(block.Time) {
s.currentFork = Interop
}
......@@ -209,6 +219,8 @@ func (s *ChainSpec) CheckForkActivation(log log.Logger, block eth.L2BlockRef) {
foundActivationBlock = s.config.IsGraniteActivationBlock(block.Time)
case Holocene:
foundActivationBlock = s.config.IsHoloceneActivationBlock(block.Time)
case Isthmus:
foundActivationBlock = s.config.IsIsthmusActivationBlock(block.Time)
case Interop:
foundActivationBlock = s.config.IsInteropActivationBlock(block.Time)
}
......
......@@ -45,6 +45,8 @@ var testConfig = Config{
EcotoneTime: u64ptr(40),
FjordTime: u64ptr(50),
GraniteTime: u64ptr(60),
HoloceneTime: u64ptr(70),
IsthmusTime: u64ptr(80),
InteropTime: nil,
BatchInboxAddress: common.HexToAddress("0xff00000000000000000000000000000000000010"),
DepositContractAddress: common.HexToAddress("0xbEb5Fc579115071764c7423A4f12eDde41f106Ed"),
......@@ -173,14 +175,26 @@ func TestCheckForkActivation(t *testing.T) {
},
{
name: "Granite activation",
block: eth.L2BlockRef{Time: 60, Number: 8, Hash: common.Hash{0x7}},
block: eth.L2BlockRef{Time: 60, Number: 8, Hash: common.Hash{0x8}},
expectedCurrentFork: Granite,
expectedLog: "Detected hardfork activation block",
},
{
name: "Holocene activation",
block: eth.L2BlockRef{Time: 70, Number: 9, Hash: common.Hash{0x9}},
expectedCurrentFork: Holocene,
expectedLog: "Detected hardfork activation block",
},
{
name: "Isthmus activation",
block: eth.L2BlockRef{Time: 80, Number: 10, Hash: common.Hash{0xa}},
expectedCurrentFork: Isthmus,
expectedLog: "Detected hardfork activation block",
},
{
name: "No more hardforks",
block: eth.L2BlockRef{Time: 700, Number: 9, Hash: common.Hash{0x8}},
expectedCurrentFork: Granite,
block: eth.L2BlockRef{Time: 700, Number: 11, Hash: common.Hash{0xb}},
expectedCurrentFork: Isthmus,
expectedLog: "",
},
}
......
......@@ -120,6 +120,10 @@ type Config struct {
// Active if HoloceneTime != nil && L2 block timestamp >= *HoloceneTime, inactive otherwise.
HoloceneTime *uint64 `json:"holocene_time,omitempty"`
// IsthmusTime sets the activation time of the Isthmus network upgrade.
// Active if IsthmusTime != nil && L2 block timestamp >= *IsthmusTime, inactive otherwise.
IsthmusTime *uint64 `json:"isthmus_time,omitempty"`
// InteropTime sets the activation time for an experimental feature-set, activated like a hardfork.
// Active if InteropTime != nil && L2 block timestamp >= *InteropTime, inactive otherwise.
InteropTime *uint64 `json:"interop_time,omitempty"`
......@@ -332,6 +336,10 @@ func (cfg *Config) Check() error {
return nil
}
func (cfg *Config) HasOptimismWithdrawalsRoot(timestamp uint64) bool {
return cfg.IsIsthmus(timestamp)
}
// validateAltDAConfig checks the two approaches to configuring alt-da mode.
// If the legacy values are set, they are copied to the new location. If both are set, they are check for consistency.
func validateAltDAConfig(cfg *Config) error {
......@@ -404,6 +412,11 @@ func (c *Config) IsHolocene(timestamp uint64) bool {
return c.HoloceneTime != nil && timestamp >= *c.HoloceneTime
}
// IsIsthmus returns true if the Isthmus hardfork is active at or past the given timestamp.
func (c *Config) IsIsthmus(timestamp uint64) bool {
return c.IsthmusTime != nil && timestamp >= *c.IsthmusTime
}
// IsInterop returns true if the Interop hardfork is active at or past the given timestamp.
func (c *Config) IsInterop(timestamp uint64) bool {
return c.InteropTime != nil && timestamp >= *c.InteropTime
......@@ -459,6 +472,14 @@ func (c *Config) IsHoloceneActivationBlock(l2BlockTime uint64) bool {
!c.IsHolocene(l2BlockTime-c.BlockTime)
}
// IsIsthmusActivationBlock returns whether the specified block is the first block subject to the
// Isthmus upgrade.
func (c *Config) IsIsthmusActivationBlock(l2BlockTime uint64) bool {
return c.IsIsthmus(l2BlockTime) &&
l2BlockTime >= c.BlockTime &&
!c.IsIsthmus(l2BlockTime-c.BlockTime)
}
func (c *Config) IsInteropActivationBlock(l2BlockTime uint64) bool {
return c.IsInterop(l2BlockTime) &&
l2BlockTime >= c.BlockTime &&
......@@ -482,6 +503,9 @@ func (c *Config) ActivateAtGenesis(hardfork ForkName) {
case Interop:
c.InteropTime = new(uint64)
fallthrough
case Isthmus:
c.IsthmusTime = new(uint64)
fallthrough
case Holocene:
c.HoloceneTime = new(uint64)
fallthrough
......@@ -621,6 +645,7 @@ func (c *Config) Description(l2Chains map[string]string) string {
banner += fmt.Sprintf(" - Fjord: %s\n", fmtForkTimeOrUnset(c.FjordTime))
banner += fmt.Sprintf(" - Granite: %s\n", fmtForkTimeOrUnset(c.GraniteTime))
banner += fmt.Sprintf(" - Holocene: %s\n", fmtForkTimeOrUnset(c.HoloceneTime))
banner += fmt.Sprintf(" - Isthmus: %s\n", fmtForkTimeOrUnset(c.IsthmusTime))
banner += fmt.Sprintf(" - Interop: %s\n", fmtForkTimeOrUnset(c.InteropTime))
// Report the protocol version
banner += fmt.Sprintf("Node supports up to OP-Stack Protocol Version: %s\n", OPStackSupport)
......@@ -657,6 +682,7 @@ func (c *Config) LogDescription(log log.Logger, l2Chains map[string]string) {
"fjord_time", fmtForkTimeOrUnset(c.FjordTime),
"granite_time", fmtForkTimeOrUnset(c.GraniteTime),
"holocene_time", fmtForkTimeOrUnset(c.HoloceneTime),
"isthmus_time", fmtForkTimeOrUnset(c.IsthmusTime),
"interop_time", fmtForkTimeOrUnset(c.InteropTime),
"alt_da", c.AltDAConfig != nil,
)
......
......@@ -169,7 +169,38 @@ func TestRandomConfigDescription(t *testing.T) {
out := config.Description(nil)
require.Contains(t, out, "Regolith: @ genesis")
})
t.Run("regolith date", func(t *testing.T) {
t.Run("optimism forks check, date", func(t *testing.T) {
config := randConfig()
r := uint64(1677119335)
config.RegolithTime = &r
c := uint64(1677119336)
config.CanyonTime = &c
d := uint64(1677119337)
config.DeltaTime = &d
e := uint64(1677119338)
config.EcotoneTime = &e
f := uint64(1677119339)
config.FjordTime = &f
h := uint64(1677119340)
config.HoloceneTime = &h
i := uint64(1677119341)
config.IsthmusTime = &i
it := uint64(1677119342)
config.InteropTime = &it
out := config.Description(nil)
// Don't check human-readable part of the date, it's timezone-dependent.
// Don't make this test fail only in Australia :')
require.Contains(t, out, fmt.Sprintf("Regolith: @ %d ~ ", r))
require.Contains(t, out, fmt.Sprintf("Canyon: @ %d ~ ", c))
require.Contains(t, out, fmt.Sprintf("Delta: @ %d ~ ", d))
require.Contains(t, out, fmt.Sprintf("Ecotone: @ %d ~ ", e))
require.Contains(t, out, fmt.Sprintf("Fjord: @ %d ~ ", f))
require.Contains(t, out, fmt.Sprintf("Holocene: @ %d ~ ", h))
require.Contains(t, out, fmt.Sprintf("Isthmus: @ %d ~ ", i))
require.Contains(t, out, fmt.Sprintf("Interop: @ %d ~ ", it))
})
t.Run("holocene & isthmus date", func(t *testing.T) {
config := randConfig()
x := uint64(1677119335)
config.RegolithTime = &x
......@@ -250,6 +281,15 @@ func TestActivations(t *testing.T) {
return c.IsHolocene(t)
},
},
{
name: "Isthmus",
setUpgradeTime: func(t *uint64, c *Config) {
c.IsthmusTime = t
},
checkEnabled: func(t uint64, c *Config) bool {
return c.IsIsthmus(t)
},
},
{
name: "Interop",
setUpgradeTime: func(t *uint64, c *Config) {
......@@ -518,10 +558,20 @@ func TestConfig_Check(t *testing.T) {
canyonTime := uint64(2)
deltaTime := uint64(3)
ecotoneTime := uint64(4)
fjordTime := uint64(5)
graniteTime := uint64(6)
holoceneTime := uint64(7)
isthmusTime := uint64(8)
interopTime := uint64(9)
cfg.RegolithTime = &regolithTime
cfg.CanyonTime = &canyonTime
cfg.DeltaTime = &deltaTime
cfg.EcotoneTime = &ecotoneTime
cfg.FjordTime = &fjordTime
cfg.GraniteTime = &graniteTime
cfg.HoloceneTime = &holoceneTime
cfg.IsthmusTime = &isthmusTime
cfg.InteropTime = &interopTime
},
expectedErr: nil,
},
......@@ -717,3 +767,37 @@ func TestConfig_IsActivationBlock(t *testing.T) {
require.Zero(t, cfg.IsActivationBlock(ts, ts+1))
}
}
func TestConfigImplementsBlockType(t *testing.T) {
config := randConfig()
isthmusTime := uint64(100)
config.IsthmusTime = &isthmusTime
tests := []struct {
name string
blockTime uint64
hasOptimismWithdrawalsRoot bool
}{
{
name: "BeforeIsthmus",
blockTime: uint64(99),
hasOptimismWithdrawalsRoot: false,
},
{
name: "AtIsthmus",
blockTime: uint64(100),
hasOptimismWithdrawalsRoot: true,
},
{
name: "AfterIsthmus",
blockTime: uint64(200),
hasOptimismWithdrawalsRoot: true,
},
}
for _, test := range tests {
test := test
t.Run(fmt.Sprintf("TestHasOptimismWithdrawalsRoot_%s", test.name), func(t *testing.T) {
assert.Equal(t, config.HasOptimismWithdrawalsRoot(test.blockTime), test.hasOptimismWithdrawalsRoot)
})
}
}
......@@ -182,6 +182,9 @@ contract L2Genesis is Deployer {
if (writeForkGenesisAllocs(_fork, Fork.HOLOCENE, _mode)) {
return;
}
if (writeForkGenesisAllocs(_fork, Fork.ISTHMUS, _mode)) {
return;
}
}
function writeForkGenesisAllocs(Fork _latest, Fork _current, OutputMode _mode) internal returns (bool isLatest_) {
......
......@@ -34,10 +34,11 @@ enum Fork {
ECOTONE,
FJORD,
GRANITE,
HOLOCENE
HOLOCENE,
ISTHMUS
}
Fork constant LATEST_FORK = Fork.HOLOCENE;
Fork constant LATEST_FORK = Fork.ISTHMUS;
library ForkUtils {
function toString(Fork _fork) internal pure returns (string memory) {
......@@ -53,6 +54,8 @@ library ForkUtils {
return "granite";
} else if (_fork == Fork.HOLOCENE) {
return "holocene";
} else if (_fork == Fork.ISTHMUS) {
return "isthmus";
} else {
return "unknown";
}
......@@ -168,6 +171,8 @@ library Config {
return Fork.GRANITE;
} else if (forkHash == keccak256(bytes("holocene"))) {
return Fork.HOLOCENE;
} else if (forkHash == keccak256(bytes("isthmus"))) {
return Fork.ISTHMUS;
} else {
revert(string.concat("Config: unknown fork: ", forkStr));
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment