@@ -80,10 +80,12 @@ func (ga *GenesisAlloc) UnmarshalJSON(data []byte) error {
8080 return nil
8181}
8282
83- // flush adds allocated genesis accounts into a fresh new statedb and
84- // commit the state changes into the given database handler.
85- func (ga * GenesisAlloc ) flush (db ethdb.Database ) (common.Hash , error ) {
86- statedb , err := state .New (common.Hash {}, state .NewDatabase (db ), nil )
83+ // deriveHash computes the state root according to the genesis specification.
84+ func (ga * GenesisAlloc ) deriveHash () (common.Hash , error ) {
85+ // Create an ephemeral in-memory database for computing hash,
86+ // all the derived states will be discarded to not pollute disk.
87+ db := state .NewDatabase (rawdb .NewMemoryDatabase ())
88+ statedb , err := state .New (common.Hash {}, db , nil )
8789 if err != nil {
8890 return common.Hash {}, err
8991 }
@@ -95,33 +97,47 @@ func (ga *GenesisAlloc) flush(db ethdb.Database) (common.Hash, error) {
9597 statedb .SetState (addr , key , value )
9698 }
9799 }
100+ return statedb .Commit (false )
101+ }
102+
103+ // flush is very similar with deriveHash, but the main difference is
104+ // all the generated states will be persisted into the given database.
105+ // Also, the genesis state specification will be flushed as well.
106+ func (ga * GenesisAlloc ) flush (db ethdb.Database ) error {
107+ statedb , err := state .New (common.Hash {}, state .NewDatabase (db ), nil )
108+ if err != nil {
109+ return err
110+ }
111+ for addr , account := range * ga {
112+ statedb .AddBalance (addr , account .Balance )
113+ statedb .SetCode (addr , account .Code )
114+ statedb .SetNonce (addr , account .Nonce )
115+ for key , value := range account .Storage {
116+ statedb .SetState (addr , key , value )
117+ }
118+ }
98119 root , err := statedb .Commit (false )
99120 if err != nil {
100- return common. Hash {}, err
121+ return err
101122 }
102123 err = statedb .Database ().TrieDB ().Commit (root , true , nil )
103124 if err != nil {
104- return common. Hash {}, err
125+ return err
105126 }
106- return root , nil
107- }
108-
109- // write writes the json marshaled genesis state into database
110- // with the given block hash as the unique identifier.
111- func (ga * GenesisAlloc ) write (db ethdb.KeyValueWriter , hash common.Hash ) error {
127+ // Marshal the genesis state specification and persist.
112128 blob , err := json .Marshal (ga )
113129 if err != nil {
114130 return err
115131 }
116- rawdb .WriteGenesisState (db , hash , blob )
132+ rawdb .WriteGenesisStateSpec (db , root , blob )
117133 return nil
118134}
119135
120136// CommitGenesisState loads the stored genesis state with the given block
121137// hash and commits them into the given database handler.
122138func CommitGenesisState (db ethdb.Database , hash common.Hash ) error {
123139 var alloc GenesisAlloc
124- blob := rawdb .ReadGenesisState (db , hash )
140+ blob := rawdb .ReadGenesisStateSpec (db , hash )
125141 if len (blob ) != 0 {
126142 if err := alloc .UnmarshalJSON (blob ); err != nil {
127143 return err
@@ -156,8 +172,7 @@ func CommitGenesisState(db ethdb.Database, hash common.Hash) error {
156172 return errors .New ("not found" )
157173 }
158174 }
159- _ , err := alloc .flush (db )
160- return err
175+ return alloc .flush (db )
161176}
162177
163178// GenesisAccount is an account in the state of the genesis block.
@@ -278,7 +293,7 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, genesis *Genesis, override
278293 genesis = DefaultGenesisBlock ()
279294 }
280295 // Ensure the stored genesis matches with the given one.
281- hash := genesis .ToBlock (nil ).Hash ()
296+ hash := genesis .ToBlock ().Hash ()
282297 if hash != stored {
283298 return genesis .Config , hash , & GenesisMismatchError {stored , hash }
284299 }
@@ -291,7 +306,7 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, genesis *Genesis, override
291306 }
292307 // Check whether the genesis block is already written.
293308 if genesis != nil {
294- hash := genesis .ToBlock (nil ).Hash ()
309+ hash := genesis .ToBlock ().Hash ()
295310 if hash != stored {
296311 return genesis .Config , hash , & GenesisMismatchError {stored , hash }
297312 }
@@ -356,13 +371,9 @@ func (g *Genesis) configOrDefault(ghash common.Hash) *params.ChainConfig {
356371 }
357372}
358373
359- // ToBlock creates the genesis block and writes state of a genesis specification
360- // to the given database (or discards it if nil).
361- func (g * Genesis ) ToBlock (db ethdb.Database ) * types.Block {
362- if db == nil {
363- db = rawdb .NewMemoryDatabase ()
364- }
365- root , err := g .Alloc .flush (db )
374+ // ToBlock returns the genesis block according to genesis specification.
375+ func (g * Genesis ) ToBlock () * types.Block {
376+ root , err := g .Alloc .deriveHash ()
366377 if err != nil {
367378 panic (err )
368379 }
@@ -399,7 +410,7 @@ func (g *Genesis) ToBlock(db ethdb.Database) *types.Block {
399410// Commit writes the block and state of a genesis specification to the database.
400411// The block is committed as the canonical head block.
401412func (g * Genesis ) Commit (db ethdb.Database ) (* types.Block , error ) {
402- block := g .ToBlock (db )
413+ block := g .ToBlock ()
403414 if block .Number ().Sign () != 0 {
404415 return nil , errors .New ("can't commit genesis block with number > 0" )
405416 }
@@ -413,7 +424,10 @@ func (g *Genesis) Commit(db ethdb.Database) (*types.Block, error) {
413424 if config .Clique != nil && len (block .Extra ()) < 32 + crypto .SignatureLength {
414425 return nil , errors .New ("can't start clique chain without signers" )
415426 }
416- if err := g .Alloc .write (db , block .Hash ()); err != nil {
427+ // All the checks has passed, flush the states derived from the genesis
428+ // specification as well as the specification itself into the provided
429+ // database.
430+ if err := g .Alloc .flush (db ); err != nil {
417431 return nil , err
418432 }
419433 rawdb .WriteTd (db , block .Hash (), block .NumberU64 (), block .Difficulty ())
@@ -437,15 +451,6 @@ func (g *Genesis) MustCommit(db ethdb.Database) *types.Block {
437451 return block
438452}
439453
440- // GenesisBlockForTesting creates and writes a block in which addr has the given wei balance.
441- func GenesisBlockForTesting (db ethdb.Database , addr common.Address , balance * big.Int ) * types.Block {
442- g := Genesis {
443- Alloc : GenesisAlloc {addr : {Balance : balance }},
444- BaseFee : big .NewInt (params .InitialBaseFee ),
445- }
446- return g .MustCommit (db )
447- }
448-
449454// DefaultGenesisBlock returns the Ethereum main net genesis block.
450455func DefaultGenesisBlock () * Genesis {
451456 return & Genesis {
@@ -529,6 +534,7 @@ func DefaultSepoliaGenesisBlock() *Genesis {
529534 }
530535}
531536
537+ // DefaultKilnGenesisBlock returns the kiln network genesis block.
532538func DefaultKilnGenesisBlock () * Genesis {
533539 g := new (Genesis )
534540 reader := strings .NewReader (KilnAllocData )
0 commit comments