arnaucube
arnaucube/go-merkletree-iden3Public Self-hosted repository
Add NewHashFromBytes & update comments
arnaucube root@arnaucube.com
Sat, 29 Aug 2020 18:06:17 +0200
commit

3232fdd5a45210deb8b4491d4b5503451a52e036

parent

cda85ddc27944db550b8b326d9a162c55db05cd3

3 files changed, 43 insertions(+), 11 deletions(-)

jump to
M merkletree.go → merkletree.go

@@ -15,8 +15,8 @@ "github.com/iden3/go-merkletree/db"

) const ( - // proofFlagsLen is the byte length of the flags in the proof header (first 32 - // bytes). + // proofFlagsLen is the byte length of the flags in the proof header + // (first 32 bytes). proofFlagsLen = 2 // ElemBytesLen is the length of the Hash byte array ElemBytesLen = 32

@@ -45,9 +45,11 @@ ErrInvalidDBValue = errors.New("the value in the DB is invalid")

// ErrEntryIndexAlreadyExists is used when the entry index already // exists in the tree. ErrEntryIndexAlreadyExists = errors.New("the entry index already exists in the tree") - // ErrNotWritable is used when the MerkleTree is not writable and a write function is called + // ErrNotWritable is used when the MerkleTree is not writable and a + // write function is called ErrNotWritable = errors.New("Merkle Tree not writable") - rootNodeValue = []byte("currentroot") + + rootNodeValue = []byte("currentroot") // HashZero is used at Empty nodes HashZero = Hash{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} )

@@ -77,7 +79,8 @@ }

return new(big.Int).SetBytes(common.SwapEndianness(h[:])) } -// Bytes returns the []byte representation of the *Hash +// Bytes returns the []byte representation of the *Hash, which always is 32 +// bytes length. func (h *Hash) Bytes() []byte { bi := new(big.Int).SetBytes(common.SwapEndianness(h[:])).Bytes() b := [32]byte{}

@@ -85,7 +88,10 @@ copy(b[:], bi[:])

return b[:] } -// NewBigIntFromBytes returns a *big.Int from a byte array, swapping the endianness in the process. This is the intended method to get a *big.Int from a byte array that previously has ben generated by the Hash.Bytes() method. +// NewBigIntFromBytes returns a *big.Int from a byte array, swapping the +// endianness in the process. This is the intended method to get a *big.Int +// from a byte array that previously has ben generated by the Hash.Bytes() +// method. func NewBigIntFromBytes(b []byte) (*big.Int, error) { if len(b) != 32 { return nil, fmt.Errorf("Expected 32 bytes, found %d bytes", len(b))

@@ -100,6 +106,18 @@ copy(r[:], common.SwapEndianness(b.Bytes()))

return r } +// NewHashFromBytes returns a *Hash from a byte array, swapping the endianness +// in the process. This is the intended method to get a *Hash from a byte array +// that previously has ben generated by the Hash.Bytes() method. +func NewHashFromBytes(b []byte) (*Hash, error) { + if len(b) != 32 { + return nil, fmt.Errorf("Expected 32 bytes, found %d bytes", len(b)) + } + var h Hash + copy(h[:], common.SwapEndianness(b)) + return &h, nil +} + // MerkleTree is the struct with the main elements of the MerkleTree type MerkleTree struct { sync.RWMutex

@@ -109,7 +127,8 @@ writable bool

maxLevels int } -// NewMerkleTree loads a new Merkletree. If in the sotrage already exists one will open that one, if not, will create a new one. +// NewMerkleTree loads a new Merkletree. If in the sotrage already exists one +// will open that one, if not, will create a new one. func NewMerkleTree(storage db.Storage, maxLevels int) (*MerkleTree, error) { mt := MerkleTree{db: storage, maxLevels: maxLevels, writable: true}

@@ -158,7 +177,8 @@ }

return &MerkleTree{db: mt.db, maxLevels: mt.maxLevels, rootKey: rootKey, writable: false}, nil } -// Add adds a Key & Value into the MerkleTree. Where the `k` determines the path from the Root to the Leaf. +// Add adds a Key & Value into the MerkleTree. Where the `k` determines the +// path from the Root to the Leaf. func (mt *MerkleTree) Add(k, v *big.Int) error { // verify that the MerkleTree is writable if !mt.writable {
M merkletree_test.go → merkletree_test.go

@@ -7,6 +7,7 @@ "fmt"

"math/big" "testing" + "github.com/iden3/go-iden3-core/common" "github.com/iden3/go-merkletree/db/memory" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require"

@@ -46,6 +47,14 @@ h := NewHashFromBigInt(b)

assert.Equal(t, "4932297968297298434239270129193057052722409868268166443802652458940273154854", h.BigInt().String()) assert.Equal(t, "49322979...", h.String()) assert.Equal(t, "0ae794eb9c3d8bbb9002e993fc2ed301dcbd2af5508ed072c375e861f1aa5b26", h.Hex()) + + b1, err := NewBigIntFromBytes(b.Bytes()) + assert.Nil(t, err) + assert.Equal(t, new(big.Int).SetBytes(common.SwapEndianness(b.Bytes())).String(), b1.String()) + + b2, err := NewHashFromBytes(b.Bytes()) + assert.Nil(t, err) + assert.Equal(t, b.String(), b2.BigInt().String()) } func TestNewTree(t *testing.T) {
M node.go → node.go

@@ -11,12 +11,14 @@

const ( // NodeTypeMiddle indicates the type of middle Node that has children. NodeTypeMiddle NodeType = 0 - // NodeTypeLeaf indicates the type of a leaf Node that contains a key & value. + // NodeTypeLeaf indicates the type of a leaf Node that contains a key & + // value. NodeTypeLeaf NodeType = 1 // NodeTypeEmpty indicates the type of an empty Node. NodeTypeEmpty NodeType = 2 - // DBEntryTypeRoot indicates the type of a DB entry that indicates the current Root of a MerkleTree + // DBEntryTypeRoot indicates the type of a DB entry that indicates the + // current Root of a MerkleTree DBEntryTypeRoot NodeType = 3 )

@@ -114,7 +116,8 @@ }

return n.key, nil } -// Value returns the value of the node. This is the content that is stored in the backend database. +// Value returns the value of the node. This is the content that is stored in +// the backend database. func (n *Node) Value() []byte { switch n.Type { case NodeTypeMiddle: // {Type || ChildL || ChildR}