core, trie: aggregate witness

This commit is contained in:
Gary Rong 2023-10-07 20:29:23 +08:00
parent 213a0eb149
commit 07eeb7d86a
3 changed files with 35 additions and 7 deletions

View file

@ -375,11 +375,11 @@ func (s *stateObject) updateRoot() {
// commit obtains a set of dirty storage trie nodes and updates the account data. // commit obtains a set of dirty storage trie nodes and updates the account data.
// The returned set can be nil if nothing to commit. This function assumes all // The returned set can be nil if nothing to commit. This function assumes all
// storage mutations have already been flushed into trie by updateRoot. // storage mutations have already been flushed into trie by updateRoot.
func (s *stateObject) commit() (*trienode.NodeSet, error) { func (s *stateObject) commit() (*trienode.NodeSet, *trienode.Witness, error) {
// Short circuit if trie is not even loaded, don't bother with committing anything // Short circuit if trie is not even loaded, don't bother with committing anything
if s.trie == nil { if s.trie == nil {
s.origin = s.data.Copy() s.origin = s.data.Copy()
return nil, nil return nil, nil, nil
} }
// Track the amount of time wasted on committing the storage trie // Track the amount of time wasted on committing the storage trie
if metrics.EnabledExpensive { if metrics.EnabledExpensive {
@ -388,15 +388,15 @@ func (s *stateObject) commit() (*trienode.NodeSet, error) {
// The trie is currently in an open state and could potentially contain // The trie is currently in an open state and could potentially contain
// cached mutations. Call commit to acquire a set of nodes that have been // cached mutations. Call commit to acquire a set of nodes that have been
// modified, the set can be nil if nothing to commit. // modified, the set can be nil if nothing to commit.
root, nodes, _, err := s.trie.Commit(false) root, nodes, witness, err := s.trie.Commit(false)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
s.data.Root = root s.data.Root = root
// Update original account data after commit // Update original account data after commit
s.origin = s.data.Copy() s.origin = s.data.Copy()
return nodes, nil return nodes, witness, nil
} }
// AddBalance adds amount to s's balance. // AddBalance adds amount to s's balance.

View file

@ -1177,6 +1177,7 @@ func (s *StateDB) Commit(block uint64, deleteEmptyObjects bool) (common.Hash, er
storageTrieNodesUpdated int storageTrieNodesUpdated int
storageTrieNodesDeleted int storageTrieNodesDeleted int
nodes = trienode.NewMergedNodeSet() nodes = trienode.NewMergedNodeSet()
witnesses = trienode.NewWitnesses()
codeWriter = s.db.DiskDB().NewBatch() codeWriter = s.db.DiskDB().NewBatch()
) )
// Handle all state deletions first // Handle all state deletions first
@ -1196,7 +1197,7 @@ func (s *StateDB) Commit(block uint64, deleteEmptyObjects bool) (common.Hash, er
obj.dirtyCode = false obj.dirtyCode = false
} }
// Write any storage changes in the state object to its storage trie // Write any storage changes in the state object to its storage trie
set, err := obj.commit() set, witness, err := obj.commit()
if err != nil { if err != nil {
return common.Hash{}, err return common.Hash{}, err
} }
@ -1211,6 +1212,9 @@ func (s *StateDB) Commit(block uint64, deleteEmptyObjects bool) (common.Hash, er
storageTrieNodesUpdated += updates storageTrieNodesUpdated += updates
storageTrieNodesDeleted += deleted storageTrieNodesDeleted += deleted
} }
if witness != nil {
witnesses.Merge(witness)
}
} }
if codeWriter.ValueSize() > 0 { if codeWriter.ValueSize() > 0 {
if err := codeWriter.Write(); err != nil { if err := codeWriter.Write(); err != nil {
@ -1222,7 +1226,7 @@ func (s *StateDB) Commit(block uint64, deleteEmptyObjects bool) (common.Hash, er
if metrics.EnabledExpensive { if metrics.EnabledExpensive {
start = time.Now() start = time.Now()
} }
root, set, _, err := s.trie.Commit(true) root, set, witness, err := s.trie.Commit(true)
if err != nil { if err != nil {
return common.Hash{}, err return common.Hash{}, err
} }
@ -1233,6 +1237,9 @@ func (s *StateDB) Commit(block uint64, deleteEmptyObjects bool) (common.Hash, er
} }
accountTrieNodesUpdated, accountTrieNodesDeleted = set.Size() accountTrieNodesUpdated, accountTrieNodesDeleted = set.Size()
} }
if witness != nil {
witnesses.Merge(witness)
}
if metrics.EnabledExpensive { if metrics.EnabledExpensive {
s.AccountCommits += time.Since(start) s.AccountCommits += time.Since(start)

View file

@ -59,3 +59,24 @@ func (w *Witness) Copy() *Witness {
} }
return cpy return cpy
} }
// Witnesses represents a set of witness for a group of tries.
type Witnesses struct {
witness map[common.Hash]*Witness
}
// NewWitnesses initializes an empty witness set.
func NewWitnesses() *Witnesses {
return &Witnesses{witness: make(map[common.Hash]*Witness)}
}
// Merge merges the provided dirty nodes of a trie into the set. The assumption
// is held that no duplicated set belonging to the same trie will be merged twice.
func (set *Witnesses) Merge(other *Witness) error {
_, present := set.witness[other.Owner]
if present {
//return subset.Merge(other.Owner, other.Nodes)
}
set.witness[other.Owner] = other
return nil
}