mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
core, trie: experimentation with state witnesses
This commit is contained in:
parent
333dd956bf
commit
387b0fe6e8
7 changed files with 54 additions and 8 deletions
|
|
@ -125,6 +125,8 @@ type Trie interface {
|
||||||
// be created with new root and updated trie database for following usage
|
// be created with new root and updated trie database for following usage
|
||||||
Commit(collectLeaf bool) (common.Hash, *trienode.NodeSet, error)
|
Commit(collectLeaf bool) (common.Hash, *trienode.NodeSet, error)
|
||||||
|
|
||||||
|
CommitAndObtainAccessList(collectLeaf bool) (common.Hash, *trienode.NodeSet, map[string][]byte, error)
|
||||||
|
|
||||||
// NodeIterator returns an iterator that returns nodes of the trie. Iteration
|
// NodeIterator returns an iterator that returns nodes of the trie. Iteration
|
||||||
// starts at the key after the given start key. And error will be returned
|
// starts at the key after the given start key. And error will be returned
|
||||||
// if fails to create node iterator.
|
// if fails to create node iterator.
|
||||||
|
|
|
||||||
|
|
@ -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, map[string][]byte, 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,16 @@ 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, accessList, err := s.trie.CommitAndObtainAccessList(false)
|
||||||
|
//root, nodes, 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, accessList, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddBalance adds amount to s's balance.
|
// AddBalance adds amount to s's balance.
|
||||||
|
|
|
||||||
|
|
@ -1169,6 +1169,7 @@ func (s *StateDB) Commit(block uint64, deleteEmptyObjects bool) (common.Hash, er
|
||||||
if s.dbErr != nil {
|
if s.dbErr != nil {
|
||||||
return common.Hash{}, fmt.Errorf("commit aborted due to earlier error: %v", s.dbErr)
|
return common.Hash{}, fmt.Errorf("commit aborted due to earlier error: %v", s.dbErr)
|
||||||
}
|
}
|
||||||
|
w := newWitness(s.originalRoot)
|
||||||
// Finalize any pending changes and merge everything into the tries
|
// Finalize any pending changes and merge everything into the tries
|
||||||
s.IntermediateRoot(deleteEmptyObjects)
|
s.IntermediateRoot(deleteEmptyObjects)
|
||||||
|
|
||||||
|
|
@ -1198,7 +1199,8 @@ 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, accessList, err := obj.commit()
|
||||||
|
w.addAccessList(obj.addrHash, accessList)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.Hash{}, err
|
return common.Hash{}, err
|
||||||
}
|
}
|
||||||
|
|
@ -1224,7 +1226,9 @@ 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, err := s.trie.Commit(true)
|
||||||
|
root, set, accessList, err := s.trie.CommitAndObtainAccessList(true)
|
||||||
|
w.addAccessList(common.Hash{}, accessList)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.Hash{}, err
|
return common.Hash{}, err
|
||||||
}
|
}
|
||||||
|
|
@ -1298,6 +1302,9 @@ func (s *StateDB) Commit(block uint64, deleteEmptyObjects bool) (common.Hash, er
|
||||||
s.storagesOrigin = make(map[common.Address]map[common.Hash][]byte)
|
s.storagesOrigin = make(map[common.Address]map[common.Hash][]byte)
|
||||||
s.stateObjectsDirty = make(map[common.Address]struct{})
|
s.stateObjectsDirty = make(map[common.Address]struct{})
|
||||||
s.stateObjectsDestruct = make(map[common.Address]*types.StateAccount)
|
s.stateObjectsDestruct = make(map[common.Address]*types.StateAccount)
|
||||||
|
|
||||||
|
w.Dump()
|
||||||
|
|
||||||
return root, nil
|
return root, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -177,6 +177,10 @@ func (t *odrTrie) DeleteAccount(address common.Address) error {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *odrTrie) CommitAndObtainAccessList(collectLeaf bool) (common.Hash, *trienode.NodeSet, map[string][]byte, error) {
|
||||||
|
panic("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
func (t *odrTrie) Commit(collectLeaf bool) (common.Hash, *trienode.NodeSet, error) {
|
func (t *odrTrie) Commit(collectLeaf bool) (common.Hash, *trienode.NodeSet, error) {
|
||||||
if t.trie == nil {
|
if t.trie == nil {
|
||||||
return t.id.Root, nil, nil
|
return t.id.Root, nil, nil
|
||||||
|
|
|
||||||
|
|
@ -216,6 +216,22 @@ func (t *StateTrie) GetKey(shaKey []byte) []byte {
|
||||||
return t.preimages.preimage(common.BytesToHash(shaKey))
|
return t.preimages.preimage(common.BytesToHash(shaKey))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *StateTrie) CommitAndObtainAccessList(collectLeaf bool) (common.Hash, *trienode.NodeSet, map[string][]byte, error) {
|
||||||
|
// Write all the pre-images to the actual disk database
|
||||||
|
if len(t.getSecKeyCache()) > 0 {
|
||||||
|
if t.preimages != nil {
|
||||||
|
preimages := make(map[common.Hash][]byte)
|
||||||
|
for hk, key := range t.secKeyCache {
|
||||||
|
preimages[common.BytesToHash([]byte(hk))] = key
|
||||||
|
}
|
||||||
|
t.preimages.insertPreimage(preimages)
|
||||||
|
}
|
||||||
|
t.secKeyCache = make(map[string][]byte)
|
||||||
|
}
|
||||||
|
// Commit the trie and return its modified nodeset.
|
||||||
|
return t.trie.CommitAndObtainAccessList(collectLeaf)
|
||||||
|
}
|
||||||
|
|
||||||
// Commit collects all dirty nodes in the trie and replaces them with the
|
// Commit collects all dirty nodes in the trie and replaces them with the
|
||||||
// corresponding node hash. All collected nodes (including dirty leaves if
|
// corresponding node hash. All collected nodes (including dirty leaves if
|
||||||
// collectLeaf is true) will be encapsulated into a nodeset for return.
|
// collectLeaf is true) will be encapsulated into a nodeset for return.
|
||||||
|
|
|
||||||
14
trie/trie.go
14
trie/trie.go
|
|
@ -601,6 +601,18 @@ func (t *Trie) Hash() common.Hash {
|
||||||
return common.BytesToHash(hash.(hashNode))
|
return common.BytesToHash(hash.(hashNode))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *Trie) CommitAndObtainAccessList(collectLeaf bool) (common.Hash, *trienode.NodeSet, map[string][]byte, error) {
|
||||||
|
accessList := t.tracer.accessList
|
||||||
|
// Commit will reset the tracer accessList, so after this
|
||||||
|
// operation, we have full ownership of the map (hence: no need to
|
||||||
|
// deep-copy or even copy).
|
||||||
|
rootHash, nodes, err := t.Commit(collectLeaf)
|
||||||
|
if err != nil {
|
||||||
|
return rootHash, nodes, nil, err
|
||||||
|
}
|
||||||
|
return rootHash, nodes, accessList, err
|
||||||
|
}
|
||||||
|
|
||||||
// Commit collects all dirty nodes in the trie and replaces them with the
|
// Commit collects all dirty nodes in the trie and replaces them with the
|
||||||
// corresponding node hash. All collected nodes (including dirty leaves if
|
// corresponding node hash. All collected nodes (including dirty leaves if
|
||||||
// collectLeaf is true) will be encapsulated into a nodeset for return.
|
// collectLeaf is true) will be encapsulated into a nodeset for return.
|
||||||
|
|
@ -608,8 +620,8 @@ func (t *Trie) Hash() common.Hash {
|
||||||
// Once the trie is committed, it's not usable anymore. A new trie must
|
// Once the trie is committed, it's not usable anymore. A new trie must
|
||||||
// be created with new root and updated trie database for following usage
|
// be created with new root and updated trie database for following usage
|
||||||
func (t *Trie) Commit(collectLeaf bool) (common.Hash, *trienode.NodeSet, error) {
|
func (t *Trie) Commit(collectLeaf bool) (common.Hash, *trienode.NodeSet, error) {
|
||||||
defer t.tracer.reset()
|
|
||||||
defer func() {
|
defer func() {
|
||||||
|
t.tracer.reset()
|
||||||
t.committed = true
|
t.committed = true
|
||||||
}()
|
}()
|
||||||
// Trie is empty and can be classified into two types of situations:
|
// Trie is empty and can be classified into two types of situations:
|
||||||
|
|
|
||||||
|
|
@ -218,6 +218,10 @@ func (t *VerkleTrie) Hash() common.Hash {
|
||||||
return t.root.Commit().Bytes()
|
return t.root.Commit().Bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *VerkleTrie) CommitAndObtainAccessList(collectLeaf bool) (common.Hash, *trienode.NodeSet, map[string][]byte, error) {
|
||||||
|
panic("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
// Commit writes all nodes to the tree's memory database.
|
// Commit writes all nodes to the tree's memory database.
|
||||||
func (t *VerkleTrie) Commit(_ bool) (common.Hash, *trienode.NodeSet, error) {
|
func (t *VerkleTrie) Commit(_ bool) (common.Hash, *trienode.NodeSet, error) {
|
||||||
root, ok := t.root.(*verkle.InternalNode)
|
root, ok := t.root.(*verkle.InternalNode)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue