Skip to content

Commit aa3c1fd

Browse files
authored
Merge pull request #91 from hyperledger-labs/index-vs-ref
Split node reference vs. index to separate interfaces for API clarity
2 parents b463b4a + 7696343 commit aa3c1fd

File tree

13 files changed

+104
-94
lines changed

13 files changed

+104
-94
lines changed

go-sdk/integration-test/db_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ func (s *SqliteTestSuite) TestSqliteStorage() {
103103
dbRoot := core.SMTRoot{Name: s.smtName}
104104
err = s.gormDB.Table(core.TreeRootsTable).First(&dbRoot).Error
105105
assert.NoError(s.T(), err)
106-
assert.Equal(s.T(), root.Hex(), dbRoot.RootIndex)
106+
assert.Equal(s.T(), root.Hex(), dbRoot.RootRef)
107107

108108
dbNode := core.SMTNode{RefKey: n1.Ref().Hex()}
109109
err = s.gormDB.Table(core.NodesTablePrefix + s.smtName).First(&dbNode).Error
@@ -155,7 +155,7 @@ func TestPostgresStorage(t *testing.T) {
155155
dbRoot := core.SMTRoot{Name: "test_1"}
156156
err = db.Table(core.TreeRootsTable).First(&dbRoot).Error
157157
assert.NoError(t, err)
158-
assert.Equal(t, root.Hex(), dbRoot.RootIndex)
158+
assert.Equal(t, root.Hex(), dbRoot.RootRef)
159159

160160
dbNode := core.SMTNode{RefKey: n1.Ref().Hex()}
161161
err = db.Table(core.NodesTablePrefix + "test_1").First(&dbNode).Error

go-sdk/internal/sparse-merkle-tree/node/node.go

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,10 @@ type nodeIndex [32]byte
3939
type node struct {
4040
nodeType core.NodeType
4141
index core.NodeIndex
42-
refKey core.NodeIndex
42+
refKey core.NodeRef
4343
value core.Indexable
44-
leftChild core.NodeIndex
45-
rightChild core.NodeIndex
44+
leftChild core.NodeRef
45+
rightChild core.NodeRef
4646
}
4747

4848
// //////////////////////////////////////
@@ -70,7 +70,7 @@ func NewLeafNode(v core.Indexable) (core.Node, error) {
7070
return n, err
7171
}
7272

73-
func NewBranchNode(leftChild, rightChild core.NodeIndex) (core.Node, error) {
73+
func NewBranchNode(leftChild, rightChild core.NodeRef) (core.Node, error) {
7474
n := &node{nodeType: core.NodeTypeBranch, leftChild: leftChild, rightChild: rightChild}
7575
elements := []*big.Int{leftChild.BigInt(), rightChild.BigInt()}
7676
hash, err := poseidon.Hash(elements)
@@ -89,19 +89,19 @@ func (n *node) Index() core.NodeIndex {
8989
return n.index
9090
}
9191

92-
func (n *node) Ref() core.NodeIndex {
92+
func (n *node) Ref() core.NodeRef {
9393
return n.refKey
9494
}
9595

9696
func (n *node) Value() core.Indexable {
9797
return n.value
9898
}
9999

100-
func (n *node) LeftChild() core.NodeIndex {
100+
func (n *node) LeftChild() core.NodeRef {
101101
return n.leftChild
102102
}
103103

104-
func (n *node) RightChild() core.NodeIndex {
104+
func (n *node) RightChild() core.NodeRef {
105105
return n.rightChild
106106
}
107107

@@ -145,20 +145,20 @@ func (idx *nodeIndex) IsZero() bool {
145145
return idx.BigInt().Sign() == 0
146146
}
147147

148-
func (idx *nodeIndex) Equal(other core.NodeIndex) bool {
148+
func (idx *nodeIndex) Equal(other core.NodeRef) bool {
149149
return idx.BigInt().Cmp(other.BigInt()) == 0
150150
}
151151

152152
// getPath returns the binary path, from the root to the leaf.
153153
func (idx *nodeIndex) ToPath(levels int) []bool {
154154
path := make([]bool, levels)
155155
for l := 0; l < levels; l++ {
156-
path[l] = idx.IsBitOn(uint(l))
156+
path[l] = idx.IsBitOne(uint(l))
157157
}
158158
return path
159159
}
160160

161-
func (idx *nodeIndex) IsBitOn(pos uint) bool {
161+
func (idx *nodeIndex) IsBitOne(pos uint) bool {
162162
if pos >= 256 {
163163
return false
164164
}

go-sdk/internal/sparse-merkle-tree/smt/merkletree.go

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ const MAX_TREE_HEIGHT = 256
3434
type sparseMerkleTree struct {
3535
sync.RWMutex
3636
db core.Storage
37-
rootKey core.NodeIndex
37+
rootKey core.NodeRef
3838
maxLevels int
3939
}
4040

@@ -44,10 +44,10 @@ func NewMerkleTree(db core.Storage, maxLevels int) (core.SparseMerkleTree, error
4444
}
4545
mt := sparseMerkleTree{db: db, maxLevels: maxLevels}
4646

47-
root, err := mt.db.GetRootNodeIndex()
47+
root, err := mt.db.GetRootNodeRef()
4848
if err == core.ErrNotFound {
4949
mt.rootKey = node.ZERO_INDEX
50-
err = mt.db.UpsertRootNodeIndex(mt.rootKey)
50+
err = mt.db.UpsertRootNodeRef(mt.rootKey)
5151
if err != nil {
5252
return nil, err
5353
}
@@ -59,7 +59,7 @@ func NewMerkleTree(db core.Storage, maxLevels int) (core.SparseMerkleTree, error
5959
return &mt, nil
6060
}
6161

62-
func (mt *sparseMerkleTree) Root() core.NodeIndex {
62+
func (mt *sparseMerkleTree) Root() core.NodeRef {
6363
mt.RLock()
6464
defer mt.RUnlock()
6565
return mt.rootKey
@@ -93,7 +93,7 @@ func (mt *sparseMerkleTree) AddLeaf(node core.Node) error {
9393

9494
// update the root node index in the storage
9595
log.L().Infof("Upserting root node index to %s", mt.rootKey.Hex())
96-
err = batch.UpsertRootNodeIndex(mt.rootKey)
96+
err = batch.UpsertRootNodeRef(mt.rootKey)
9797
if err != nil {
9898
log.L().Errorf("Error upserting root node %s: %v, rolling back", mt.rootKey.Hex(), err)
9999
_ = batch.Rollback()
@@ -114,7 +114,7 @@ func (mt *sparseMerkleTree) AddLeaf(node core.Node) error {
114114

115115
// GetNode gets a node by key from the merkle tree. Empty nodes are not stored in the
116116
// tree: they are all the same and assumed to always exist.
117-
func (mt *sparseMerkleTree) GetNode(key core.NodeIndex) (core.Node, error) {
117+
func (mt *sparseMerkleTree) GetNode(key core.NodeRef) (core.Node, error) {
118118
mt.RLock()
119119
defer mt.RUnlock()
120120
return mt.getNode(key)
@@ -123,7 +123,7 @@ func (mt *sparseMerkleTree) GetNode(key core.NodeIndex) (core.Node, error) {
123123
// GenerateProofs generates a list of proofs of existence (or non-existence) of the provided
124124
// leaf nodes that are represented by their indexes. An optional Merkle tree root can be provided.
125125
// If rootKey is not provided, the current Merkle tree root is used
126-
func (mt *sparseMerkleTree) GenerateProofs(keys []*big.Int, rootKey core.NodeIndex) ([]core.Proof, []*big.Int, error) {
126+
func (mt *sparseMerkleTree) GenerateProofs(keys []*big.Int, rootKey core.NodeRef) ([]core.Proof, []*big.Int, error) {
127127
mt.RLock()
128128
defer mt.RUnlock()
129129

@@ -141,9 +141,9 @@ func (mt *sparseMerkleTree) GenerateProofs(keys []*big.Int, rootKey core.NodeInd
141141
return merkleProofs, foundValues, nil
142142
}
143143

144-
func (mt *sparseMerkleTree) generateProof(key *big.Int, rootKey core.NodeIndex) (core.Proof, *big.Int, error) {
144+
func (mt *sparseMerkleTree) generateProof(key *big.Int, rootKey core.NodeRef) (core.Proof, *big.Int, error) {
145145
p := &proof{}
146-
var siblingKey core.NodeIndex
146+
var siblingKey core.NodeRef
147147

148148
kHash, err := node.NewNodeIndexFromBigInt(key)
149149
if err != nil {
@@ -198,7 +198,7 @@ func (mt *sparseMerkleTree) generateProof(key *big.Int, rootKey core.NodeIndex)
198198
}
199199

200200
// must be called from inside a read lock
201-
func (mt *sparseMerkleTree) getNode(key core.NodeIndex) (core.Node, error) {
201+
func (mt *sparseMerkleTree) getNode(key core.NodeRef) (core.Node, error) {
202202
if key.IsZero() {
203203
return node.NewEmptyNode(), nil
204204
}
@@ -219,7 +219,7 @@ func (mt *sparseMerkleTree) getNode(key core.NodeIndex) (core.Node, error) {
219219
// as children of a new branch node.
220220
// - if the current node is a branch node, it will continue traversing the tree, using the
221221
// next bit of the new node's index to determine which child to go down to.
222-
func (mt *sparseMerkleTree) addLeaf(batch core.Transaction, newLeaf core.Node, currentNodeIndex core.NodeIndex, level int, path []bool) (core.NodeIndex, error) {
222+
func (mt *sparseMerkleTree) addLeaf(batch core.Transaction, newLeaf core.Node, currentNodeRef core.NodeRef, level int, path []bool) (core.NodeRef, error) {
223223
log.WithLogField("level", strconv.Itoa(level)).Debugf("Adding leaf node %s", newLeaf.Ref().Hex())
224224
if level > mt.maxLevels-1 {
225225
// we have exhausted all levels but could not find a unique path for the new leaf.
@@ -228,8 +228,8 @@ func (mt *sparseMerkleTree) addLeaf(batch core.Transaction, newLeaf core.Node, c
228228
return nil, ErrReachedMaxLevel
229229
}
230230

231-
var nextKey core.NodeIndex
232-
currentNode, err := mt.getNode(currentNodeIndex)
231+
var nextKey core.NodeRef
232+
currentNode, err := mt.getNode(currentNodeRef)
233233
if err != nil {
234234
return nil, err
235235
}
@@ -289,7 +289,7 @@ func (mt *sparseMerkleTree) addLeaf(batch core.Transaction, newLeaf core.Node, c
289289
// must be called from inside a write lock
290290
// addNode adds a node into the MT. Empty nodes are not stored in the tree;
291291
// they are all the same and assumed to always exist.
292-
func (mt *sparseMerkleTree) addNode(batch core.Transaction, n core.Node) (core.NodeIndex, error) {
292+
func (mt *sparseMerkleTree) addNode(batch core.Transaction, n core.Node) (core.NodeRef, error) {
293293
if n.Type() == core.NodeTypeEmpty {
294294
return n.Ref(), nil
295295
}
@@ -301,7 +301,7 @@ func (mt *sparseMerkleTree) addNode(batch core.Transaction, n core.Node) (core.N
301301
// must be called from inside a write lock
302302
// extendPath extends the path of two leaf nodes, which share the same beginnging part of
303303
// their indexes, until their paths diverge, creating ancestor branch nodes as needed.
304-
func (mt *sparseMerkleTree) extendPath(batch core.Transaction, newLeaf core.Node, oldLeaf core.Node, level int, pathNewLeaf []bool, pathOldLeaf []bool) (core.NodeIndex, error) {
304+
func (mt *sparseMerkleTree) extendPath(batch core.Transaction, newLeaf core.Node, oldLeaf core.Node, level int, pathNewLeaf []bool, pathOldLeaf []bool) (core.NodeRef, error) {
305305
if level > mt.maxLevels-2 {
306306
return nil, ErrReachedMaxLevel
307307
}

go-sdk/internal/sparse-merkle-tree/smt/merkletree_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,16 @@ type mockStorage struct {
2828
GetRootNodeIndex_customError bool
2929
}
3030

31-
func (ms *mockStorage) GetRootNodeIndex() (core.NodeIndex, error) {
31+
func (ms *mockStorage) GetRootNodeRef() (core.NodeRef, error) {
3232
if ms.GetRootNodeIndex_customError {
3333
return nil, fmt.Errorf("nasty error in get root")
3434
}
3535
return nil, core.ErrNotFound
3636
}
37-
func (ms *mockStorage) UpsertRootNodeIndex(core.NodeIndex) error {
37+
func (ms *mockStorage) UpsertRootNodeRef(core.NodeRef) error {
3838
return fmt.Errorf("nasty error in upsert root")
3939
}
40-
func (ms *mockStorage) GetNode(core.NodeIndex) (core.Node, error) {
40+
func (ms *mockStorage) GetNode(core.NodeRef) (core.Node, error) {
4141
return nil, nil
4242
}
4343
func (ms *mockStorage) InsertNode(core.Node) error {

go-sdk/internal/sparse-merkle-tree/smt/proof.go

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import (
2828
// non-existence.
2929
type proof struct {
3030
existence bool
31-
siblings []core.NodeIndex
31+
siblings []core.NodeRef
3232
depth uint
3333
existingNode core.Node
3434
// nonEmptySiblings is a bitmap of non-empty Siblings found in Siblings. This helps
@@ -40,7 +40,7 @@ func (p *proof) IsExistenceProof() bool {
4040
return p.existence
4141
}
4242

43-
func (p *proof) Siblings() []core.NodeIndex {
43+
func (p *proof) Siblings() []core.NodeRef {
4444
return p.siblings
4545
}
4646

@@ -71,9 +71,9 @@ func (p *proof) IsNonEmptySibling(level uint) bool {
7171
return isBitOnBigEndian(p.nonEmptySiblings, level)
7272
}
7373

74-
func (p *proof) AllSiblings() []core.NodeIndex {
74+
func (p *proof) AllSiblings() []core.NodeRef {
7575
sibIdx := 0
76-
siblings := []core.NodeIndex{}
76+
siblings := []core.NodeRef{}
7777
for level := 0; level < int(p.depth); level++ {
7878
if p.IsNonEmptySibling(uint(level)) {
7979
siblings = append(siblings, p.siblings[sibIdx])
@@ -89,15 +89,15 @@ func (p *proof) AllSiblings() []core.NodeIndex {
8989
func (p *proof) getPath(index core.NodeIndex) []bool {
9090
path := make([]bool, p.depth)
9191
for n := 0; n < int(p.depth); n++ {
92-
path[n] = index.IsBitOn(uint(n))
92+
path[n] = index.IsBitOne(uint(n))
9393
}
9494
return path
9595
}
9696

9797
// ToCircomVerifierProof enhances the generic merkle proof with additional
9898
// signals required by the circuit for Sparse Merkle Tree proof verification:
9999
// https://github.com/iden3/circomlib/blob/master/circuits/smt/smtverifier.circom
100-
func (p *proof) ToCircomVerifierProof(k, v *big.Int, rootKey core.NodeIndex, levels int) (*core.CircomVerifierProof, error) {
100+
func (p *proof) ToCircomVerifierProof(k, v *big.Int, rootKey core.NodeRef, levels int) (*core.CircomVerifierProof, error) {
101101
var cp core.CircomVerifierProof
102102
cp.Root = rootKey
103103
cp.Siblings = p.AllSiblings()
@@ -131,7 +131,7 @@ func (p *proof) ToCircomVerifierProof(k, v *big.Int, rootKey core.NodeIndex, lev
131131
}
132132

133133
// VerifyProof verifies the Merkle Proof for the entry and root.
134-
func VerifyProof(rootKey core.NodeIndex, p core.Proof, leafNode core.Node) bool {
134+
func VerifyProof(rootKey core.NodeRef, p core.Proof, leafNode core.Node) bool {
135135
rootFromProof, err := calculateRootFromProof(p.(*proof), leafNode)
136136
if err != nil {
137137
return false
@@ -141,9 +141,9 @@ func VerifyProof(rootKey core.NodeIndex, p core.Proof, leafNode core.Node) bool
141141

142142
// CalculateRootFromProof calculates the root that would correspond to a tree whose
143143
// siblings are the ones in the proof with the leaf node
144-
func calculateRootFromProof(proof *proof, leafNode core.Node) (core.NodeIndex, error) {
144+
func calculateRootFromProof(proof *proof, leafNode core.Node) (core.NodeRef, error) {
145145
sibIdx := len(proof.siblings) - 1
146-
var midKey core.NodeIndex
146+
var midKey core.NodeRef
147147
if proof.existence {
148148
midKey = leafNode.Ref()
149149
} else {
@@ -157,7 +157,7 @@ func calculateRootFromProof(proof *proof, leafNode core.Node) (core.NodeIndex, e
157157
}
158158
}
159159
path := proof.getPath(leafNode.Index())
160-
var siblingKey core.NodeIndex
160+
var siblingKey core.NodeRef
161161
for level := int(proof.depth) - 1; level >= 0; level-- {
162162
if proof.IsNonEmptySibling(uint(level)) {
163163
siblingKey = proof.siblings[sibIdx]

go-sdk/internal/sparse-merkle-tree/smt/smt_test.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,9 +152,12 @@ func (s *MerkleTreeTestSuite) TestAddNode() {
152152

153153
// test storage persistence
154154
rawDB := mt.(*sparseMerkleTree).db
155-
rootIdx, err := rawDB.GetRootNodeIndex()
155+
rootIdx, err := rawDB.GetRootNodeRef()
156156
assert.NoError(s.T(), err)
157157
assert.Equal(s.T(), "abacf46f5217552ee28fe50b8fd7ca6aa46daeb9acf9f60928654c3b1a472f23", rootIdx.Hex())
158+
dbNode1, err := rawDB.GetNode(n1.Ref())
159+
assert.NoError(s.T(), err)
160+
assert.Equal(s.T(), n1.Index().Hex(), dbNode1.Index().Hex())
158161

159162
// test storage persistence across tree creation
160163
mt2, err := NewMerkleTree(s.db, 10)
@@ -242,7 +245,6 @@ func (s *MerkleTreeTestSuite) TestVerifyProof() {
242245
assert.NoError(s.T(), err)
243246
startProving <- node
244247
done <- true
245-
fmt.Printf("Added node %d\n", idx)
246248
}(value, idx)
247249
}
248250

go-sdk/internal/sparse-merkle-tree/storage/sql.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ func NewSqlStorage(p core.SqlDBProvider, smtName string) *sqlStorage {
4141
}
4242
}
4343

44-
func (s *sqlStorage) GetRootNodeIndex() (core.NodeIndex, error) {
44+
func (s *sqlStorage) GetRootNodeRef() (core.NodeRef, error) {
4545
root := core.SMTRoot{
4646
Name: s.smtName,
4747
}
@@ -51,15 +51,15 @@ func (s *sqlStorage) GetRootNodeIndex() (core.NodeIndex, error) {
5151
} else if err != nil {
5252
return nil, err
5353
}
54-
idx, err := node.NewNodeIndexFromHex(root.RootIndex)
54+
idx, err := node.NewNodeIndexFromHex(root.RootRef)
5555
return idx, err
5656
}
5757

58-
func (s *sqlStorage) UpsertRootNodeIndex(root core.NodeIndex) error {
59-
return upsertRootNodeIndex(s.p.DB(), s.smtName, root)
58+
func (s *sqlStorage) UpsertRootNodeRef(root core.NodeRef) error {
59+
return upsertRootNodeRef(s.p.DB(), s.smtName, root)
6060
}
6161

62-
func (s *sqlStorage) GetNode(ref core.NodeIndex) (core.Node, error) {
62+
func (s *sqlStorage) GetNode(ref core.NodeRef) (core.Node, error) {
6363
return getNode(s.p.DB(), s.nodesTableName, ref)
6464
}
6565

@@ -81,11 +81,11 @@ type sqlTxStorage struct {
8181
nodesTableName string
8282
}
8383

84-
func (b *sqlTxStorage) UpsertRootNodeIndex(root core.NodeIndex) error {
85-
return upsertRootNodeIndex(b.tx, b.smtName, root)
84+
func (b *sqlTxStorage) UpsertRootNodeRef(root core.NodeRef) error {
85+
return upsertRootNodeRef(b.tx, b.smtName, root)
8686
}
8787

88-
func (b *sqlTxStorage) GetNode(ref core.NodeIndex) (core.Node, error) {
88+
func (b *sqlTxStorage) GetNode(ref core.NodeRef) (core.Node, error) {
8989
return getNode(b.tx, b.nodesTableName, ref)
9090
}
9191

@@ -105,15 +105,15 @@ func (m *sqlStorage) Close() {
105105
m.p.Close()
106106
}
107107

108-
func upsertRootNodeIndex(batchOrDb *gorm.DB, name string, root core.NodeIndex) error {
108+
func upsertRootNodeRef(batchOrDb *gorm.DB, name string, root core.NodeRef) error {
109109
err := batchOrDb.Table(core.TreeRootsTable).Save(&core.SMTRoot{
110-
RootIndex: root.Hex(),
111-
Name: name,
110+
RootRef: root.Hex(),
111+
Name: name,
112112
}).Error
113113
return err
114114
}
115115

116-
func getNode(batchOrDb *gorm.DB, nodesTableName string, ref core.NodeIndex) (core.Node, error) {
116+
func getNode(batchOrDb *gorm.DB, nodesTableName string, ref core.NodeRef) (core.Node, error) {
117117
// the node's reference key (not the index) is used as the key to
118118
// store the node in the DB
119119
n := core.SMTNode{

0 commit comments

Comments
 (0)