2019-12-04 12:48:38 +00:00
|
|
|
package trie
|
|
|
|
|
|
|
|
import (
|
2021-05-20 18:25:53 +00:00
|
|
|
"github.com/ledgerwatch/erigon/common"
|
|
|
|
"github.com/ledgerwatch/erigon/core/types/accounts"
|
2019-12-04 12:48:38 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type keyTransformFunc func([]byte) []byte
|
|
|
|
|
|
|
|
func transformSubTrie(nd node, hex []byte, newTrie *Trie, transformFunc keyTransformFunc) {
|
|
|
|
switch n := nd.(type) {
|
|
|
|
case nil:
|
|
|
|
return
|
|
|
|
case valueNode:
|
|
|
|
nCopy := make(valueNode, len(n))
|
|
|
|
copy(nCopy, n)
|
2020-04-16 07:42:25 +00:00
|
|
|
_, newTrie.root = newTrie.insert(newTrie.root, transformFunc(hex), nCopy)
|
2019-12-04 12:48:38 +00:00
|
|
|
return
|
|
|
|
case *accountNode:
|
|
|
|
accountCopy := accounts.NewAccount()
|
|
|
|
accountCopy.Copy(&n.Account)
|
2020-03-23 22:10:36 +00:00
|
|
|
var code []byte = nil
|
|
|
|
if n.code != nil {
|
|
|
|
code = make([]byte, len(n.code))
|
|
|
|
copy(code, n.code)
|
|
|
|
}
|
2022-08-13 11:51:25 +00:00
|
|
|
_, newTrie.root = newTrie.insert(newTrie.root, transformFunc(hex), &accountNode{accountCopy, nil, true, code, n.codeSize})
|
2019-12-04 12:48:38 +00:00
|
|
|
aHex := hex
|
|
|
|
if aHex[len(aHex)-1] == 16 {
|
|
|
|
aHex = aHex[:len(aHex)-1]
|
|
|
|
}
|
|
|
|
transformSubTrie(n.storage, aHex, newTrie, transformFunc)
|
|
|
|
case hashNode:
|
2020-07-05 06:17:27 +00:00
|
|
|
_, newTrie.root = newTrie.insert(newTrie.root, transformFunc(hex), hashNode{hash: common.CopyBytes(n.hash)})
|
2019-12-04 12:48:38 +00:00
|
|
|
return
|
|
|
|
case *shortNode:
|
|
|
|
var hexVal []byte
|
|
|
|
hexVal = concat(hex, n.Key...)
|
|
|
|
transformSubTrie(n.Val, hexVal, newTrie, transformFunc)
|
|
|
|
case *duoNode:
|
|
|
|
i1, i2 := n.childrenIdx()
|
|
|
|
hex1 := make([]byte, len(hex)+1)
|
|
|
|
copy(hex1, hex)
|
|
|
|
hex1[len(hex)] = i1
|
|
|
|
hex2 := make([]byte, len(hex)+1)
|
|
|
|
copy(hex2, hex)
|
|
|
|
hex2[len(hex)] = i2
|
|
|
|
transformSubTrie(n.child1, hex1, newTrie, transformFunc)
|
|
|
|
transformSubTrie(n.child2, hex2, newTrie, transformFunc)
|
|
|
|
case *fullNode:
|
|
|
|
for i, child := range n.Children {
|
|
|
|
if child != nil {
|
|
|
|
transformSubTrie(child, concat(hex, byte(i)), newTrie, transformFunc)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
panic("")
|
|
|
|
}
|
|
|
|
}
|