-
Notifications
You must be signed in to change notification settings - Fork 901
/
nmt_adder.go
62 lines (52 loc) · 1.62 KB
/
nmt_adder.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
package ipld
import (
"context"
"github.com/ipfs/go-blockservice"
"github.com/ipfs/go-merkledag"
"github.com/ipfs/go-cid"
ipld "github.com/ipfs/go-ipld-format"
"github.com/celestiaorg/celestia-node/ipld/plugin"
)
// NmtNodeAdder adds ipld.Nodes to the underlying ipld.Batch if it is inserted
// into a nmt tree.
type NmtNodeAdder struct {
ctx context.Context
add *ipld.Batch
leaves *cid.Set
err error
}
// NewNmtNodeAdder returns a new NmtNodeAdder with the provided context and
// batch. Note that the context provided should have a timeout
// It is not thread-safe.
func NewNmtNodeAdder(ctx context.Context, bs blockservice.BlockService, opts ...ipld.BatchOption) *NmtNodeAdder {
return &NmtNodeAdder{
add: ipld.NewBatch(ctx, merkledag.NewDAGService(bs), opts...),
ctx: ctx,
leaves: cid.NewSet(),
}
}
// Visit is a NodeVisitor that can be used during the creation of a new NMT to
// create and add ipld.Nodes to the Batch while computing the root of the NMT.
func (n *NmtNodeAdder) Visit(hash []byte, children ...[]byte) {
if n.err != nil {
return // protect from further visits if there is an error
}
id := plugin.MustCidFromNamespacedSha256(hash)
switch len(children) {
case 1:
if n.leaves.Visit(id) {
n.err = n.add.Add(n.ctx, plugin.NewNMTLeafNode(id, children[0]))
}
case 2:
n.err = n.add.Add(n.ctx, plugin.NewNMTNode(id, children[0], children[1]))
default:
panic("expected a binary tree")
}
}
// Commit checks for errors happened during Visit and if absent commits data to inner Batch.
func (n *NmtNodeAdder) Commit() error {
if n.err != nil {
return n.err
}
return n.add.Commit()
}