@@ -80,16 +80,33 @@ 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 won't be leaked into disk for sure.
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 }
90- // Short circuit if nothing to flush
91- if len (* ga ) == 0 {
92- return statedb .Commit (false )
92+ for addr , account := range * ga {
93+ statedb .AddBalance (addr , account .Balance )
94+ statedb .SetCode (addr , account .Code )
95+ statedb .SetNonce (addr , account .Nonce )
96+ for key , value := range account .Storage {
97+ statedb .SetState (addr , key , value )
98+ }
99+ }
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
93110 }
94111 for addr , account := range * ga {
95112 statedb .AddBalance (addr , account .Balance )
@@ -101,31 +118,26 @@ func (ga *GenesisAlloc) flush(db ethdb.Database) (common.Hash, error) {
101118 }
102119 root , err := statedb .Commit (false )
103120 if err != nil {
104- return common. Hash {}, err
121+ return err
105122 }
106123 err = statedb .Database ().TrieDB ().Commit (root , true , nil )
107124 if err != nil {
108- return common. Hash {}, err
125+ return err
109126 }
110- return root , nil
111- }
112-
113- // write writes the json marshaled genesis state into database
114- // with the given block hash as the unique identifier.
115- func (ga * GenesisAlloc ) write (db ethdb.KeyValueWriter , hash common.Hash ) error {
127+ // Marshal the genesis state specification and persist.
116128 blob , err := json .Marshal (ga )
117129 if err != nil {
118130 return err
119131 }
120- rawdb .WriteGenesisState (db , hash , blob )
132+ rawdb .WriteGenesisStateSpec (db , root , blob )
121133 return nil
122134}
123135
124136// CommitGenesisState loads the stored genesis state with the given block
125137// hash and commits them into the given database handler.
126138func CommitGenesisState (db ethdb.Database , hash common.Hash ) error {
127139 var alloc GenesisAlloc
128- blob := rawdb .ReadGenesisState (db , hash )
140+ blob := rawdb .ReadGenesisStateSpec (db , hash )
129141 if len (blob ) != 0 {
130142 if err := alloc .UnmarshalJSON (blob ); err != nil {
131143 return err
@@ -155,8 +167,7 @@ func CommitGenesisState(db ethdb.Database, hash common.Hash) error {
155167 return errors .New ("not found" )
156168 }
157169 }
158- _ , err := alloc .flush (db )
159- return err
170+ return alloc .flush (db )
160171}
161172
162173// GenesisAccount is an account in the state of the genesis block.
@@ -351,13 +362,9 @@ func (g *Genesis) configOrDefault(ghash common.Hash) *params.ChainConfig {
351362 }
352363}
353364
354- // toBlock creates the genesis block and writes state of a genesis specification
355- // to the given database (or discards it if nil).
356- func (g * Genesis ) toBlock (db ethdb.Database ) * types.Block {
357- if db == nil {
358- db = rawdb .NewMemoryDatabase ()
359- }
360- root , err := g .Alloc .flush (db )
365+ // ToBlock returns the genesis block according to genesis specification.
366+ func (g * Genesis ) ToBlock () * types.Block {
367+ root , err := g .Alloc .deriveHash ()
361368 if err != nil {
362369 panic (err )
363370 }
@@ -391,15 +398,10 @@ func (g *Genesis) toBlock(db ethdb.Database) *types.Block {
391398 return types .NewBlock (head , nil , nil , nil , trie .NewStackTrie (nil ))
392399}
393400
394- // ToBlock returns the genesis block according to genesis specification.
395- func (g * Genesis ) ToBlock () * types.Block {
396- return g .toBlock (nil )
397- }
398-
399401// Commit writes the block and state of a genesis specification to the database.
400402// The block is committed as the canonical head block.
401403func (g * Genesis ) Commit (db ethdb.Database ) (* types.Block , error ) {
402- block := g .toBlock ( db )
404+ block := g .ToBlock ( )
403405 if block .Number ().Sign () != 0 {
404406 return nil , errors .New ("can't commit genesis block with number > 0" )
405407 }
@@ -413,7 +415,10 @@ func (g *Genesis) Commit(db ethdb.Database) (*types.Block, error) {
413415 if config .Clique != nil && len (block .Extra ()) < 32 + crypto .SignatureLength {
414416 return nil , errors .New ("can't start clique chain without signers" )
415417 }
416- if err := g .Alloc .write (db , block .Hash ()); err != nil {
418+ // All the checks has passed, flush the states derived from the genesis
419+ // specification as well as the specification itself into the provided
420+ // database.
421+ if err := g .Alloc .flush (db ); err != nil {
417422 return nil , err
418423 }
419424 rawdb .WriteTd (db , block .Hash (), block .NumberU64 (), block .Difficulty ())
0 commit comments