diff --git a/trie/hasher.go b/trie/hasher.go index 9a0b55530a..060f15f138 100644 --- a/trie/hasher.go +++ b/trie/hasher.go @@ -65,9 +65,11 @@ func (h *hasher) hash(n node, force bool) []byte { case *shortNode: enc := h.encodeShortNode(n) if len(enc) < 32 && !force { + // Nodes smaller than 32 bytes are embedded directly in their parent. + // In such cases, return the raw encoded blob instead of the node hash. buf := make([]byte, len(enc)) copy(buf, enc) - return buf // Nodes smaller than 32 bytes are stored inside their parent + return buf } hash := h.hashData(enc) n.flags.hash = hash @@ -76,9 +78,11 @@ func (h *hasher) hash(n node, force bool) []byte { case *fullNode: enc := h.encodeFullNode(n) if len(enc) < 32 && !force { + // Nodes smaller than 32 bytes are embedded directly in their parent. + // In such cases, return the raw encoded blob instead of the node hash. buf := make([]byte, len(enc)) copy(buf, enc) - return buf // Nodes smaller than 32 bytes are stored inside their parent + return buf } hash := h.hashData(enc) n.flags.hash = hash @@ -110,6 +114,8 @@ func (h *hasher) encodeShortNode(n *shortNode) []byte { return h.encodedBytes() } +// fnEncoderPool is the pool for storing shared fullNode encoder to mitigate +// the significant memory allocation overhead. var fnEncoderPool = sync.Pool{ New: func() interface{} { var enc fullnodeEncoder @@ -189,10 +195,7 @@ func (h *hasher) hashDataTo(dst, data []byte) { h.sha.Read(dst) } -// proofHash is used to construct trie proofs, and returns the 'collapsed' -// node (for later RLP encoding) as well as the hashed node -- unless the -// node is smaller than 32 bytes, in which case it will be returned as is. -// This method does not do anything on value- or hash-nodes. +// proofHash is used to construct trie proofs, returning the rlp-encoded node blobs. func (h *hasher) proofHash(original node) []byte { switch n := original.(type) { case *shortNode: diff --git a/trie/iterator.go b/trie/iterator.go index 9dcd98e2d8..d4f1e60a61 100644 --- a/trie/iterator.go +++ b/trie/iterator.go @@ -20,6 +20,7 @@ import ( "bytes" "container/heap" "errors" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" ) diff --git a/trie/node_enc.go b/trie/node_enc.go index 81b3677f06..02b93ee6f3 100644 --- a/trie/node_enc.go +++ b/trie/node_enc.go @@ -46,14 +46,11 @@ func (n *fullnodeEncoder) encode(w rlp.EncoderBuffer) { if len(c) == 0 { w.Write(rlp.EmptyString) } else { - if i == 16 { - w.WriteBytes(c) // valueNode + // valueNode or hashNode + if i == 16 || len(c) >= 32 { + w.WriteBytes(c) } else { - if len(c) < 32 { - w.Write(c) // rawNode - } else { - w.WriteBytes(c) // hashNode - } + w.Write(c) // rawNode } } } @@ -84,7 +81,7 @@ func (n *extNodeEncoder) encode(w rlp.EncoderBuffer) { w.WriteBytes(n.Key) if n.Val == nil { - w.Write(rlp.EmptyString) + w.Write(rlp.EmptyString) // theoretically impossible to happen } else if len(n.Val) < 32 { w.Write(n.Val) // rawNode } else { diff --git a/trie/proof.go b/trie/proof.go index dd9a105bea..53b7acc30c 100644 --- a/trie/proof.go +++ b/trie/proof.go @@ -87,9 +87,6 @@ func (t *Trie) Prove(key []byte, proofDb ethdb.KeyValueWriter) error { for i, n := range nodes { enc := hasher.proofHash(n) - if len(enc) == 32 { - fmt.Println("DEBUG") - } if len(enc) >= 32 || i == 0 { proofDb.Put(crypto.Keccak256(enc), enc) }