feat: add scroll network (#751)

* update core/genesis_alloc.go

* update eth/ethconfig/config.go

* update cmd/utils/flags.go

* fix cmd/utils/flags.go

* update params/bootnodes.go

* update cmd/geth/main.go

* update cmd/utils/flags.go

* update core/genesis.go

* update params/config.go

* try fix fork ordering 1

* try fix fork ordering 2

* update `TestGenesisHashes`

* update `TestCustomGenesis`

* allow shanghai in clique & ethhash
This commit is contained in:
HAOYUatHZ 2024-05-17 20:20:43 +08:00 committed by GitHub
parent 47f5a9668d
commit 62c81eee01
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 534 additions and 33 deletions

View file

@ -89,6 +89,7 @@ func TestCustomGenesis(t *testing.T) {
// Query the custom genesis block
geth := runGeth(t, "--networkid", "1337", "--syncmode=full", "--cache", "16",
"--snapshot=false",
"--datadir", datadir, "--maxpeers", "0", "--port", "0", "--authrpc.port", "0",
"--nodiscover", "--nat", "none", "--ipcdisable",
"--exec", tt.query, "console")

View file

@ -289,6 +289,12 @@ func prepare(ctx *cli.Context) {
case ctx.IsSet(utils.HoleskyFlag.Name):
log.Info("Starting Geth on Holesky testnet...")
case ctx.IsSet(utils.ScrollAlphaFlag.Name):
log.Info("Starting l2geth on Scroll Alpha testnet...")
case ctx.IsSet(utils.ScrollSepoliaFlag.Name):
log.Info("Starting l2geth on Scroll Sepolia testnet...")
case ctx.IsSet(utils.DeveloperFlag.Name):
log.Info("Starting Geth in ephemeral dev mode...")
log.Warn(`You are running Geth in --dev mode. Please note the following:
@ -316,6 +322,8 @@ func prepare(ctx *cli.Context) {
if !ctx.IsSet(utils.HoleskyFlag.Name) &&
!ctx.IsSet(utils.SepoliaFlag.Name) &&
!ctx.IsSet(utils.GoerliFlag.Name) &&
!ctx.IsSet(utils.ScrollAlphaFlag.Name) &&
!ctx.IsSet(utils.ScrollSepoliaFlag.Name) &&
!ctx.IsSet(utils.DeveloperFlag.Name) {
// Nope, we're really on mainnet. Bump that cache up!
log.Info("Bumping default cache on mainnet", "provided", ctx.Int(utils.CacheFlag.Name), "updated", 4096)

View file

@ -81,6 +81,11 @@ import (
"github.com/urfave/cli/v2"
)
const (
GCModeFull = "full"
GCModeArchive = "archive"
)
// These are all the command line flags we support.
// If you add to this list, please remember to include the
// flag in the appropriate command definition.
@ -159,6 +164,21 @@ var (
Usage: "Holesky network: pre-configured proof-of-stake test network",
Category: flags.EthCategory,
}
ScrollFlag = &cli.BoolFlag{
Name: "scroll",
Usage: "Scroll mainnet",
Category: flags.EthCategory,
}
ScrollAlphaFlag = &cli.BoolFlag{
Name: "scroll-alpha",
Usage: "Scroll Alpha test network",
Category: flags.EthCategory,
}
ScrollSepoliaFlag = &cli.BoolFlag{
Name: "scroll-sepolia",
Usage: "Scroll Sepolia test network",
Category: flags.EthCategory,
}
// Dev mode
DeveloperFlag = &cli.BoolFlag{
Name: "dev",
@ -265,7 +285,7 @@ var (
GCModeFlag = &cli.StringFlag{
Name: "gcmode",
Usage: `Blockchain garbage collection mode, only relevant in state.scheme=hash ("full", "archive")`,
Value: "full",
Value: GCModeArchive,
Category: flags.StateCategory,
}
StateSchemeFlag = &cli.StringFlag{
@ -991,9 +1011,11 @@ var (
GoerliFlag,
SepoliaFlag,
HoleskyFlag,
ScrollAlphaFlag,
ScrollSepoliaFlag,
}
// NetworkFlags is the flag group of all built-in supported networks.
NetworkFlags = append([]cli.Flag{MainnetFlag}, TestnetFlags...)
NetworkFlags = append([]cli.Flag{MainnetFlag, ScrollFlag}, TestnetFlags...)
// DatabaseFlags is the flag group of all database flags.
DatabaseFlags = []cli.Flag{
@ -1020,6 +1042,15 @@ func MakeDataDir(ctx *cli.Context) string {
if ctx.Bool(HoleskyFlag.Name) {
return filepath.Join(path, "holesky")
}
if ctx.Bool(ScrollAlphaFlag.Name) {
return filepath.Join(path, "scroll-alpha")
}
if ctx.Bool(ScrollSepoliaFlag.Name) {
return filepath.Join(path, "scroll-sepolia")
}
if ctx.Bool(ScrollFlag.Name) {
return filepath.Join(path, "scroll")
}
return path
}
Fatalf("Cannot determine default data directory, please set manually (--datadir)")
@ -1082,6 +1113,12 @@ func setBootstrapNodes(ctx *cli.Context, cfg *p2p.Config) {
urls = params.SepoliaBootnodes
case ctx.Bool(GoerliFlag.Name):
urls = params.GoerliBootnodes
case ctx.Bool(ScrollAlphaFlag.Name):
urls = params.ScrollAlphaBootnodes
case ctx.Bool(ScrollSepoliaFlag.Name):
urls = params.ScrollSepoliaBootnodes
case ctx.Bool(ScrollFlag.Name):
urls = params.ScrollMainnetBootnodes
}
}
cfg.BootstrapNodes = mustParseBootnodes(urls)
@ -1569,6 +1606,12 @@ func SetDataDir(ctx *cli.Context, cfg *node.Config) {
cfg.DataDir = filepath.Join(node.DefaultDataDir(), "sepolia")
case ctx.Bool(HoleskyFlag.Name) && cfg.DataDir == node.DefaultDataDir():
cfg.DataDir = filepath.Join(node.DefaultDataDir(), "holesky")
case ctx.Bool(ScrollAlphaFlag.Name) && cfg.DataDir == node.DefaultDataDir():
cfg.DataDir = filepath.Join(node.DefaultDataDir(), "scroll-alpha")
case ctx.Bool(ScrollSepoliaFlag.Name) && cfg.DataDir == node.DefaultDataDir():
cfg.DataDir = filepath.Join(node.DefaultDataDir(), "scroll-sepolia")
case ctx.Bool(ScrollFlag.Name) && cfg.DataDir == node.DefaultDataDir():
cfg.DataDir = filepath.Join(node.DefaultDataDir(), "scroll")
}
}
@ -1748,7 +1791,7 @@ func CheckExclusive(ctx *cli.Context, args ...interface{}) {
// SetEthConfig applies eth-related command line flags to the config.
func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
// Avoid conflicting network flags
CheckExclusive(ctx, MainnetFlag, DeveloperFlag, GoerliFlag, SepoliaFlag, HoleskyFlag)
CheckExclusive(ctx, MainnetFlag, DeveloperFlag, GoerliFlag, SepoliaFlag, HoleskyFlag, ScrollAlphaFlag, ScrollSepoliaFlag, ScrollFlag)
CheckExclusive(ctx, LightServeFlag, SyncModeFlag, "light")
CheckExclusive(ctx, DeveloperFlag, ExternalSignerFlag) // Can't use both ephemeral unlocked and external signer
@ -1799,11 +1842,11 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
cfg.DatabaseFreezer = ctx.String(AncientFlag.Name)
}
if gcmode := ctx.String(GCModeFlag.Name); gcmode != "full" && gcmode != "archive" {
if gcmode := ctx.String(GCModeFlag.Name); gcmode != GCModeFull && gcmode != GCModeArchive {
Fatalf("--%s must be either 'full' or 'archive'", GCModeFlag.Name)
}
if ctx.IsSet(GCModeFlag.Name) {
cfg.NoPruning = ctx.String(GCModeFlag.Name) == "archive"
cfg.NoPruning = ctx.String(GCModeFlag.Name) == GCModeArchive
}
if ctx.IsSet(CacheNoPrefetchFlag.Name) {
cfg.NoPrefetch = ctx.Bool(CacheNoPrefetchFlag.Name)
@ -1832,7 +1875,7 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
log.Warn("The flag --txlookuplimit is deprecated and will be removed, please use --history.transactions")
cfg.TransactionHistory = ctx.Uint64(TxLookupLimitFlag.Name)
}
if ctx.String(GCModeFlag.Name) == "archive" && cfg.TransactionHistory != 0 {
if ctx.String(GCModeFlag.Name) == GCModeArchive && cfg.TransactionHistory != 0 {
cfg.TransactionHistory = 0
log.Warn("Disabled transaction unindexing for archive node")
}
@ -1918,6 +1961,50 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
}
cfg.Genesis = core.DefaultGoerliGenesisBlock()
SetDNSDiscoveryDefaults(cfg, params.GoerliGenesisHash)
case ctx.Bool(ScrollAlphaFlag.Name):
if !ctx.IsSet(NetworkIdFlag.Name) {
cfg.NetworkId = 534353
}
cfg.Genesis = core.DefaultScrollAlphaGenesisBlock()
// SetDNSDiscoveryDefaults(cfg, params.ScrollAlphaGenesisHash)
case ctx.Bool(ScrollSepoliaFlag.Name):
if !ctx.IsSet(NetworkIdFlag.Name) {
cfg.NetworkId = 534351
}
cfg.Genesis = core.DefaultScrollSepoliaGenesisBlock()
// forced for sepolia
log.Info("Setting flag", "--l1.confirmations", "finalized")
stack.Config().L1Confirmations = rpc.FinalizedBlockNumber
log.Info("Setting flag", "--l1.sync.startblock", "4038000")
stack.Config().L1DeploymentBlock = 4038000
// disable pruning
if ctx.String(GCModeFlag.Name) != GCModeArchive {
log.Crit("Must use --gcmode=archive")
}
log.Info("Pruning disabled")
cfg.NoPruning = true
// disable prefetch
log.Info("Prefetch disabled")
cfg.NoPrefetch = true
case ctx.Bool(ScrollFlag.Name):
if !ctx.IsSet(NetworkIdFlag.Name) {
cfg.NetworkId = 534352
}
cfg.Genesis = core.DefaultScrollMainnetGenesisBlock()
// forced for mainnet
log.Info("Setting flag", "--l1.confirmations", "finalized")
stack.Config().L1Confirmations = rpc.FinalizedBlockNumber
log.Info("Setting flag", "--l1.sync.startblock", "18306000")
stack.Config().L1DeploymentBlock = 18306000
// disable pruning
if ctx.String(GCModeFlag.Name) != GCModeArchive {
log.Crit("Must use --gcmode=archive")
}
log.Info("Pruning disabled")
cfg.NoPruning = true
// disable prefetch
log.Info("Prefetch disabled")
cfg.NoPrefetch = true
case ctx.Bool(DeveloperFlag.Name):
if !ctx.IsSet(NetworkIdFlag.Name) {
cfg.NetworkId = 1337
@ -2256,6 +2343,12 @@ func MakeGenesis(ctx *cli.Context) *core.Genesis {
genesis = core.DefaultSepoliaGenesisBlock()
case ctx.Bool(GoerliFlag.Name):
genesis = core.DefaultGoerliGenesisBlock()
case ctx.Bool(ScrollAlphaFlag.Name):
genesis = core.DefaultScrollAlphaGenesisBlock()
case ctx.Bool(ScrollSepoliaFlag.Name):
genesis = core.DefaultScrollSepoliaGenesisBlock()
case ctx.Bool(ScrollFlag.Name):
genesis = core.DefaultScrollMainnetGenesisBlock()
case ctx.Bool(DeveloperFlag.Name):
Fatalf("Developer chains are ephemeral")
}
@ -2276,7 +2369,7 @@ func MakeChain(ctx *cli.Context, stack *node.Node, readonly bool) (*core.BlockCh
if err != nil {
Fatalf("%v", err)
}
if gcmode := ctx.String(GCModeFlag.Name); gcmode != "full" && gcmode != "archive" {
if gcmode := ctx.String(GCModeFlag.Name); gcmode != GCModeFull && gcmode != GCModeArchive {
Fatalf("--%s must be either 'full' or 'archive'", GCModeFlag.Name)
}
scheme, err := rawdb.ParseStateScheme(ctx.String(StateSchemeFlag.Name), chainDb)
@ -2287,7 +2380,7 @@ func MakeChain(ctx *cli.Context, stack *node.Node, readonly bool) (*core.BlockCh
TrieCleanLimit: ethconfig.Defaults.TrieCleanCache,
TrieCleanNoPrefetch: ctx.Bool(CacheNoPrefetchFlag.Name),
TrieDirtyLimit: ethconfig.Defaults.TrieDirtyCache,
TrieDirtyDisabled: ctx.String(GCModeFlag.Name) == "archive",
TrieDirtyDisabled: ctx.String(GCModeFlag.Name) == GCModeArchive,
TrieTimeLimit: ethconfig.Defaults.TrieTimeout,
SnapshotLimit: ethconfig.Defaults.SnapshotCache,
Preimages: ctx.Bool(CachePreimagesFlag.Name),

View file

@ -299,9 +299,9 @@ func (c *Clique) verifyHeader(chain consensus.ChainHeaderReader, header *types.H
if header.GasLimit > params.MaxGasLimit {
return fmt.Errorf("invalid gasLimit: have %v, max %v", header.GasLimit, params.MaxGasLimit)
}
if chain.Config().IsShanghai(header.Number, header.Time) {
return errors.New("clique does not support shanghai fork")
}
// if chain.Config().IsShanghai(header.Number, header.Time) {
// return errors.New("clique does not support shanghai fork")
// }
if chain.Config().IsCancun(header.Number, header.Time) {
return errors.New("clique does not support cancun fork")
}

View file

@ -263,9 +263,9 @@ func (ethash *Ethash) verifyHeader(chain consensus.ChainHeaderReader, header, pa
if diff := new(big.Int).Sub(header.Number, parent.Number); diff.Cmp(big.NewInt(1)) != 0 {
return consensus.ErrInvalidNumber
}
if chain.Config().IsShanghai(header.Number, header.Time) {
return errors.New("ethash does not support shanghai fork")
}
// if chain.Config().IsShanghai(header.Number, header.Time) {
// return errors.New("ethash does not support shanghai fork")
// }
if chain.Config().IsCancun(header.Number, header.Time) {
return errors.New("ethash does not support cancun fork")
}

View file

@ -581,6 +581,42 @@ func DefaultHoleskyGenesisBlock() *Genesis {
}
}
// DefaultScrollAlphaGenesisBlock returns the Scroll Alpha network genesis block.
func DefaultScrollAlphaGenesisBlock() *Genesis {
return &Genesis{
Config: params.ScrollAlphaChainConfig,
Timestamp: 0x63f67207,
ExtraData: hexutil.MustDecode("0x0000000000000000000000000000000000000000000000000000000000000000b7C0c58702D0781C0e2eB3aaE301E4c340073448Ec9c139eFCBBe6323DA406fffBF4Db02a60A9720589c71deC4302fE718bE62350c174922782Cc6600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
GasLimit: 8000000,
Difficulty: big.NewInt(1),
Alloc: decodePrealloc(scrollAlphaAllocData),
}
}
// DefaultScrollSepoliaGenesisBlock returns the Scroll Sepolia network genesis block.
func DefaultScrollSepoliaGenesisBlock() *Genesis {
return &Genesis{
Config: params.ScrollSepoliaChainConfig,
Timestamp: 0x64cfd015,
ExtraData: hexutil.MustDecode("0x000000000000000000000000000000000000000000000000000000000000000048C3F81f3D998b6652900e1C3183736C238Fe4290000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
GasLimit: 8000000,
Difficulty: big.NewInt(1),
Alloc: decodePrealloc(scrollSepoliaAllocData),
}
}
// DefaultScrollMainnetGenesisBlock returns the Scroll mainnet genesis block.
func DefaultScrollMainnetGenesisBlock() *Genesis {
return &Genesis{
Config: params.ScrollMainnetChainConfig,
Timestamp: 0x6524e860,
ExtraData: hexutil.MustDecode("0x4c61206573746f6e7465636f206573746173206d616c6665726d6974612e0000d2ACF5d16a983DB0d909d9D761B8337Fabd6cBd10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
GasLimit: 10000000,
Difficulty: big.NewInt(1),
Alloc: decodePrealloc(scrollMainnetAllocData),
}
}
// DeveloperGenesisBlock returns the 'geth --dev' genesis block.
func DeveloperGenesisBlock(gasLimit uint64, faucet common.Address) *Genesis {
// Override the default period to the user requested one
@ -602,12 +638,46 @@ func DeveloperGenesisBlock(gasLimit uint64, faucet common.Address) *Genesis {
common.BytesToAddress([]byte{7}): {Balance: big.NewInt(1)}, // ECScalarMul
common.BytesToAddress([]byte{8}): {Balance: big.NewInt(1)}, // ECPairing
common.BytesToAddress([]byte{9}): {Balance: big.NewInt(1)}, // BLAKE2b
faucet: {Balance: new(big.Int).Sub(new(big.Int).Lsh(big.NewInt(1), 256), big.NewInt(9))},
// faucet: {Balance: new(big.Int).Sub(new(big.Int).Lsh(big.NewInt(1), 256), big.NewInt(9))},
faucet: {Balance: new(big.Int).Sub(new(big.Int).Lsh(big.NewInt(1), 250), big.NewInt(9))}, // LSH 250 due to finite field limitation
},
}
}
// decodePrealloc does not support code and storage in prealloc config,
// so we provide an alternative implementation here.
func decodePreallocScroll(data string) (GenesisAlloc, error) {
var p []struct {
Addr, Balance *big.Int
Code []byte
Storage []struct{ Key, Value *big.Int }
}
if err := rlp.NewStream(strings.NewReader(data), 0).Decode(&p); err != nil {
return nil, err
}
ga := make(GenesisAlloc, len(p))
for _, account := range p {
s := make(map[common.Hash]common.Hash)
for _, entry := range account.Storage {
s[common.BigToHash(entry.Key)] = common.BigToHash(entry.Value)
}
ga[common.BigToAddress(account.Addr)] = GenesisAccount{
Balance: account.Balance,
Code: account.Code,
Storage: s,
}
}
return ga, nil
}
func decodePrealloc(data string) GenesisAlloc {
if ga, err := decodePreallocScroll(data); err == nil {
return ga
}
var p []struct {
Addr *big.Int
Balance *big.Int

File diff suppressed because one or more lines are too long

View file

@ -184,10 +184,17 @@ func TestGenesisHashes(t *testing.T) {
// {DefaultGenesisBlock(), params.MainnetGenesisHash},
// {DefaultGoerliGenesisBlock(), params.GoerliGenesisHash},
// {DefaultSepoliaGenesisBlock(), params.SepoliaGenesisHash},
// {DefaultScrollAlphaGenesisBlock(), params.ScrollAlphaGenesisHash},
{DefaultScrollSepoliaGenesisBlock(), params.ScrollSepoliaGenesisHash},
{DefaultScrollMainnetGenesisBlock(), params.ScrollMainnetGenesisHash},
} {
// Test via MustCommit
db := rawdb.NewMemoryDatabase()
if have := c.genesis.MustCommit(db, trie.NewDatabase(db, trie.HashDefaults)).Hash(); have != c.want {
trieConfig := trie.HashDefaults
if c.genesis.Config.Scroll.ZktrieEnabled() {
trieConfig = trie.HashDefaultsWithZktrie
}
if have := c.genesis.MustCommit(db, trie.NewDatabase(db, trieConfig)).Hash(); have != c.want {
t.Errorf("case: %d a), want: %s, got: %s", i, c.want.Hex(), have.Hex())
}
// Test via ToBlock

View file

@ -58,7 +58,7 @@ var LightClientGPO = gasprice.Config{
// Defaults contains default settings for use on the Ethereum main net.
var Defaults = Config{
SyncMode: downloader.SnapSync,
SyncMode: downloader.FullSync,
NetworkId: 1,
TxLookupLimit: 2350000,
TransactionHistory: 2350000,

View file

@ -133,6 +133,17 @@ func newTestBackend(t *testing.T, londonBlock *big.Int, pending bool) *testBacke
config.LondonBlock = londonBlock
config.ArrowGlacierBlock = londonBlock
config.GrayGlacierBlock = londonBlock
config.ArchimedesBlock = londonBlock
config.BernoulliBlock = londonBlock
config.CurieBlock = londonBlock
config.DescartesBlock = londonBlock
config.ShanghaiTime = nil
if londonBlock != nil {
shanghaiTime := londonBlock.Uint64() * 12
config.ShanghaiTime = &shanghaiTime
}
config.TerminalTotalDifficulty = common.Big0
engine := ethash.NewFaker()

View file

@ -64,6 +64,29 @@ var GoerliBootnodes = []string{
"enode://d2b720352e8216c9efc470091aa91ddafc53e222b32780f505c817ceef69e01d5b0b0797b69db254c586f493872352f5a022b4d8479a00fc92ec55f9ad46a27e@88.99.70.182:30303",
}
// ScrollAlphaBootnodes are the enode URLs of the P2P bootstrap nodes running on the Scroll Alpha test network.
var ScrollAlphaBootnodes = []string{
"enode://996a655365e731321ca35636f5a62fdf37c0b75dc56a8832c472d077da5af47effe45874196268f6083b8f65e1a9589ed25015f68f47598c7bcc93ac8ea29e8a@35.85.116.190:30303",
"enode://a4e90d8108bbcd8b13066567c786f800812a9b6b3eeb92947e64edd19ac9231bf371da1a86796af2ccd7b7e781218ebbe2d04130d63f7b3f25d6372a706fc022@44.224.134.190:30303",
"enode://cf85bfa5828239b1f6b21758579ee8aaaba2a1fb4c658d6967c5f7ed4f040d95dee5b5cef0c77d656a191f6b0875dd03f05b30a3b2b3e15bfcf18b500d8f634c@35.155.117.77:30303",
}
// ScrollSepoliaBootnodes are the enode URLs of the P2P bootstrap nodes running on the Scroll Sepolia test network.
var ScrollSepoliaBootnodes = []string{
"enode://ceb1636bac5cbb262e5ad5b2cd22014bdb35ffe7f58b3506970d337a63099481814a338dbcd15f2d28757151e3ecd40ba38b41350b793cd0d910ff0436654f8c@35.85.84.250:30303",
"enode://29cee709c400533ae038a875b9ca975c8abef9eade956dcf3585e940acd5c0ae916968f514bd37d1278775aad1b7db30f7032a70202a87fd7365bd8de3c9f5fc@44.242.39.33:30303",
"enode://dd1ac5433c5c2b04ca3166f4cb726f8ff6d2da83dbc16d9b68b1ea83b7079b371eb16ef41c00441b6e85e32e33087f3b7753ea9e8b1e3f26d3e4df9208625e7f@54.148.111.168:30303",
}
// ScrollMainnetBootnodes are the enode URLs of the P2P bootstrap nodes running on the Scroll mainnet.
var ScrollMainnetBootnodes = []string{
"enode://c6ac91f43df3d63916ac1ae411cdd5ba249d55d48a7bec7f8cd5bb351a31aba437e5a69e8a1de74d73fdfeba8af1cfe9caf9846ecd3abf60d1ffdf4925b55b23@54.186.123.248:30303",
"enode://fdcc807b5d1353f3a1e98b90208ce6ef1b7d446136e51eaa8ad657b55518a2f8b37655e42375d61622e6ea18f3faf9d070c9bbdf012cf5484bcbad33b7a15fb1@44.227.91.206:30303",
"enode://6beb5a3efbb39be73d17630b6da48e94c0ce7ec665172111463cb470197b20c12faa1fa6f835b81c28571277d1017e65c4e426cc92a46141cf69118ecf28ac03@44.237.194.52:30303",
"enode://7cf893d444eb8e129dca0f6485b3df579911606e7c728be4fa55fcc5f155a37c3ce07d217ccec5447798bde465ac2bdba2cb8763d107e9f3257e787579e9f27e@52.35.203.107:30303",
"enode://c7b2d94e95da343db6e667a01cef90376a592f2d277fbcbf6e9c9186734ed8003d01389571bd10cdbab7a6e5adfa6f0c7b55644d0db24e0b9deb4ec80f842075@54.70.236.187:30303",
}
var V5Bootnodes = []string{
// Teku team's bootnode
"enr:-KG4QOtcP9X1FbIMOe17QNMKqDxCpm14jcX5tiOE4_TyMrFqbmhPZHK_ZPG2Gxb1GE2xdtodOfx9-cgvNtxnRyHEmC0ghGV0aDKQ9aX9QgAAAAD__________4JpZIJ2NIJpcIQDE8KdiXNlY3AyNTZrMaEDhpehBDbZjM_L9ek699Y7vhUJ-eAdMyQW_Fil522Y0fODdGNwgiMog3VkcIIjKA",

View file

@ -21,6 +21,7 @@ import (
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/rollup/rcfg"
)
// Genesis hashes to enforce below configs on.
@ -29,6 +30,10 @@ var (
HoleskyGenesisHash = common.HexToHash("0xb5f7f912443c940f21fd611f12828d75b534364ed9e95ca4e307729a4661bde4")
SepoliaGenesisHash = common.HexToHash("0x25a5cc106eea7138acab33231d7160d69cb777ee0c2c553fcddf5138993e6dd9")
GoerliGenesisHash = common.HexToHash("0xbf7e331f7f7c1dd2e05159666b3bf8bc7a8a3a9eb1d518969eab529dd9b88c1a")
ScrollAlphaGenesisHash = common.HexToHash("0xa4fc62b9b0643e345bdcebe457b3ae898bef59c7203c3db269200055e037afda")
ScrollSepoliaGenesisHash = common.HexToHash("0xaa62d1a8b2bffa9e5d2368b63aae0d98d54928bd713125e3fd9e5c896c68592c")
ScrollMainnetGenesisHash = common.HexToHash("0xbbc05efd412b7cd47a2ed0e5ddfcf87af251e414ea4c801d78b6784513180a80")
)
func newUint64(val uint64) *uint64 { return &val }
@ -152,7 +157,7 @@ var (
ArrowGlacierBlock: big.NewInt(0),
GrayGlacierBlock: big.NewInt(0),
MergeNetsplitBlock: nil,
ShanghaiTime: nil,
ShanghaiTime: newUint64(0),
CancunTime: nil,
PragueTime: nil,
VerkleTime: nil,
@ -160,6 +165,138 @@ var (
TerminalTotalDifficultyPassed: true,
Ethash: new(EthashConfig),
Clique: nil,
ArchimedesBlock: big.NewInt(0),
BernoulliBlock: big.NewInt(0),
CurieBlock: big.NewInt(0),
DescartesBlock: big.NewInt(0),
Scroll: ScrollConfig{
UseZktrie: false,
FeeVaultAddress: nil,
MaxTxPerBlock: nil,
MaxTxPayloadBytesPerBlock: nil,
L1Config: &L1Config{
L1ChainId: 5,
L1MessageQueueAddress: common.HexToAddress("0x0000000000000000000000000000000000000000"),
NumL1MessagesPerBlock: 0,
ScrollChainAddress: common.HexToAddress("0x0000000000000000000000000000000000000000"),
},
},
}
// ScrollAlphaChainConfig contains the chain parameters to run a node on the Scroll Alpha test network.
ScrollAlphaChainConfig = &ChainConfig{
ChainID: big.NewInt(534353),
HomesteadBlock: big.NewInt(0),
DAOForkBlock: nil,
DAOForkSupport: true,
EIP150Block: big.NewInt(0),
EIP155Block: big.NewInt(0),
EIP158Block: big.NewInt(0),
ByzantiumBlock: big.NewInt(0),
ConstantinopleBlock: big.NewInt(0),
PetersburgBlock: big.NewInt(0),
IstanbulBlock: big.NewInt(0),
MuirGlacierBlock: nil,
BerlinBlock: big.NewInt(0),
LondonBlock: big.NewInt(0),
ArrowGlacierBlock: nil,
ShanghaiTime: nil,
ArchimedesBlock: big.NewInt(2646311),
BernoulliBlock: nil,
CurieBlock: nil,
DescartesBlock: nil,
Clique: &CliqueConfig{
Period: 3,
Epoch: 30000,
},
Scroll: ScrollConfig{
UseZktrie: true,
MaxTxPerBlock: &rcfg.ScrollMaxTxPerBlock,
MaxTxPayloadBytesPerBlock: &rcfg.ScrollMaxTxPayloadBytesPerBlock,
FeeVaultAddress: &rcfg.ScrollFeeVaultAddress,
L1Config: &L1Config{
L1ChainId: 5,
L1MessageQueueAddress: common.HexToAddress("0x79DB48002Aa861C8cb189cabc21c6B1468BC83BB"),
NumL1MessagesPerBlock: 0,
ScrollChainAddress: common.HexToAddress("0x3C584eC7f0f2764CC715ac3180Ae9828465E9833"),
},
},
}
ScrollSepoliaChainConfig = &ChainConfig{
ChainID: big.NewInt(534351),
HomesteadBlock: big.NewInt(0),
DAOForkBlock: nil,
DAOForkSupport: true,
EIP150Block: big.NewInt(0),
EIP155Block: big.NewInt(0),
EIP158Block: big.NewInt(0),
ByzantiumBlock: big.NewInt(0),
ConstantinopleBlock: big.NewInt(0),
PetersburgBlock: big.NewInt(0),
IstanbulBlock: big.NewInt(0),
MuirGlacierBlock: nil,
BerlinBlock: big.NewInt(0),
LondonBlock: big.NewInt(0),
ArrowGlacierBlock: nil,
ShanghaiTime: newUint64(0),
ArchimedesBlock: big.NewInt(0),
BernoulliBlock: big.NewInt(3747132),
CurieBlock: nil,
DescartesBlock: nil,
Clique: &CliqueConfig{
Period: 3,
Epoch: 30000,
},
Scroll: ScrollConfig{
UseZktrie: true,
MaxTxPerBlock: &rcfg.ScrollMaxTxPerBlock,
MaxTxPayloadBytesPerBlock: &rcfg.ScrollMaxTxPayloadBytesPerBlock,
FeeVaultAddress: &rcfg.ScrollFeeVaultAddress,
L1Config: &L1Config{
L1ChainId: 11155111,
L1MessageQueueAddress: common.HexToAddress("0xF0B2293F5D834eAe920c6974D50957A1732de763"),
NumL1MessagesPerBlock: 10,
ScrollChainAddress: common.HexToAddress("0x2D567EcE699Eabe5afCd141eDB7A4f2D0D6ce8a0"),
},
},
}
ScrollMainnetChainConfig = &ChainConfig{
ChainID: big.NewInt(534352),
HomesteadBlock: big.NewInt(0),
DAOForkBlock: nil,
DAOForkSupport: true,
EIP150Block: big.NewInt(0),
EIP155Block: big.NewInt(0),
EIP158Block: big.NewInt(0),
ByzantiumBlock: big.NewInt(0),
ConstantinopleBlock: big.NewInt(0),
PetersburgBlock: big.NewInt(0),
IstanbulBlock: big.NewInt(0),
MuirGlacierBlock: nil,
BerlinBlock: big.NewInt(0),
LondonBlock: big.NewInt(0),
ArrowGlacierBlock: nil,
ShanghaiTime: newUint64(0),
ArchimedesBlock: big.NewInt(0),
BernoulliBlock: big.NewInt(5220340),
CurieBlock: nil,
DescartesBlock: nil,
Clique: &CliqueConfig{
Period: 3,
Epoch: 30000,
},
Scroll: ScrollConfig{
UseZktrie: true,
MaxTxPerBlock: &rcfg.ScrollMaxTxPerBlock,
MaxTxPayloadBytesPerBlock: &rcfg.ScrollMaxTxPayloadBytesPerBlock,
FeeVaultAddress: &rcfg.ScrollFeeVaultAddress,
L1Config: &L1Config{
L1ChainId: 1,
L1MessageQueueAddress: common.HexToAddress("0x0d7E906BD9cAFa154b048cFa766Cc1E54E39AF9B"),
NumL1MessagesPerBlock: 10,
ScrollChainAddress: common.HexToAddress("0xa13BAF47339d63B743e7Da8741db5456DAc1E556"),
},
},
}
AllDevChainProtocolChanges = &ChainConfig{
@ -203,7 +340,7 @@ var (
ArrowGlacierBlock: nil,
GrayGlacierBlock: nil,
MergeNetsplitBlock: nil,
ShanghaiTime: nil,
ShanghaiTime: newUint64(0),
CancunTime: nil,
PragueTime: nil,
VerkleTime: nil,
@ -211,6 +348,22 @@ var (
TerminalTotalDifficultyPassed: false,
Ethash: nil,
Clique: &CliqueConfig{Period: 0, Epoch: 30000},
ArchimedesBlock: big.NewInt(0),
BernoulliBlock: big.NewInt(0),
CurieBlock: big.NewInt(0),
DescartesBlock: big.NewInt(0),
Scroll: ScrollConfig{
UseZktrie: false,
FeeVaultAddress: nil,
MaxTxPerBlock: nil,
MaxTxPayloadBytesPerBlock: nil,
L1Config: &L1Config{
L1ChainId: 5,
L1MessageQueueAddress: common.HexToAddress("0x0000000000000000000000000000000000000000"),
NumL1MessagesPerBlock: 0,
ScrollChainAddress: common.HexToAddress("0x0000000000000000000000000000000000000000"),
},
},
}
// TestChainConfig contains every protocol change (EIPs) introduced
@ -233,7 +386,7 @@ var (
ArrowGlacierBlock: big.NewInt(0),
GrayGlacierBlock: big.NewInt(0),
MergeNetsplitBlock: nil,
ShanghaiTime: nil,
ShanghaiTime: newUint64(0),
CancunTime: nil,
PragueTime: nil,
VerkleTime: nil,
@ -241,6 +394,66 @@ var (
TerminalTotalDifficultyPassed: false,
Ethash: new(EthashConfig),
Clique: nil,
ArchimedesBlock: big.NewInt(0),
BernoulliBlock: big.NewInt(0),
CurieBlock: big.NewInt(0),
DescartesBlock: big.NewInt(0),
Scroll: ScrollConfig{
UseZktrie: false,
FeeVaultAddress: &common.Address{123},
MaxTxPerBlock: nil,
MaxTxPayloadBytesPerBlock: nil,
L1Config: &L1Config{
L1ChainId: 5,
L1MessageQueueAddress: common.HexToAddress("0x0000000000000000000000000000000000000000"),
NumL1MessagesPerBlock: 0,
ScrollChainAddress: common.HexToAddress("0x0000000000000000000000000000000000000000"),
},
},
}
TestNoL1DataFeeChainConfig = &ChainConfig{
ChainID: big.NewInt(1),
HomesteadBlock: big.NewInt(0),
DAOForkBlock: nil,
DAOForkSupport: false,
EIP150Block: big.NewInt(0),
EIP155Block: big.NewInt(0),
EIP158Block: big.NewInt(0),
ByzantiumBlock: big.NewInt(0),
ConstantinopleBlock: big.NewInt(0),
PetersburgBlock: big.NewInt(0),
IstanbulBlock: big.NewInt(0),
MuirGlacierBlock: big.NewInt(0),
BerlinBlock: big.NewInt(0),
LondonBlock: big.NewInt(0),
ArrowGlacierBlock: big.NewInt(0),
GrayGlacierBlock: big.NewInt(0),
MergeNetsplitBlock: nil,
ShanghaiTime: newUint64(0),
CancunTime: nil,
PragueTime: nil,
VerkleTime: nil,
TerminalTotalDifficulty: nil,
TerminalTotalDifficultyPassed: false,
Ethash: new(EthashConfig),
Clique: nil,
ArchimedesBlock: big.NewInt(0),
BernoulliBlock: big.NewInt(0),
CurieBlock: big.NewInt(0),
DescartesBlock: big.NewInt(0),
Scroll: ScrollConfig{
UseZktrie: false,
FeeVaultAddress: nil,
MaxTxPerBlock: nil,
MaxTxPayloadBytesPerBlock: nil,
L1Config: &L1Config{
L1ChainId: 5,
L1MessageQueueAddress: common.HexToAddress("0x0000000000000000000000000000000000000000"),
NumL1MessagesPerBlock: 0,
ScrollChainAddress: common.HexToAddress("0x0000000000000000000000000000000000000000"),
},
},
}
// NonActivatedConfig defines the chain configuration without activating
@ -281,6 +494,10 @@ var NetworkNames = map[string]string{
GoerliChainConfig.ChainID.String(): "goerli",
SepoliaChainConfig.ChainID.String(): "sepolia",
HoleskyChainConfig.ChainID.String(): "holesky",
ScrollAlphaChainConfig.ChainID.String(): "scroll-alpha",
ScrollSepoliaChainConfig.ChainID.String(): "scroll-sepolia",
ScrollMainnetChainConfig.ChainID.String(): "scroll",
}
// ChainConfig is the core config which determines the blockchain settings.
@ -309,10 +526,14 @@ type ChainConfig struct {
BerlinBlock *big.Int `json:"berlinBlock,omitempty"` // Berlin switch block (nil = no fork, 0 = already on berlin)
LondonBlock *big.Int `json:"londonBlock,omitempty"` // London switch block (nil = no fork, 0 = already on london)
ArrowGlacierBlock *big.Int `json:"arrowGlacierBlock,omitempty"` // Eip-4345 (bomb delay) switch block (nil = no fork, 0 = already activated)
ArchimedesBlock *big.Int `json:"archimedesBlock,omitempty"` // Archimedes switch block (nil = no fork, 0 = already on archimedes)
GrayGlacierBlock *big.Int `json:"grayGlacierBlock,omitempty"` // Eip-5133 (bomb delay) switch block (nil = no fork, 0 = already activated)
MergeNetsplitBlock *big.Int `json:"mergeNetsplitBlock,omitempty"` // Virtual fork after The Merge to use as a network splitter
ArchimedesBlock *big.Int `json:"archimedesBlock,omitempty"` // Archimedes switch block (nil = no fork, 0 = already on archimedes)
BernoulliBlock *big.Int `json:"bernoulliBlock,omitempty"` // Bernoulli switch block (nil = no fork, 0 = already on bernoulli)
CurieBlock *big.Int `json:"curieBlock,omitempty"` // Curie switch block (nil = no fork, 0 = already on curie)
DescartesBlock *big.Int `json:"descartesBlock,omitempty"` // Descartes switch block (nil = no fork, 0 = already on descartes)
// Fork scheduling was switched from blocks to timestamps here
ShanghaiTime *uint64 `json:"shanghaiTime,omitempty"` // Shanghai switch time (nil = no fork, 0 = already on shanghai)
@ -395,6 +616,21 @@ func (s ScrollConfig) IsValidBlockSize(size uint64) bool {
return s.MaxTxPayloadBytesPerBlock == nil || size <= uint64(*s.MaxTxPayloadBytesPerBlock)
}
func (s ScrollConfig) String() string {
maxTxPerBlock := "<nil>"
if s.MaxTxPerBlock != nil {
maxTxPerBlock = fmt.Sprintf("%v", *s.MaxTxPerBlock)
}
maxTxPayloadBytesPerBlock := "<nil>"
if s.MaxTxPayloadBytesPerBlock != nil {
maxTxPayloadBytesPerBlock = fmt.Sprintf("%v", *s.MaxTxPayloadBytesPerBlock)
}
return fmt.Sprintf("{useZktrie: %v, maxTxPerBlock: %v, MaxTxPayloadBytesPerBlock: %v, feeVaultAddress: %v, l1Config: %v}",
s.UseZktrie, maxTxPerBlock, maxTxPayloadBytesPerBlock, s.FeeVaultAddress, s.L1Config.String())
}
// EthashConfig is the consensus engine configs for proof-of-work based sealing.
type EthashConfig struct{}
@ -469,12 +705,21 @@ func (c *ChainConfig) Description() string {
if c.ArrowGlacierBlock != nil {
banner += fmt.Sprintf(" - Arrow Glacier: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/arrow-glacier.md)\n", c.ArrowGlacierBlock)
}
if c.ArchimedesBlock != nil {
banner += fmt.Sprintf(" - Archimedes: #%-8v\n", c.ArchimedesBlock) // TODO: add archimedes execution-specs
}
if c.GrayGlacierBlock != nil {
banner += fmt.Sprintf(" - Gray Glacier: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/gray-glacier.md)\n", c.GrayGlacierBlock)
}
if c.ArchimedesBlock != nil {
banner += fmt.Sprintf(" - Archimedes: #%-8v\n", c.ArchimedesBlock) // TODO: add Archimedes execution-specs
}
if c.BernoulliBlock != nil {
banner += fmt.Sprintf(" - Bernoulli: #%-8v\n", c.BernoulliBlock) // TODO: add Bernoulli execution-specs
}
if c.CurieBlock != nil {
banner += fmt.Sprintf(" - Curie: #%-8v\n", c.CurieBlock) // TODO: add Curie execution-specs
}
if c.DescartesBlock != nil {
banner += fmt.Sprintf(" - Descartes: #%-8v\n", c.DescartesBlock) // TODO: add Descartes execution-specs
}
banner += "\n"
// Add a special section for the merge as it's non-obvious
@ -506,6 +751,12 @@ func (c *ChainConfig) Description() string {
if c.VerkleTime != nil {
banner += fmt.Sprintf(" - Verkle: @%-10v\n", *c.VerkleTime)
}
banner += "\n"
banner += "Scroll Config:\n"
banner += c.Scroll.String()
banner += "\n"
return banner
}
@ -576,11 +827,6 @@ func (c *ChainConfig) IsArrowGlacier(num *big.Int) bool {
return isBlockForked(c.ArrowGlacierBlock, num)
}
// IsArchimedes returns whether num is either equal to the Archimedes fork block or greater.
func (c *ChainConfig) IsArchimedes(num *big.Int) bool {
return isBlockForked(c.ArchimedesBlock, num)
}
// IsGrayGlacier returns whether num is either equal to the Gray Glacier (EIP-5133) fork block or greater.
func (c *ChainConfig) IsGrayGlacier(num *big.Int) bool {
return isBlockForked(c.GrayGlacierBlock, num)
@ -614,6 +860,26 @@ func (c *ChainConfig) IsVerkle(num *big.Int, time uint64) bool {
return c.IsLondon(num) && isTimestampForked(c.VerkleTime, time)
}
// IsArchimedes returns whether num is either equal to the Archimedes fork block or greater.
func (c *ChainConfig) IsArchimedes(num *big.Int) bool {
return isBlockForked(c.ArchimedesBlock, num)
}
// IsBernoulli returns whether num is either equal to the Bernoulli fork block or greater.
func (c *ChainConfig) IsBernoulli(num *big.Int) bool {
return isBlockForked(c.BernoulliBlock, num)
}
// IsCurie returns whether num is either equal to the Curie fork block or greater.
func (c *ChainConfig) IsCurie(num *big.Int) bool {
return isBlockForked(c.CurieBlock, num)
}
// IsDescartes returns whether num is either equal to the Descartes fork block or greater.
func (c *ChainConfig) IsDescartes(num *big.Int) bool {
return isBlockForked(c.DescartesBlock, num)
}
// CheckCompatible checks whether scheduled fork transitions have been imported
// with a mismatching chain configuration.
func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64, time uint64) *ConfigCompatError {
@ -663,13 +929,17 @@ func (c *ChainConfig) CheckConfigForkOrder() error {
{name: "berlinBlock", block: c.BerlinBlock},
{name: "londonBlock", block: c.LondonBlock},
{name: "arrowGlacierBlock", block: c.ArrowGlacierBlock, optional: true},
{name: "archimedesBlock", block: c.ArchimedesBlock, optional: true},
{name: "grayGlacierBlock", block: c.GrayGlacierBlock, optional: true},
{name: "mergeNetsplitBlock", block: c.MergeNetsplitBlock, optional: true},
{name: "shanghaiTime", timestamp: c.ShanghaiTime},
// {name: "shanghaiTime", timestamp: c.ShanghaiTime},
{name: "cancunTime", timestamp: c.CancunTime, optional: true},
{name: "pragueTime", timestamp: c.PragueTime, optional: true},
{name: "verkleTime", timestamp: c.VerkleTime, optional: true},
{name: "archimedesBlock", block: c.ArchimedesBlock, optional: true},
{name: "bernoulliBlock", block: c.BernoulliBlock, optional: true},
{name: "shanghaiTime", timestamp: c.ShanghaiTime},
{name: "curieBlock", block: c.CurieBlock, optional: true},
{name: "descartesBlock", block: c.DescartesBlock, optional: true},
} {
if lastFork.name != "" {
switch {
@ -779,6 +1049,18 @@ func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, headNumber *big.Int,
if isForkTimestampIncompatible(c.VerkleTime, newcfg.VerkleTime, headTimestamp) {
return newTimestampCompatError("Verkle fork timestamp", c.VerkleTime, newcfg.VerkleTime)
}
if isForkBlockIncompatible(c.ArchimedesBlock, newcfg.ArchimedesBlock, headNumber) {
return newBlockCompatError("Archimedes fork block", c.ArchimedesBlock, newcfg.ArchimedesBlock)
}
if isForkBlockIncompatible(c.BernoulliBlock, newcfg.BernoulliBlock, headNumber) {
return newBlockCompatError("Bernoulli fork block", c.BernoulliBlock, newcfg.BernoulliBlock)
}
if isForkBlockIncompatible(c.CurieBlock, newcfg.CurieBlock, headNumber) {
return newBlockCompatError("Curie fork block", c.CurieBlock, newcfg.CurieBlock)
}
if isForkBlockIncompatible(c.DescartesBlock, newcfg.DescartesBlock, headNumber) {
return newBlockCompatError("Descartes fork block", c.DescartesBlock, newcfg.DescartesBlock)
}
return nil
}
@ -923,9 +1205,9 @@ type Rules struct {
IsHomestead, IsEIP150, IsEIP155, IsEIP158 bool
IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool
IsBerlin, IsLondon bool
IsArchimedes bool
IsMerge, IsShanghai, IsCancun, IsPrague bool
IsVerkle bool
IsArchimedes, IsBernoulli, IsCurie, IsDescartes bool
}
// Rules ensures c's ChainID is not nil.
@ -946,11 +1228,14 @@ func (c *ChainConfig) Rules(num *big.Int, isMerge bool, timestamp uint64) Rules
IsIstanbul: c.IsIstanbul(num),
IsBerlin: c.IsBerlin(num),
IsLondon: c.IsLondon(num),
IsArchimedes: c.IsArchimedes(num),
IsMerge: isMerge,
IsShanghai: c.IsShanghai(num, timestamp),
IsCancun: c.IsCancun(num, timestamp),
IsPrague: c.IsPrague(num, timestamp),
IsVerkle: c.IsVerkle(num, timestamp),
IsArchimedes: c.IsArchimedes(num),
IsBernoulli: c.IsBernoulli(num),
IsCurie: c.IsCurie(num),
IsDescartes: c.IsDescartes(num),
}
}