Skip to content

Commit

Permalink
chore(lib/trie): remove Store method (#2922)
Browse files Browse the repository at this point in the history
- `WriteDirty` is just the clever version of `Store`, where we write only nodes that got changed in-memory from the version we have in the database.
- This also ensures all the nodes are set as dirty correctly
  • Loading branch information
qdm12 authored Nov 15, 2022
1 parent 8d809aa commit b2a8a86
Show file tree
Hide file tree
Showing 9 changed files with 25 additions and 75 deletions.
2 changes: 1 addition & 1 deletion dot/state/base_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func TestTrie_StoreAndLoadFromDB(t *testing.T) {
tt.Put(key, value)
}

err := tt.Store(db)
err := tt.WriteDirty(db)
require.NoError(t, err)

encroot, err := tt.Hash()
Expand Down
4 changes: 2 additions & 2 deletions dot/state/initialize.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func (s *Service) Initialise(gen *genesis.Genesis, header *types.Header, t *trie
return fmt.Errorf("failed to clear database: %s", err)
}

if err = t.Store(chaindb.NewTable(db, storagePrefix)); err != nil {
if err = t.WriteDirty(chaindb.NewTable(db, storagePrefix)); err != nil {
return fmt.Errorf("failed to write genesis trie to database: %w", err)
}

Expand Down Expand Up @@ -137,7 +137,7 @@ func loadGrandpaAuthorities(t *trie.Trie) ([]types.GrandpaVoter, error) {
// storeInitialValues writes initial genesis values to the state database
func (s *Service) storeInitialValues(data *genesis.Data, t *trie.Trie) error {
// write genesis trie to database
if err := t.Store(chaindb.NewTable(s.db, storagePrefix)); err != nil {
if err := t.WriteDirty(chaindb.NewTable(s.db, storagePrefix)); err != nil {
return fmt.Errorf("failed to write trie to database: %s", err)
}

Expand Down
2 changes: 1 addition & 1 deletion dot/state/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ func (s *Service) Import(header *types.Header, t *trie.Trie, firstSlot uint64) e
logger.Info("importing storage trie from base path " +
s.dbPath + " with root " + root.String() + "...")

if err := t.Store(storage.db); err != nil {
if err := t.WriteDirty(storage.db); err != nil {
return err
}

Expand Down
13 changes: 12 additions & 1 deletion dot/state/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,24 @@ func TestService_Initialise(t *testing.T) {
state := newTestService(t)

genData, genTrie, genesisHeader := newTestGenesisWithTrieAndHeader(t)

// Deep copy the trie because of the following:
// Initialise clears the database, writes only dirty nodes to disk
// and marks them as clean.
// Initialise is called twice.
// The first call writes all nodes to disk and marks them as clean in the
// in-memory trie representation.
// If the same trie is re-used for the second call, the database is cleared
// and nothing is written to disk since all nodes are marked as clean.
genTrieCopy := genTrie.DeepCopy()

err := state.Initialise(&genData, &genesisHeader, &genTrie)
require.NoError(t, err)

genesisHeaderPtr := types.NewHeader(common.NewHash([]byte{77}),
genTrie.MustHash(), trie.EmptyHash, 0, types.NewDigest())

err = state.Initialise(&genData, genesisHeaderPtr, &genTrie)
err = state.Initialise(&genData, genesisHeaderPtr, genTrieCopy)
require.NoError(t, err)

err = state.SetupBase()
Expand Down
2 changes: 1 addition & 1 deletion lib/runtime/wasmer/imports_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1789,7 +1789,7 @@ func Test_ext_trie_blake2_256_verify_proof_version_1(t *testing.T) {
tr.Put([]byte("otherwise"), []byte("randomstuff"))
tr.Put([]byte("cat"), []byte("another animal"))

err = tr.Store(memdb)
err = tr.WriteDirty(memdb)
require.NoError(t, err)

hash, err := tr.Hash()
Expand Down
61 changes: 0 additions & 61 deletions lib/trie/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,67 +20,6 @@ type Database interface {
Get(key []byte) (value []byte, err error)
}

// Store stores each trie node in the database,
// where the key is the hash of the encoded node
// and the value is the encoded node.
// Generally, this will only be used for the genesis trie.
func (t *Trie) Store(db chaindb.Database) error {
for _, v := range t.childTries {
if err := v.Store(db); err != nil {
return fmt.Errorf("failed to store child trie with root hash=0x%x in the db: %w", v.root.MerkleValue, err)
}
}

batch := db.NewBatch()
err := t.storeNode(batch, t.root)
if err != nil {
batch.Reset()
return err
}

return batch.Flush()
}

func (t *Trie) storeNode(db chaindb.Batch, n *Node) (err error) {
if n == nil {
return nil
}

var encoding, hash []byte
if n == t.root {
encoding, hash, err = n.EncodeAndHashRoot()
} else {
encoding, hash, err = n.EncodeAndHash()
}
if err != nil {
return err
}

err = db.Put(hash, encoding)
if err != nil {
return err
}

if n.Kind() == node.Branch {
for _, child := range n.Children {
if child == nil {
continue
}

err = t.storeNode(db, child)
if err != nil {
return err
}
}
}

if n.Dirty {
n.SetClean()
}

return nil
}

// Load reconstructs the trie from the database from the given root hash.
// It is used when restarting the node to load the current state trie.
func (t *Trie) Load(db Database, rootHash common.Hash) error {
Expand Down
12 changes: 6 additions & 6 deletions lib/trie/database_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func Test_Trie_Store_Load(t *testing.T) {
rootHash := trie.MustHash()

db := newTestDB(t)
err := trie.Store(db)
err := trie.WriteDirty(db)
require.NoError(t, err)

trieFromDB := NewEmptyTrie()
Expand Down Expand Up @@ -64,7 +64,7 @@ func Test_Trie_WriteDirty_Put(t *testing.T) {
assert.Equalf(t, value, valueFromDB, "for key=%x", key)
}

err := trie.Store(db)
err := trie.WriteDirty(db)
require.NoError(t, err)

// Pick an existing key and replace its value
Expand Down Expand Up @@ -100,7 +100,7 @@ func Test_Trie_WriteDirty_Delete(t *testing.T) {
keysToDelete := pickKeys(keyValues, generator, size/50)

db := newTestDB(t)
err := trie.Store(db)
err := trie.WriteDirty(db)
require.NoError(t, err)

deletedKeys := make(map[string]struct{}, len(keysToDelete))
Expand Down Expand Up @@ -141,7 +141,7 @@ func Test_Trie_WriteDirty_ClearPrefix(t *testing.T) {
keysToClearPrefix := pickKeys(keyValues, generator, size/50)

db := newTestDB(t)
err := trie.Store(db)
err := trie.WriteDirty(db)
require.NoError(t, err)

for _, keyToClearPrefix := range keysToClearPrefix {
Expand Down Expand Up @@ -261,7 +261,7 @@ func Test_GetFromDB(t *testing.T) {
trie, keyValues := makeSeededTrie(t, size)

db := newTestDB(t)
err := trie.Store(db)
err := trie.WriteDirty(db)
require.NoError(t, err)

root := trie.MustHash()
Expand Down Expand Up @@ -298,7 +298,7 @@ func Test_Trie_PutChild_Store_Load(t *testing.T) {
err := trie.PutChild(keyToChildTrie, childTrie)
require.NoError(t, err)

err = trie.Store(db)
err = trie.WriteDirty(db)
require.NoError(t, err)

trieFromDB := NewEmptyTrie()
Expand Down
2 changes: 1 addition & 1 deletion lib/trie/proof/proof_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func Test_Generate_Verify(t *testing.T) {
InMemory: true,
})
require.NoError(t, err)
err = trie.Store(database)
err = trie.WriteDirty(database)
require.NoError(t, err)

for i, key := range keys {
Expand Down
2 changes: 1 addition & 1 deletion lib/trie/trie_endtoend_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ func TestTrieDiff(t *testing.T) {
}

newTrie := trie.Snapshot()
err = trie.Store(storageDB)
err = trie.WriteDirty(storageDB)
require.NoError(t, err)

tests = []keyValues{
Expand Down

0 comments on commit b2a8a86

Please sign in to comment.