Skip to content

Commit 209cde5

Browse files
committed
core: apply feedback from Guillaume
1 parent 5c09ef9 commit 209cde5

File tree

4 files changed

+50
-44
lines changed

4 files changed

+50
-44
lines changed

core/genesis.go

Lines changed: 38 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
126138
func 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.
401403
func (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())

core/genesis_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -217,12 +217,12 @@ func TestReadWriteGenesisAlloc(t *testing.T) {
217217
{1}: {Balance: big.NewInt(1), Storage: map[common.Hash]common.Hash{{1}: {1}}},
218218
{2}: {Balance: big.NewInt(2), Storage: map[common.Hash]common.Hash{{2}: {2}}},
219219
}
220-
hash = common.HexToHash("0xdeadbeef")
220+
hash, _ = alloc.deriveHash()
221221
)
222-
alloc.write(db, hash)
222+
alloc.flush(db)
223223

224224
var reload GenesisAlloc
225-
err := reload.UnmarshalJSON(rawdb.ReadGenesisState(db, hash))
225+
err := reload.UnmarshalJSON(rawdb.ReadGenesisStateSpec(db, hash))
226226
if err != nil {
227227
t.Fatalf("Failed to load genesis state %v", err)
228228
}

core/rawdb/accessors_metadata.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,15 +81,16 @@ func WriteChainConfig(db ethdb.KeyValueWriter, hash common.Hash, cfg *params.Cha
8181
}
8282
}
8383

84-
// ReadGenesisState retrieves the genesis state based on the given genesis hash.
85-
func ReadGenesisState(db ethdb.KeyValueReader, hash common.Hash) []byte {
86-
data, _ := db.Get(genesisKey(hash))
84+
// ReadGenesisStateSpec retrieves the genesis state specification based on the
85+
// given genesis hash.
86+
func ReadGenesisStateSpec(db ethdb.KeyValueReader, hash common.Hash) []byte {
87+
data, _ := db.Get(genesisStateSpecKey(hash))
8788
return data
8889
}
8990

90-
// WriteGenesisState writes the genesis state into the disk.
91-
func WriteGenesisState(db ethdb.KeyValueWriter, hash common.Hash, data []byte) {
92-
if err := db.Put(genesisKey(hash), data); err != nil {
91+
// WriteGenesisStateSpec writes the genesis state specification into the disk.
92+
func WriteGenesisStateSpec(db ethdb.KeyValueWriter, hash common.Hash, data []byte) {
93+
if err := db.Put(genesisStateSpecKey(hash), data); err != nil {
9394
log.Crit("Failed to store genesis state", "err", err)
9495
}
9596
}

core/rawdb/schema.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ func configKey(hash common.Hash) []byte {
247247
return append(configPrefix, hash.Bytes()...)
248248
}
249249

250-
// genesisKey = genesisPrefix + hash
251-
func genesisKey(hash common.Hash) []byte {
250+
// genesisStateSpecKey = genesisPrefix + hash
251+
func genesisStateSpecKey(hash common.Hash) []byte {
252252
return append(genesisPrefix, hash.Bytes()...)
253253
}

0 commit comments

Comments
 (0)