trie: don't store empty value nodes (12 bytes less)

This commit is contained in:
Péter Szilágyi 2018-06-18 11:33:54 +03:00
parent 574378edb5
commit 7ab347e909
No known key found for this signature in database
GPG key ID: E9AE538CEDF8293D
2 changed files with 16 additions and 11 deletions

View file

@ -137,9 +137,6 @@ func (h *hasher) hashChildren(original node, db *Database) (node, node, error) {
return original, original, err return original, original, err
} }
} }
if collapsed.Val == nil {
collapsed.Val = valueNode(nil) // Ensure that nil children are encoded as empty strings.
}
return collapsed, cached, nil return collapsed, cached, nil
case *fullNode: case *fullNode:
@ -152,14 +149,9 @@ func (h *hasher) hashChildren(original node, db *Database) (node, node, error) {
if err != nil { if err != nil {
return original, original, err return original, original, err
} }
} else {
collapsed.Children[i] = valueNode(nil) // Ensure that nil children are encoded as empty strings.
} }
} }
cached.Children[16] = n.Children[16] cached.Children[16] = n.Children[16]
if collapsed.Children[16] == nil {
collapsed.Children[16] = valueNode(nil)
}
return collapsed, cached, nil return collapsed, cached, nil
default: default:
@ -214,12 +206,12 @@ func (h *hasher) store(n node, db *Database, force bool) (node, error) {
if h.onleaf != nil { if h.onleaf != nil {
switch n := n.(type) { switch n := n.(type) {
case *shortNode: case *shortNode:
if child, ok := n.Val.(valueNode); ok && child != nil { if child, ok := n.Val.(valueNode); ok {
h.onleaf(child, hash) h.onleaf(child, hash)
} }
case *fullNode: case *fullNode:
for i := 0; i < 16; i++ { for i := 0; i < 16; i++ {
if child, ok := n.Children[i].(valueNode); ok && child != nil { if child, ok := n.Children[i].(valueNode); ok {
h.onleaf(child, hash) h.onleaf(child, hash)
} }
} }

View file

@ -47,9 +47,22 @@ type (
valueNode []byte valueNode []byte
) )
// nilValueNode is used when collapsing internal trie nodes for hashing, since
// unset children need to serialize correctly.
var nilValueNode = valueNode(nil)
// EncodeRLP encodes a full node into the consensus RLP format. // EncodeRLP encodes a full node into the consensus RLP format.
func (n *fullNode) EncodeRLP(w io.Writer) error { func (n *fullNode) EncodeRLP(w io.Writer) error {
return rlp.Encode(w, n.Children) var nodes [17]node
for i, child := range n.Children {
if child != nil {
nodes[i] = child
} else {
nodes[i] = nilValueNode
}
}
return rlp.Encode(w, nodes)
} }
func (n *fullNode) copy() *fullNode { copy := *n; return &copy } func (n *fullNode) copy() *fullNode { copy := *n; return &copy }