From 9c1f4b057c0f95fbf225851633489aad8f70851c Mon Sep 17 00:00:00 2001 From: arnaucube Date: Sun, 7 Jul 2019 17:02:14 +0200 Subject: [PATCH] small updates, add travis --- .travis.yml | 7 +++++++ README.md | 4 +++- merkletree.go | 7 ++++--- merkletreeSpecification_test.go | 18 ++++++++++++++++-- node_test.go | 16 ++++++++++++++++ print.go | 4 ++-- utils.go | 1 - 7 files changed, 48 insertions(+), 9 deletions(-) create mode 100644 .travis.yml create mode 100644 node_test.go diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..197076e --- /dev/null +++ b/.travis.yml @@ -0,0 +1,7 @@ +language: go + +go: + - "1.12" + +env: + - GO111MODULE=on diff --git a/README.md b/README.md index 9f3abef..e616c74 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ -# go-merkletree [![Go Report Card](https://goreportcard.com/badge/github.com/arnaucube/go-merkletree)](https://goreportcard.com/report/github.com/arnaucube/go-merkletree) [![GoDoc](https://godoc.org/github.com/arnaucube/go-merkletree?status.svg)](https://godoc.org/github.com/arnaucube/go-merkletree) +# go-merkletree [![Go Report Card](https://goreportcard.com/badge/github.com/arnaucube/go-merkletree)](https://goreportcard.com/report/github.com/arnaucube/go-merkletree) [![Build Status](https://travis-ci.org/arnaucube/go-merkletree.svg?branch=master)](https://travis-ci.org/arnaucube/go-merkletree) [![GoDoc](https://godoc.org/github.com/arnaucube/go-merkletree?status.svg)](https://godoc.org/github.com/arnaucube/go-merkletree) Optimized MerkleTree implementation in Go. +Compatible with Rust version: https://github.com/arnaucube/merkletree-rs + The MerkleTree is optimized in the design and concepts, to have a faster and lighter MerkleTree, maintaining compatibility with a non optimized MerkleTree. In this way, the MerkleRoot of the optimized MerkleTree will be the same that the MerkleRoot of the non optimized MerkleTree. This repo is holds the nostalgic (old) version of the MerkleTree implementation that we used in the past in iden3, as now has been substituted by a new specification. diff --git a/merkletree.go b/merkletree.go index 9985508..d767f0b 100644 --- a/merkletree.go +++ b/merkletree.go @@ -25,7 +25,7 @@ var ( ErrNodeAlreadyExists = errors.New("node already exists") rootNodeValue = HashBytes([]byte("root")) // EmptyNodeValue is a [32]byte EmptyNodeValue array, all to zero - EmptyNodeValue = 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} + EmptyNodeValue = 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} ) // Hash used in this tree, is the [32]byte keccak() @@ -113,6 +113,7 @@ func (mt *MerkleTree) Add(v Value) error { } } siblings = append(siblings, getEmptiesBetweenIAndPosHash(mt, i, posDiff+1)...) + if mt.root, err = mt.replaceLeaf(siblings, path[posDiff+1:], parentNode.Ht(), normalNodeType, 0, parentNode.Bytes()); err != nil { return err } @@ -233,8 +234,8 @@ func (mt *MerkleTree) GetValueInPos(hi Hash) ([]byte, error) { if nodeType == byte(finalNodeType) { // check if nodeBytes path is different of hi index := nodeBytes[:indexLength] - hi := HashBytes(index) - nodePath := getPath(mt.numLevels, hi) + nodeHi := HashBytes(index) + nodePath := getPath(mt.numLevels, nodeHi) posDiff := comparePaths(path, nodePath) // if is different, return an EmptyNodeValue, else return the nodeBytes if posDiff != -1 { diff --git a/merkletreeSpecification_test.go b/merkletreeSpecification_test.go index f477440..75a4642 100644 --- a/merkletreeSpecification_test.go +++ b/merkletreeSpecification_test.go @@ -48,6 +48,16 @@ func TestIden3MerkletreeSpecification(t *testing.T) { // empty tree assert.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000000", mt.Root().Hex()) + leafN := testBytesLeaf{ + data: []byte{1, 2, 3, 4, 5}, + indexLength: 3, + } + assert.Nil(t, mt.Add(leafN)) + assert.Equal(t, "0xa0e72cc948119fcb71b413cf5ada12b2b825d5133299b20a6d9325ffc3e2fbf1", mt.Root().Hex()) + + mt = newTestingMerkle(t, 140) + defer mt.storage.Close() + // add leaf leaf := testBytesLeaf{ data: []byte("this is a test leaf"), @@ -129,24 +139,28 @@ func TestIden3MerkletreeSpecification(t *testing.T) { // add leafs in different orders mt1 := newTestingMerkle(t, 140) - defer mt.storage.Close() + defer mt1.storage.Close() mt1.Add(newTestBytesLeaf("0 this is a test leaf", 15)) mt1.Add(newTestBytesLeaf("1 this is a test leaf", 15)) mt1.Add(newTestBytesLeaf("2 this is a test leaf", 15)) mt1.Add(newTestBytesLeaf("3 this is a test leaf", 15)) mt1.Add(newTestBytesLeaf("4 this is a test leaf", 15)) + mt1.Add(newTestBytesLeaf("5 this is a test leaf", 15)) + // mt1.PrintFullMT() mt2 := newTestingMerkle(t, 140) - defer mt.storage.Close() + defer mt2.storage.Close() mt2.Add(newTestBytesLeaf("2 this is a test leaf", 15)) mt2.Add(newTestBytesLeaf("1 this is a test leaf", 15)) mt2.Add(newTestBytesLeaf("0 this is a test leaf", 15)) + mt2.Add(newTestBytesLeaf("5 this is a test leaf", 15)) mt2.Add(newTestBytesLeaf("3 this is a test leaf", 15)) mt2.Add(newTestBytesLeaf("4 this is a test leaf", 15)) assert.Equal(t, mt1.Root().Hex(), mt2.Root().Hex()) + assert.Equal(t, mt1.Root().Hex(), "0x264397f84da141b3134dcde1d7540d27a2bf0d787bbe8365d9ad5c9c18d3c621") // adding 1000 leafs mt1000 := newTestingMerkle(t, 140) diff --git a/node_test.go b/node_test.go new file mode 100644 index 0000000..1152633 --- /dev/null +++ b/node_test.go @@ -0,0 +1,16 @@ +package merkletree + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestNode(t *testing.T) { + n := treeNode{ + ChildL: EmptyNodeValue, + ChildR: EmptyNodeValue, + } + assert.Equal(t, "0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5", n.Ht().Hex()) + +} diff --git a/print.go b/print.go index 5bb8882..bd3c5da 100644 --- a/print.go +++ b/print.go @@ -1,7 +1,6 @@ package merkletree import ( - "encoding/hex" "fmt" "github.com/fatih/color" @@ -35,7 +34,8 @@ func (mt *MerkleTree) printLevel(parent Hash, iLevel int, maxLevel int) { for i := 0; i < iLevel; i++ { fmt.Print(" ") } - color.Cyan(" leaf value: 0x" + hex.EncodeToString(leafNodeBytes)) + // color.Cyan(" leaf value: 0x" + hex.EncodeToString(leafNodeBytes)) + color.Cyan(" leaf value: " + string(leafNodeBytes)) } else { //EMPTY_NODE fmt.Print("[EmptyBranch]:") diff --git a/utils.go b/utils.go index 5d470c8..3bfb3c8 100644 --- a/utils.go +++ b/utils.go @@ -34,7 +34,6 @@ func HashBytes(b []byte) (hash Hash) { // getPath returns the binary path, from the leaf to the root func getPath(numLevels int, hi Hash) []bool { - path := []bool{} for bitno := numLevels - 2; bitno >= 0; bitno-- { path = append(path, testbitmap(hi[:], uint(bitno)))