hasher.go 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. // Copyright 2019 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. "sync"
  19. "github.com/ethereum/go-ethereum/crypto"
  20. "github.com/ethereum/go-ethereum/rlp"
  21. "golang.org/x/crypto/sha3"
  22. )
  23. type sliceBuffer []byte
  24. func (b *sliceBuffer) Write(data []byte) (n int, err error) {
  25. *b = append(*b, data...)
  26. return len(data), nil
  27. }
  28. func (b *sliceBuffer) Reset() {
  29. *b = (*b)[:0]
  30. }
  31. // hasher is a type used for the trie Hash operation. A hasher has some
  32. // internal preallocated temp space
  33. type hasher struct {
  34. sha crypto.KeccakState
  35. tmp sliceBuffer
  36. parallel bool // Whether to use paralallel threads when hashing
  37. }
  38. // hasherPool holds pureHashers
  39. var hasherPool = sync.Pool{
  40. New: func() interface{} {
  41. return &hasher{
  42. tmp: make(sliceBuffer, 0, 550), // cap is as large as a full fullNode.
  43. sha: sha3.NewLegacyKeccak256().(crypto.KeccakState),
  44. }
  45. },
  46. }
  47. func newHasher(parallel bool) *hasher {
  48. h := hasherPool.Get().(*hasher)
  49. h.parallel = parallel
  50. return h
  51. }
  52. func returnHasherToPool(h *hasher) {
  53. hasherPool.Put(h)
  54. }
  55. // hash collapses a node down into a hash node, also returning a copy of the
  56. // original node initialized with the computed hash to replace the original one.
  57. func (h *hasher) hash(n node, force bool) (hashed node, cached node) {
  58. // Return the cached hash if it's available
  59. if hash, _ := n.cache(); hash != nil {
  60. return hash, n
  61. }
  62. // Trie not processed yet, walk the children
  63. switch n := n.(type) {
  64. case *shortNode:
  65. collapsed, cached := h.hashShortNodeChildren(n)
  66. hashed := h.shortnodeToHash(collapsed, force)
  67. // We need to retain the possibly _not_ hashed node, in case it was too
  68. // small to be hashed
  69. if hn, ok := hashed.(hashNode); ok {
  70. cached.flags.hash = hn
  71. } else {
  72. cached.flags.hash = nil
  73. }
  74. return hashed, cached
  75. case *fullNode:
  76. collapsed, cached := h.hashFullNodeChildren(n)
  77. hashed = h.fullnodeToHash(collapsed, force)
  78. if hn, ok := hashed.(hashNode); ok {
  79. cached.flags.hash = hn
  80. } else {
  81. cached.flags.hash = nil
  82. }
  83. return hashed, cached
  84. default:
  85. // Value and hash nodes don't have children so they're left as were
  86. return n, n
  87. }
  88. }
  89. // hashShortNodeChildren collapses the short node. The returned collapsed node
  90. // holds a live reference to the Key, and must not be modified.
  91. // The cached
  92. func (h *hasher) hashShortNodeChildren(n *shortNode) (collapsed, cached *shortNode) {
  93. // Hash the short node's child, caching the newly hashed subtree
  94. collapsed, cached = n.copy(), n.copy()
  95. // Previously, we did copy this one. We don't seem to need to actually
  96. // do that, since we don't overwrite/reuse keys
  97. //cached.Key = common.CopyBytes(n.Key)
  98. collapsed.Key = hexToCompact(n.Key)
  99. // Unless the child is a valuenode or hashnode, hash it
  100. switch n.Val.(type) {
  101. case *fullNode, *shortNode:
  102. collapsed.Val, cached.Val = h.hash(n.Val, false)
  103. }
  104. return collapsed, cached
  105. }
  106. func (h *hasher) hashFullNodeChildren(n *fullNode) (collapsed *fullNode, cached *fullNode) {
  107. // Hash the full node's children, caching the newly hashed subtrees
  108. cached = n.copy()
  109. collapsed = n.copy()
  110. if h.parallel {
  111. var wg sync.WaitGroup
  112. wg.Add(16)
  113. for i := 0; i < 16; i++ {
  114. go func(i int) {
  115. hasher := newHasher(false)
  116. if child := n.Children[i]; child != nil {
  117. collapsed.Children[i], cached.Children[i] = hasher.hash(child, false)
  118. } else {
  119. collapsed.Children[i] = nilValueNode
  120. }
  121. returnHasherToPool(hasher)
  122. wg.Done()
  123. }(i)
  124. }
  125. wg.Wait()
  126. } else {
  127. for i := 0; i < 16; i++ {
  128. if child := n.Children[i]; child != nil {
  129. collapsed.Children[i], cached.Children[i] = h.hash(child, false)
  130. } else {
  131. collapsed.Children[i] = nilValueNode
  132. }
  133. }
  134. }
  135. return collapsed, cached
  136. }
  137. // shortnodeToHash creates a hashNode from a shortNode. The supplied shortnode
  138. // should have hex-type Key, which will be converted (without modification)
  139. // into compact form for RLP encoding.
  140. // If the rlp data is smaller than 32 bytes, `nil` is returned.
  141. func (h *hasher) shortnodeToHash(n *shortNode, force bool) node {
  142. h.tmp.Reset()
  143. if err := rlp.Encode(&h.tmp, n); err != nil {
  144. panic("encode error: " + err.Error())
  145. }
  146. if len(h.tmp) < 32 && !force {
  147. return n // Nodes smaller than 32 bytes are stored inside their parent
  148. }
  149. return h.hashData(h.tmp)
  150. }
  151. // shortnodeToHash is used to creates a hashNode from a set of hashNodes, (which
  152. // may contain nil values)
  153. func (h *hasher) fullnodeToHash(n *fullNode, force bool) node {
  154. h.tmp.Reset()
  155. // Generate the RLP encoding of the node
  156. if err := n.EncodeRLP(&h.tmp); err != nil {
  157. panic("encode error: " + err.Error())
  158. }
  159. if len(h.tmp) < 32 && !force {
  160. return n // Nodes smaller than 32 bytes are stored inside their parent
  161. }
  162. return h.hashData(h.tmp)
  163. }
  164. // hashData hashes the provided data
  165. func (h *hasher) hashData(data []byte) hashNode {
  166. n := make(hashNode, 32)
  167. h.sha.Reset()
  168. h.sha.Write(data)
  169. h.sha.Read(n)
  170. return n
  171. }
  172. // proofHash is used to construct trie proofs, and returns the 'collapsed'
  173. // node (for later RLP encoding) aswell as the hashed node -- unless the
  174. // node is smaller than 32 bytes, in which case it will be returned as is.
  175. // This method does not do anything on value- or hash-nodes.
  176. func (h *hasher) proofHash(original node) (collapsed, hashed node) {
  177. switch n := original.(type) {
  178. case *shortNode:
  179. sn, _ := h.hashShortNodeChildren(n)
  180. return sn, h.shortnodeToHash(sn, false)
  181. case *fullNode:
  182. fn, _ := h.hashFullNodeChildren(n)
  183. return fn, h.fullnodeToHash(fn, false)
  184. default:
  185. // Value and hash nodes don't have children so they're left as were
  186. return n, n
  187. }
  188. }