Browse Source

Merge pull request #13 from iden3/feature/upgrade-linters

Upgrade linter rules
feature/sc-siblings
Eduard S 3 years ago
committed by GitHub
parent
commit
8f3905f15f
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 269 additions and 265 deletions
  1. +1
    -1
      .github/workflows/lint.yml
  2. +17
    -0
      .golangci.yml
  3. +0
    -1
      db/db.go
  4. +23
    -61
      db/leveldb/leveldb.go
  5. +1
    -1
      db/leveldb/leveldb_test.go
  6. +27
    -29
      db/memory/memory.go
  7. +39
    -59
      db/pebble/pebble.go
  8. +1
    -1
      db/pebble/pebble_test.go
  9. +1
    -1
      db/test/test.go
  10. +1
    -2
      go.mod
  11. +4
    -5
      go.sum
  12. +88
    -76
      merkletree.go
  13. +42
    -28
      merkletree_test.go
  14. +24
    -0
      utils.go

+ 1
- 1
.github/workflows/lint.yml

@ -13,4 +13,4 @@ jobs:
- name: Lint
run: |
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.30.0
$(go env GOPATH)/bin/golangci-lint run --timeout=5m -E whitespace -E gosec -E gci -E misspell -E gomnd --max-same-issues 0
$(go env GOPATH)/bin/golangci-lint run --timeout=5m -c .golangci.yml

+ 17
- 0
.golangci.yml

@ -0,0 +1,17 @@
issues:
max-same-issues: 0
exclude-use-default: false
linters:
enable:
- whitespace
- gosec
- gci
- misspell
- gomnd
- gofmt
- goimports
- lll
- golint
linters-settings:
lll:
line-length: 100

+ 0
- 1
db/db.go

@ -19,7 +19,6 @@ type Storage interface {
Get([]byte) ([]byte, error)
List(int) ([]KV, error)
Close()
Info() string
Iterate(func([]byte, []byte) (bool, error)) error
}

+ 23
- 61
db/leveldb/leveldb.go

@ -1,8 +1,6 @@
package leveldb
import (
"encoding/json"
"github.com/iden3/go-merkletree/db"
log "github.com/sirupsen/logrus"
"github.com/syndtr/goleveldb/leveldb"
@ -11,20 +9,20 @@ import (
"github.com/syndtr/goleveldb/leveldb/util"
)
// LevelDbStorage implements the db.Storage interface
type LevelDbStorage struct {
// Storage implements the db.Storage interface
type Storage struct {
ldb *leveldb.DB
prefix []byte
}
// LevelDbStorageTx implements the db.Tx interface
type LevelDbStorageTx struct {
*LevelDbStorage
// StorageTx implements the db.Tx interface
type StorageTx struct {
*Storage
cache db.KvMap
}
// NewLevelDbStorage returns a new LevelDbStorage
func NewLevelDbStorage(path string, errorIfMissing bool) (*LevelDbStorage, error) {
// NewLevelDbStorage returns a new Storage
func NewLevelDbStorage(path string, errorIfMissing bool) (*Storage, error) {
o := &opt.Options{
ErrorIfMissing: errorIfMissing,
}
@ -32,57 +30,21 @@ func NewLevelDbStorage(path string, errorIfMissing bool) (*LevelDbStorage, error
if err != nil {
return nil, err
}
return &LevelDbStorage{ldb, []byte{}}, nil
}
type storageInfo struct {
KeyCount int
ClaimCount int
}
// Info implements the method Info of the interface db.Storage
func (l *LevelDbStorage) Info() string {
snapshot, err := l.ldb.GetSnapshot()
if err != nil {
return err.Error()
}
keycount := 0
claimcount := 0
iter := snapshot.NewIterator(nil, nil)
for iter.Next() {
if iter.Value()[0] == byte(1) {
claimcount++
}
keycount++
}
iter.Release()
if err := iter.Error(); err != nil {
return err.Error()
}
json, _ := json.MarshalIndent(
storageInfo{
KeyCount: keycount,
ClaimCount: claimcount,
},
"", " ",
)
return string(json)
return &Storage{ldb, []byte{}}, nil
}
// WithPrefix implements the method WithPrefix of the interface db.Storage
func (l *LevelDbStorage) WithPrefix(prefix []byte) db.Storage {
return &LevelDbStorage{l.ldb, db.Concat(l.prefix, prefix)}
func (l *Storage) WithPrefix(prefix []byte) db.Storage {
return &Storage{l.ldb, db.Concat(l.prefix, prefix)}
}
// NewTx implements the method NewTx of the interface db.Storage
func (l *LevelDbStorage) NewTx() (db.Tx, error) {
return &LevelDbStorageTx{l, make(db.KvMap)}, nil
func (l *Storage) NewTx() (db.Tx, error) {
return &StorageTx{l, make(db.KvMap)}, nil
}
// Get retreives a value from a key in the db.Storage
func (l *LevelDbStorage) Get(key []byte) ([]byte, error) {
func (l *Storage) Get(key []byte) ([]byte, error) {
v, err := l.ldb.Get(db.Concat(l.prefix, key[:]), nil)
if err == errors.ErrNotFound {
return nil, db.ErrNotFound
@ -91,7 +53,7 @@ func (l *LevelDbStorage) Get(key []byte) ([]byte, error) {
}
// Iterate implements the method Iterate of the interface db.Storage
func (l *LevelDbStorage) Iterate(f func([]byte, []byte) (bool, error)) error {
func (l *Storage) Iterate(f func([]byte, []byte) (bool, error)) error {
// FIXME: Use the prefix!
snapshot, err := l.ldb.GetSnapshot()
if err != nil {
@ -112,7 +74,7 @@ func (l *LevelDbStorage) Iterate(f func([]byte, []byte) (bool, error)) error {
}
// Get retreives a value from a key in the interface db.Tx
func (tx *LevelDbStorageTx) Get(key []byte) ([]byte, error) {
func (tx *StorageTx) Get(key []byte) ([]byte, error) {
var err error
fullkey := db.Concat(tx.prefix, key)
@ -130,14 +92,14 @@ func (tx *LevelDbStorageTx) Get(key []byte) ([]byte, error) {
}
// Put saves a key:value into the db.Storage
func (tx *LevelDbStorageTx) Put(k, v []byte) error {
func (tx *StorageTx) Put(k, v []byte) error {
tx.cache.Put(db.Concat(tx.prefix, k[:]), v)
return nil
}
// Add implements the method Add of the interface db.Tx
func (tx *LevelDbStorageTx) Add(atx db.Tx) error {
ldbtx := atx.(*LevelDbStorageTx)
func (tx *StorageTx) Add(atx db.Tx) error {
ldbtx := atx.(*StorageTx)
for _, v := range ldbtx.cache {
tx.cache.Put(v.K, v.V)
}
@ -145,7 +107,7 @@ func (tx *LevelDbStorageTx) Add(atx db.Tx) error {
}
// Commit implements the method Commit of the interface db.Tx
func (tx *LevelDbStorageTx) Commit() error {
func (tx *StorageTx) Commit() error {
var batch leveldb.Batch
for _, v := range tx.cache {
batch.Put(v.K, v.V)
@ -156,12 +118,12 @@ func (tx *LevelDbStorageTx) Commit() error {
}
// Close implements the method Close of the interface db.Tx
func (tx *LevelDbStorageTx) Close() {
func (tx *StorageTx) Close() {
tx.cache = nil
}
// Close implements the method Close of the interface db.Storage
func (l *LevelDbStorage) Close() {
func (l *Storage) Close() {
if err := l.ldb.Close(); err != nil {
panic(err)
}
@ -169,12 +131,12 @@ func (l *LevelDbStorage) Close() {
}
// LevelDB is an extra method that returns the *leveldb.DB
func (l *LevelDbStorage) LevelDB() *leveldb.DB {
func (l *Storage) LevelDB() *leveldb.DB {
return l.ldb
}
// List implements the method List of the interface db.Storage
func (l *LevelDbStorage) List(limit int) ([]db.KV, error) {
func (l *Storage) List(limit int) ([]db.KV, error) {
ret := []db.KV{}
err := l.Iterate(func(key []byte, value []byte) (bool, error) {
ret = append(ret, db.KV{K: db.Clone(key), V: db.Clone(value)})

+ 1
- 1
db/leveldb/leveldb_test.go

@ -51,7 +51,7 @@ func TestLevelDbInterface(t *testing.T) {
func TestMain(m *testing.M) {
result := m.Run()
for _, dir := range rmDirs {
os.RemoveAll(dir)
os.RemoveAll(dir) //nolint:errcheck,gosec
}
os.Exit(result)
}

+ 27
- 29
db/memory/memory.go

@ -7,41 +7,36 @@ import (
"github.com/iden3/go-merkletree/db"
)
// MemoryStorage implements the db.Storage interface
type MemoryStorage struct {
// Storage implements the db.Storage interface
type Storage struct {
prefix []byte
kv db.KvMap
}
// MemoryStorageTx implements the db.Tx interface
type MemoryStorageTx struct {
s *MemoryStorage
// StorageTx implements the db.Tx interface
type StorageTx struct {
s *Storage
kv db.KvMap
}
// NewMemoryStorage returns a new MemoryStorage
func NewMemoryStorage() *MemoryStorage {
// NewMemoryStorage returns a new Storage
func NewMemoryStorage() *Storage {
kvmap := make(db.KvMap)
return &MemoryStorage{[]byte{}, kvmap}
}
// Info implements the method Info of the interface db.Storage
func (m *MemoryStorage) Info() string {
return "in-memory"
return &Storage{[]byte{}, kvmap}
}
// WithPrefix implements the method WithPrefix of the interface db.Storage
func (m *MemoryStorage) WithPrefix(prefix []byte) db.Storage {
return &MemoryStorage{db.Concat(m.prefix, prefix), m.kv}
func (m *Storage) WithPrefix(prefix []byte) db.Storage {
return &Storage{db.Concat(m.prefix, prefix), m.kv}
}
// NewTx implements the method NewTx of the interface db.Storage
func (m *MemoryStorage) NewTx() (db.Tx, error) {
return &MemoryStorageTx{m, make(db.KvMap)}, nil
func (m *Storage) NewTx() (db.Tx, error) {
return &StorageTx{m, make(db.KvMap)}, nil
}
// Get retreives a value from a key in the db.Storage
func (m *MemoryStorage) Get(key []byte) ([]byte, error) {
func (m *Storage) Get(key []byte) ([]byte, error) {
if v, ok := m.kv.Get(db.Concat(m.prefix, key[:])); ok {
return v, nil
}
@ -49,16 +44,19 @@ func (m *MemoryStorage) Get(key []byte) ([]byte, error) {
}
// Iterate implements the method Iterate of the interface db.Storage
func (m *MemoryStorage) Iterate(f func([]byte, []byte) (bool, error)) error {
func (m *Storage) Iterate(f func([]byte, []byte) (bool, error)) error {
kvs := make([]db.KV, 0)
for _, v := range m.kv {
if len(v.K) < len(m.prefix) || !bytes.Equal(v.K[:len(m.prefix)], m.prefix) {
if len(v.K) < len(m.prefix) ||
!bytes.Equal(v.K[:len(m.prefix)], m.prefix) {
continue
}
localkey := v.K[len(m.prefix):]
kvs = append(kvs, db.KV{K: localkey, V: v.V})
}
sort.SliceStable(kvs, func(i, j int) bool { return bytes.Compare(kvs[i].K, kvs[j].K) < 0 })
sort.SliceStable(kvs, func(i, j int) bool {
return bytes.Compare(kvs[i].K, kvs[j].K) < 0
})
for _, kv := range kvs {
if cont, err := f(kv.K, kv.V); err != nil {
@ -71,7 +69,7 @@ func (m *MemoryStorage) Iterate(f func([]byte, []byte) (bool, error)) error {
}
// Get implements the method Get of the interface db.Tx
func (tx *MemoryStorageTx) Get(key []byte) ([]byte, error) {
func (tx *StorageTx) Get(key []byte) ([]byte, error) {
if v, ok := tx.kv.Get(db.Concat(tx.s.prefix, key)); ok {
return v, nil
}
@ -83,13 +81,13 @@ func (tx *MemoryStorageTx) Get(key []byte) ([]byte, error) {
}
// Put implements the method Put of the interface db.Tx
func (tx *MemoryStorageTx) Put(k, v []byte) error {
func (tx *StorageTx) Put(k, v []byte) error {
tx.kv.Put(db.Concat(tx.s.prefix, k), v)
return nil
}
// Commit implements the method Commit of the interface db.Tx
func (tx *MemoryStorageTx) Commit() error {
func (tx *StorageTx) Commit() error {
for _, v := range tx.kv {
tx.s.kv.Put(v.K, v.V)
}
@ -98,8 +96,8 @@ func (tx *MemoryStorageTx) Commit() error {
}
// Add implements the method Add of the interface db.Tx
func (tx *MemoryStorageTx) Add(atx db.Tx) error {
mstx := atx.(*MemoryStorageTx)
func (tx *StorageTx) Add(atx db.Tx) error {
mstx := atx.(*StorageTx)
for _, v := range mstx.kv {
tx.kv.Put(v.K, v.V)
}
@ -107,16 +105,16 @@ func (tx *MemoryStorageTx) Add(atx db.Tx) error {
}
// Close implements the method Close of the interface db.Tx
func (tx *MemoryStorageTx) Close() {
func (tx *StorageTx) Close() {
tx.kv = nil
}
// Close implements the method Close of the interface db.Storage
func (m *MemoryStorage) Close() {
func (m *Storage) Close() {
}
// List implements the method List of the interface db.Storage
func (m *MemoryStorage) List(limit int) ([]db.KV, error) {
func (m *Storage) List(limit int) ([]db.KV, error) {
ret := []db.KV{}
err := m.Iterate(func(key []byte, value []byte) (bool, error) {
ret = append(ret, db.KV{K: db.Clone(key), V: db.Clone(value)})

+ 39
- 59
db/pebble/pebble.go

@ -1,27 +1,25 @@
package pebble
import (
"encoding/json"
"github.com/cockroachdb/pebble"
"github.com/iden3/go-merkletree/db"
log "github.com/sirupsen/logrus"
)
// PebbleStorage implements the db.Storage interface
type PebbleStorage struct {
// Storage implements the db.Storage interface
type Storage struct {
pdb *pebble.DB
prefix []byte
}
// PebbleStorageTx implements the db.Tx interface
type PebbleStorageTx struct {
*PebbleStorage
// StorageTx implements the db.Tx interface
type StorageTx struct {
*Storage
batch *pebble.Batch
}
// NewPebbleStorage returns a new PebbleStorage
func NewPebbleStorage(path string, errorIfMissing bool) (*PebbleStorage, error) {
// NewPebbleStorage returns a new Storage
func NewPebbleStorage(path string, errorIfMissing bool) (*Storage, error) {
o := &pebble.Options{
ErrorIfNotExists: errorIfMissing,
}
@ -29,59 +27,33 @@ func NewPebbleStorage(path string, errorIfMissing bool) (*PebbleStorage, error)
if err != nil {
return nil, err
}
return &PebbleStorage{rdb, []byte{}}, nil
}
type storageInfo struct {
KeyCount int
ClaimCount int
}
// Info implements the method Info of the interface db.Storage
func (p *PebbleStorage) Info() string {
keycount := 0
claimcount := 0
err := p.Iterate(func(key []byte, value []byte) (bool, error) {
if value[0] == byte(1) {
claimcount++
}
keycount++
return true, nil
})
if err != nil {
return err.Error()
}
json, _ := json.MarshalIndent(
storageInfo{
KeyCount: keycount,
ClaimCount: claimcount,
},
"", " ",
)
return string(json)
return &Storage{rdb, []byte{}}, nil
}
// WithPrefix implements the method WithPrefix of the interface db.Storage
func (p *PebbleStorage) WithPrefix(prefix []byte) db.Storage {
return &PebbleStorage{p.pdb, db.Concat(p.prefix, prefix)}
func (p *Storage) WithPrefix(prefix []byte) db.Storage {
return &Storage{p.pdb, db.Concat(p.prefix, prefix)}
}
// NewTx implements the method NewTx of the interface db.Storage
func (p *PebbleStorage) NewTx() (db.Tx, error) {
return &PebbleStorageTx{p, p.pdb.NewIndexedBatch()}, nil
func (p *Storage) NewTx() (db.Tx, error) {
return &StorageTx{p, p.pdb.NewIndexedBatch()}, nil
}
// Get retreives a value from a key in the db.Storage
func (p *PebbleStorage) Get(key []byte) ([]byte, error) {
func (p *Storage) Get(key []byte) ([]byte, error) {
v, closer, err := p.pdb.Get(db.Concat(p.prefix, key[:]))
if err == pebble.ErrNotFound {
return nil, db.ErrNotFound
}
closer.Close()
if err != nil {
return nil, err
}
err = closer.Close()
return v, err
}
//nolint:lll
// https://github.com/cockroachdb/pebble/pull/923/files#diff-c2ade2f386c41794d5ebc57ee49b57a5fca8082e03255e5bff13977cbc061287R39
func keyUpperBound(b []byte) []byte {
end := make([]byte, len(b))
@ -102,7 +74,7 @@ func prefixIterOptions(prefix []byte) *pebble.IterOptions {
}
// Iterate implements the method Iterate of the interface db.Storage
func (p *PebbleStorage) Iterate(f func([]byte, []byte) (bool, error)) error {
func (p *Storage) Iterate(f func([]byte, []byte) (bool, error)) (err error) {
// NewIter already provides a point-in-time view of the current DB
// state, but if is used for long term (is not the case), should use an
// iterator over an snapshot:
@ -110,7 +82,13 @@ func (p *PebbleStorage) Iterate(f func([]byte, []byte) (bool, error)) error {
// defer snapshot.Close()
// iter := snapshot.NewIter(nil)
iter := p.pdb.NewIter(prefixIterOptions(p.prefix))
defer iter.Close()
defer func() {
err1 := iter.Close()
if err != nil {
return
}
err = err1
}()
for iter.First(); iter.Valid(); iter.Next() {
localKey := iter.Key()[len(p.prefix):]
@ -124,7 +102,7 @@ func (p *PebbleStorage) Iterate(f func([]byte, []byte) (bool, error)) error {
}
// Get retreives a value from a key in the interface db.Tx
func (tx *PebbleStorageTx) Get(key []byte) ([]byte, error) {
func (tx *StorageTx) Get(key []byte) ([]byte, error) {
var err error
fullkey := db.Concat(tx.prefix, key)
@ -133,34 +111,36 @@ func (tx *PebbleStorageTx) Get(key []byte) ([]byte, error) {
if err == pebble.ErrNotFound {
return nil, db.ErrNotFound
}
closer.Close()
if err != nil {
return nil, err
}
err = closer.Close()
return v, err
}
// Put saves a key:value into the db.Storage
func (tx *PebbleStorageTx) Put(k, v []byte) error {
func (tx *StorageTx) Put(k, v []byte) error {
return tx.batch.Set(db.Concat(tx.prefix, k[:]), v, nil)
}
// Add implements the method Add of the interface db.Tx
func (tx *PebbleStorageTx) Add(atx db.Tx) error {
patx := atx.(*PebbleStorageTx)
func (tx *StorageTx) Add(atx db.Tx) error {
patx := atx.(*StorageTx)
return tx.batch.Apply(patx.batch, nil)
}
// Commit implements the method Commit of the interface db.Tx
func (tx *PebbleStorageTx) Commit() error {
func (tx *StorageTx) Commit() error {
return tx.batch.Commit(nil)
}
// Close implements the method Close of the interface db.Tx
func (tx *PebbleStorageTx) Close() {
func (tx *StorageTx) Close() {
_ = tx.batch.Close()
}
// Close implements the method Close of the interface db.Storage
func (p *PebbleStorage) Close() {
func (p *Storage) Close() {
if err := p.pdb.Close(); err != nil {
panic(err)
}
@ -168,12 +148,12 @@ func (p *PebbleStorage) Close() {
}
// Pebble is an extra method that returns the *pebble.DB
func (p *PebbleStorage) Pebble() *pebble.DB {
func (p *Storage) Pebble() *pebble.DB {
return p.pdb
}
// List implements the method List of the interface db.Storage
func (p *PebbleStorage) List(limit int) ([]db.KV, error) {
func (p *Storage) List(limit int) ([]db.KV, error) {
ret := []db.KV{}
err := p.Iterate(func(key []byte, value []byte) (bool, error) {
ret = append(ret, db.KV{K: db.Clone(key), V: db.Clone(value)})

+ 1
- 1
db/pebble/pebble_test.go

@ -51,7 +51,7 @@ func TestPebbleInterface(t *testing.T) {
func TestMain(m *testing.M) {
result := m.Run()
for _, dir := range rmDirs {
os.RemoveAll(dir)
os.RemoveAll(dir) //nolint:errcheck,gosec
}
os.Exit(result)
}

+ 1
- 1
db/test/test.go

@ -1,4 +1,4 @@
//nolint:gomnd
//nolint:gomnd,golint
package test
import (

+ 1
- 2
go.mod

@ -4,8 +4,7 @@ go 1.14
require (
github.com/cockroachdb/pebble v0.0.0-20200814004841-77c18adb0ee3
github.com/iden3/go-iden3-core v0.0.8
github.com/iden3/go-iden3-crypto v0.0.6-0.20200819064831-09d161e9f670
github.com/iden3/go-iden3-crypto v0.0.6-0.20201218111145-a2015adb2f1b
github.com/sirupsen/logrus v1.5.0
github.com/stretchr/testify v1.6.1
github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d

+ 4
- 5
go.sum

@ -132,11 +132,11 @@ github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3
github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0/go.mod h1:N0Wam8K1arqPXNWjMo21EXnBPOPp36vB07FNRdD2geA=
github.com/iden3/go-circom-prover-verifier v0.0.1/go.mod h1:1FkpX4nUXxYcY2fpzqd27wHHEnWeo1v1nwDnz2TgBRo=
github.com/iden3/go-circom-witnesscalc v0.0.1/go.mod h1:xjT1BlFZDBioHOlbD75SmZZLC1d1AfOycqbSa/1QRJU=
github.com/iden3/go-iden3-core v0.0.8 h1:PLw7iCiX7Pw1dqBkR+JaLQWqB5RKd+vgu25UBdvFXGQ=
github.com/iden3/go-iden3-core v0.0.8/go.mod h1:URNjIhMql6sEbWubIGrjJdw5wHCE1Pk1XghxjBOtA3s=
github.com/iden3/go-iden3-crypto v0.0.5/go.mod h1:XKw1oDwYn2CIxKOtr7m/mL5jMn4mLOxAxtZBRxQBev8=
github.com/iden3/go-iden3-crypto v0.0.6-0.20200819064831-09d161e9f670 h1:gNBFu/WnRfNn+xywE04fgCWSHlb6wr0nIIll9i4R2fc=
github.com/iden3/go-iden3-crypto v0.0.6-0.20200819064831-09d161e9f670/go.mod h1:oBgthFLboAWi9feaBUFy7OxEcyn9vA1khHSL/WwWFyg=
github.com/iden3/go-iden3-crypto v0.0.6-0.20201203095229-821a601d2002 h1:f2twuL20aAqq1TlSdfQgL5r68hKjB/ioQdSctREQLuY=
github.com/iden3/go-iden3-crypto v0.0.6-0.20201203095229-821a601d2002/go.mod h1:oBgthFLboAWi9feaBUFy7OxEcyn9vA1khHSL/WwWFyg=
github.com/iden3/go-iden3-crypto v0.0.6-0.20201218111145-a2015adb2f1b h1:U2EsJRdonl0lhWvNiDscXZRDqSsPLIJHZg5DmU10IDo=
github.com/iden3/go-iden3-crypto v0.0.6-0.20201218111145-a2015adb2f1b/go.mod h1:oBgthFLboAWi9feaBUFy7OxEcyn9vA1khHSL/WwWFyg=
github.com/iden3/go-wasm3 v0.0.1/go.mod h1:j+TcAB94Dfrjlu5kJt83h2OqAU+oyNUTwNZnQyII1sI=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/influxdata/influxdb v1.2.3-0.20180221223340-01288bdb0883/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY=
@ -255,7 +255,6 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200311171314-f7b00557c8c4 h1:QmwruyY+bKbDDL0BaglrbZABEali68eoMFhTZpCjYVA=
golang.org/x/crypto v0.0.0-20200311171314-f7b00557c8c4/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4=

+ 88
- 76
merkletree.go

@ -10,7 +10,6 @@ import (
"strings"
"sync"
"github.com/iden3/go-iden3-core/common"
cryptoUtils "github.com/iden3/go-iden3-crypto/utils"
"github.com/iden3/go-merkletree/db"
)
@ -54,7 +53,8 @@ var (
dbKeyRootNode = []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}
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}
)
// Hash is the generic type stored in the MerkleTree
@ -87,16 +87,16 @@ func (h Hash) Hex() string {
// alternatively equivalent, but with too extra steps:
// bRaw := h.BigInt().Bytes()
// b := [32]byte{}
// copy(b[:], common.SwapEndianness(bRaw[:]))
// copy(b[:], SwapEndianness(bRaw[:]))
// return hex.EncodeToString(b[:])
}
// BigInt returns the *big.Int representation of the *Hash
func (h *Hash) BigInt() *big.Int {
if new(big.Int).SetBytes(common.SwapEndianness(h[:])) == nil {
if new(big.Int).SetBytes(SwapEndianness(h[:])) == nil {
return big.NewInt(0)
}
return new(big.Int).SetBytes(common.SwapEndianness(h[:]))
return new(big.Int).SetBytes(SwapEndianness(h[:]))
}
// Bytes returns the []byte representation of the *Hash, which always is 32
@ -104,7 +104,7 @@ func (h *Hash) BigInt() *big.Int {
func (h *Hash) Bytes() []byte {
bi := new(big.Int).SetBytes(h[:]).Bytes()
b := [32]byte{}
copy(b[:], common.SwapEndianness(bi[:]))
copy(b[:], SwapEndianness(bi[:]))
return b[:]
}
@ -126,7 +126,7 @@ func NewBigIntFromHashBytes(b []byte) (*big.Int, error) {
// NewHashFromBigInt returns a *Hash representation of the given *big.Int
func NewHashFromBigInt(b *big.Int) *Hash {
r := &Hash{}
copy(r[:], common.SwapEndianness(b.Bytes()))
copy(r[:], SwapEndianness(b.Bytes()))
return r
}
@ -138,7 +138,7 @@ func NewHashFromBytes(b []byte) (*Hash, error) {
return nil, fmt.Errorf("Expected 32 bytes, found %d bytes", len(b))
}
var h Hash
copy(h[:], common.SwapEndianness(b))
copy(h[:], SwapEndianness(b))
return &h, nil
}
@ -149,7 +149,7 @@ func NewHashFromHex(h string) (*Hash, error) {
if err != nil {
return nil, err
}
return NewHashFromBytes(common.SwapEndianness(b[:]))
return NewHashFromBytes(SwapEndianness(b[:]))
}
// NewHashFromString returns a *Hash representation of the given decimal string
@ -281,7 +281,8 @@ func (mt *MerkleTree) Add(k, v *big.Int) error {
}
// AddAndGetCircomProof does an Add, and returns a CircomProcessorProof
func (mt *MerkleTree) AddAndGetCircomProof(k, v *big.Int) (*CircomProcessorProof, error) {
func (mt *MerkleTree) AddAndGetCircomProof(k,
v *big.Int) (*CircomProcessorProof, error) {
var cp CircomProcessorProof
cp.Fnc = 2
cp.OldRoot = mt.rootKey
@ -315,8 +316,8 @@ func (mt *MerkleTree) AddAndGetCircomProof(k, v *big.Int) (*CircomProcessorProof
// pushLeaf recursively pushes an existing oldLeaf down until its path diverges
// from newLeaf, at which point both leafs are stored, all while updating the
// path.
func (mt *MerkleTree) pushLeaf(tx db.Tx, newLeaf *Node, oldLeaf *Node,
lvl int, pathNewLeaf []bool, pathOldLeaf []bool) (*Hash, error) {
func (mt *MerkleTree) pushLeaf(tx db.Tx, newLeaf *Node, oldLeaf *Node, lvl int,
pathNewLeaf []bool, pathOldLeaf []bool) (*Hash, error) {
if lvl > mt.maxLevels-2 {
return nil, ErrReachedMaxLevel
}
@ -326,34 +327,34 @@ func (mt *MerkleTree) pushLeaf(tx db.Tx, newLeaf *Node, oldLeaf *Node,
if err != nil {
return nil, err
}
if pathNewLeaf[lvl] {
newNodeMiddle = NewNodeMiddle(&HashZero, nextKey) // go right
} else {
newNodeMiddle = NewNodeMiddle(nextKey, &HashZero) // go left
if pathNewLeaf[lvl] { // go right
newNodeMiddle = NewNodeMiddle(&HashZero, nextKey)
} else { // go left
newNodeMiddle = NewNodeMiddle(nextKey, &HashZero)
}
return mt.addNode(tx, newNodeMiddle)
} else {
oldLeafKey, err := oldLeaf.Key()
if err != nil {
return nil, err
}
newLeafKey, err := newLeaf.Key()
if err != nil {
return nil, err
}
}
oldLeafKey, err := oldLeaf.Key()
if err != nil {
return nil, err
}
newLeafKey, err := newLeaf.Key()
if err != nil {
return nil, err
}
if pathNewLeaf[lvl] {
newNodeMiddle = NewNodeMiddle(oldLeafKey, newLeafKey)
} else {
newNodeMiddle = NewNodeMiddle(newLeafKey, oldLeafKey)
}
// We can add newLeaf now. We don't need to add oldLeaf because it's already in the tree.
_, err = mt.addNode(tx, newLeaf)
if err != nil {
return nil, err
}
return mt.addNode(tx, newNodeMiddle)
if pathNewLeaf[lvl] {
newNodeMiddle = NewNodeMiddle(oldLeafKey, newLeafKey)
} else {
newNodeMiddle = NewNodeMiddle(newLeafKey, oldLeafKey)
}
// We can add newLeaf now. We don't need to add oldLeaf because it's
// already in the tree.
_, err = mt.addNode(tx, newLeaf)
if err != nil {
return nil, err
}
return mt.addNode(tx, newNodeMiddle)
}
// addLeaf recursively adds a newLeaf in the MT while updating the path.
@ -374,23 +375,25 @@ func (mt *MerkleTree) addLeaf(tx db.Tx, newLeaf *Node, key *Hash,
return mt.addNode(tx, newLeaf)
case NodeTypeLeaf:
nKey := n.Entry[0]
// Check if leaf node found contains the leaf node we are trying to add
// Check if leaf node found contains the leaf node we are
// trying to add
newLeafKey := newLeaf.Entry[0]
if bytes.Equal(nKey[:], newLeafKey[:]) {
return nil, ErrEntryIndexAlreadyExists
}
pathOldLeaf := getPath(mt.maxLevels, nKey[:])
// We need to push newLeaf down until its path diverges from n's path
// We need to push newLeaf down until its path diverges from
// n's path
return mt.pushLeaf(tx, newLeaf, n, lvl, path, pathOldLeaf)
case NodeTypeMiddle:
// We need to go deeper, continue traversing the tree, left or
// right depending on path
var newNodeMiddle *Node
if path[lvl] {
nextKey, err = mt.addLeaf(tx, newLeaf, n.ChildR, lvl+1, path) // go right
if path[lvl] { // go right
nextKey, err = mt.addLeaf(tx, newLeaf, n.ChildR, lvl+1, path)
newNodeMiddle = NewNodeMiddle(n.ChildL, nextKey)
} else {
nextKey, err = mt.addLeaf(tx, newLeaf, n.ChildL, lvl+1, path) // go left
} else { // go left
nextKey, err = mt.addLeaf(tx, newLeaf, n.ChildL, lvl+1, path)
newNodeMiddle = NewNodeMiddle(nextKey, n.ChildR)
}
if err != nil {
@ -468,9 +471,8 @@ func (mt *MerkleTree) Get(k *big.Int) (*big.Int, *big.Int, []*Hash, error) {
case NodeTypeLeaf:
if bytes.Equal(kHash[:], n.Entry[0][:]) {
return n.Entry[0].BigInt(), n.Entry[1].BigInt(), siblings, nil
} else {
return n.Entry[0].BigInt(), n.Entry[1].BigInt(), siblings, ErrKeyNotFound
}
return n.Entry[0].BigInt(), n.Entry[1].BigInt(), siblings, ErrKeyNotFound
case NodeTypeMiddle:
if path[i] {
nextKey = n.ChildR
@ -541,7 +543,8 @@ func (mt *MerkleTree) Update(k, v *big.Int) (*CircomProcessorProof, error) {
if err != nil {
return nil, err
}
newRootKey, err := mt.recalculatePathUntilRoot(tx, path, newNodeLeaf, siblings)
newRootKey, err :=
mt.recalculatePathUntilRoot(tx, path, newNodeLeaf, siblings)
if err != nil {
return nil, err
}
@ -555,9 +558,8 @@ func (mt *MerkleTree) Update(k, v *big.Int) (*CircomProcessorProof, error) {
return nil, err
}
return &cp, nil
} else {
return nil, ErrKeyNotFound
}
return nil, ErrKeyNotFound
case NodeTypeMiddle:
if path[i] {
nextKey = n.ChildR
@ -619,9 +621,8 @@ func (mt *MerkleTree) Delete(k *big.Int) error {
// remove and go up with the sibling
err = mt.rmAndUpload(tx, path, kHash, siblings)
return err
} else {
return ErrKeyNotFound
}
return ErrKeyNotFound
case NodeTypeMiddle:
if path[i] {
nextKey = n.ChildR
@ -638,7 +639,8 @@ func (mt *MerkleTree) Delete(k *big.Int) error {
return ErrKeyNotFound
}
// rmAndUpload removes the key, and goes up until the root updating all the nodes with the new values.
// rmAndUpload removes the key, and goes up until the root updating all the
// nodes with the new values.
func (mt *MerkleTree) rmAndUpload(tx db.Tx, path []bool, kHash *Hash, siblings []*Hash) error {
if len(siblings) == 0 {
mt.rootKey = &HashZero
@ -671,7 +673,8 @@ func (mt *MerkleTree) rmAndUpload(tx db.Tx, path []bool, kHash *Hash, siblings [
return err
}
// go up until the root
newRootKey, err := mt.recalculatePathUntilRoot(tx, path, newNode, siblings[:i])
newRootKey, err := mt.recalculatePathUntilRoot(tx, path, newNode,
siblings[:i])
if err != nil {
return err
}
@ -682,7 +685,8 @@ func (mt *MerkleTree) rmAndUpload(tx db.Tx, path []bool, kHash *Hash, siblings [
}
break
}
// if i==0 (root position), stop and store the sibling of the deleted leaf as root
// if i==0 (root position), stop and store the sibling of the
// deleted leaf as root
if i == 0 {
mt.rootKey = toUpload
err := mt.dbInsert(tx, dbKeyRootNode, DBEntryTypeRoot, mt.rootKey[:])
@ -700,7 +704,8 @@ func (mt *MerkleTree) rmAndUpload(tx db.Tx, path []bool, kHash *Hash, siblings [
}
// recalculatePathUntilRoot recalculates the nodes until the Root
func (mt *MerkleTree) recalculatePathUntilRoot(tx db.Tx, path []bool, node *Node, siblings []*Hash) (*Hash, error) {
func (mt *MerkleTree) recalculatePathUntilRoot(tx db.Tx, path []bool, node *Node,
siblings []*Hash) (*Hash, error) {
for i := len(siblings) - 1; i >= 0; i-- {
nodeKey, err := node.Key()
if err != nil {
@ -746,7 +751,7 @@ func (mt *MerkleTree) GetNode(key *Hash) (*Node, error) {
func getPath(numLevels int, k []byte) []bool {
path := make([]bool, numLevels)
for n := 0; n < numLevels; n++ {
path[n] = common.TestBit(k[:], uint(n))
path[n] = TestBit(k[:], uint(n))
}
return path
}
@ -757,9 +762,11 @@ type NodeAux struct {
Value *Hash
}
// Proof defines the required elements for a MT proof of existence or non-existence.
// Proof defines the required elements for a MT proof of existence or
// non-existence.
type Proof struct {
// existence indicates wether this is a proof of existence or non-existence.
// existence indicates wether this is a proof of existence or
// non-existence.
Existence bool
// depth indicates how deep in the tree the proof goes.
depth uint
@ -784,7 +791,7 @@ func NewProofFromBytes(bs []byte) (*Proof, error) {
siblingBytes := bs[ElemBytesLen:]
sibIdx := 0
for i := uint(0); i < p.depth; i++ {
if common.TestBitBigEndian(p.notempties[:], i) {
if TestBitBigEndian(p.notempties[:], i) {
if len(siblingBytes) < (sibIdx+1)*ElemBytesLen {
return nil, ErrInvalidProofBytes
}
@ -837,7 +844,7 @@ func SiblingsFromProof(proof *Proof) []*Hash {
sibIdx := 0
var siblings []*Hash
for lvl := 0; lvl < int(proof.depth); lvl++ {
if common.TestBitBigEndian(proof.notempties[:], uint(lvl)) {
if TestBitBigEndian(proof.notempties[:], uint(lvl)) {
siblings = append(siblings, proof.Siblings[sibIdx])
sibIdx++
} else {
@ -872,7 +879,8 @@ type CircomProcessorProof struct {
NewKey *Hash `json:"newKey"`
NewValue *Hash `json:"newValue"`
IsOld0 bool `json:"isOld0"`
Fnc int `json:"fnc"` // 0: NOP, 1: Update, 2: Insert, 3: Delete
// 0: NOP, 1: Update, 2: Insert, 3: Delete
Fnc int `json:"fnc"`
}
// String returns a human readable string representation of the
@ -912,7 +920,8 @@ type CircomVerifierProof struct {
// GenerateCircomVerifierProof returns the CircomVerifierProof for a certain
// key in the MerkleTree. If the rootKey is nil, the current merkletree root
// is used.
func (mt *MerkleTree) GenerateCircomVerifierProof(k *big.Int, rootKey *Hash) (*CircomVerifierProof, error) {
func (mt *MerkleTree) GenerateCircomVerifierProof(k *big.Int,
rootKey *Hash) (*CircomVerifierProof, error) {
if rootKey == nil {
rootKey = mt.Root()
}
@ -939,7 +948,8 @@ func (mt *MerkleTree) GenerateCircomVerifierProof(k *big.Int, rootKey *Hash) (*C
// GenerateProof generates the proof of existence (or non-existence) of an
// Entry's hash Index for a Merkle Tree given the root.
// If the rootKey is nil, the current merkletree root is used
func (mt *MerkleTree) GenerateProof(k *big.Int, rootKey *Hash) (*Proof, *big.Int, error) {
func (mt *MerkleTree) GenerateProof(k *big.Int, rootKey *Hash) (*Proof,
*big.Int, error) {
p := &Proof{}
var siblingKey *Hash
@ -961,11 +971,10 @@ func (mt *MerkleTree) GenerateProof(k *big.Int, rootKey *Hash) (*Proof, *big.Int
if bytes.Equal(kHash[:], n.Entry[0][:]) {
p.Existence = true
return p, n.Entry[1].BigInt(), nil
} else {
// We found a leaf whose entry didn't match hIndex
p.NodeAux = &NodeAux{Key: n.Entry[0], Value: n.Entry[1]}
return p, n.Entry[1].BigInt(), nil
}
// We found a leaf whose entry didn't match hIndex
p.NodeAux = &NodeAux{Key: n.Entry[0], Value: n.Entry[1]}
return p, n.Entry[1].BigInt(), nil
case NodeTypeMiddle:
if path[p.depth] {
nextKey = n.ChildR
@ -978,7 +987,7 @@ func (mt *MerkleTree) GenerateProof(k *big.Int, rootKey *Hash) (*Proof, *big.Int
return nil, nil, ErrInvalidNodeFound
}
if !bytes.Equal(siblingKey[:], HashZero[:]) {
common.SetBitBigEndian(p.notempties[:], uint(p.depth))
SetBitBigEndian(p.notempties[:], uint(p.depth))
p.Siblings = append(p.Siblings, siblingKey)
}
}
@ -1013,7 +1022,8 @@ func RootFromProof(proof *Proof, k, v *big.Int) (*Hash, error) {
midKey = &HashZero
} else {
if bytes.Equal(kHash[:], proof.NodeAux.Key[:]) {
return nil, fmt.Errorf("Non-existence proof being checked against hIndex equal to nodeAux")
return nil,
fmt.Errorf("Non-existence proof being checked against hIndex equal to nodeAux")
}
midKey, err = LeafKey(proof.NodeAux.Key, proof.NodeAux.Value)
if err != nil {
@ -1024,7 +1034,7 @@ func RootFromProof(proof *Proof, k, v *big.Int) (*Hash, error) {
path := getPath(int(proof.depth), kHash[:])
var siblingKey *Hash
for lvl := int(proof.depth) - 1; lvl >= 0; lvl-- {
if common.TestBitBigEndian(proof.notempties[:], uint(lvl)) {
if TestBitBigEndian(proof.notempties[:], uint(lvl)) {
siblingKey = proof.Siblings[sibIdx]
sibIdx--
} else {
@ -1071,10 +1081,10 @@ func (mt *MerkleTree) walk(key *Hash, f func(*Node)) error {
}
// Walk iterates over all the branches of a MerkleTree with the given rootKey
// if rootKey is nil, it will get the current RootKey of the current state of the MerkleTree.
// For each node, it calls the f function given in the parameters.
// See some examples of the Walk function usage in the merkletree.go and
// merkletree_test.go
// if rootKey is nil, it will get the current RootKey of the current state of
// the MerkleTree. For each node, it calls the f function given in the
// parameters. See some examples of the Walk function usage in the
// merkletree.go and merkletree_test.go
func (mt *MerkleTree) Walk(rootKey *Hash, f func(*Node)) error {
if rootKey == nil {
rootKey = mt.Root()
@ -1083,8 +1093,8 @@ func (mt *MerkleTree) Walk(rootKey *Hash, f func(*Node)) error {
return err
}
// GraphViz uses Walk function to generate a string GraphViz representation of the
// tree and writes it to w
// GraphViz uses Walk function to generate a string GraphViz representation of
// the tree and writes it to w
func (mt *MerkleTree) GraphViz(w io.Writer, rootKey *Hash) error {
fmt.Fprintf(w, `digraph hierarchy {
node [fontname=Monospace,fontsize=10,shape=box]
@ -1128,12 +1138,14 @@ func (mt *MerkleTree) PrintGraphViz(rootKey *Hash) error {
rootKey = mt.Root()
}
w := bytes.NewBufferString("")
fmt.Fprintf(w, "--------\nGraphViz of the MerkleTree with RootKey "+rootKey.BigInt().String()+"\n")
fmt.Fprintf(w,
"--------\nGraphViz of the MerkleTree with RootKey "+rootKey.BigInt().String()+"\n")
err := mt.GraphViz(w, nil)
if err != nil {
return err
}
fmt.Fprintf(w, "End of GraphViz of the MerkleTree with RootKey "+rootKey.BigInt().String()+"\n--------\n")
fmt.Fprintf(w,
"End of GraphViz of the MerkleTree with RootKey "+rootKey.BigInt().String()+"\n--------\n")
fmt.Println(w)
return nil

+ 42
- 28
merkletree_test.go

@ -43,10 +43,10 @@ func TestHashParsers(t *testing.T) {
h8l := NewHashFromBigInt(big.NewInt(12345678))
assert.Equal(t, "12345678...", h8l.String())
b, ok := new(big.Int).SetString("4932297968297298434239270129193057052722409868268166443802652458940273154854", 10)
b, ok := new(big.Int).SetString("4932297968297298434239270129193057052722409868268166443802652458940273154854", 10) //nolint:lll
assert.True(t, ok)
h := NewHashFromBigInt(b)
assert.Equal(t, "4932297968297298434239270129193057052722409868268166443802652458940273154854", h.BigInt().String())
assert.Equal(t, "4932297968297298434239270129193057052722409868268166443802652458940273154854", h.BigInt().String()) //nolint:lll
assert.Equal(t, "49322979...", h.String())
assert.Equal(t, "265baaf161e875c372d08e50f52abddc01d32efc93e90290bb8b3d9ceb94e70a", h.Hex())
@ -98,15 +98,15 @@ func TestNewTree(t *testing.T) {
// test vectors generated using https://github.com/iden3/circomlib smt.js
err = mt.Add(big.NewInt(1), big.NewInt(2))
assert.Nil(t, err)
assert.Equal(t, "6449712043256457369579901840927028403950625973089336675272087704159094984964", mt.Root().BigInt().String())
assert.Equal(t, "6449712043256457369579901840927028403950625973089336675272087704159094984964", mt.Root().BigInt().String()) //nolint:lll
err = mt.Add(big.NewInt(33), big.NewInt(44))
assert.Nil(t, err)
assert.Equal(t, "11404118908468506234838877883514126008995570353394659302846433035311596046064", mt.Root().BigInt().String())
assert.Equal(t, "11404118908468506234838877883514126008995570353394659302846433035311596046064", mt.Root().BigInt().String()) //nolint:lll
err = mt.Add(big.NewInt(1234), big.NewInt(9876))
assert.Nil(t, err)
assert.Equal(t, "12841932325181810040554102151615400973767747666110051836366805309524360490677", mt.Root().BigInt().String())
assert.Equal(t, "12841932325181810040554102151615400973767747666110051836366805309524360490677", mt.Root().BigInt().String()) //nolint:lll
dbRoot, err := mt.dbGetRoot()
require.Nil(t, err)
@ -142,7 +142,7 @@ func TestAddDifferentOrder(t *testing.T) {
}
assert.Equal(t, mt1.Root().Hex(), mt2.Root().Hex())
assert.Equal(t, "268e25964aa9d6ba42d66ae9eb44b5528540acb19a3644d1367d8c6f7cb23006", mt1.Root().Hex())
assert.Equal(t, "268e25964aa9d6ba42d66ae9eb44b5528540acb19a3644d1367d8c6f7cb23006", mt1.Root().Hex()) //nolint:lll
}
func TestAddRepeatedIndex(t *testing.T) {
@ -299,12 +299,24 @@ func TestSiblingsFromProof(t *testing.T) {
siblings := SiblingsFromProof(proof)
assert.Equal(t, 6, len(siblings))
assert.Equal(t, "5b478bdd58595ead03ebf494a74014cbb576ba0d9456aa0916885b9eefae592f", siblings[0].Hex())
assert.Equal(t, "c1e8ab120a4e475ea1bf00633228bfb9d248f7ddec2aa6367f98d0defb9fb22e", siblings[1].Hex())
assert.Equal(t, "f4dafd8ac2b9165adc3f6d125af67d5a4d8a7a263dcc90a373d0338929e16e0c", siblings[2].Hex())
assert.Equal(t, "a94aa346bd85f96aba2e85b67920e44fe6ed767b0e13bea602784e0b8b897515", siblings[3].Hex())
assert.Equal(t, "54791d7514030ded79301dbf221f5bf186facbc5800912411852fdc101b7151d", siblings[4].Hex())
assert.Equal(t, "435d28bc0511f8feb93b5f1649a049b460947702ce0baaefcf596175370fe01e", siblings[5].Hex())
assert.Equal(t,
"5b478bdd58595ead03ebf494a74014cbb576ba0d9456aa0916885b9eefae592f",
siblings[0].Hex())
assert.Equal(t,
"c1e8ab120a4e475ea1bf00633228bfb9d248f7ddec2aa6367f98d0defb9fb22e",
siblings[1].Hex())
assert.Equal(t,
"f4dafd8ac2b9165adc3f6d125af67d5a4d8a7a263dcc90a373d0338929e16e0c",
siblings[2].Hex())
assert.Equal(t,
"a94aa346bd85f96aba2e85b67920e44fe6ed767b0e13bea602784e0b8b897515",
siblings[3].Hex())
assert.Equal(t,
"54791d7514030ded79301dbf221f5bf186facbc5800912411852fdc101b7151d",
siblings[4].Hex())
assert.Equal(t,
"435d28bc0511f8feb93b5f1649a049b460947702ce0baaefcf596175370fe01e",
siblings[5].Hex())
}
func TestVerifyProofCases(t *testing.T) {
@ -318,14 +330,13 @@ func TestVerifyProofCases(t *testing.T) {
}
// Existence proof
proof, _, err := mt.GenerateProof(big.NewInt(4), nil)
if err != nil {
t.Fatal(err)
}
assert.Equal(t, proof.Existence, true)
assert.True(t, VerifyProof(mt.Root(), proof, big.NewInt(4), big.NewInt(0)))
assert.Equal(t, "0003000000000000000000000000000000000000000000000000000000000007a6d6b46fefe213a6b579844a1bb7ab5c2db4a13f8662d9c5e729c36728f42730211ddfcc8d30ebd157d1d6912769b8e4abdca41e5dc2b57b026a361c091a8c14c748530e61bf8ea80c987657c3d24b134ece1ef8e2d4bd3f74437bf4392a6b1e", hex.EncodeToString(proof.Bytes()))
assert.Equal(t, "0003000000000000000000000000000000000000000000000000000000000007a6d6b46fefe213a6b579844a1bb7ab5c2db4a13f8662d9c5e729c36728f42730211ddfcc8d30ebd157d1d6912769b8e4abdca41e5dc2b57b026a361c091a8c14c748530e61bf8ea80c987657c3d24b134ece1ef8e2d4bd3f74437bf4392a6b1e", hex.EncodeToString(proof.Bytes())) //nolint:lll
for i := 8; i < 32; i++ {
proof, _, err = mt.GenerateProof(big.NewInt(int64(i)), nil)
@ -342,7 +353,7 @@ func TestVerifyProofCases(t *testing.T) {
assert.Equal(t, proof.Existence, false)
// assert.True(t, proof.nodeAux == nil)
assert.True(t, VerifyProof(mt.Root(), proof, big.NewInt(12), big.NewInt(0)))
assert.Equal(t, "0303000000000000000000000000000000000000000000000000000000000007a6d6b46fefe213a6b579844a1bb7ab5c2db4a13f8662d9c5e729c36728f42730211ddfcc8d30ebd157d1d6912769b8e4abdca41e5dc2b57b026a361c091a8c14c748530e61bf8ea80c987657c3d24b134ece1ef8e2d4bd3f74437bf4392a6b1e04000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", hex.EncodeToString(proof.Bytes()))
assert.Equal(t, "0303000000000000000000000000000000000000000000000000000000000007a6d6b46fefe213a6b579844a1bb7ab5c2db4a13f8662d9c5e729c36728f42730211ddfcc8d30ebd157d1d6912769b8e4abdca41e5dc2b57b026a361c091a8c14c748530e61bf8ea80c987657c3d24b134ece1ef8e2d4bd3f74437bf4392a6b1e04000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", hex.EncodeToString(proof.Bytes())) //nolint:lll
// Non-existence proof, diff. node aux
proof, _, err = mt.GenerateProof(big.NewInt(10), nil)
@ -352,7 +363,7 @@ func TestVerifyProofCases(t *testing.T) {
assert.Equal(t, proof.Existence, false)
assert.True(t, proof.NodeAux != nil)
assert.True(t, VerifyProof(mt.Root(), proof, big.NewInt(10), big.NewInt(0)))
assert.Equal(t, "0303000000000000000000000000000000000000000000000000000000000007a6d6b46fefe213a6b579844a1bb7ab5c2db4a13f8662d9c5e729c36728f42730e667e2ca15909c4a23beff18e3cc74348fbd3c1a4c765a5bbbca126c9607a42b77e008a73926f1280f8531b139dc1cacf8d83fcec31d405f5c51b7cbddfe152902000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", hex.EncodeToString(proof.Bytes()))
assert.Equal(t, "0303000000000000000000000000000000000000000000000000000000000007a6d6b46fefe213a6b579844a1bb7ab5c2db4a13f8662d9c5e729c36728f42730e667e2ca15909c4a23beff18e3cc74348fbd3c1a4c765a5bbbca126c9607a42b77e008a73926f1280f8531b139dc1cacf8d83fcec31d405f5c51b7cbddfe152902000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", hex.EncodeToString(proof.Bytes())) //nolint:lll
}
func TestVerifyProofFalse(t *testing.T) {
@ -383,7 +394,8 @@ func TestVerifyProofFalse(t *testing.T) {
// Now we change the proof from existence to non-existence, and add e's
// data as auxiliary node.
proof.Existence = false
proof.NodeAux = &NodeAux{Key: NewHashFromBigInt(big.NewInt(int64(4))), Value: NewHashFromBigInt(big.NewInt(4))}
proof.NodeAux = &NodeAux{Key: NewHashFromBigInt(big.NewInt(int64(4))),
Value: NewHashFromBigInt(big.NewInt(4))}
assert.True(t, !VerifyProof(mt.Root(), proof, big.NewInt(int64(4)), big.NewInt(0)))
}
@ -435,22 +447,22 @@ func TestDelete(t *testing.T) {
// test vectors generated using https://github.com/iden3/circomlib smt.js
err = mt.Add(big.NewInt(1), big.NewInt(2))
assert.Nil(t, err)
assert.Equal(t, "6449712043256457369579901840927028403950625973089336675272087704159094984964", mt.Root().BigInt().String())
assert.Equal(t, "6449712043256457369579901840927028403950625973089336675272087704159094984964", mt.Root().BigInt().String()) //nolint:lll
err = mt.Add(big.NewInt(33), big.NewInt(44))
assert.Nil(t, err)
assert.Equal(t, "11404118908468506234838877883514126008995570353394659302846433035311596046064", mt.Root().BigInt().String())
assert.Equal(t, "11404118908468506234838877883514126008995570353394659302846433035311596046064", mt.Root().BigInt().String()) //nolint:lll
err = mt.Add(big.NewInt(1234), big.NewInt(9876))
assert.Nil(t, err)
assert.Equal(t, "12841932325181810040554102151615400973767747666110051836366805309524360490677", mt.Root().BigInt().String())
assert.Equal(t, "12841932325181810040554102151615400973767747666110051836366805309524360490677", mt.Root().BigInt().String()) //nolint:lll
// mt.PrintGraphViz(nil)
err = mt.Delete(big.NewInt(33))
// mt.PrintGraphViz(nil)
assert.Nil(t, err)
assert.Equal(t, "16195585003843604118922861401064871511855368913846540536604351220077317790615", mt.Root().BigInt().String())
assert.Equal(t, "16195585003843604118922861401064871511855368913846540536604351220077317790615", mt.Root().BigInt().String()) //nolint:lll
err = mt.Delete(big.NewInt(1234))
assert.Nil(t, err)
@ -507,10 +519,10 @@ func TestDelete3(t *testing.T) {
err = mt.Add(big.NewInt(2), big.NewInt(2))
assert.Nil(t, err)
assert.Equal(t, "6701939280963330813043570145125351311131831356446202146710280245621673558344", mt.Root().BigInt().String())
assert.Equal(t, "6701939280963330813043570145125351311131831356446202146710280245621673558344", mt.Root().BigInt().String()) //nolint:lll
err = mt.Delete(big.NewInt(1))
assert.Nil(t, err)
assert.Equal(t, "10304354743004778619823249005484018655542356856535590307973732141291410579841", mt.Root().BigInt().String())
assert.Equal(t, "10304354743004778619823249005484018655542356856535590307973732141291410579841", mt.Root().BigInt().String()) //nolint:lll
mt2 := newTestingMerkle(t, 140)
defer mt2.db.Close()
@ -532,10 +544,10 @@ func TestDelete4(t *testing.T) {
err = mt.Add(big.NewInt(3), big.NewInt(3))
assert.Nil(t, err)
assert.Equal(t, "6989694633650442615746486460134957295274675622748484439660143938730686550248", mt.Root().BigInt().String())
assert.Equal(t, "6989694633650442615746486460134957295274675622748484439660143938730686550248", mt.Root().BigInt().String()) //nolint:lll
err = mt.Delete(big.NewInt(1))
assert.Nil(t, err)
assert.Equal(t, "1192610901536912535888866440319084773171371421781091005185759505381507049136", mt.Root().BigInt().String())
assert.Equal(t, "1192610901536912535888866440319084773171371421781091005185759505381507049136", mt.Root().BigInt().String()) //nolint:lll
mt2 := newTestingMerkle(t, 140)
defer mt2.db.Close()
@ -554,11 +566,11 @@ func TestDelete5(t *testing.T) {
assert.Nil(t, err)
err = mt.Add(big.NewInt(33), big.NewInt(44))
assert.Nil(t, err)
assert.Equal(t, "11404118908468506234838877883514126008995570353394659302846433035311596046064", mt.Root().BigInt().String())
assert.Equal(t, "11404118908468506234838877883514126008995570353394659302846433035311596046064", mt.Root().BigInt().String()) //nolint:lll
err = mt.Delete(big.NewInt(1))
assert.Nil(t, err)
assert.Equal(t, "12802904154263054831102426711825443668153853847661287611768065280921698471037", mt.Root().BigInt().String())
assert.Equal(t, "12802904154263054831102426711825443668153853847661287611768065280921698471037", mt.Root().BigInt().String()) //nolint:lll
mt2 := newTestingMerkle(t, 140)
defer mt2.db.Close()
@ -689,7 +701,9 @@ func TestUpdateCircomProcessorProof(t *testing.T) {
assert.Equal(t, "10", cpp.NewKey.String())
assert.Equal(t, "1024", cpp.NewValue.String())
assert.Equal(t, false, cpp.IsOld0)
assert.Equal(t, "[19625419... 46910949... 18399594... 20473908... 0 0 0 0 0 0 0]", fmt.Sprintf("%v", cpp.Siblings))
assert.Equal(t,
"[19625419... 46910949... 18399594... 20473908... 0 0 0 0 0 0 0]",
fmt.Sprintf("%v", cpp.Siblings))
}
func TestTypesMarshalers(t *testing.T) {

+ 24
- 0
utils.go

@ -32,3 +32,27 @@ func HashElemsKey(key *big.Int, elems ...*big.Int) (*Hash, error) {
}
return NewHashFromBigInt(poseidonHash), nil
}
// SetBitBigEndian sets the bit n in the bitmap to 1, in Big Endian.
func SetBitBigEndian(bitmap []byte, n uint) {
bitmap[uint(len(bitmap))-n/8-1] |= 1 << (n % 8)
}
// TestBit tests whether the bit n in bitmap is 1.
func TestBit(bitmap []byte, n uint) bool {
return bitmap[n/8]&(1<<(n%8)) != 0
}
// TestBitBigEndian tests whether the bit n in bitmap is 1, in Big Endian.
func TestBitBigEndian(bitmap []byte, n uint) bool {
return bitmap[uint(len(bitmap))-n/8-1]&(1<<(n%8)) != 0
}
// SwapEndianness swaps the order of the bytes in the slice.
func SwapEndianness(b []byte) []byte {
o := make([]byte, len(b))
for i := range b {
o[len(b)-1-i] = b[i]
}
return o
}

Loading…
Cancel
Save