Skip to content

Commit

Permalink
fix(state): node hashes vs merkle values
Browse files Browse the repository at this point in the history
- Pruners only care about node hashes
- Rename variables, functions and methods only dealing with node hashes
- Do not write or read inlined nodes with a non-hash Merkle value
- Clarify error wrappings and comments
  • Loading branch information
qdm12 committed Nov 2, 2022
1 parent b4d3789 commit 1d957d2
Show file tree
Hide file tree
Showing 10 changed files with 141 additions and 119 deletions.
10 changes: 5 additions & 5 deletions dot/state/offline_pruner.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ func (p *OfflinePruner) SetBloomFilter() (err error) {
}

latestBlockNum := header.Number
merkleValues := make(map[string]struct{})
nodeHashes := make(map[common.Hash]struct{})

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

Expand All @@ -121,7 +121,7 @@ func (p *OfflinePruner) SetBloomFilter() (err error) {
return err
}

trie.PopulateNodeHashes(tr.RootNode(), merkleValues)
trie.PopulateNodeHashes(tr.RootNode(), nodeHashes)

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

for key := range merkleValues {
err = p.bloom.put([]byte(key))
for key := range nodeHashes {
err = p.bloom.put(key.ToBytes())
if err != nil {
return err
}
}

logger.Infof("Total keys added in bloom filter: %d", len(merkleValues))
logger.Infof("Total keys added in bloom filter: %d", len(nodeHashes))
return nil
}

Expand Down
66 changes: 33 additions & 33 deletions dot/state/pruner/pruner.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,22 +51,22 @@ type Config struct {

// Pruner is implemented by FullNode and ArchiveNode.
type Pruner interface {
StoreJournalRecord(deletedMerkleValues, insertedMerkleValues map[string]struct{},
StoreJournalRecord(deletedNodeHashes, insertedNodeHashes map[common.Hash]struct{},
blockHash common.Hash, blockNum int64) error
}

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

// StoreJournalRecord for archive node doesn't do anything.
func (*ArchiveNode) StoreJournalRecord(_, _ map[string]struct{},
func (*ArchiveNode) StoreJournalRecord(_, _ map[common.Hash]struct{},
_ common.Hash, _ int64) error {
return nil
}

type deathRecord struct {
blockHash common.Hash
deletedMerkleValueToBlockNumber map[string]int64
blockHash common.Hash
deletedNodeHashToBlockNumber map[common.Hash]int64
}

type deathRow []*deathRecord
Expand All @@ -77,8 +77,8 @@ type FullNode struct {
deathList []deathRow
storageDB chaindb.Database
journalDB chaindb.Database
// deathIndex is the mapping from deleted node Merkle value to block number.
deathIndex map[string]int64
// deathIndex is the mapping from deleted node hash to block number.
deathIndex map[common.Hash]int64
// pendingNumber is the block number to be pruned.
// Initial value is set to 1 and is incremented after every block pruning.
pendingNumber int64
Expand All @@ -89,31 +89,31 @@ type FullNode struct {
type journalRecord struct {
// blockHash of the block corresponding to journal record
blockHash common.Hash
// Merkle values of nodes inserted in the state trie of the block
insertedMerkleValues map[string]struct{}
// Merkle values of nodes deleted from the state trie of the block
deletedMerkleValues map[string]struct{}
// Node hashes of nodes inserted in the state trie of the block
insertedNodeHashes map[common.Hash]struct{}
// Node hashes of nodes deleted from the state trie of the block
deletedNodeHashes map[common.Hash]struct{}
}

type journalKey struct {
blockNum int64
blockHash common.Hash
}

func newJournalRecord(hash common.Hash, insertedMerkleValues,
deletedMerkleValues map[string]struct{}) *journalRecord {
func newJournalRecord(hash common.Hash, insertedNodeHashes,
deletedNodeHashes map[common.Hash]struct{}) *journalRecord {
return &journalRecord{
blockHash: hash,
insertedMerkleValues: insertedMerkleValues,
deletedMerkleValues: deletedMerkleValues,
blockHash: hash,
insertedNodeHashes: insertedNodeHashes,
deletedNodeHashes: deletedNodeHashes,
}
}

// NewFullNode creates a Pruner for full node.
func NewFullNode(db, storageDB chaindb.Database, retainBlocks uint32, l log.LeveledLogger) (Pruner, error) {
p := &FullNode{
deathList: make([]deathRow, 0),
deathIndex: make(map[string]int64),
deathIndex: make(map[common.Hash]int64),
storageDB: storageDB,
journalDB: chaindb.NewTable(db, journalPrefix),
retainBlocks: retainBlocks,
Expand Down Expand Up @@ -141,9 +141,9 @@ func NewFullNode(db, storageDB chaindb.Database, retainBlocks uint32, l log.Leve
}

// StoreJournalRecord stores journal record into DB and add deathRow into deathList
func (p *FullNode) StoreJournalRecord(deletedMerkleValues, insertedMerkleValues map[string]struct{},
func (p *FullNode) StoreJournalRecord(deletedNodeHashes, insertedNodeHashes map[common.Hash]struct{},
blockHash common.Hash, blockNum int64) error {
jr := newJournalRecord(blockHash, insertedMerkleValues, deletedMerkleValues)
jr := newJournalRecord(blockHash, insertedNodeHashes, deletedNodeHashes)

key := &journalKey{blockNum, blockHash}
err := p.storeJournal(key, jr)
Expand All @@ -169,13 +169,13 @@ func (p *FullNode) addDeathRow(jr *journalRecord, blockNum int64) {
return
}

p.processInsertedKeys(jr.insertedMerkleValues, jr.blockHash)
p.processInsertedKeys(jr.insertedNodeHashes, jr.blockHash)

// add deleted node Merkle values from journal to death index
deletedMerkleValueToBlockNumber := make(map[string]int64, len(jr.deletedMerkleValues))
for k := range jr.deletedMerkleValues {
// add deleted node hashes from journal to death index
deletedNodeHashToBlockNumber := make(map[common.Hash]int64, len(jr.deletedNodeHashes))
for k := range jr.deletedNodeHashes {
p.deathIndex[k] = blockNum
deletedMerkleValueToBlockNumber[k] = blockNum
deletedNodeHashToBlockNumber[k] = blockNum
}

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

record := &deathRecord{
blockHash: jr.blockHash,
deletedMerkleValueToBlockNumber: deletedMerkleValueToBlockNumber,
blockHash: jr.blockHash,
deletedNodeHashToBlockNumber: deletedNodeHashToBlockNumber,
}

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

// Remove re-inserted keys
func (p *FullNode) processInsertedKeys(insertedMerkleValues map[string]struct{}, blockHash common.Hash) {
for k := range insertedMerkleValues {
func (p *FullNode) processInsertedKeys(insertedNodeHashes map[common.Hash]struct{}, blockHash common.Hash) {
for k := range insertedNodeHashes {
num, ok := p.deathIndex[k]
if !ok {
continue
}
records := p.deathList[num-p.pendingNumber]
for _, v := range records {
if v.blockHash == blockHash {
delete(v.deletedMerkleValueToBlockNumber, k)
delete(v.deletedNodeHashToBlockNumber, k)
}
}
delete(p.deathIndex, k)
Expand Down Expand Up @@ -230,14 +230,14 @@ func (p *FullNode) start() {

sdbBatch := p.storageDB.NewBatch()
for _, record := range row {
err := p.deleteKeys(sdbBatch, record.deletedMerkleValueToBlockNumber)
err := p.deleteKeys(sdbBatch, record.deletedNodeHashToBlockNumber)
if err != nil {
p.logger.Warnf("failed to prune keys for block number %d: %s", blockNum, err)
sdbBatch.Reset()
return
}

for k := range record.deletedMerkleValueToBlockNumber {
for k := range record.deletedNodeHashToBlockNumber {
delete(p.deathIndex, k)
}
}
Expand Down Expand Up @@ -374,9 +374,9 @@ func (p *FullNode) getLastPrunedIndex() (int64, error) {
return blockNum, nil
}

func (*FullNode) deleteKeys(b chaindb.Batch, deletedMerkleValueToBlockNumber map[string]int64) error {
for merkleValue := range deletedMerkleValueToBlockNumber {
err := b.Del([]byte(merkleValue))
func (*FullNode) deleteKeys(b chaindb.Batch, deletedNodeHashToBlockNumber map[common.Hash]int64) error {
for nodeHash := range deletedNodeHashToBlockNumber {
err := b.Del(nodeHash.ToBytes())
if err != nil {
return err
}
Expand Down
8 changes: 4 additions & 4 deletions dot/state/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,13 @@ func (s *StorageState) StoreTrie(ts *rtstorage.TrieState, header *types.Header)
}

if header != nil {
insertedMerkleValues, err := ts.GetInsertedMerkleValues()
insertedNodeHashes, err := ts.GetInsertedNodeHashes()
if err != nil {
return fmt.Errorf("failed to get state trie inserted keys: block %s %w", header.Hash(), err)
return fmt.Errorf("getting trie inserted node hashes for block hash %s: %w", header.Hash(), err)
}

deletedMerkleValues := ts.GetDeletedMerkleValues()
err = s.pruner.StoreJournalRecord(deletedMerkleValues, insertedMerkleValues, header.Hash(), int64(header.Number))
deletedNodeHashes := ts.GetDeletedNodeHashes()
err = s.pruner.StoreJournalRecord(deletedNodeHashes, insertedNodeHashes, header.Hash(), int64(header.Number))
if err != nil {
return err
}
Expand Down
12 changes: 6 additions & 6 deletions lib/runtime/storage/trie.go
Original file line number Diff line number Diff line change
Expand Up @@ -291,18 +291,18 @@ func (s *TrieState) LoadCodeHash() (common.Hash, error) {
return common.Blake2bHash(code)
}

// GetInsertedMerkleValues returns the set of all node Merkle value inserted
// GetInsertedNodeHashes returns the set of all node hashes inserted
// into the state trie since the last block produced.
func (s *TrieState) GetInsertedMerkleValues() (merkleValues map[string]struct{}, err error) {
func (s *TrieState) GetInsertedNodeHashes() (nodeHashes map[common.Hash]struct{}, err error) {
s.lock.RLock()
defer s.lock.RUnlock()
return s.t.GetInsertedMerkleValues()
return s.t.GetInsertedNodeHashes()
}

// GetDeletedMerkleValues returns the set of all node Merkle values deleted
// GetDeletedNodeHashes returns the set of all node hashes deleted
// from the state trie since the last block produced.
func (s *TrieState) GetDeletedMerkleValues() (merkleValues map[string]struct{}) {
func (s *TrieState) GetDeletedNodeHashes() (nodeHashes map[common.Hash]struct{}) {
s.lock.RLock()
defer s.lock.RUnlock()
return s.t.GetDeletedMerkleValues()
return s.t.GetDeletedNodeHashes()
}
Loading

0 comments on commit 1d957d2

Please sign in to comment.