stacktrie.go 12 KB

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