Skip to content

Commit 1a3c3ae

Browse files
authored
fix(trie): use direct Merkle value for database keys (#2725)
1 parent 9dc11e4 commit 1a3c3ae

File tree

8 files changed

+150
-158
lines changed

8 files changed

+150
-158
lines changed

dot/state/offline_pruner.go

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

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

110110
logger.Infof("Latest block number is %d", latestBlockNum)
111111

@@ -121,7 +121,7 @@ func (p *OfflinePruner) SetBloomFilter() (err error) {
121121
return err
122122
}
123123

124-
tr.PopulateNodeHashes(tr.RootNode(), keys)
124+
tr.PopulateMerkleValues(tr.RootNode(), merkleValues)
125125

126126
// get parent header of current block
127127
header, err = p.blockState.GetHeader(header.ParentHash)
@@ -131,14 +131,14 @@ func (p *OfflinePruner) SetBloomFilter() (err error) {
131131
blockNum = header.Number
132132
}
133133

134-
for key := range keys {
135-
err = p.bloom.put(key.ToBytes())
134+
for key := range merkleValues {
135+
err = p.bloom.put([]byte(key))
136136
if err != nil {
137137
return err
138138
}
139139
}
140140

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

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
@@ -85,13 +85,13 @@ func (s *StorageState) StoreTrie(ts *rtstorage.TrieState, header *types.Header)
8585
}
8686

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

93-
deletedNodeHashes := ts.GetDeletedNodeHashes()
94-
err = s.pruner.StoreJournalRecord(deletedNodeHashes, insertedNodeHashes, header.Hash(), int64(header.Number))
93+
deletedMerkleValues := ts.GetDeletedMerkleValues()
94+
err = s.pruner.StoreJournalRecord(deletedMerkleValues, insertedMerkleValues, header.Hash(), int64(header.Number))
9595
if err != nil {
9696
return err
9797
}

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: 22 additions & 25 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.MerkleValue)
202-
hashesSet[hash] = struct{}{}
201+
merkleValues[string(child.MerkleValue)] = struct{}{}
203202

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

@@ -354,20 +353,18 @@ func (t *Trie) writeDirtyNode(db chaindb.Batch, n *Node) (err error) {
354353
return nil
355354
}
356355

357-
// GetInsertedNodeHashes returns a set of hashes with all
358-
// the hashes of all nodes that were inserted in the state trie
359-
// since the last snapshot.
360-
// We need to compute the hash values of each newly inserted node.
361-
func (t *Trie) GetInsertedNodeHashes() (hashesSet map[common.Hash]struct{}, err error) {
362-
hashesSet = make(map[common.Hash]struct{})
363-
err = t.getInsertedNodeHashesAtNode(t.root, hashesSet)
356+
// GetInsertedMerkleValues returns the set of node Merkle values
357+
// for each node that was inserted in the state trie since the last snapshot.
358+
func (t *Trie) GetInsertedMerkleValues() (merkleValues map[string]struct{}, err error) {
359+
merkleValues = make(map[string]struct{})
360+
err = t.getInsertedNodeHashesAtNode(t.root, merkleValues)
364361
if err != nil {
365362
return nil, err
366363
}
367-
return hashesSet, nil
364+
return merkleValues, nil
368365
}
369366

370-
func (t *Trie) getInsertedNodeHashesAtNode(n *Node, hashes map[common.Hash]struct{}) (err error) {
367+
func (t *Trie) getInsertedNodeHashesAtNode(n *Node, merkleValues map[string]struct{}) (err error) {
371368
if n == nil || !n.Dirty {
372369
return nil
373370
}
@@ -384,7 +381,7 @@ func (t *Trie) getInsertedNodeHashesAtNode(n *Node, hashes map[common.Hash]struc
384381
n.MerkleValue, err)
385382
}
386383

387-
hashes[common.BytesToHash(merkleValue)] = struct{}{}
384+
merkleValues[string(merkleValue)] = struct{}{}
388385

389386
if n.Kind() != node.Branch {
390387
return nil
@@ -395,7 +392,7 @@ func (t *Trie) getInsertedNodeHashesAtNode(n *Node, hashes map[common.Hash]struc
395392
continue
396393
}
397394

398-
err := t.getInsertedNodeHashesAtNode(child, hashes)
395+
err := t.getInsertedNodeHashesAtNode(child, merkleValues)
399396
if err != nil {
400397
// Note: do not wrap error since this is called recursively.
401398
return err
@@ -405,13 +402,13 @@ func (t *Trie) getInsertedNodeHashesAtNode(n *Node, hashes map[common.Hash]struc
405402
return nil
406403
}
407404

408-
// GetDeletedNodeHashes returns a set of all the hashes of nodes that were
409-
// deleted from the trie since the last snapshot was made.
410-
// The returned set is a copy of the internal set to prevent data races.
411-
func (t *Trie) GetDeletedNodeHashes() (hashesSet map[common.Hash]struct{}) {
412-
hashesSet = make(map[common.Hash]struct{}, len(t.deletedKeys))
413-
for k := range t.deletedKeys {
414-
hashesSet[k] = struct{}{}
405+
// GetDeletedMerkleValues returns a set of all the node Merkle values for each
406+
// node that was deleted from the trie since the last snapshot was made.
407+
// The returned set is a copy of the internal set to prevent data corruption.
408+
func (t *Trie) GetDeletedMerkleValues() (merkleValues map[string]struct{}) {
409+
merkleValues = make(map[string]struct{}, len(t.deletedMerkleValues))
410+
for k := range t.deletedMerkleValues {
411+
merkleValues[k] = struct{}{}
415412
}
416-
return hashesSet
413+
return merkleValues
417414
}

0 commit comments

Comments
 (0)