Skip to content

Commit 668118b

Browse files
params: add hoodi testnet definition (#31406)
Adds support for the new hoodi testnet. Hoodi is meant for stakers to test their setup. For more info please refer to https://hoodi.ethpandaops.io/.
1 parent 40ad6be commit 668118b

File tree

14 files changed

+140
-2
lines changed

14 files changed

+140
-2
lines changed

beacon/params/networks.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,17 @@ var (
5555
AddFork("CAPELLA", 256, []byte{4, 1, 112, 0}).
5656
AddFork("DENEB", 29696, []byte{5, 1, 112, 0}).
5757
AddFork("ELECTRA", 115968, []byte{6, 1, 112, 0})
58+
59+
HoodiLightConfig = (&ChainConfig{
60+
GenesisValidatorsRoot: common.HexToHash("0x212f13fc4df078b6cb7db228f1c8307566dcecf900867401a92023d7ba99cb5f"),
61+
GenesisTime: 1742212800,
62+
Checkpoint: common.HexToHash(""),
63+
}).
64+
AddFork("GENESIS", 0, common.FromHex("0x10000910")).
65+
AddFork("ALTAIR", 0, common.FromHex("0x20000910")).
66+
AddFork("BELLATRIX", 0, common.FromHex("0x30000910")).
67+
AddFork("CAPELLA", 0, common.FromHex("0x40000910")).
68+
AddFork("DENEB", 0, common.FromHex("0x50000910")).
69+
AddFork("ELECTRA", 2048, common.FromHex("0x60000910")).
70+
AddFork("FULU", 18446744073709551615, common.FromHex("0x70000910"))
5871
)

cmd/blsync/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ func main() {
4747
utils.MainnetFlag,
4848
utils.SepoliaFlag,
4949
utils.HoleskyFlag,
50+
utils.HoodiFlag,
5051
utils.BlsyncApiFlag,
5152
utils.BlsyncJWTSecretFlag,
5253
},

cmd/devp2p/nodesetcmd.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,8 @@ func ethFilter(args []string) (nodeFilter, error) {
234234
filter = forkid.NewStaticFilter(params.SepoliaChainConfig, core.DefaultSepoliaGenesisBlock().ToBlock())
235235
case "holesky":
236236
filter = forkid.NewStaticFilter(params.HoleskyChainConfig, core.DefaultHoleskyGenesisBlock().ToBlock())
237+
case "hoodi":
238+
filter = forkid.NewStaticFilter(params.HoodiChainConfig, core.DefaultHoodiGenesisBlock().ToBlock())
237239
default:
238240
return nil, fmt.Errorf("unknown network %q", args[0])
239241
}

cmd/geth/main.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,9 @@ func prepare(ctx *cli.Context) {
296296
case ctx.IsSet(utils.HoleskyFlag.Name):
297297
log.Info("Starting Geth on Holesky testnet...")
298298

299+
case ctx.IsSet(utils.HoodiFlag.Name):
300+
log.Info("Starting Geth on Hoodi testnet...")
301+
299302
case ctx.IsSet(utils.DeveloperFlag.Name):
300303
log.Info("Starting Geth in ephemeral dev mode...")
301304
log.Warn(`You are running Geth in --dev mode. Please note the following:
@@ -322,6 +325,7 @@ func prepare(ctx *cli.Context) {
322325
// Make sure we're not on any supported preconfigured testnet either
323326
if !ctx.IsSet(utils.HoleskyFlag.Name) &&
324327
!ctx.IsSet(utils.SepoliaFlag.Name) &&
328+
!ctx.IsSet(utils.HoodiFlag.Name) &&
325329
!ctx.IsSet(utils.DeveloperFlag.Name) {
326330
// Nope, we're really on mainnet. Bump that cache up!
327331
log.Info("Bumping default cache on mainnet", "provided", ctx.Int(utils.CacheFlag.Name), "updated", 4096)

cmd/utils/flags.go

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ var (
134134
}
135135
NetworkIdFlag = &cli.Uint64Flag{
136136
Name: "networkid",
137-
Usage: "Explicitly set network id (integer)(For testnets: use --sepolia, --holesky instead)",
137+
Usage: "Explicitly set network id (integer)(For testnets: use --sepolia, --holesky, --hoodi instead)",
138138
Value: ethconfig.Defaults.NetworkId,
139139
Category: flags.EthCategory,
140140
}
@@ -153,6 +153,11 @@ var (
153153
Usage: "Holesky network: pre-configured proof-of-stake test network",
154154
Category: flags.EthCategory,
155155
}
156+
HoodiFlag = &cli.BoolFlag{
157+
Name: "hoodi",
158+
Usage: "Hoodi network: pre-configured proof-of-stake test network",
159+
Category: flags.EthCategory,
160+
}
156161
// Dev mode
157162
DeveloperFlag = &cli.BoolFlag{
158163
Name: "dev",
@@ -958,6 +963,7 @@ var (
958963
TestnetFlags = []cli.Flag{
959964
SepoliaFlag,
960965
HoleskyFlag,
966+
HoodiFlag,
961967
}
962968
// NetworkFlags is the flag group of all built-in supported networks.
963969
NetworkFlags = append([]cli.Flag{MainnetFlag}, TestnetFlags...)
@@ -984,6 +990,9 @@ func MakeDataDir(ctx *cli.Context) string {
984990
if ctx.Bool(HoleskyFlag.Name) {
985991
return filepath.Join(path, "holesky")
986992
}
993+
if ctx.Bool(HoodiFlag.Name) {
994+
return filepath.Join(path, "hoodi")
995+
}
987996
return path
988997
}
989998
Fatalf("Cannot determine default data directory, please set manually (--datadir)")
@@ -1044,6 +1053,8 @@ func setBootstrapNodes(ctx *cli.Context, cfg *p2p.Config) {
10441053
urls = params.HoleskyBootnodes
10451054
case ctx.Bool(SepoliaFlag.Name):
10461055
urls = params.SepoliaBootnodes
1056+
case ctx.Bool(HoodiFlag.Name):
1057+
urls = params.HoodiBootnodes
10471058
}
10481059
}
10491060
cfg.BootstrapNodes = mustParseBootnodes(urls)
@@ -1428,6 +1439,8 @@ func SetDataDir(ctx *cli.Context, cfg *node.Config) {
14281439
cfg.DataDir = filepath.Join(node.DefaultDataDir(), "sepolia")
14291440
case ctx.Bool(HoleskyFlag.Name) && cfg.DataDir == node.DefaultDataDir():
14301441
cfg.DataDir = filepath.Join(node.DefaultDataDir(), "holesky")
1442+
case ctx.Bool(HoodiFlag.Name) && cfg.DataDir == node.DefaultDataDir():
1443+
cfg.DataDir = filepath.Join(node.DefaultDataDir(), "hoodi")
14311444
}
14321445
}
14331446

@@ -1554,7 +1567,7 @@ func setRequiredBlocks(ctx *cli.Context, cfg *ethconfig.Config) {
15541567
// SetEthConfig applies eth-related command line flags to the config.
15551568
func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
15561569
// Avoid conflicting network flags
1557-
flags.CheckExclusive(ctx, MainnetFlag, DeveloperFlag, SepoliaFlag, HoleskyFlag)
1570+
flags.CheckExclusive(ctx, MainnetFlag, DeveloperFlag, SepoliaFlag, HoleskyFlag, HoodiFlag)
15581571
flags.CheckExclusive(ctx, DeveloperFlag, ExternalSignerFlag) // Can't use both ephemeral unlocked and external signer
15591572

15601573
// Set configurations from CLI flags
@@ -1738,6 +1751,12 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
17381751
}
17391752
cfg.Genesis = core.DefaultSepoliaGenesisBlock()
17401753
SetDNSDiscoveryDefaults(cfg, params.SepoliaGenesisHash)
1754+
case ctx.Bool(HoodiFlag.Name):
1755+
if !ctx.IsSet(NetworkIdFlag.Name) {
1756+
cfg.NetworkId = 560048
1757+
}
1758+
cfg.Genesis = core.DefaultHoodiGenesisBlock()
1759+
SetDNSDiscoveryDefaults(cfg, params.HoodiGenesisHash)
17411760
case ctx.Bool(DeveloperFlag.Name):
17421761
if !ctx.IsSet(NetworkIdFlag.Name) {
17431762
cfg.NetworkId = 1337
@@ -1852,6 +1871,8 @@ func MakeBeaconLightConfig(ctx *cli.Context) bparams.ClientConfig {
18521871
config.ChainConfig = *bparams.SepoliaLightConfig
18531872
case ctx.Bool(HoleskyFlag.Name):
18541873
config.ChainConfig = *bparams.HoleskyLightConfig
1874+
case ctx.Bool(HoodiFlag.Name):
1875+
config.ChainConfig = *bparams.HoodiLightConfig
18551876
default:
18561877
if !customConfig {
18571878
config.ChainConfig = *bparams.MainnetLightConfig
@@ -2118,6 +2139,8 @@ func MakeGenesis(ctx *cli.Context) *core.Genesis {
21182139
genesis = core.DefaultHoleskyGenesisBlock()
21192140
case ctx.Bool(SepoliaFlag.Name):
21202141
genesis = core.DefaultSepoliaGenesisBlock()
2142+
case ctx.Bool(HoodiFlag.Name):
2143+
genesis = core.DefaultHoodiGenesisBlock()
21212144
case ctx.Bool(DeveloperFlag.Name):
21222145
Fatalf("Developer chains are ephemeral")
21232146
}

core/filtermaps/checkpoints.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,17 @@ var checkpointsSepoliaJSON []byte
4646
//go:embed checkpoints_holesky.json
4747
var checkpointsHoleskyJSON []byte
4848

49+
//go:embed checkpoints_hoodi.json
50+
var checkpointsHoodiJSON []byte
51+
4952
// checkpoints lists sets of checkpoints for multiple chains. The matching
5053
// checkpoint set is autodetected by the indexer once the canonical chain is
5154
// known.
5255
var checkpoints = []checkpointList{
5356
decodeCheckpoints(checkpointsMainnetJSON),
5457
decodeCheckpoints(checkpointsSepoliaJSON),
5558
decodeCheckpoints(checkpointsHoleskyJSON),
59+
decodeCheckpoints(checkpointsHoodiJSON),
5660
}
5761

5862
func decodeCheckpoints(encoded []byte) (result checkpointList) {
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[]

core/forkid/forkid_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,17 @@ func TestCreation(t *testing.T) {
112112
{123, 2740434112, ID{Hash: checksumToBytes(0xdfbd9bed), Next: 0}}, // Future Prague block
113113
},
114114
},
115+
// Hoodi test cases
116+
{
117+
params.HoodiChainConfig,
118+
core.DefaultHoodiGenesisBlock().ToBlock(),
119+
[]testcase{
120+
{0, 0, ID{Hash: checksumToBytes(0xbef71d30), Next: 1742999832}}, // Unsynced, last Frontier, Homestead, Tangerine, Spurious, Byzantium, Constantinople, Petersburg, Istanbul, Berlin, London, Paris, Shanghai, Cancun block
121+
{123, 1742999831, ID{Hash: checksumToBytes(0xbef71d30), Next: 1742999832}}, // Last Cancun block
122+
{123, 1742999832, ID{Hash: checksumToBytes(0x0929e24e), Next: 0}}, // First Prague block
123+
{123, 2740434112, ID{Hash: checksumToBytes(0x0929e24e), Next: 0}}, // Future Prague block
124+
},
125+
},
115126
}
116127
for i, tt := range tests {
117128
for j, ttt := range tt.cases {

core/genesis.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,8 @@ func getGenesisState(db ethdb.Database, blockhash common.Hash) (alloc types.Gene
221221
genesis = DefaultSepoliaGenesisBlock()
222222
case params.HoleskyGenesisHash:
223223
genesis = DefaultHoleskyGenesisBlock()
224+
case params.HoodiGenesisHash:
225+
genesis = DefaultHoodiGenesisBlock()
224226
}
225227
if genesis != nil {
226228
return genesis.Alloc, nil
@@ -431,6 +433,8 @@ func (g *Genesis) chainConfigOrDefault(ghash common.Hash, stored *params.ChainCo
431433
return params.HoleskyChainConfig
432434
case ghash == params.SepoliaGenesisHash:
433435
return params.SepoliaChainConfig
436+
case ghash == params.HoodiGenesisHash:
437+
return params.HoodiChainConfig
434438
default:
435439
return stored
436440
}
@@ -625,6 +629,18 @@ func DefaultHoleskyGenesisBlock() *Genesis {
625629
}
626630
}
627631

632+
// DefaultHoodiGenesisBlock returns the Hoodi network genesis block.
633+
func DefaultHoodiGenesisBlock() *Genesis {
634+
return &Genesis{
635+
Config: params.HoodiChainConfig,
636+
Nonce: 0x1234,
637+
GasLimit: 0x2255100,
638+
Difficulty: big.NewInt(0x01),
639+
Timestamp: 1742212800,
640+
Alloc: decodePrealloc(hoodiAllocData),
641+
}
642+
}
643+
628644
// DeveloperGenesisBlock returns the 'geth --dev' genesis block.
629645
func DeveloperGenesisBlock(gasLimit uint64, faucet *common.Address) *Genesis {
630646
// Override the default period to the user requested one

core/genesis_alloc.go

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

core/genesis_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,15 @@ func testSetupGenesis(t *testing.T, scheme string) {
104104
},
105105
wantErr: &GenesisMismatchError{Stored: customghash, New: params.SepoliaGenesisHash},
106106
},
107+
{
108+
name: "custom block in DB, genesis == hoodi",
109+
fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) {
110+
tdb := triedb.NewDatabase(db, newDbConfig(scheme))
111+
customg.Commit(db, tdb)
112+
return SetupGenesisBlock(db, tdb, DefaultHoodiGenesisBlock())
113+
},
114+
wantErr: &GenesisMismatchError{Stored: customghash, New: params.HoodiGenesisHash},
115+
},
107116
{
108117
name: "compatible config in DB",
109118
fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) {
@@ -178,6 +187,8 @@ func TestGenesisHashes(t *testing.T) {
178187
}{
179188
{DefaultGenesisBlock(), params.MainnetGenesisHash},
180189
{DefaultSepoliaGenesisBlock(), params.SepoliaGenesisHash},
190+
{DefaultHoleskyGenesisBlock(), params.HoleskyGenesisHash},
191+
{DefaultHoodiGenesisBlock(), params.HoodiGenesisHash},
181192
} {
182193
// Test via MustCommit
183194
db := rawdb.NewMemoryDatabase()

core/rawdb/accessors_indexes_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ func TestDeleteBloomBits(t *testing.T) {
119119
for s := uint64(0); s < 2; s++ {
120120
WriteBloomBits(db, i, s, params.MainnetGenesisHash, []byte{0x01, 0x02})
121121
WriteBloomBits(db, i, s, params.SepoliaGenesisHash, []byte{0x01, 0x02})
122+
WriteBloomBits(db, i, s, params.HoodiGenesisHash, []byte{0x01, 0x02})
122123
}
123124
}
124125
check := func(bit uint, section uint64, head common.Hash, exist bool) {
@@ -133,24 +134,31 @@ func TestDeleteBloomBits(t *testing.T) {
133134
// Check the existence of written data.
134135
check(0, 0, params.MainnetGenesisHash, true)
135136
check(0, 0, params.SepoliaGenesisHash, true)
137+
check(0, 0, params.HoodiGenesisHash, true)
136138

137139
// Check the existence of deleted data.
138140
DeleteBloombits(db, 0, 0, 1)
139141
check(0, 0, params.MainnetGenesisHash, false)
140142
check(0, 0, params.SepoliaGenesisHash, false)
143+
check(0, 0, params.HoodiGenesisHash, false)
141144
check(0, 1, params.MainnetGenesisHash, true)
142145
check(0, 1, params.SepoliaGenesisHash, true)
146+
check(0, 1, params.HoodiGenesisHash, true)
143147

144148
// Check the existence of deleted data.
145149
DeleteBloombits(db, 0, 0, 2)
146150
check(0, 0, params.MainnetGenesisHash, false)
147151
check(0, 0, params.SepoliaGenesisHash, false)
152+
check(0, 0, params.HoodiGenesisHash, false)
148153
check(0, 1, params.MainnetGenesisHash, false)
149154
check(0, 1, params.SepoliaGenesisHash, false)
155+
check(0, 1, params.HoodiGenesisHash, false)
150156

151157
// Bit1 shouldn't be affect.
152158
check(1, 0, params.MainnetGenesisHash, true)
153159
check(1, 0, params.SepoliaGenesisHash, true)
160+
check(1, 0, params.HoodiGenesisHash, true)
154161
check(1, 1, params.MainnetGenesisHash, true)
155162
check(1, 1, params.SepoliaGenesisHash, true)
163+
check(1, 1, params.HoodiGenesisHash, true)
156164
}

params/bootnodes.go

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

31+
// HoodiBootnodes are the enode URLs of the P2P bootstrap nodes running on the
32+
// Hoodi test network.
33+
var HoodiBootnodes = []string{
34+
// EF DevOps
35+
"enode://2112dd3839dd752813d4df7f40936f06829fc54c0e051a93967c26e5f5d27d99d886b57b4ffcc3c475e930ec9e79c56ef1dbb7d86ca5ee83a9d2ccf36e5c240c@134.209.138.84:30303",
36+
"enode://60203fcb3524e07c5df60a14ae1c9c5b24023ea5d47463dfae051d2c9f3219f309657537576090ca0ae641f73d419f53d8e8000d7a464319d4784acd7d2abc41@209.38.124.160:30303",
37+
"enode://8ae4a48101b2299597341263da0deb47cc38aa4d3ef4b7430b897d49bfa10eb1ccfe1655679b1ed46928ef177fbf21b86837bd724400196c508427a6f41602cd@134.199.184.23:30303",
38+
}
39+
3140
// HoleskyBootnodes are the enode URLs of the P2P bootstrap nodes running on the
3241
// Holesky test network.
3342
var HoleskyBootnodes = []string{
@@ -84,6 +93,8 @@ func KnownDNSNetwork(genesis common.Hash, protocol string) string {
8493
net = "sepolia"
8594
case HoleskyGenesisHash:
8695
net = "holesky"
96+
case HoodiGenesisHash:
97+
net = "hoodi"
8798
default:
8899
return ""
89100
}

params/config.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ var (
3131
MainnetGenesisHash = common.HexToHash("0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3")
3232
HoleskyGenesisHash = common.HexToHash("0xb5f7f912443c940f21fd611f12828d75b534364ed9e95ca4e307729a4661bde4")
3333
SepoliaGenesisHash = common.HexToHash("0x25a5cc106eea7138acab33231d7160d69cb777ee0c2c553fcddf5138993e6dd9")
34+
HoodiGenesisHash = common.HexToHash("0xbbe312868b376a3001692a646dd2d7d1e4406380dfd86b98aa8a34d1557c971b")
3435
)
3536

3637
func newUint64(val uint64) *uint64 { return &val }
@@ -125,6 +126,36 @@ var (
125126
Prague: DefaultPragueBlobConfig,
126127
},
127128
}
129+
// HoodiChainConfig contains the chain parameters to run a node on the Hoodi test network.
130+
HoodiChainConfig = &ChainConfig{
131+
ChainID: big.NewInt(560048),
132+
HomesteadBlock: big.NewInt(0),
133+
DAOForkBlock: nil,
134+
DAOForkSupport: true,
135+
EIP150Block: big.NewInt(0),
136+
EIP155Block: big.NewInt(0),
137+
EIP158Block: big.NewInt(0),
138+
ByzantiumBlock: big.NewInt(0),
139+
ConstantinopleBlock: big.NewInt(0),
140+
PetersburgBlock: big.NewInt(0),
141+
IstanbulBlock: big.NewInt(0),
142+
MuirGlacierBlock: big.NewInt(0),
143+
BerlinBlock: big.NewInt(0),
144+
LondonBlock: big.NewInt(0),
145+
ArrowGlacierBlock: nil,
146+
GrayGlacierBlock: nil,
147+
TerminalTotalDifficulty: big.NewInt(0),
148+
MergeNetsplitBlock: big.NewInt(0),
149+
ShanghaiTime: newUint64(0),
150+
CancunTime: newUint64(0),
151+
PragueTime: newUint64(1742999832),
152+
DepositContractAddress: common.HexToAddress("0x00000000219ab540356cBB839Cbe05303d7705Fa"),
153+
Ethash: new(EthashConfig),
154+
BlobScheduleConfig: &BlobScheduleConfig{
155+
Cancun: DefaultCancunBlobConfig,
156+
Prague: DefaultPragueBlobConfig,
157+
},
158+
}
128159
// AllEthashProtocolChanges contains every protocol change (EIPs) introduced
129160
// and accepted by the Ethereum core developers into the Ethash consensus.
130161
AllEthashProtocolChanges = &ChainConfig{
@@ -338,6 +369,7 @@ var NetworkNames = map[string]string{
338369
MainnetChainConfig.ChainID.String(): "mainnet",
339370
SepoliaChainConfig.ChainID.String(): "sepolia",
340371
HoleskyChainConfig.ChainID.String(): "holesky",
372+
HoodiChainConfig.ChainID.String(): "hoodi",
341373
}
342374

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

0 commit comments

Comments
 (0)