Skip to content

Commit cb3e450

Browse files
committed
trie: make value node resolvable via a callback
1 parent 6608a2a commit cb3e450

File tree

9 files changed

+31
-17
lines changed

9 files changed

+31
-17
lines changed

tests/testdata

trie/committer.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ func (c *committer) store(path []byte, n node) node {
158158
if c.collectLeaf {
159159
if sn, ok := n.(*shortNode); ok {
160160
if val, ok := sn.Val.(valueNode); ok {
161-
c.nodes.AddLeaf(nhash, val)
161+
c.nodes.AddLeaf(nhash, val())
162162
}
163163
}
164164
}

trie/hasher.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ func (h *hasher) encodeShortNode(n *shortNode) []byte {
110110
if hasTerm(n.Key) {
111111
var ln leafNodeEncoder
112112
ln.Key = hexToCompact(n.Key)
113-
ln.Val = n.Val.(valueNode)
113+
ln.Val = n.Val.(valueNode)()
114114
ln.encode(h.encbuf)
115115
return h.encodedBytes()
116116
}
@@ -162,7 +162,7 @@ func (h *hasher) encodeFullNode(n *fullNode) []byte {
162162
}
163163
}
164164
if n.Children[16] != nil {
165-
fn.Children[16] = n.Children[16].(valueNode)
165+
fn.Children[16] = n.Children[16].(valueNode)()
166166
}
167167
fn.encode(h.encbuf)
168168
fnEncoderPool.Put(fn)

trie/iterator.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ func (it *nodeIterator) LeafKey() []byte {
225225
func (it *nodeIterator) LeafBlob() []byte {
226226
if len(it.stack) > 0 {
227227
if node, ok := it.stack[len(it.stack)-1].node.(valueNode); ok {
228-
return node
228+
return node()
229229
}
230230
}
231231
panic("not at leaf")

trie/node.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ type (
4444
flags nodeFlag
4545
}
4646
hashNode []byte
47-
valueNode []byte
47+
valueNode func() []byte
4848

4949
// fullnodeEncoder is a type used exclusively for encoding fullNode.
5050
// Briefly instantiating a fullnodeEncoder and initializing with
@@ -118,7 +118,7 @@ func (n hashNode) fstring(ind string) string {
118118
return fmt.Sprintf("<%x> ", []byte(n))
119119
}
120120
func (n valueNode) fstring(ind string) string {
121-
return fmt.Sprintf("%x ", []byte(n))
121+
return fmt.Sprintf("%x ", n())
122122
}
123123

124124
// mustDecodeNode is a wrapper of decodeNode and panic if any error is encountered.
@@ -185,7 +185,7 @@ func decodeShort(hash, elems []byte) (node, error) {
185185
if err != nil {
186186
return nil, fmt.Errorf("invalid value node: %v", err)
187187
}
188-
return &shortNode{key, valueNode(val), flag}, nil
188+
return &shortNode{key, valueNode(func() []byte { return val }), flag}, nil
189189
}
190190
r, _, err := decodeRef(rest)
191191
if err != nil {
@@ -208,7 +208,7 @@ func decodeFull(hash, elems []byte) (*fullNode, error) {
208208
return n, err
209209
}
210210
if len(val) > 0 {
211-
n.Children[16] = valueNode(val)
211+
n.Children[16] = valueNode(func() []byte { return val })
212212
}
213213
return n, nil
214214
}

trie/node_enc.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,5 +102,5 @@ func (n hashNode) encode(w rlp.EncoderBuffer) {
102102
}
103103

104104
func (n valueNode) encode(w rlp.EncoderBuffer) {
105-
w.WriteBytes(n)
105+
w.WriteBytes(n())
106106
}

trie/proof.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ func VerifyProof(rootHash common.Hash, key []byte, proofDb ethdb.KeyValueReader)
129129
key = keyrest
130130
copy(wantHash[:], cld)
131131
case valueNode:
132-
return cld, nil
132+
return cld(), nil
133133
}
134134
}
135135
}
@@ -192,7 +192,7 @@ func proofToPath(rootHash common.Hash, root node, key []byte, proofDb ethdb.KeyV
192192
return nil, nil, err
193193
}
194194
case valueNode:
195-
valnode = cld
195+
valnode = cld()
196196
}
197197
// Link the parent and child.
198198
switch pnode := parent.(type) {

trie/sync.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -620,7 +620,7 @@ func (s *Sync) children(req *nodeRequest, object node) ([]*nodeRequest, error) {
620620
paths = append(paths, hexToKeybytes(child.path[:2*common.HashLength]))
621621
paths = append(paths, hexToKeybytes(child.path[2*common.HashLength:]))
622622
}
623-
if err := req.callback(paths, child.path, node, req.hash, req.path); err != nil {
623+
if err := req.callback(paths, child.path, node(), req.hash, req.path); err != nil {
624624
return nil, err
625625
}
626626
}

trie/trie.go

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ func (t *Trie) get(origNode node, key []byte, pos int) (value []byte, newnode no
194194
case nil:
195195
return nil, nil, false, nil
196196
case valueNode:
197-
return n, n, false, nil
197+
return n(), n, false, nil
198198
case *shortNode:
199199
if !bytes.HasPrefix(key[pos:], n.Key) {
200200
// key not found in trie
@@ -382,12 +382,26 @@ func (t *Trie) Update(key, value []byte) error {
382382
return t.update(key, value)
383383
}
384384

385+
func (t *Trie) UpdateAsync(key []byte, valueResolver func() []byte) error {
386+
t.unhashed++
387+
t.uncommitted++
388+
k := keybytesToHex(key)
389+
390+
// NOTE: this does not support deletions (the length of the value is not known until it is resolved)
391+
_, n, err := t.insert(t.root, nil, k, valueNode(valueResolver))
392+
if err != nil {
393+
return err
394+
}
395+
t.root = n
396+
return nil
397+
}
398+
385399
func (t *Trie) update(key, value []byte) error {
386400
t.unhashed++
387401
t.uncommitted++
388402
k := keybytesToHex(key)
389403
if len(value) != 0 {
390-
_, n, err := t.insert(t.root, nil, k, valueNode(value))
404+
_, n, err := t.insert(t.root, nil, k, valueNode(func() []byte { return value }))
391405
if err != nil {
392406
return err
393407
}
@@ -405,7 +419,7 @@ func (t *Trie) update(key, value []byte) error {
405419
func (t *Trie) insert(n node, prefix, key []byte, value node) (bool, node, error) {
406420
if len(key) == 0 {
407421
if v, ok := n.(valueNode); ok {
408-
return !bytes.Equal(v, value.(valueNode)), value, nil
422+
return !bytes.Equal(v(), value.(valueNode)()), value, nil
409423
}
410424
return true, value, nil
411425
}
@@ -647,7 +661,7 @@ func copyNode(n node) node {
647661
case nil:
648662
return nil
649663
case valueNode:
650-
return valueNode(common.CopyBytes(n))
664+
return valueNode(func() []byte { return common.CopyBytes(n()) })
651665

652666
case *shortNode:
653667
return &shortNode{

0 commit comments

Comments
 (0)