Skip to content

Commit 6b98d18

Browse files
authored
cmd, core, params: add support for the Holesky testnet (#28007)
* cmd, core, params: add support for the Holesky testnet * cmd/devp2p: add support for holesky for the dns crawler
1 parent 5e0eb62 commit 6b98d18

File tree

9 files changed

+139
-12
lines changed

9 files changed

+139
-12
lines changed

cmd/devp2p/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ set to standard output. The following filters are supported:
4444
- `-limit <N>` limits the output set to N entries, taking the top N nodes by score
4545
- `-ip <CIDR>` filters nodes by IP subnet
4646
- `-min-age <duration>` filters nodes by 'first seen' time
47-
- `-eth-network <mainnet/goerli/sepolia>` filters nodes by "eth" ENR entry
47+
- `-eth-network <mainnet/goerli/sepolia/holesky>` filters nodes by "eth" ENR entry
4848
- `-les-server` filters nodes by LES server support
4949
- `-snap` filters nodes by snap protocol support
5050

cmd/devp2p/nodesetcmd.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,8 @@ func ethFilter(args []string) (nodeFilter, error) {
233233
filter = forkid.NewStaticFilter(params.GoerliChainConfig, params.GoerliGenesisHash)
234234
case "sepolia":
235235
filter = forkid.NewStaticFilter(params.SepoliaChainConfig, params.SepoliaGenesisHash)
236+
case "holesky":
237+
filter = forkid.NewStaticFilter(params.HoleskyChainConfig, params.HoleskyGenesisHash)
236238
default:
237239
return nil, fmt.Errorf("unknown network %q", args[0])
238240
}

cmd/geth/main.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,9 @@ func prepare(ctx *cli.Context) {
275275
case ctx.IsSet(utils.SepoliaFlag.Name):
276276
log.Info("Starting Geth on Sepolia testnet...")
277277

278+
case ctx.IsSet(utils.HoleskyFlag.Name):
279+
log.Info("Starting Geth on Holesky testnet...")
280+
278281
case ctx.IsSet(utils.DeveloperFlag.Name):
279282
log.Info("Starting Geth in ephemeral dev mode...")
280283
log.Warn(`You are running Geth in --dev mode. Please note the following:
@@ -299,7 +302,8 @@ func prepare(ctx *cli.Context) {
299302
// If we're a full node on mainnet without --cache specified, bump default cache allowance
300303
if ctx.String(utils.SyncModeFlag.Name) != "light" && !ctx.IsSet(utils.CacheFlag.Name) && !ctx.IsSet(utils.NetworkIdFlag.Name) {
301304
// Make sure we're not on any supported preconfigured testnet either
302-
if !ctx.IsSet(utils.SepoliaFlag.Name) &&
305+
if !ctx.IsSet(utils.HoleskyFlag.Name) &&
306+
!ctx.IsSet(utils.SepoliaFlag.Name) &&
303307
!ctx.IsSet(utils.GoerliFlag.Name) &&
304308
!ctx.IsSet(utils.DeveloperFlag.Name) {
305309
// Nope, we're really on mainnet. Bump that cache up!

cmd/utils/flags.go

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ var (
136136
}
137137
NetworkIdFlag = &cli.Uint64Flag{
138138
Name: "networkid",
139-
Usage: "Explicitly set network id (integer)(For testnets: use --goerli, --sepolia instead)",
139+
Usage: "Explicitly set network id (integer)(For testnets: use --goerli, --sepolia, --holesky instead)",
140140
Value: ethconfig.Defaults.NetworkId,
141141
Category: flags.EthCategory,
142142
}
@@ -155,7 +155,11 @@ var (
155155
Usage: "Sepolia network: pre-configured proof-of-work test network",
156156
Category: flags.EthCategory,
157157
}
158-
158+
HoleskyFlag = &cli.BoolFlag{
159+
Name: "holesky",
160+
Usage: "Holesky network: pre-configured proof-of-stake test network",
161+
Category: flags.EthCategory,
162+
}
159163
// Dev mode
160164
DeveloperFlag = &cli.BoolFlag{
161165
Name: "dev",
@@ -952,6 +956,7 @@ var (
952956
TestnetFlags = []cli.Flag{
953957
GoerliFlag,
954958
SepoliaFlag,
959+
HoleskyFlag,
955960
}
956961
// NetworkFlags is the flag group of all built-in supported networks.
957962
NetworkFlags = append([]cli.Flag{MainnetFlag}, TestnetFlags...)
@@ -982,6 +987,9 @@ func MakeDataDir(ctx *cli.Context) string {
982987
if ctx.Bool(SepoliaFlag.Name) {
983988
return filepath.Join(path, "sepolia")
984989
}
990+
if ctx.Bool(HoleskyFlag.Name) {
991+
return filepath.Join(path, "holesky")
992+
}
985993
return path
986994
}
987995
Fatalf("Cannot determine default data directory, please set manually (--datadir)")
@@ -1028,6 +1036,8 @@ func setBootstrapNodes(ctx *cli.Context, cfg *p2p.Config) {
10281036
switch {
10291037
case ctx.IsSet(BootnodesFlag.Name):
10301038
urls = SplitAndTrim(ctx.String(BootnodesFlag.Name))
1039+
case ctx.Bool(HoleskyFlag.Name):
1040+
urls = params.HoleskyBootnodes
10311041
case ctx.Bool(SepoliaFlag.Name):
10321042
urls = params.SepoliaBootnodes
10331043
case ctx.Bool(GoerliFlag.Name):
@@ -1480,6 +1490,8 @@ func SetDataDir(ctx *cli.Context, cfg *node.Config) {
14801490
cfg.DataDir = filepath.Join(node.DefaultDataDir(), "goerli")
14811491
case ctx.Bool(SepoliaFlag.Name) && cfg.DataDir == node.DefaultDataDir():
14821492
cfg.DataDir = filepath.Join(node.DefaultDataDir(), "sepolia")
1493+
case ctx.Bool(HoleskyFlag.Name) && cfg.DataDir == node.DefaultDataDir():
1494+
cfg.DataDir = filepath.Join(node.DefaultDataDir(), "holesky")
14831495
}
14841496
}
14851497

@@ -1636,7 +1648,7 @@ func CheckExclusive(ctx *cli.Context, args ...interface{}) {
16361648
// SetEthConfig applies eth-related command line flags to the config.
16371649
func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
16381650
// Avoid conflicting network flags
1639-
CheckExclusive(ctx, MainnetFlag, DeveloperFlag, GoerliFlag, SepoliaFlag)
1651+
CheckExclusive(ctx, MainnetFlag, DeveloperFlag, GoerliFlag, SepoliaFlag, HoleskyFlag)
16401652
CheckExclusive(ctx, LightServeFlag, SyncModeFlag, "light")
16411653
CheckExclusive(ctx, DeveloperFlag, ExternalSignerFlag) // Can't use both ephemeral unlocked and external signer
16421654

@@ -1789,6 +1801,12 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
17891801
}
17901802
cfg.Genesis = core.DefaultGenesisBlock()
17911803
SetDNSDiscoveryDefaults(cfg, params.MainnetGenesisHash)
1804+
case ctx.Bool(HoleskyFlag.Name):
1805+
if !ctx.IsSet(NetworkIdFlag.Name) {
1806+
cfg.NetworkId = 17000
1807+
}
1808+
cfg.Genesis = core.DefaultHoleskyGenesisBlock()
1809+
SetDNSDiscoveryDefaults(cfg, params.HoleskyGenesisHash)
17921810
case ctx.Bool(SepoliaFlag.Name):
17931811
if !ctx.IsSet(NetworkIdFlag.Name) {
17941812
cfg.NetworkId = 11155111
@@ -2121,6 +2139,8 @@ func MakeGenesis(ctx *cli.Context) *core.Genesis {
21212139
switch {
21222140
case ctx.Bool(MainnetFlag.Name):
21232141
genesis = core.DefaultGenesisBlock()
2142+
case ctx.Bool(HoleskyFlag.Name):
2143+
genesis = core.DefaultHoleskyGenesisBlock()
21242144
case ctx.Bool(SepoliaFlag.Name):
21252145
genesis = core.DefaultSepoliaGenesisBlock()
21262146
case ctx.Bool(GoerliFlag.Name):

core/genesis.go

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,19 @@ func DefaultSepoliaGenesisBlock() *Genesis {
580580
}
581581
}
582582

583+
// DefaultHoleskyGenesisBlock returns the Holesky network genesis block.
584+
func DefaultHoleskyGenesisBlock() *Genesis {
585+
return &Genesis{
586+
Config: params.HoleskyChainConfig,
587+
Nonce: 0x1234,
588+
ExtraData: hexutil.MustDecode("0x686f77206d7563682069732074686520666973683f"),
589+
GasLimit: 0x17d7840,
590+
Difficulty: big.NewInt(0x01),
591+
Timestamp: 1694786100,
592+
Alloc: decodePrealloc(holeskyAllocData),
593+
}
594+
}
595+
583596
// DeveloperGenesisBlock returns the 'geth --dev' genesis block.
584597
func DeveloperGenesisBlock(gasLimit uint64, faucet common.Address) *Genesis {
585598
// Override the default period to the user requested one
@@ -607,13 +620,34 @@ func DeveloperGenesisBlock(gasLimit uint64, faucet common.Address) *Genesis {
607620
}
608621

609622
func decodePrealloc(data string) GenesisAlloc {
610-
var p []struct{ Addr, Balance *big.Int }
623+
var p []struct {
624+
Addr *big.Int
625+
Balance *big.Int
626+
Misc *struct {
627+
Nonce uint64
628+
Code []byte
629+
Slots []struct {
630+
Key common.Hash
631+
Val common.Hash
632+
}
633+
} `rlp:"optional"`
634+
}
611635
if err := rlp.NewStream(strings.NewReader(data), 0).Decode(&p); err != nil {
612636
panic(err)
613637
}
614638
ga := make(GenesisAlloc, len(p))
615639
for _, account := range p {
616-
ga[common.BigToAddress(account.Addr)] = GenesisAccount{Balance: account.Balance}
640+
acc := GenesisAccount{Balance: account.Balance}
641+
if account.Misc != nil {
642+
acc.Nonce = account.Misc.Nonce
643+
acc.Code = account.Misc.Code
644+
645+
acc.Storage = make(map[common.Hash]common.Hash)
646+
for _, slot := range account.Misc.Slots {
647+
acc.Storage[slot.Key] = slot.Val
648+
}
649+
}
650+
ga[common.BigToAddress(account.Addr)] = acc
617651
}
618652
return ga
619653
}

core/genesis_alloc.go

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

core/mkalloc.go

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,24 +32,51 @@ import (
3232
"os"
3333
"strconv"
3434

35+
"github.com/ethereum/go-ethereum/common"
3536
"github.com/ethereum/go-ethereum/core"
3637
"github.com/ethereum/go-ethereum/rlp"
3738
"golang.org/x/exp/slices"
3839
)
3940

40-
type allocItem struct{ Addr, Balance *big.Int }
41+
type allocItem struct {
42+
Addr *big.Int
43+
Balance *big.Int
44+
Misc *allocItemMisc `rlp:"optional"`
45+
}
46+
47+
type allocItemMisc struct {
48+
Nonce uint64
49+
Code []byte
50+
Slots []allocItemStorageItem
51+
}
52+
53+
type allocItemStorageItem struct {
54+
Key common.Hash
55+
Val common.Hash
56+
}
4157

4258
func makelist(g *core.Genesis) []allocItem {
4359
items := make([]allocItem, 0, len(g.Alloc))
4460
for addr, account := range g.Alloc {
61+
var misc *allocItemMisc
4562
if len(account.Storage) > 0 || len(account.Code) > 0 || account.Nonce != 0 {
46-
panic(fmt.Sprintf("can't encode account %x", addr))
63+
misc = &allocItemMisc{
64+
Nonce: account.Nonce,
65+
Code: account.Code,
66+
Slots: make([]allocItemStorageItem, 0, len(account.Storage)),
67+
}
68+
for key, val := range account.Storage {
69+
misc.Slots = append(misc.Slots, allocItemStorageItem{key, val})
70+
}
71+
slices.SortFunc(misc.Slots, func(a, b allocItemStorageItem) int {
72+
return a.Key.Cmp(b.Key)
73+
})
4774
}
4875
bigAddr := new(big.Int).SetBytes(addr.Bytes())
49-
items = append(items, allocItem{bigAddr, account.Balance})
76+
items = append(items, allocItem{bigAddr, account.Balance, misc})
5077
}
51-
slices.SortFunc(items, func(a, b allocItem) bool {
52-
return a.Addr.Cmp(b.Addr) < 0
78+
slices.SortFunc(items, func(a, b allocItem) int {
79+
return a.Addr.Cmp(b.Addr)
5380
})
5481
return items
5582
}

params/bootnodes.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@ var MainnetBootnodes = []string{
2828
"enode://4aeb4ab6c14b23e2c4cfdce879c04b0748a20d8e9b59e25ded2a08143e265c6c25936e74cbc8e641e3312ca288673d91f2f93f8e277de3cfa444ecdaaf982052@157.90.35.166:30303", // bootnode-hetzner-fsn
2929
}
3030

31+
// HoleskyBootnodes are the enode URLs of the P2P bootstrap nodes running on the
32+
// Holesky test network.
33+
var HoleskyBootnodes = []string{
34+
// EF DevOps
35+
"enode://ac906289e4b7f12df423d654c5a962b6ebe5b3a74cc9e06292a85221f9a64a6f1cfdd6b714ed6dacef51578f92b34c60ee91e9ede9c7f8fadc4d347326d95e2b@146.190.13.128:30303",
36+
"enode://a3435a0155a3e837c02f5e7f5662a2f1fbc25b48e4dc232016e1c51b544cb5b4510ef633ea3278c0e970fa8ad8141e2d4d0f9f95456c537ff05fdf9b31c15072@178.128.136.233:30303",
37+
}
38+
3139
// SepoliaBootnodes are the enode URLs of the P2P bootstrap nodes running on the
3240
// Sepolia test network.
3341
var SepoliaBootnodes = []string{
@@ -88,6 +96,8 @@ func KnownDNSNetwork(genesis common.Hash, protocol string) string {
8896
net = "goerli"
8997
case SepoliaGenesisHash:
9098
net = "sepolia"
99+
case HoleskyGenesisHash:
100+
net = "holesky"
91101
default:
92102
return ""
93103
}

params/config.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
// Genesis hashes to enforce below configs on.
2727
var (
2828
MainnetGenesisHash = common.HexToHash("0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3")
29+
HoleskyGenesisHash = common.HexToHash("0xff9006519a8ce843ac9c28549d24211420b546e12ce2d170c77a8cca7964f23d")
2930
SepoliaGenesisHash = common.HexToHash("0x25a5cc106eea7138acab33231d7160d69cb777ee0c2c553fcddf5138993e6dd9")
3031
GoerliGenesisHash = common.HexToHash("0xbf7e331f7f7c1dd2e05159666b3bf8bc7a8a3a9eb1d518969eab529dd9b88c1a")
3132
)
@@ -58,6 +59,31 @@ var (
5859
ShanghaiTime: newUint64(1681338455),
5960
Ethash: new(EthashConfig),
6061
}
62+
// HoleskyChainConfig contains the chain parameters to run a node on the Holesky test network.
63+
HoleskyChainConfig = &ChainConfig{
64+
ChainID: big.NewInt(17000),
65+
HomesteadBlock: big.NewInt(0),
66+
DAOForkBlock: nil,
67+
DAOForkSupport: true,
68+
EIP150Block: big.NewInt(0),
69+
EIP155Block: big.NewInt(0),
70+
EIP158Block: big.NewInt(0),
71+
ByzantiumBlock: big.NewInt(0),
72+
ConstantinopleBlock: big.NewInt(0),
73+
PetersburgBlock: big.NewInt(0),
74+
IstanbulBlock: big.NewInt(0),
75+
MuirGlacierBlock: nil,
76+
BerlinBlock: big.NewInt(0),
77+
LondonBlock: big.NewInt(0),
78+
ArrowGlacierBlock: nil,
79+
GrayGlacierBlock: nil,
80+
TerminalTotalDifficulty: big.NewInt(0),
81+
TerminalTotalDifficultyPassed: true,
82+
MergeNetsplitBlock: nil,
83+
ShanghaiTime: newUint64(1694790240),
84+
CancunTime: newUint64(2000000000),
85+
Ethash: new(EthashConfig),
86+
}
6187
// SepoliaChainConfig contains the chain parameters to run a node on the Sepolia test network.
6288
SepoliaChainConfig = &ChainConfig{
6389
ChainID: big.NewInt(11155111),
@@ -74,6 +100,8 @@ var (
74100
MuirGlacierBlock: big.NewInt(0),
75101
BerlinBlock: big.NewInt(0),
76102
LondonBlock: big.NewInt(0),
103+
ArrowGlacierBlock: nil,
104+
GrayGlacierBlock: nil,
77105
TerminalTotalDifficulty: big.NewInt(17_000_000_000_000_000),
78106
TerminalTotalDifficultyPassed: true,
79107
MergeNetsplitBlock: big.NewInt(1735371),
@@ -253,6 +281,7 @@ var NetworkNames = map[string]string{
253281
MainnetChainConfig.ChainID.String(): "mainnet",
254282
GoerliChainConfig.ChainID.String(): "goerli",
255283
SepoliaChainConfig.ChainID.String(): "sepolia",
284+
HoleskyChainConfig.ChainID.String(): "holesky",
256285
}
257286

258287
// ChainConfig is the core config which determines the blockchain settings.

0 commit comments

Comments
 (0)