all: introduce trie owner notion (#24750)

* cmd, core/state, light, trie, eth: add trie owner notion

* all: refactor

* tests: fix goimports

* core/state/snapshot: fix ineffasigns

Co-authored-by: Martin Holst Swende <martin@swende.se>
This commit is contained in:
rjl493456442
2022-06-06 17:14:55 +02:00
committed by GitHub
co-authored by Martin Holst Swende
parent c375ee91e9
commit 22defa5af7
40 changed files with 578 additions and 548 deletions
+32 -15
View File
@@ -38,9 +38,10 @@ var stPool = sync.Pool{
},
}
func stackTrieFromPool(db ethdb.KeyValueWriter) *StackTrie {
func stackTrieFromPool(db ethdb.KeyValueWriter, owner common.Hash) *StackTrie {
st := stPool.Get().(*StackTrie)
st.db = db
st.owner = owner
return st
}
@@ -53,6 +54,7 @@ func returnToPool(st *StackTrie) {
// in order. Once it determines that a subtree will no longer be inserted
// into, it will hash it and free up the memory it uses.
type StackTrie struct {
owner common.Hash // the owner of the trie
nodeType uint8 // node type (as in branch, ext, leaf)
val []byte // value contained by this node if it's a leaf
key []byte // key chunk covered by this (leaf|ext) node
@@ -68,6 +70,16 @@ func NewStackTrie(db ethdb.KeyValueWriter) *StackTrie {
}
}
// NewStackTrieWithOwner allocates and initializes an empty trie, but with
// the additional owner field.
func NewStackTrieWithOwner(db ethdb.KeyValueWriter, owner common.Hash) *StackTrie {
return &StackTrie{
owner: owner,
nodeType: emptyNode,
db: db,
}
}
// NewFromBinary initialises a serialized stacktrie with the given db.
func NewFromBinary(data []byte, db ethdb.KeyValueWriter) (*StackTrie, error) {
var st StackTrie
@@ -88,10 +100,12 @@ func (st *StackTrie) MarshalBinary() (data []byte, err error) {
w = bufio.NewWriter(&b)
)
if err := gob.NewEncoder(w).Encode(struct {
Nodetype uint8
Owner common.Hash
NodeType uint8
Val []byte
Key []byte
}{
st.owner,
st.nodeType,
st.val,
st.key,
@@ -122,12 +136,14 @@ func (st *StackTrie) UnmarshalBinary(data []byte) error {
func (st *StackTrie) unmarshalBinary(r io.Reader) error {
var dec struct {
Nodetype uint8
Owner common.Hash
NodeType uint8
Val []byte
Key []byte
}
gob.NewDecoder(r).Decode(&dec)
st.nodeType = dec.Nodetype
st.owner = dec.Owner
st.nodeType = dec.NodeType
st.val = dec.Val
st.key = dec.Key
@@ -154,16 +170,16 @@ func (st *StackTrie) setDb(db ethdb.KeyValueWriter) {
}
}
func newLeaf(key, val []byte, db ethdb.KeyValueWriter) *StackTrie {
st := stackTrieFromPool(db)
func newLeaf(owner common.Hash, key, val []byte, db ethdb.KeyValueWriter) *StackTrie {
st := stackTrieFromPool(db, owner)
st.nodeType = leafNode
st.key = append(st.key, key...)
st.val = val
return st
}
func newExt(key []byte, child *StackTrie, db ethdb.KeyValueWriter) *StackTrie {
st := stackTrieFromPool(db)
func newExt(owner common.Hash, key []byte, child *StackTrie, db ethdb.KeyValueWriter) *StackTrie {
st := stackTrieFromPool(db, owner)
st.nodeType = extNode
st.key = append(st.key, key...)
st.children[0] = child
@@ -196,6 +212,7 @@ func (st *StackTrie) Update(key, value []byte) {
}
func (st *StackTrie) Reset() {
st.owner = common.Hash{}
st.db = nil
st.key = st.key[:0]
st.val = nil
@@ -236,7 +253,7 @@ func (st *StackTrie) insert(key, value []byte) {
// Add new child
if st.children[idx] == nil {
st.children[idx] = newLeaf(key[1:], value, st.db)
st.children[idx] = newLeaf(st.owner, key[1:], value, st.db)
} else {
st.children[idx].insert(key[1:], value)
}
@@ -262,7 +279,7 @@ func (st *StackTrie) insert(key, value []byte) {
// node directly.
var n *StackTrie
if diffidx < len(st.key)-1 {
n = newExt(st.key[diffidx+1:], st.children[0], st.db)
n = newExt(st.owner, st.key[diffidx+1:], st.children[0], st.db)
} else {
// Break on the last byte, no need to insert
// an extension node: reuse the current node
@@ -282,12 +299,12 @@ func (st *StackTrie) insert(key, value []byte) {
// the common prefix is at least one byte
// long, insert a new intermediate branch
// node.
st.children[0] = stackTrieFromPool(st.db)
st.children[0] = stackTrieFromPool(st.db, st.owner)
st.children[0].nodeType = branchNode
p = st.children[0]
}
// Create a leaf for the inserted part
o := newLeaf(key[diffidx+1:], value, st.db)
o := newLeaf(st.owner, key[diffidx+1:], value, st.db)
// Insert both child leaves where they belong:
origIdx := st.key[diffidx]
@@ -323,7 +340,7 @@ func (st *StackTrie) insert(key, value []byte) {
// Convert current node into an ext,
// and insert a child branch node.
st.nodeType = extNode
st.children[0] = NewStackTrie(st.db)
st.children[0] = NewStackTrieWithOwner(st.db, st.owner)
st.children[0].nodeType = branchNode
p = st.children[0]
}
@@ -332,11 +349,11 @@ func (st *StackTrie) insert(key, value []byte) {
// value and another containing the new value. The child leaf
// is hashed directly in order to free up some memory.
origIdx := st.key[diffidx]
p.children[origIdx] = newLeaf(st.key[diffidx+1:], st.val, st.db)
p.children[origIdx] = newLeaf(st.owner, st.key[diffidx+1:], st.val, st.db)
p.children[origIdx].hash()
newIdx := key[diffidx]
p.children[newIdx] = newLeaf(key[diffidx+1:], value, st.db)
p.children[newIdx] = newLeaf(st.owner, key[diffidx+1:], value, st.db)
// Finally, cut off the key part that has been passed
// over to the children.