hasher.go 6.4 KB

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