Skip to content

Commit 665c851

Browse files
core: copy genesis before modifying (#31097)
This PR fixes a data race in SetupGenesisWithOverride.
1 parent 0ad0966 commit 665c851

File tree

1 file changed

+25
-20
lines changed

1 file changed

+25
-20
lines changed

core/genesis.go

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,19 @@ type Genesis struct {
7575
BlobGasUsed *uint64 `json:"blobGasUsed"` // EIP-4844
7676
}
7777

78+
// copy copies the genesis.
79+
func (g *Genesis) copy() *Genesis {
80+
if g != nil {
81+
cpy := *g
82+
if g.Config != nil {
83+
conf := *g.Config
84+
cpy.Config = &conf
85+
}
86+
return &cpy
87+
}
88+
return nil
89+
}
90+
7891
func ReadGenesis(db ethdb.Database) (*Genesis, error) {
7992
var genesis Genesis
8093
stored := rawdb.ReadCanonicalHash(db, 0)
@@ -248,21 +261,17 @@ type ChainOverrides struct {
248261
}
249262

250263
// apply applies the chain overrides on the supplied chain config.
251-
func (o *ChainOverrides) apply(cfg *params.ChainConfig) (*params.ChainConfig, error) {
264+
func (o *ChainOverrides) apply(cfg *params.ChainConfig) error {
252265
if o == nil || cfg == nil {
253-
return cfg, nil
266+
return nil
254267
}
255-
cpy := *cfg
256268
if o.OverrideCancun != nil {
257-
cpy.CancunTime = o.OverrideCancun
269+
cfg.CancunTime = o.OverrideCancun
258270
}
259271
if o.OverrideVerkle != nil {
260-
cpy.VerkleTime = o.OverrideVerkle
272+
cfg.VerkleTime = o.OverrideVerkle
261273
}
262-
if err := cpy.CheckConfigForkOrder(); err != nil {
263-
return nil, err
264-
}
265-
return &cpy, nil
274+
return cfg.CheckConfigForkOrder()
266275
}
267276

268277
// SetupGenesisBlock writes or updates the genesis block in db.
@@ -281,6 +290,8 @@ func SetupGenesisBlock(db ethdb.Database, triedb *triedb.Database, genesis *Gene
281290
}
282291

283292
func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *triedb.Database, genesis *Genesis, overrides *ChainOverrides) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) {
293+
// Copy the genesis, so we can operate on a copy.
294+
genesis = genesis.copy()
284295
// Sanitize the supplied genesis, ensuring it has the associated chain
285296
// config attached.
286297
if genesis != nil && genesis.Config == nil {
@@ -295,17 +306,15 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *triedb.Database, g
295306
} else {
296307
log.Info("Writing custom genesis block")
297308
}
298-
chainCfg, err := overrides.apply(genesis.Config)
299-
if err != nil {
309+
if err := overrides.apply(genesis.Config); err != nil {
300310
return nil, common.Hash{}, nil, err
301311
}
302-
genesis.Config = chainCfg
303312

304313
block, err := genesis.Commit(db, triedb)
305314
if err != nil {
306315
return nil, common.Hash{}, nil, err
307316
}
308-
return chainCfg, block.Hash(), nil, nil
317+
return genesis.Config, block.Hash(), nil, nil
309318
}
310319
// Commit the genesis if the genesis block exists in the ancient database
311320
// but the key-value database is empty without initializing the genesis
@@ -322,11 +331,9 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *triedb.Database, g
322331
} else {
323332
log.Info("Writing custom genesis block")
324333
}
325-
chainCfg, err := overrides.apply(genesis.Config)
326-
if err != nil {
334+
if err := overrides.apply(genesis.Config); err != nil {
327335
return nil, common.Hash{}, nil, err
328336
}
329-
genesis.Config = chainCfg
330337

331338
if hash := genesis.ToBlock().Hash(); hash != ghash {
332339
return nil, common.Hash{}, nil, &GenesisMismatchError{ghash, hash}
@@ -335,17 +342,15 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *triedb.Database, g
335342
if err != nil {
336343
return nil, common.Hash{}, nil, err
337344
}
338-
return chainCfg, block.Hash(), nil, nil
345+
return genesis.Config, block.Hash(), nil, nil
339346
}
340347
// The genesis block has already been committed previously. Verify that the
341348
// provided genesis with chain overrides matches the existing one, and update
342349
// the stored chain config if necessary.
343350
if genesis != nil {
344-
chainCfg, err := overrides.apply(genesis.Config)
345-
if err != nil {
351+
if err := overrides.apply(genesis.Config); err != nil {
346352
return nil, common.Hash{}, nil, err
347353
}
348-
genesis.Config = chainCfg
349354

350355
if hash := genesis.ToBlock().Hash(); hash != ghash {
351356
return nil, common.Hash{}, nil, &GenesisMismatchError{ghash, hash}

0 commit comments

Comments
 (0)