Skip to content

Commit 3c25b41

Browse files
committed
fix(trie): use Merkle value for database keys
1 parent 4f311a5 commit 3c25b41

File tree

9 files changed

+158
-166
lines changed

9 files changed

+158
-166
lines changed

dot/state/offline_pruner.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ func (p *OfflinePruner) SetBloomFilter() (err error) {
107107
}
108108

109109
latestBlockNum := header.Number
110-
keys := make(map[common.Hash]struct{})
110+
merkleValues := make(map[string]struct{})
111111

112112
logger.Infof("Latest block number is %d", latestBlockNum)
113113

@@ -123,7 +123,7 @@ func (p *OfflinePruner) SetBloomFilter() (err error) {
123123
return err
124124
}
125125

126-
tr.PopulateNodeHashes(tr.RootNode(), keys)
126+
tr.PopulateMerkleValues(tr.RootNode(), merkleValues)
127127

128128
// get parent header of current block
129129
header, err = p.blockState.GetHeader(header.ParentHash)
@@ -133,14 +133,14 @@ func (p *OfflinePruner) SetBloomFilter() (err error) {
133133
blockNum = header.Number
134134
}
135135

136-
for key := range keys {
137-
err = p.bloom.put(key.ToBytes())
136+
for key := range merkleValues {
137+
err = p.bloom.put([]byte(key))
138138
if err != nil {
139139
return err
140140
}
141141
}
142142

143-
logger.Infof("Total keys added in bloom filter: %d", len(keys))
143+
logger.Infof("Total keys added in bloom filter: %d", len(merkleValues))
144144
return nil
145145
}
146146

dot/state/pruner/pruner.go

Lines changed: 37 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -51,33 +51,34 @@ type Config struct {
5151

5252
// Pruner is implemented by FullNode and ArchiveNode.
5353
type Pruner interface {
54-
StoreJournalRecord(deletedHashesSet, insertedHashesSet map[common.Hash]struct{},
54+
StoreJournalRecord(deletedMerkleValues, insertedMerkleValues map[string]struct{},
5555
blockHash common.Hash, blockNum int64) error
5656
}
5757

5858
// ArchiveNode is a no-op since we don't prune nodes in archive mode.
5959
type ArchiveNode struct{}
6060

6161
// StoreJournalRecord for archive node doesn't do anything.
62-
func (*ArchiveNode) StoreJournalRecord(_, _ map[common.Hash]struct{},
62+
func (*ArchiveNode) StoreJournalRecord(_, _ map[string]struct{},
6363
_ common.Hash, _ int64) error {
6464
return nil
6565
}
6666

6767
type deathRecord struct {
68-
blockHash common.Hash
69-
deletedKeys map[common.Hash]int64 // Mapping from deleted key hash to block number.
68+
blockHash common.Hash
69+
deletedMerkleValueToBlockNumber map[string]int64
7070
}
7171

7272
type deathRow []*deathRecord
7373

7474
// FullNode stores state trie diff and allows online state trie pruning
7575
type FullNode struct {
76-
logger log.LeveledLogger
77-
deathList []deathRow
78-
storageDB chaindb.Database
79-
journalDB chaindb.Database
80-
deathIndex map[common.Hash]int64 // Mapping from deleted key hash to block number.
76+
logger log.LeveledLogger
77+
deathList []deathRow
78+
storageDB chaindb.Database
79+
journalDB chaindb.Database
80+
// deathIndex is the mapping from deleted node Merkle value to block number.
81+
deathIndex map[string]int64
8182
// pendingNumber is the block number to be pruned.
8283
// Initial value is set to 1 and is incremented after every block pruning.
8384
pendingNumber int64
@@ -88,31 +89,31 @@ type FullNode struct {
8889
type journalRecord struct {
8990
// blockHash of the block corresponding to journal record
9091
blockHash common.Hash
91-
// Hash of keys that are inserted into state trie of the block
92-
insertedHashesSet map[common.Hash]struct{}
93-
// Hash of keys that are deleted from state trie of the block
94-
deletedHashesSet map[common.Hash]struct{}
92+
// Merkle values of nodes inserted in the state trie of the block
93+
insertedMerkleValues map[string]struct{}
94+
// Merkle values of nodes deleted from the state trie of the block
95+
deletedMerkleValues map[string]struct{}
9596
}
9697

9798
type journalKey struct {
9899
blockNum int64
99100
blockHash common.Hash
100101
}
101102

102-
func newJournalRecord(hash common.Hash, insertedHashesSet,
103-
deletedHashesSet map[common.Hash]struct{}) *journalRecord {
103+
func newJournalRecord(hash common.Hash, insertedMerkleValues,
104+
deletedMerkleValues map[string]struct{}) *journalRecord {
104105
return &journalRecord{
105-
blockHash: hash,
106-
insertedHashesSet: insertedHashesSet,
107-
deletedHashesSet: deletedHashesSet,
106+
blockHash: hash,
107+
insertedMerkleValues: insertedMerkleValues,
108+
deletedMerkleValues: deletedMerkleValues,
108109
}
109110
}
110111

111112
// NewFullNode creates a Pruner for full node.
112113
func NewFullNode(db, storageDB chaindb.Database, retainBlocks int64, l log.LeveledLogger) (Pruner, error) {
113114
p := &FullNode{
114115
deathList: make([]deathRow, 0),
115-
deathIndex: make(map[common.Hash]int64),
116+
deathIndex: make(map[string]int64),
116117
storageDB: storageDB,
117118
journalDB: chaindb.NewTable(db, journalPrefix),
118119
retainBlocks: retainBlocks,
@@ -140,9 +141,9 @@ func NewFullNode(db, storageDB chaindb.Database, retainBlocks int64, l log.Level
140141
}
141142

142143
// StoreJournalRecord stores journal record into DB and add deathRow into deathList
143-
func (p *FullNode) StoreJournalRecord(deletedHashesSet, insertedHashesSet map[common.Hash]struct{},
144+
func (p *FullNode) StoreJournalRecord(deletedMerkleValues, insertedMerkleValues map[string]struct{},
144145
blockHash common.Hash, blockNum int64) error {
145-
jr := newJournalRecord(blockHash, insertedHashesSet, deletedHashesSet)
146+
jr := newJournalRecord(blockHash, insertedMerkleValues, deletedMerkleValues)
146147

147148
key := &journalKey{blockNum, blockHash}
148149
err := p.storeJournal(key, jr)
@@ -168,13 +169,13 @@ func (p *FullNode) addDeathRow(jr *journalRecord, blockNum int64) {
168169
return
169170
}
170171

171-
p.processInsertedKeys(jr.insertedHashesSet, jr.blockHash)
172+
p.processInsertedKeys(jr.insertedMerkleValues, jr.blockHash)
172173

173-
// add deleted keys from journal to death index
174-
deletedKeys := make(map[common.Hash]int64, len(jr.deletedHashesSet))
175-
for k := range jr.deletedHashesSet {
174+
// add deleted node Merkle values from journal to death index
175+
deletedMerkleValueToBlockNumber := make(map[string]int64, len(jr.deletedMerkleValues))
176+
for k := range jr.deletedMerkleValues {
176177
p.deathIndex[k] = blockNum
177-
deletedKeys[k] = blockNum
178+
deletedMerkleValueToBlockNumber[k] = blockNum
178179
}
179180

180181
blockIndex := blockNum - p.pendingNumber
@@ -183,25 +184,25 @@ func (p *FullNode) addDeathRow(jr *journalRecord, blockNum int64) {
183184
}
184185

185186
record := &deathRecord{
186-
blockHash: jr.blockHash,
187-
deletedKeys: deletedKeys,
187+
blockHash: jr.blockHash,
188+
deletedMerkleValueToBlockNumber: deletedMerkleValueToBlockNumber,
188189
}
189190

190191
// add deathRow to deathList
191192
p.deathList[blockIndex] = append(p.deathList[blockIndex], record)
192193
}
193194

194195
// Remove re-inserted keys
195-
func (p *FullNode) processInsertedKeys(insertedHashesSet map[common.Hash]struct{}, blockHash common.Hash) {
196-
for k := range insertedHashesSet {
196+
func (p *FullNode) processInsertedKeys(insertedMerkleValues map[string]struct{}, blockHash common.Hash) {
197+
for k := range insertedMerkleValues {
197198
num, ok := p.deathIndex[k]
198199
if !ok {
199200
continue
200201
}
201202
records := p.deathList[num-p.pendingNumber]
202203
for _, v := range records {
203204
if v.blockHash == blockHash {
204-
delete(v.deletedKeys, k)
205+
delete(v.deletedMerkleValueToBlockNumber, k)
205206
}
206207
}
207208
delete(p.deathIndex, k)
@@ -229,14 +230,14 @@ func (p *FullNode) start() {
229230

230231
sdbBatch := p.storageDB.NewBatch()
231232
for _, record := range row {
232-
err := p.deleteKeys(sdbBatch, record.deletedKeys)
233+
err := p.deleteKeys(sdbBatch, record.deletedMerkleValueToBlockNumber)
233234
if err != nil {
234235
p.logger.Warnf("failed to prune keys for block number %d: %s", blockNum, err)
235236
sdbBatch.Reset()
236237
return
237238
}
238239

239-
for k := range record.deletedKeys {
240+
for k := range record.deletedMerkleValueToBlockNumber {
240241
delete(p.deathIndex, k)
241242
}
242243
}
@@ -373,9 +374,9 @@ func (p *FullNode) getLastPrunedIndex() (int64, error) {
373374
return blockNum, nil
374375
}
375376

376-
func (*FullNode) deleteKeys(b chaindb.Batch, nodesHash map[common.Hash]int64) error {
377-
for k := range nodesHash {
378-
err := b.Del(k.ToBytes())
377+
func (*FullNode) deleteKeys(b chaindb.Batch, deletedMerkleValueToBlockNumber map[string]int64) error {
378+
for merkleValue := range deletedMerkleValueToBlockNumber {
379+
err := b.Del([]byte(merkleValue))
379380
if err != nil {
380381
return err
381382
}

dot/state/storage.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,13 +83,13 @@ func (s *StorageState) StoreTrie(ts *rtstorage.TrieState, header *types.Header)
8383
}
8484

8585
if header != nil {
86-
insertedNodeHashes, err := ts.GetInsertedNodeHashes()
86+
insertedMerkleValues, err := ts.GetInsertedMerkleValues()
8787
if err != nil {
8888
return fmt.Errorf("failed to get state trie inserted keys: block %s %w", header.Hash(), err)
8989
}
9090

91-
deletedNodeHashes := ts.GetDeletedNodeHashes()
92-
err = s.pruner.StoreJournalRecord(deletedNodeHashes, insertedNodeHashes, header.Hash(), int64(header.Number))
91+
deletedMerkleValues := ts.GetDeletedMerkleValues()
92+
err = s.pruner.StoreJournalRecord(deletedMerkleValues, insertedMerkleValues, header.Hash(), int64(header.Number))
9393
if err != nil {
9494
return err
9595
}

internal/trie/node/hash.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import (
1212

1313
// EncodeAndHash returns the encoding of the node and
1414
// the Merkle value of the node.
15-
func (n *Node) EncodeAndHash() (encoding, hash []byte, err error) {
15+
func (n *Node) EncodeAndHash() (encoding, merkleValue []byte, err error) {
1616
if !n.Dirty && n.Encoding != nil && n.HashDigest != nil {
1717
return n.Encoding, n.HashDigest, nil
1818
}
@@ -37,8 +37,8 @@ func (n *Node) EncodeAndHash() (encoding, hash []byte, err error) {
3737
if buffer.Len() < 32 {
3838
n.HashDigest = make([]byte, len(bufferBytes))
3939
copy(n.HashDigest, bufferBytes)
40-
hash = n.HashDigest // no need to copy
41-
return encoding, hash, nil
40+
merkleValue = n.HashDigest // no need to copy
41+
return encoding, merkleValue, nil
4242
}
4343

4444
// Note: using the sync.Pool's buffer is useful here.
@@ -47,9 +47,9 @@ func (n *Node) EncodeAndHash() (encoding, hash []byte, err error) {
4747
return nil, nil, err
4848
}
4949
n.HashDigest = hashArray[:]
50-
hash = n.HashDigest // no need to copy
50+
merkleValue = n.HashDigest // no need to copy
5151

52-
return encoding, hash, nil
52+
return encoding, merkleValue, nil
5353
}
5454

5555
// EncodeAndHashRoot returns the encoding of the root node and

lib/runtime/storage/trie.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -271,18 +271,18 @@ func (s *TrieState) LoadCodeHash() (common.Hash, error) {
271271
return common.Blake2bHash(code)
272272
}
273273

274-
// GetInsertedNodeHashes returns a set of hashes of all nodes
275-
// that were inserted into state trie since the last block produced.
276-
func (s *TrieState) GetInsertedNodeHashes() (hashesSet map[common.Hash]struct{}, err error) {
274+
// GetInsertedMerkleValues returns the set of all node Merkle value inserted
275+
// into the state trie since the last block produced.
276+
func (s *TrieState) GetInsertedMerkleValues() (merkleValues map[string]struct{}, err error) {
277277
s.lock.RLock()
278278
defer s.lock.RUnlock()
279-
return s.t.GetInsertedNodeHashes()
279+
return s.t.GetInsertedMerkleValues()
280280
}
281281

282-
// GetDeletedNodeHashes returns the hash of nodes that were deleted
282+
// GetDeletedMerkleValues returns the set of all node Merkle values deleted
283283
// from the state trie since the last block produced.
284-
func (s *TrieState) GetDeletedNodeHashes() (hashesSet map[common.Hash]struct{}) {
284+
func (s *TrieState) GetDeletedMerkleValues() (merkleValues map[string]struct{}) {
285285
s.lock.RLock()
286286
defer s.lock.RUnlock()
287-
return s.t.GetDeletedNodeHashes()
287+
return s.t.GetDeletedMerkleValues()
288288
}

lib/trie/database.go

Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -185,9 +185,9 @@ func (t *Trie) loadNode(db Database, n *Node) error {
185185
return nil
186186
}
187187

188-
// PopulateNodeHashes writes hashes of each children of the node given
189-
// as keys to the map hashesSet.
190-
func (t *Trie) PopulateNodeHashes(n *Node, hashesSet map[common.Hash]struct{}) {
188+
// PopulateMerkleValues writes the Merkle value of each children of the node given
189+
// as keys to the map merkleValues.
190+
func (t *Trie) PopulateMerkleValues(n *Node, merkleValues map[string]struct{}) {
191191
if n.Kind() != node.Branch {
192192
return
193193
}
@@ -198,10 +198,9 @@ func (t *Trie) PopulateNodeHashes(n *Node, hashesSet map[common.Hash]struct{}) {
198198
continue
199199
}
200200

201-
hash := common.BytesToHash(child.HashDigest)
202-
hashesSet[hash] = struct{}{}
201+
merkleValues[string(child.HashDigest)] = struct{}{}
203202

204-
t.PopulateNodeHashes(child, hashesSet)
203+
t.PopulateMerkleValues(child, merkleValues)
205204
}
206205
}
207206

@@ -379,37 +378,35 @@ func (t *Trie) writeDirtyNode(db chaindb.Batch, n *Node) (err error) {
379378
return nil
380379
}
381380

382-
// GetInsertedNodeHashes returns a set of hashes with all
383-
// the hashes of all nodes that were inserted in the state trie
384-
// since the last snapshot.
385-
// We need to compute the hash values of each newly inserted node.
386-
func (t *Trie) GetInsertedNodeHashes() (hashesSet map[common.Hash]struct{}, err error) {
387-
hashesSet = make(map[common.Hash]struct{})
388-
err = t.getInsertedNodeHashesAtNode(t.root, hashesSet)
381+
// GetInsertedMerkleValues returns the set of node Merkle values
382+
// for each node that was inserted in the state trie since the last snapshot.
383+
func (t *Trie) GetInsertedMerkleValues() (merkleValues map[string]struct{}, err error) {
384+
merkleValues = make(map[string]struct{})
385+
err = t.getInsertedNodeHashesAtNode(t.root, merkleValues)
389386
if err != nil {
390387
return nil, err
391388
}
392-
return hashesSet, nil
389+
return merkleValues, nil
393390
}
394391

395-
func (t *Trie) getInsertedNodeHashesAtNode(n *Node, hashes map[common.Hash]struct{}) (err error) {
392+
func (t *Trie) getInsertedNodeHashesAtNode(n *Node, merkleValues map[string]struct{}) (err error) {
396393
if n == nil || !n.Dirty {
397394
return nil
398395
}
399396

400-
var hash []byte
397+
var merkleValue []byte
401398
if n == t.root {
402-
_, hash, err = n.EncodeAndHashRoot()
399+
_, merkleValue, err = n.EncodeAndHashRoot()
403400
} else {
404-
_, hash, err = n.EncodeAndHash()
401+
_, merkleValue, err = n.EncodeAndHash()
405402
}
406403
if err != nil {
407404
return fmt.Errorf(
408405
"cannot encode and hash node with hash 0x%x: %w",
409406
n.HashDigest, err)
410407
}
411408

412-
hashes[common.BytesToHash(hash)] = struct{}{}
409+
merkleValues[string(merkleValue)] = struct{}{}
413410

414411
if n.Kind() != node.Branch {
415412
return nil
@@ -420,7 +417,7 @@ func (t *Trie) getInsertedNodeHashesAtNode(n *Node, hashes map[common.Hash]struc
420417
continue
421418
}
422419

423-
err := t.getInsertedNodeHashesAtNode(child, hashes)
420+
err := t.getInsertedNodeHashesAtNode(child, merkleValues)
424421
if err != nil {
425422
// Note: do not wrap error since this is called recursively.
426423
return err
@@ -430,13 +427,13 @@ func (t *Trie) getInsertedNodeHashesAtNode(n *Node, hashes map[common.Hash]struc
430427
return nil
431428
}
432429

433-
// GetDeletedNodeHashes returns a set of all the hashes of nodes that were
434-
// deleted from the trie since the last snapshot was made.
435-
// The returned set is a copy of the internal set to prevent data races.
436-
func (t *Trie) GetDeletedNodeHashes() (hashesSet map[common.Hash]struct{}) {
437-
hashesSet = make(map[common.Hash]struct{}, len(t.deletedKeys))
438-
for k := range t.deletedKeys {
439-
hashesSet[k] = struct{}{}
430+
// GetDeletedMerkleValues returns a set of all the node Merkle values for each
431+
// node that was deleted from the trie since the last snapshot was made.
432+
// The returned set is a copy of the internal set to prevent data corruption.
433+
func (t *Trie) GetDeletedMerkleValues() (merkleValues map[string]struct{}) {
434+
merkleValues = make(map[string]struct{}, len(t.deletedMerkleValues))
435+
for k := range t.deletedMerkleValues {
436+
merkleValues[k] = struct{}{}
440437
}
441-
return hashesSet
438+
return merkleValues
442439
}

0 commit comments

Comments
 (0)