Skip to content

Commit

Permalink
Actually change the method signature to only take one argument
Browse files Browse the repository at this point in the history
  • Loading branch information
liamsi committed Mar 20, 2021
1 parent 901d0bd commit 59ac120
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 53 deletions.
2 changes: 1 addition & 1 deletion fuzz_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func TestFuzzProveVerifyNameSpace(t *testing.T) {
for _, ns := range sortedKeys {
leafDataList := nidDataMap[ns]
for _, d := range leafDataList {
err := tree.Push(d[:size], d[size:])
err := tree.Push(d[:size])
if err != nil {
t.Fatalf("error on Push(): %v", err)
}
Expand Down
27 changes: 14 additions & 13 deletions nmt.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,16 +246,16 @@ func (n NamespacedMerkleTree) NamespaceSize() namespace.IDSize {
// Returns an error if the namespace ID size of the input
// does not match the tree's NamespaceSize() or the leaves are not pushed in
// order (i.e. lexicographically sorted by namespace ID).
func (n *NamespacedMerkleTree) Push(id namespace.ID, data []byte) error {
err := n.validateNamespace(id)
func (n *NamespacedMerkleTree) Push(namespacedData namespace.PrefixedData) error {
nID, err := n.validateAndExtractNamespace(namespacedData)
if err != nil {
return err
}
leafData := append(id, data...)

// update relevant "caches":
n.leaves = append(n.leaves, leafData)
n.leaves = append(n.leaves, namespacedData)
n.updateNamespaceRanges()
n.updateMinMaxID(id)
n.updateMinMaxID(nID)
return nil
}

Expand Down Expand Up @@ -321,24 +321,25 @@ func (n *NamespacedMerkleTree) updateNamespaceRanges() {
}
}
}
func (n *NamespacedMerkleTree) validateNamespace(id namespace.ID) error {
nidSize := n.treeHasher.NamespaceSize()
if id.Size() != nidSize {
return fmt.Errorf("%w: got: %v, want: %v", ErrMismatchedNamespaceSize, id.Size(), nidSize)
func (n *NamespacedMerkleTree) validateAndExtractNamespace(ndata namespace.PrefixedData) (namespace.ID, error) {
nidSize := int(n.NamespaceSize())
if len(ndata) < nidSize {
return nil, fmt.Errorf("%w: got: %v, want >= %v", ErrMismatchedNamespaceSize, len(ndata), nidSize)
}
nID := namespace.ID(ndata[:n.NamespaceSize()])
// ensure pushed data doesn't have a smaller namespace than the previous one:
curSize := len(n.leaves)
if curSize > 0 {
if id.Less(n.leaves[curSize-1][:nidSize]) {
return fmt.Errorf(
if nID.Less(n.leaves[curSize-1][:nidSize]) {
return nil, fmt.Errorf(
"%w: last namespace: %x, pushed: %x",
ErrInvalidPushOrder,
n.leaves[curSize-1][:nidSize],
id,
nID,
)
}
}
return nil
return nID, nil
}

func (n *NamespacedMerkleTree) updateMinMaxID(id namespace.ID) {
Expand Down
69 changes: 31 additions & 38 deletions nmt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,16 @@ func ExampleNamespacedMerkleTree() {
// the tree will use this namespace size
nidSize := 1
// the leaves that will be pushed
data := []namespaceDataPair{
newNamespaceDataPair(namespace.ID{0}, []byte("leaf_0")),
newNamespaceDataPair(namespace.ID{0}, []byte("leaf_1")),
newNamespaceDataPair(namespace.ID{1}, []byte("leaf_2")),
newNamespaceDataPair(namespace.ID{1}, []byte("leaf_3"))}
data := [][]byte{
append(namespace.ID{0}, []byte("leaf_0")...),
append(namespace.ID{0}, []byte("leaf_1")...),
append(namespace.ID{1}, []byte("leaf_2")...),
append(namespace.ID{1}, []byte("leaf_3")...)}
// Init a tree with the namespace size as well as
// the underlying hash function:
tree := New(sha256.New(), NamespaceIDSize(nidSize))
for _, d := range data {
if err := tree.Push(d.ID, d.Data); err != nil {
if err := tree.Push(d); err != nil {
panic("unexpected error")
}
}
Expand Down Expand Up @@ -89,27 +89,28 @@ func ExampleNamespacedMerkleTree() {
func TestNamespacedMerkleTree_Push(t *testing.T) {
tests := []struct {
name string
data namespaceDataPair
data namespace.PrefixedData
wantErr bool
}{
{"1st push: always OK", newNamespaceDataPair([]byte{0, 0, 0}, []byte("dummy data")), false},
{"push with same namespace: OK", newNamespaceDataPair([]byte{0, 0, 0}, []byte("dummy data")), false},
{"push with greater namespace: OK", newNamespaceDataPair([]byte{0, 0, 1}, []byte("dummy data")), false},
{"push with smaller namespace: Err", newNamespaceDataPair([]byte{0, 0, 0}, []byte("dummy data")), true},
{"push with same namespace: Ok", newNamespaceDataPair([]byte{0, 0, 1}, []byte("dummy data")), false},
{"push with greater namespace: Ok", newNamespaceDataPair([]byte{1, 0, 0}, []byte("dummy data")), false},
{"push with smaller namespace: Err", newNamespaceDataPair([]byte{0, 0, 1}, []byte("dummy data")), true},
{"push with smaller namespace: Err", newNamespaceDataPair([]byte{0, 0, 0}, []byte("dummy data")), true},
{"push with smaller namespace: Err", newNamespaceDataPair([]byte{0, 1, 0}, []byte("dummy data")), true},
{"push with same as last namespace: OK", newNamespaceDataPair([]byte{1, 0, 0}, []byte("dummy data")), false},
{"push with greater as last namespace: OK", newNamespaceDataPair([]byte{1, 1, 0}, []byte("dummy data")), false},
// note this tests for another kind of error: ErrMismatchedNamespaceSize
{"push with wrong namespace size: Err", newNamespaceDataPair([]byte{1, 1, 0, 0}, []byte("dummy data")), true},
{"1st push: always OK", append([]byte{0, 0, 0}, []byte("dummy data")...), false},
{"push with same namespace: OK", append([]byte{0, 0, 0}, []byte("dummy data")...), false},
{"push with greater namespace: OK", append([]byte{0, 0, 1}, []byte("dummy data")...), false},
{"push with smaller namespace: Err", append([]byte{0, 0, 0}, []byte("dummy data")...), true},
{"push with same namespace: Ok", append([]byte{0, 0, 1}, []byte("dummy data")...), false},
{"push with greater namespace: Ok", append([]byte{1, 0, 0}, []byte("dummy data")...), false},
{"push with smaller namespace: Err", append([]byte{0, 0, 1}, []byte("dummy data")...), true},
{"push with smaller namespace: Err", append([]byte{0, 0, 0}, []byte("dummy data")...), true},
{"push with smaller namespace: Err", append([]byte{0, 1, 0}, []byte("dummy data")...), true},
{"push with same as last namespace: OK", append([]byte{1, 0, 0}, []byte("dummy data")...), false},
{"push with greater as last namespace: OK", append([]byte{1, 1, 0}, []byte("dummy data")...), false},
// This will error, as the NMT will treat the first bytes as the namespace. If the passed data is
// too short though, it can't extract the namespace and hence will complain:
{"push with wrong namespace size: Err", []byte{1, 1}, true},
}
n := New(sha256.New(), NamespaceIDSize(3))
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := n.Push(tt.data.ID, tt.data.Data); (err != nil) != tt.wantErr {
if err := n.Push(tt.data); (err != nil) != tt.wantErr {
t.Errorf("Push() error = %v, wantErr %v", err, tt.wantErr)
}
})
Expand Down Expand Up @@ -148,7 +149,7 @@ func TestNamespacedMerkleTreeRoot(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
n := New(sha256.New(), NamespaceIDSize(tt.nidLen))
for _, d := range tt.pushedData {
if err := n.Push(d.ID, d.Data); err != nil {
if err := n.Push(namespace.PrefixedData(append(d.ID, d.Data...))); err != nil {
t.Errorf("Push() error = %v, expected no error", err)
}
}
Expand Down Expand Up @@ -202,17 +203,17 @@ func TestNamespacedMerkleTree_ProveNamespace_Ranges_And_Verify(t *testing.T) {
2, 3,
true},
{"three leaves and not found but with range", 2,
append(repeat(generateLeafData(2, 0, 1, []byte("_data")), 2), makeLeafData([]byte{1, 1}, []byte("_data"))),
append(repeat(generateLeafData(2, 0, 1, []byte("_data")), 2), newNamespaceDataPair([]byte{1, 1}, []byte("_data"))),
[]byte{0, 1},
2, 3,
false},
{"three leaves and not found but within range", 2,
append(repeat(generateLeafData(2, 0, 1, []byte("_data")), 2), makeLeafData([]byte{1, 1}, []byte("_data"))),
append(repeat(generateLeafData(2, 0, 1, []byte("_data")), 2), newNamespaceDataPair([]byte{1, 1}, []byte("_data"))),
[]byte{0, 1},
2, 3,
false},
{"5 leaves and not found but within range", 2,
append(generateLeafData(2, 0, 4, []byte("_data")), makeLeafData([]byte{1, 1}, []byte("_data"))),
append(generateLeafData(2, 0, 4, []byte("_data")), newNamespaceDataPair([]byte{1, 1}, []byte("_data"))),
[]byte{1, 0},
4, 5,
false},
Expand All @@ -233,7 +234,7 @@ func TestNamespacedMerkleTree_ProveNamespace_Ranges_And_Verify(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
n := New(sha256.New(), NamespaceIDSize(tt.nidLen))
for _, d := range tt.pushData {
err := n.Push(d.ID, d.Data)
err := n.Push(namespace.PrefixedData(append(d.ID, d.Data...)))
if err != nil {
t.Fatalf("invalid test case: %v, error on Push(): %v", tt.name, err)
}
Expand Down Expand Up @@ -435,7 +436,7 @@ func TestIgnoreMaxNamespace(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
tree := New(hash, NamespaceIDSize(nidSize), IgnoreMaxNamespace(tc.ignoreMaxNamespace))
for _, d := range tc.pushData {
if err := tree.Push(d.NamespaceID(), d.Data()); err != nil {
if err := tree.Push(namespace.PrefixedData(d)); err != nil {
panic("unexpected error")
}
}
Expand Down Expand Up @@ -485,7 +486,7 @@ func TestNodeVisitor(t *testing.T) {
data := generateRandNamespacedRawData(numLeaves, nidSize, leafSize)
n := New(sha256.New(), NamespaceIDSize(nidSize), NodeVisitor(collectNodeHashes))
for j := 0; j < numLeaves; j++ {
if err := n.Push(data[j][:nidSize], data[j][nidSize:]); err != nil {
if err := n.Push(data[j][:nidSize]); err != nil {
t.Errorf("err: %v", err)
}
}
Expand Down Expand Up @@ -522,7 +523,7 @@ func TestNamespacedMerkleTree_ProveErrors(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
n := New(sha256.New(), NamespaceIDSize(tt.nidLen), InitialCapacity(len(tt.pushData)))
for _, d := range tt.pushData {
err := n.Push(d.ID, d.Data)
err := n.Push(namespace.PrefixedData(append(d.ID, d.Data...)))
if err != nil {
t.Fatalf("invalid test case: %v, error on Push(): %v", tt.name, err)
}
Expand Down Expand Up @@ -603,7 +604,7 @@ func BenchmarkComputeRoot(b *testing.B) {
for i := 0; i < b.N; i++ {
n := New(sha256.New())
for j := 0; j < tt.numLeaves; j++ {
if err := n.Push(data[j][:tt.nidSize], data[j][tt.nidSize:]); err != nil {
if err := n.Push(data[j][:tt.nidSize]); err != nil {
b.Errorf("err: %v", err)
}
}
Expand All @@ -621,14 +622,6 @@ func shouldPanic(t *testing.T, f func()) {
t.Errorf("should have panicked")
}

// TODO remove
func makeLeafData(ns []byte, data []byte) namespaceDataPair {
if len(ns) > math.MaxUint8 {
panic("namespace too large")
}
return newNamespaceDataPair(ns, data)
}

// generates a consecutive range of leaf data
// starting from namespace zero+start till zero+end,
// where zero := 0*nsLen interpreted Uvarint
Expand Down
2 changes: 1 addition & 1 deletion proof_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func TestProof_VerifyNamespace_False(t *testing.T) {
generateLeafData(testNidLen, 0, 9, []byte("data"))...,
), newNamespaceDataPair([]byte{0, 0, 8}, []byte("last leaf")))
for _, d := range data {
err := n.Push(d.ID, d.Data)
err := n.Push(namespace.PrefixedData(append(d.ID, d.Data...)))
if err != nil {
t.Fatalf("invalid test setup: error on Push(): %v", err)
}
Expand Down

0 comments on commit 59ac120

Please sign in to comment.