Skip to content

Commit

Permalink
Refactoring: Push(namespace.PrefixedData)->Push(namespace.ID, []byte)
Browse files Browse the repository at this point in the history
for details see: #55
  • Loading branch information
liamsi committed May 5, 2022
1 parent b43d67c commit c1fbf91
Show file tree
Hide file tree
Showing 8 changed files with 118 additions and 135 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)
err := tree.Push(d[:size], d[size:])
if err != nil {
t.Fatalf("error on Push(): %v", err)
}
Expand Down
22 changes: 0 additions & 22 deletions namespace/data.go

This file was deleted.

4 changes: 1 addition & 3 deletions namespace/doc.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
// Package namespace contains the core namespaced data types:
// * PrefixedData represents the leaf data that gets pushed to the NMT (data prefixed with a namespace.ID)
// * IntervalDigest is the result of a namespaced hashing operation (minNs, maxNs, rawRoot).
// Package namespace contains core namespaced data types.
package namespace
14 changes: 13 additions & 1 deletion namespace/id.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,19 @@
package namespace

import "bytes"
import (
"bytes"
"math"
)

// IDMaxSize defines the max. allowed namespace ID size in bytes.
const IDMaxSize = math.MaxUint8

// IDSize is the number of bytes a namespace uses.
// Valid values are in [0,255].
type IDSize uint8

// ID represents a namespace ID.
// It's just augments byte slices with a few convenience methods.
type ID []byte

func (nid ID) Less(other ID) bool {
Expand Down
10 changes: 0 additions & 10 deletions namespace/size.go

This file was deleted.

25 changes: 15 additions & 10 deletions nmt.go
Original file line number Diff line number Diff line change
Expand Up @@ -249,14 +249,23 @@ 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(namespacedData namespace.PrefixedData) error {
nID, err := n.validateAndExtractNamespace(namespacedData)
func (n *NamespacedMerkleTree) Push(nID namespace.ID, data []byte) error {
err := n.validateNamespace(nID)
if err != nil {
return err
}

// TODO(liamsi): this is bad and lazy! We are copying the nid and data here once instead of just
// using the referenced slices we got. Reason is that internally we still treat a leaf as a single slice
// of bytes. We can and should fix this. For now we are living with the copying to have the API updated from
// Push(prefixedData) to Push(nID, data). See: https://github.com/celestiaorg/nmt/issues/55
// We intentionally do the copying here instead of forcing the user to merge (copy) the nid and data
// externally (bad UX).
leafDataCopy := make([]byte, len(nID)+len(data))
copy(leafDataCopy[:len(nID)], nID)
copy(leafDataCopy[len(nID):], data)
// update relevant "caches":
n.leaves = append(n.leaves, namespacedData)
n.leaves = append(n.leaves, leafDataCopy)
n.updateNamespaceRanges()
n.updateMinMaxID(nID)
n.rawRoot = nil
Expand Down Expand Up @@ -328,25 +337,21 @@ func (n *NamespacedMerkleTree) updateNamespaceRanges() {
}
}
}
func (n *NamespacedMerkleTree) validateAndExtractNamespace(ndata namespace.PrefixedData) (namespace.ID, error) {
func (n *NamespacedMerkleTree) validateNamespace(nID 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 nID.Less(n.leaves[curSize-1][:nidSize]) {
return nil, fmt.Errorf(
return fmt.Errorf(
"%w: last namespace: %x, pushed: %x",
ErrInvalidPushOrder,
n.leaves[curSize-1][:nidSize],
nID,
)
}
}
return nID, nil
return nil
}

func (n *NamespacedMerkleTree) updateMinMaxID(id namespace.ID) {
Expand Down
Loading

0 comments on commit c1fbf91

Please sign in to comment.