Skip to content

Commit

Permalink
Merge pull request #27 from lazyledger/ismail/refactor_push
Browse files Browse the repository at this point in the history
Change Push signature to take in namespace and data pair as one argument (instead of splitting them up to merge them back together internally)
  • Loading branch information
liamsi committed Mar 22, 2021
2 parents d7fca90 + 1feed0c commit 14db874
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 115 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)
if err != nil {
t.Fatalf("error on Push(): %v", err)
}
Expand Down
38 changes: 11 additions & 27 deletions namespace/data.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
package namespace

// PrefixedData simply represents a slice of bytes which consists of
// a namespace.ID and raw data.
// The user has to guarantee that the bytes are valid namespace prefixed data.
// Go's type system does not allow enforcing the structure we want:
// [namespaceID, rawData ...], especially as this type does not expect any
// particular size for the namespace.
type PrefixedData []byte

// PrefixedData8 like PrefixedData is just a slice of bytes.
// It assumes that the slice it represents is at least 8 bytes.
// This assumption is not enforced by the type system though.
type PrefixedData8 []byte

func (d PrefixedData8) NamespaceID() ID {
Expand All @@ -9,30 +20,3 @@ func (d PrefixedData8) NamespaceID() ID {
func (d PrefixedData8) Data() []byte {
return d[8:]
}

type PrefixedData struct {
namespaceLen IDSize
prefixedData []byte
}

func (n PrefixedData) NamespaceID() ID {
return n.prefixedData[:n.namespaceLen]
}

func (n PrefixedData) Data() []byte {
return n.prefixedData[n.namespaceLen:]
}

func NewPrefixedData(namespaceLen IDSize, prefixedData []byte) PrefixedData {
return PrefixedData{
namespaceLen: namespaceLen,
prefixedData: prefixedData,
}
}

func PrefixedDataFrom(nID ID, data []byte) PrefixedData {
return PrefixedData{
namespaceLen: nID.Size(),
prefixedData: append(nID, data...),
}
}
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
Loading

0 comments on commit 14db874

Please sign in to comment.