mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-24 05:36:46 +00:00
changes with witness tracking
This commit is contained in:
parent
80bc2f3ac1
commit
97519e0ff2
7 changed files with 36 additions and 54 deletions
|
|
@ -130,11 +130,7 @@ type Trie interface {
|
||||||
|
|
||||||
// Witness returns a set containing all trie nodes that have been accessed.
|
// Witness returns a set containing all trie nodes that have been accessed.
|
||||||
// The returned map could be nil if the witness is empty.
|
// The returned map could be nil if the witness is empty.
|
||||||
Witness() map[string]struct{}
|
Witness() map[string][]byte
|
||||||
|
|
||||||
// WitnessPaths returns a set of paths for all trie nodes. For future reference,
|
|
||||||
// witness can be deprecated and used as a replacement to witness.
|
|
||||||
WitnessPaths() map[string]struct{}
|
|
||||||
|
|
||||||
// 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
|
||||||
|
|
|
||||||
|
|
@ -841,7 +841,7 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
|
||||||
// If witness building is enabled and the state object has a trie,
|
// If witness building is enabled and the state object has a trie,
|
||||||
// gather the witnesses for its specific storage trie
|
// gather the witnesses for its specific storage trie
|
||||||
if s.witness != nil && obj.trie != nil {
|
if s.witness != nil && obj.trie != nil {
|
||||||
s.witness.AddState(obj.trie.Witness(), obj.trie.WitnessPaths())
|
s.witness.AddState(obj.trie.Witness())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -858,9 +858,9 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if trie := obj.getPrefetchedTrie(); trie != nil {
|
if trie := obj.getPrefetchedTrie(); trie != nil {
|
||||||
s.witness.AddState(trie.Witness(), trie.WitnessPaths())
|
s.witness.AddState(trie.Witness())
|
||||||
} else if obj.trie != nil {
|
} else if obj.trie != nil {
|
||||||
s.witness.AddState(obj.trie.Witness(), obj.trie.WitnessPaths())
|
s.witness.AddState(obj.trie.Witness())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Pull in only-read and non-destructed trie witnesses
|
// Pull in only-read and non-destructed trie witnesses
|
||||||
|
|
@ -874,9 +874,9 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if trie := obj.getPrefetchedTrie(); trie != nil {
|
if trie := obj.getPrefetchedTrie(); trie != nil {
|
||||||
s.witness.AddState(trie.Witness(), trie.WitnessPaths())
|
s.witness.AddState(trie.Witness())
|
||||||
} else if obj.trie != nil {
|
} else if obj.trie != nil {
|
||||||
s.witness.AddState(obj.trie.Witness(), obj.trie.WitnessPaths())
|
s.witness.AddState(obj.trie.Witness())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -942,7 +942,7 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
|
||||||
|
|
||||||
// If witness building is enabled, gather the account trie witness
|
// If witness building is enabled, gather the account trie witness
|
||||||
if s.witness != nil {
|
if s.witness != nil {
|
||||||
s.witness.AddState(s.trie.Witness(), nil)
|
s.witness.AddState(s.trie.Witness())
|
||||||
}
|
}
|
||||||
return hash
|
return hash
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -91,16 +91,15 @@ func (w *Witness) AddCode(code []byte) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddState inserts a batch of MPT trie nodes into the witness.
|
// AddState inserts a batch of MPT trie nodes into the witness.
|
||||||
func (w *Witness) AddState(nodes map[string]struct{}, paths map[string]struct{}) {
|
func (w *Witness) AddState(nodemap map[string][]byte) {
|
||||||
if len(nodes) == 0 {
|
if len(nodemap) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.lock.Lock()
|
w.lock.Lock()
|
||||||
defer w.lock.Unlock()
|
defer w.lock.Unlock()
|
||||||
|
for path, value := range nodemap {
|
||||||
maps.Copy(w.State, nodes)
|
w.State[string(value)] = struct{}{}
|
||||||
if paths != nil {
|
w.Paths[string(path)] = struct{}{} // Also track the path for the node
|
||||||
maps.Copy(w.Paths, paths)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -273,7 +273,7 @@ func (t *StateTrie) GetKey(shaKey []byte) []byte {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Witness returns a set containing all trie nodes that have been accessed.
|
// Witness returns a set containing all trie nodes that have been accessed.
|
||||||
func (t *StateTrie) Witness() map[string]struct{} {
|
func (t *StateTrie) Witness() map[string][]byte {
|
||||||
return t.trie.Witness()
|
return t.trie.Witness()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -158,6 +158,10 @@ func (t *prevalueTracer) keys() []string {
|
||||||
return slices.Collect(maps.Keys(t.data))
|
return slices.Collect(maps.Keys(t.data))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *prevalueTracer) getMap() map[string][]byte {
|
||||||
|
return maps.Clone(t.data)
|
||||||
|
}
|
||||||
|
|
||||||
// reset resets the cached content in the prevalueTracer.
|
// reset resets the cached content in the prevalueTracer.
|
||||||
func (t *prevalueTracer) reset() {
|
func (t *prevalueTracer) reset() {
|
||||||
t.lock.Lock()
|
t.lock.Lock()
|
||||||
|
|
|
||||||
48
trie/trie.go
48
trie/trie.go
|
|
@ -133,6 +133,12 @@ func (t *Trie) NodeIterator(start []byte) (NodeIterator, error) {
|
||||||
return newNodeIterator(t, start), nil
|
return newNodeIterator(t, start), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Owner returns the owner of the trie, allowing us to distinguis between
|
||||||
|
// storage and account tries.
|
||||||
|
func (t *Trie) Owner() common.Hash {
|
||||||
|
return t.owner
|
||||||
|
}
|
||||||
|
|
||||||
// MustGet is a wrapper of Get and will omit any encountered error but just
|
// MustGet is a wrapper of Get and will omit any encountered error but just
|
||||||
// print out an error message.
|
// print out an error message.
|
||||||
func (t *Trie) MustGet(key []byte) []byte {
|
func (t *Trie) MustGet(key []byte) []byte {
|
||||||
|
|
@ -517,9 +523,6 @@ func (t *Trie) delete(n node, prefix, key []byte) (bool, node, error) {
|
||||||
// always creates a new slice) instead of append to
|
// always creates a new slice) instead of append to
|
||||||
// avoid modifying n.Key since it might be shared with
|
// avoid modifying n.Key since it might be shared with
|
||||||
// other nodes.
|
// other nodes.
|
||||||
if t.owner == (common.Hash{}) {
|
|
||||||
stateDepthAggregator.record(int64(len(prefix) + len(key)))
|
|
||||||
}
|
|
||||||
return true, &shortNode{concat(n.Key, child.Key...), child.Val, t.newFlag()}, nil
|
return true, &shortNode{concat(n.Key, child.Key...), child.Val, t.newFlag()}, nil
|
||||||
default:
|
default:
|
||||||
return true, &shortNode{n.Key, child, t.newFlag()}, nil
|
return true, &shortNode{n.Key, child, t.newFlag()}, nil
|
||||||
|
|
@ -577,10 +580,7 @@ func (t *Trie) delete(n node, prefix, key []byte) (bool, node, error) {
|
||||||
// Replace the entire full node with the short node.
|
// Replace the entire full node with the short node.
|
||||||
// Mark the original short node as deleted since the
|
// Mark the original short node as deleted since the
|
||||||
// value is embedded into the parent now.
|
// value is embedded into the parent now.
|
||||||
t.tracer.onDelete(append(prefix, byte(pos)))
|
t.opTracer.onDelete(append(prefix, byte(pos)))
|
||||||
if t.owner == (common.Hash{}) {
|
|
||||||
stateDepthAggregator.record(int64(len(prefix) + 1))
|
|
||||||
}
|
|
||||||
|
|
||||||
k := append([]byte{byte(pos)}, cnode.Key...)
|
k := append([]byte{byte(pos)}, cnode.Key...)
|
||||||
return true, &shortNode{k, cnode.Val, t.newFlag()}, nil
|
return true, &shortNode{k, cnode.Val, t.newFlag()}, nil
|
||||||
|
|
@ -618,6 +618,13 @@ func (t *Trie) delete(n node, prefix, key []byte) (bool, node, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func concat(s1 []byte, s2 ...byte) []byte {
|
||||||
|
r := make([]byte, len(s1)+len(s2))
|
||||||
|
copy(r, s1)
|
||||||
|
copy(r[len(s1):], s2)
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
// copyNode deep-copies the supplied node along with its children recursively.
|
// copyNode deep-copies the supplied node along with its children recursively.
|
||||||
func copyNode(n node) node {
|
func copyNode(n node) node {
|
||||||
switch n := (n).(type) {
|
switch n := (n).(type) {
|
||||||
|
|
@ -757,31 +764,12 @@ func (t *Trie) hashRoot() []byte {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Witness returns a set containing all trie nodes that have been accessed.
|
// Witness returns a set containing all trie nodes that have been accessed.
|
||||||
func (t *Trie) Witness() map[string]struct{} {
|
func (t *Trie) Witness() map[string][]byte {
|
||||||
values := t.prevalueTracer.values()
|
dataMap := t.prevalueTracer.getMap()
|
||||||
if len(values) == 0 {
|
if len(dataMap) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
witnessStates := make(map[string]struct{}, len(values))
|
return dataMap
|
||||||
for _, val := range values {
|
|
||||||
witnessStates[string(val)] = struct{}{}
|
|
||||||
}
|
|
||||||
|
|
||||||
return witnessStates
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *Trie) WitnessPaths() map[string]struct{} {
|
|
||||||
// Return the paths of all nodes that have been accessed.
|
|
||||||
// The paths are the keys of the prevalue tracer.
|
|
||||||
keys := t.prevalueTracer.keys()
|
|
||||||
if len(keys) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
witnessPaths := make(map[string]struct{}, len(keys))
|
|
||||||
for _, key := range keys {
|
|
||||||
witnessPaths[string(key)] = struct{}{}
|
|
||||||
}
|
|
||||||
return witnessPaths
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset drops the referenced root node and cleans all internal state.
|
// Reset drops the referenced root node and cleans all internal state.
|
||||||
|
|
|
||||||
|
|
@ -452,11 +452,6 @@ func (t *VerkleTrie) nodeResolver(path []byte) ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Witness returns a set containing all trie nodes that have been accessed.
|
// Witness returns a set containing all trie nodes that have been accessed.
|
||||||
func (t *VerkleTrie) Witness() map[string]struct{} {
|
func (t *VerkleTrie) Witness() map[string][]byte {
|
||||||
panic("not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Witness returns a set containing all trie nodes that have been accessed.
|
|
||||||
func (t *VerkleTrie) WitnessPaths() map[string]struct{} {
|
|
||||||
panic("not implemented")
|
panic("not implemented")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue