stacktrie.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  1. // Copyright 2020 The go-ethereum Authors
  2. // This file is part of the go-ethereum library.
  3. //
  4. // The go-ethereum library is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU Lesser General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // The go-ethereum library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU Lesser General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU Lesser General Public License
  15. // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
  16. package trie
  17. import (
  18. "fmt"
  19. "sync"
  20. "github.com/ethereum/go-ethereum/common"
  21. "github.com/ethereum/go-ethereum/ethdb"
  22. "github.com/ethereum/go-ethereum/log"
  23. "github.com/ethereum/go-ethereum/rlp"
  24. )
  25. var stPool = sync.Pool{
  26. New: func() interface{} {
  27. return NewStackTrie(nil)
  28. },
  29. }
  30. func stackTrieFromPool(db ethdb.KeyValueStore) *StackTrie {
  31. st := stPool.Get().(*StackTrie)
  32. st.db = db
  33. return st
  34. }
  35. func returnToPool(st *StackTrie) {
  36. st.Reset()
  37. stPool.Put(st)
  38. }
  39. // StackTrie is a trie implementation that expects keys to be inserted
  40. // in order. Once it determines that a subtree will no longer be inserted
  41. // into, it will hash it and free up the memory it uses.
  42. type StackTrie struct {
  43. nodeType uint8 // node type (as in branch, ext, leaf)
  44. val []byte // value contained by this node if it's a leaf
  45. key []byte // key chunk covered by this (full|ext) node
  46. keyOffset int // offset of the key chunk inside a full key
  47. children [16]*StackTrie // list of children (for fullnodes and exts)
  48. db ethdb.KeyValueStore // Pointer to the commit db, can be nil
  49. }
  50. // NewStackTrie allocates and initializes an empty trie.
  51. func NewStackTrie(db ethdb.KeyValueStore) *StackTrie {
  52. return &StackTrie{
  53. nodeType: emptyNode,
  54. db: db,
  55. }
  56. }
  57. func newLeaf(ko int, key, val []byte, db ethdb.KeyValueStore) *StackTrie {
  58. st := stackTrieFromPool(db)
  59. st.nodeType = leafNode
  60. st.keyOffset = ko
  61. st.key = append(st.key, key[ko:]...)
  62. st.val = val
  63. return st
  64. }
  65. func newExt(ko int, key []byte, child *StackTrie, db ethdb.KeyValueStore) *StackTrie {
  66. st := stackTrieFromPool(db)
  67. st.nodeType = extNode
  68. st.keyOffset = ko
  69. st.key = append(st.key, key[ko:]...)
  70. st.children[0] = child
  71. return st
  72. }
  73. // List all values that StackTrie#nodeType can hold
  74. const (
  75. emptyNode = iota
  76. branchNode
  77. extNode
  78. leafNode
  79. hashedNode
  80. )
  81. // TryUpdate inserts a (key, value) pair into the stack trie
  82. func (st *StackTrie) TryUpdate(key, value []byte) error {
  83. k := keybytesToHex(key)
  84. if len(value) == 0 {
  85. panic("deletion not supported")
  86. }
  87. st.insert(k[:len(k)-1], value)
  88. return nil
  89. }
  90. func (st *StackTrie) Update(key, value []byte) {
  91. if err := st.TryUpdate(key, value); err != nil {
  92. log.Error(fmt.Sprintf("Unhandled trie error: %v", err))
  93. }
  94. }
  95. func (st *StackTrie) Reset() {
  96. st.db = nil
  97. st.key = st.key[:0]
  98. st.val = st.val[:0]
  99. for i := range st.children {
  100. st.children[i] = nil
  101. }
  102. st.nodeType = emptyNode
  103. st.keyOffset = 0
  104. }
  105. // Helper function that, given a full key, determines the index
  106. // at which the chunk pointed by st.keyOffset is different from
  107. // the same chunk in the full key.
  108. func (st *StackTrie) getDiffIndex(key []byte) int {
  109. diffindex := 0
  110. for ; diffindex < len(st.key) && st.key[diffindex] == key[st.keyOffset+diffindex]; diffindex++ {
  111. }
  112. return diffindex
  113. }
  114. // Helper function to that inserts a (key, value) pair into
  115. // the trie.
  116. func (st *StackTrie) insert(key, value []byte) {
  117. switch st.nodeType {
  118. case branchNode: /* Branch */
  119. idx := int(key[st.keyOffset])
  120. // Unresolve elder siblings
  121. for i := idx - 1; i >= 0; i-- {
  122. if st.children[i] != nil {
  123. if st.children[i].nodeType != hashedNode {
  124. st.children[i].hash()
  125. }
  126. break
  127. }
  128. }
  129. // Add new child
  130. if st.children[idx] == nil {
  131. st.children[idx] = stackTrieFromPool(st.db)
  132. st.children[idx].keyOffset = st.keyOffset + 1
  133. }
  134. st.children[idx].insert(key, value)
  135. case extNode: /* Ext */
  136. // Compare both key chunks and see where they differ
  137. diffidx := st.getDiffIndex(key)
  138. // Check if chunks are identical. If so, recurse into
  139. // the child node. Otherwise, the key has to be split
  140. // into 1) an optional common prefix, 2) the fullnode
  141. // representing the two differing path, and 3) a leaf
  142. // for each of the differentiated subtrees.
  143. if diffidx == len(st.key) {
  144. // Ext key and key segment are identical, recurse into
  145. // the child node.
  146. st.children[0].insert(key, value)
  147. return
  148. }
  149. // Save the original part. Depending if the break is
  150. // at the extension's last byte or not, create an
  151. // intermediate extension or use the extension's child
  152. // node directly.
  153. var n *StackTrie
  154. if diffidx < len(st.key)-1 {
  155. n = newExt(diffidx+1, st.key, st.children[0], st.db)
  156. } else {
  157. // Break on the last byte, no need to insert
  158. // an extension node: reuse the current node
  159. n = st.children[0]
  160. }
  161. // Convert to hash
  162. n.hash()
  163. var p *StackTrie
  164. if diffidx == 0 {
  165. // the break is on the first byte, so
  166. // the current node is converted into
  167. // a branch node.
  168. st.children[0] = nil
  169. p = st
  170. st.nodeType = branchNode
  171. } else {
  172. // the common prefix is at least one byte
  173. // long, insert a new intermediate branch
  174. // node.
  175. st.children[0] = stackTrieFromPool(st.db)
  176. st.children[0].nodeType = branchNode
  177. st.children[0].keyOffset = st.keyOffset + diffidx
  178. p = st.children[0]
  179. }
  180. // Create a leaf for the inserted part
  181. o := newLeaf(st.keyOffset+diffidx+1, key, value, st.db)
  182. // Insert both child leaves where they belong:
  183. origIdx := st.key[diffidx]
  184. newIdx := key[diffidx+st.keyOffset]
  185. p.children[origIdx] = n
  186. p.children[newIdx] = o
  187. st.key = st.key[:diffidx]
  188. case leafNode: /* Leaf */
  189. // Compare both key chunks and see where they differ
  190. diffidx := st.getDiffIndex(key)
  191. // Overwriting a key isn't supported, which means that
  192. // the current leaf is expected to be split into 1) an
  193. // optional extension for the common prefix of these 2
  194. // keys, 2) a fullnode selecting the path on which the
  195. // keys differ, and 3) one leaf for the differentiated
  196. // component of each key.
  197. if diffidx >= len(st.key) {
  198. panic("Trying to insert into existing key")
  199. }
  200. // Check if the split occurs at the first nibble of the
  201. // chunk. In that case, no prefix extnode is necessary.
  202. // Otherwise, create that
  203. var p *StackTrie
  204. if diffidx == 0 {
  205. // Convert current leaf into a branch
  206. st.nodeType = branchNode
  207. p = st
  208. st.children[0] = nil
  209. } else {
  210. // Convert current node into an ext,
  211. // and insert a child branch node.
  212. st.nodeType = extNode
  213. st.children[0] = NewStackTrie(st.db)
  214. st.children[0].nodeType = branchNode
  215. st.children[0].keyOffset = st.keyOffset + diffidx
  216. p = st.children[0]
  217. }
  218. // Create the two child leaves: the one containing the
  219. // original value and the one containing the new value
  220. // The child leave will be hashed directly in order to
  221. // free up some memory.
  222. origIdx := st.key[diffidx]
  223. p.children[origIdx] = newLeaf(diffidx+1, st.key, st.val, st.db)
  224. p.children[origIdx].hash()
  225. newIdx := key[diffidx+st.keyOffset]
  226. p.children[newIdx] = newLeaf(p.keyOffset+1, key, value, st.db)
  227. // Finally, cut off the key part that has been passed
  228. // over to the children.
  229. st.key = st.key[:diffidx]
  230. st.val = nil
  231. case emptyNode: /* Empty */
  232. st.nodeType = leafNode
  233. st.key = key[st.keyOffset:]
  234. st.val = value
  235. case hashedNode:
  236. panic("trying to insert into hash")
  237. default:
  238. panic("invalid type")
  239. }
  240. }
  241. // hash() hashes the node 'st' and converts it into 'hashedNode', if possible.
  242. // Possible outcomes:
  243. // 1. The rlp-encoded value was >= 32 bytes:
  244. // - Then the 32-byte `hash` will be accessible in `st.val`.
  245. // - And the 'st.type' will be 'hashedNode'
  246. // 2. The rlp-encoded value was < 32 bytes
  247. // - Then the <32 byte rlp-encoded value will be accessible in 'st.val'.
  248. // - And the 'st.type' will be 'hashedNode' AGAIN
  249. //
  250. // This method will also:
  251. // set 'st.type' to hashedNode
  252. // clear 'st.key'
  253. func (st *StackTrie) hash() {
  254. /* Shortcut if node is already hashed */
  255. if st.nodeType == hashedNode {
  256. return
  257. }
  258. // The 'hasher' is taken from a pool, but we don't actually
  259. // claim an instance until all children are done with their hashing,
  260. // and we actually need one
  261. var h *hasher
  262. switch st.nodeType {
  263. case branchNode:
  264. var nodes [17]node
  265. for i, child := range st.children {
  266. if child == nil {
  267. nodes[i] = nilValueNode
  268. continue
  269. }
  270. child.hash()
  271. if len(child.val) < 32 {
  272. nodes[i] = rawNode(child.val)
  273. } else {
  274. nodes[i] = hashNode(child.val)
  275. }
  276. st.children[i] = nil // Reclaim mem from subtree
  277. returnToPool(child)
  278. }
  279. nodes[16] = nilValueNode
  280. h = newHasher(false)
  281. defer returnHasherToPool(h)
  282. h.tmp.Reset()
  283. if err := rlp.Encode(&h.tmp, nodes); err != nil {
  284. panic(err)
  285. }
  286. case extNode:
  287. h = newHasher(false)
  288. defer returnHasherToPool(h)
  289. h.tmp.Reset()
  290. st.children[0].hash()
  291. // This is also possible:
  292. //sz := hexToCompactInPlace(st.key)
  293. //n := [][]byte{
  294. // st.key[:sz],
  295. // st.children[0].val,
  296. //}
  297. n := [][]byte{
  298. hexToCompact(st.key),
  299. st.children[0].val,
  300. }
  301. if err := rlp.Encode(&h.tmp, n); err != nil {
  302. panic(err)
  303. }
  304. returnToPool(st.children[0])
  305. st.children[0] = nil // Reclaim mem from subtree
  306. case leafNode:
  307. h = newHasher(false)
  308. defer returnHasherToPool(h)
  309. h.tmp.Reset()
  310. st.key = append(st.key, byte(16))
  311. sz := hexToCompactInPlace(st.key)
  312. n := [][]byte{st.key[:sz], st.val}
  313. if err := rlp.Encode(&h.tmp, n); err != nil {
  314. panic(err)
  315. }
  316. case emptyNode:
  317. st.val = st.val[:0]
  318. st.val = append(st.val, emptyRoot[:]...)
  319. st.key = st.key[:0]
  320. st.nodeType = hashedNode
  321. return
  322. default:
  323. panic("Invalid node type")
  324. }
  325. st.key = st.key[:0]
  326. st.nodeType = hashedNode
  327. if len(h.tmp) < 32 {
  328. st.val = st.val[:0]
  329. st.val = append(st.val, h.tmp...)
  330. return
  331. }
  332. // Going to write the hash to the 'val'. Need to ensure it's properly sized first
  333. // Typically, 'branchNode's will have no 'val', and require this allocation
  334. if required := 32 - len(st.val); required > 0 {
  335. buf := make([]byte, required)
  336. st.val = append(st.val, buf...)
  337. }
  338. st.val = st.val[:32]
  339. h.sha.Reset()
  340. h.sha.Write(h.tmp)
  341. h.sha.Read(st.val)
  342. if st.db != nil {
  343. // TODO! Is it safe to Put the slice here?
  344. // Do all db implementations copy the value provided?
  345. st.db.Put(st.val, h.tmp)
  346. }
  347. }
  348. // Hash returns the hash of the current node
  349. func (st *StackTrie) Hash() (h common.Hash) {
  350. st.hash()
  351. if len(st.val) != 32 {
  352. // If the node's RLP isn't 32 bytes long, the node will not
  353. // be hashed, and instead contain the rlp-encoding of the
  354. // node. For the top level node, we need to force the hashing.
  355. ret := make([]byte, 32)
  356. h := newHasher(false)
  357. defer returnHasherToPool(h)
  358. h.sha.Reset()
  359. h.sha.Write(st.val)
  360. h.sha.Read(ret)
  361. return common.BytesToHash(ret)
  362. }
  363. return common.BytesToHash(st.val)
  364. }
  365. // Commit will commit the current node to database db
  366. func (st *StackTrie) Commit(db ethdb.KeyValueStore) common.Hash {
  367. oldDb := st.db
  368. st.db = db
  369. defer func() {
  370. st.db = oldDb
  371. }()
  372. st.hash()
  373. h := common.BytesToHash(st.val)
  374. return h
  375. }