mirror of
https://github.com/vocdoni/arbo.git
synced 2026-01-09 13:57:54 -05:00
update dependencies, upgrade code and add a memory database
Signed-off-by: p4u <pau@dabax.net>
This commit is contained in:
@@ -12,8 +12,8 @@ import (
|
||||
"time"
|
||||
|
||||
qt "github.com/frankban/quicktest"
|
||||
"github.com/vocdoni/arbo/memdb"
|
||||
"go.vocdoni.io/dvote/db"
|
||||
"go.vocdoni.io/dvote/db/badgerdb"
|
||||
"go.vocdoni.io/dvote/db/pebbledb"
|
||||
)
|
||||
|
||||
@@ -40,14 +40,12 @@ func debugTime(descr string, time1, time2 time.Duration) {
|
||||
}
|
||||
|
||||
func testInit(c *qt.C, n int) (*Tree, *Tree) {
|
||||
database1, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
database1 := memdb.New()
|
||||
tree1, err := NewTree(Config{Database: database1, MaxLevels: 256,
|
||||
HashFunction: HashFunctionPoseidon})
|
||||
c.Assert(err, qt.IsNil)
|
||||
|
||||
database2, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
database2 := memdb.New()
|
||||
tree2, err := NewTree(Config{Database: database2, MaxLevels: 256,
|
||||
HashFunction: HashFunctionPoseidon})
|
||||
c.Assert(err, qt.IsNil)
|
||||
@@ -73,7 +71,7 @@ func TestAddBatchTreeEmpty(t *testing.T) {
|
||||
|
||||
nLeafs := 1024
|
||||
|
||||
database, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree, err := NewTree(Config{database, 256, DefaultThresholdNLeafs,
|
||||
HashFunctionPoseidon})
|
||||
@@ -97,7 +95,7 @@ func TestAddBatchTreeEmpty(t *testing.T) {
|
||||
}
|
||||
time1 := time.Since(start)
|
||||
|
||||
database2, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database2, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree2, err := NewTree(Config{database2, 256, DefaultThresholdNLeafs,
|
||||
HashFunctionPoseidon})
|
||||
@@ -125,7 +123,7 @@ func TestAddBatchTreeEmptyNotPowerOf2(t *testing.T) {
|
||||
|
||||
nLeafs := 1027
|
||||
|
||||
database, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree, err := NewTree(Config{database, 256, DefaultThresholdNLeafs,
|
||||
HashFunctionPoseidon})
|
||||
@@ -141,7 +139,7 @@ func TestAddBatchTreeEmptyNotPowerOf2(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
database2, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database2, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree2, err := NewTree(Config{database2, 256, DefaultThresholdNLeafs,
|
||||
HashFunctionPoseidon})
|
||||
@@ -174,14 +172,14 @@ func randomBytes(n int) []byte {
|
||||
|
||||
func TestAddBatchTestVector1(t *testing.T) {
|
||||
c := qt.New(t)
|
||||
database1, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database1, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree1, err := NewTree(Config{database1, 256, DefaultThresholdNLeafs,
|
||||
HashFunctionBlake2b})
|
||||
c.Assert(err, qt.IsNil)
|
||||
defer tree1.db.Close() //nolint:errcheck
|
||||
|
||||
database2, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database2, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree2, err := NewTree(Config{database2, 256, DefaultThresholdNLeafs,
|
||||
HashFunctionBlake2b})
|
||||
@@ -216,14 +214,14 @@ func TestAddBatchTestVector1(t *testing.T) {
|
||||
checkRoots(c, tree1, tree2)
|
||||
|
||||
// 2nd test vectors
|
||||
database1, err = badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database1, err = pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree1, err = NewTree(Config{database1, 256, DefaultThresholdNLeafs,
|
||||
HashFunctionBlake2b})
|
||||
c.Assert(err, qt.IsNil)
|
||||
defer tree1.db.Close() //nolint:errcheck
|
||||
|
||||
database2, err = badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database2, err = pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree2, err = NewTree(Config{database2, 256, DefaultThresholdNLeafs,
|
||||
HashFunctionBlake2b})
|
||||
@@ -266,14 +264,14 @@ func TestAddBatchTestVector2(t *testing.T) {
|
||||
// test vector with unbalanced tree
|
||||
c := qt.New(t)
|
||||
|
||||
database, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree1, err := NewTree(Config{database, 256, DefaultThresholdNLeafs,
|
||||
HashFunctionPoseidon})
|
||||
c.Assert(err, qt.IsNil)
|
||||
defer tree1.db.Close() //nolint:errcheck
|
||||
|
||||
database2, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database2, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree2, err := NewTree(Config{database2, 256, DefaultThresholdNLeafs,
|
||||
HashFunctionPoseidon})
|
||||
@@ -313,14 +311,14 @@ func TestAddBatchTestVector3(t *testing.T) {
|
||||
// test vector with unbalanced tree
|
||||
c := qt.New(t)
|
||||
|
||||
database, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree1, err := NewTree(Config{database, 256, DefaultThresholdNLeafs,
|
||||
HashFunctionPoseidon})
|
||||
c.Assert(err, qt.IsNil)
|
||||
defer tree1.db.Close() //nolint:errcheck
|
||||
|
||||
database2, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database2, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree2, err := NewTree(Config{database2, 256, DefaultThresholdNLeafs,
|
||||
HashFunctionPoseidon})
|
||||
@@ -364,14 +362,14 @@ func TestAddBatchTreeEmptyRandomKeys(t *testing.T) {
|
||||
|
||||
nLeafs := 8
|
||||
|
||||
database1, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database1, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree1, err := NewTree(Config{database1, 256, DefaultThresholdNLeafs,
|
||||
HashFunctionBlake2b})
|
||||
c.Assert(err, qt.IsNil)
|
||||
defer tree1.db.Close() //nolint:errcheck
|
||||
|
||||
database2, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database2, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree2, err := NewTree(Config{database2, 256, DefaultThresholdNLeafs,
|
||||
HashFunctionBlake2b})
|
||||
@@ -716,7 +714,7 @@ func TestAddBatchNotEmptyUnbalanced(t *testing.T) {
|
||||
}
|
||||
time1 := time.Since(start)
|
||||
|
||||
database2, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database2, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree2, err := NewTree(Config{database2, 256, DefaultThresholdNLeafs,
|
||||
HashFunctionPoseidon})
|
||||
@@ -775,7 +773,7 @@ func TestFlp2(t *testing.T) {
|
||||
|
||||
func TestAddBatchBench(t *testing.T) {
|
||||
nLeafs := 50_000
|
||||
printTestContext("TestAddBatchBench: ", nLeafs, "Blake2b", "badgerdb")
|
||||
printTestContext("TestAddBatchBench: ", nLeafs, "Blake2b", "pebbledb")
|
||||
|
||||
// prepare inputs
|
||||
var ks, vs [][]byte
|
||||
@@ -794,7 +792,7 @@ func TestAddBatchBench(t *testing.T) {
|
||||
func benchAdd(t *testing.T, ks, vs [][]byte) {
|
||||
c := qt.New(t)
|
||||
|
||||
database, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree, err := NewTree(Config{database, 256, DefaultThresholdNLeafs,
|
||||
HashFunctionBlake2b})
|
||||
@@ -815,7 +813,7 @@ func benchAdd(t *testing.T, ks, vs [][]byte) {
|
||||
func benchAddBatch(t *testing.T, ks, vs [][]byte) {
|
||||
c := qt.New(t)
|
||||
|
||||
database, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree, err := NewTree(Config{database, 256, DefaultThresholdNLeafs,
|
||||
HashFunctionBlake2b})
|
||||
@@ -849,7 +847,7 @@ func TestDbgStats(t *testing.T) {
|
||||
}
|
||||
|
||||
// 1
|
||||
database1, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database1, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree1, err := NewTree(Config{database1, 256, DefaultThresholdNLeafs,
|
||||
HashFunctionBlake2b})
|
||||
@@ -864,7 +862,7 @@ func TestDbgStats(t *testing.T) {
|
||||
}
|
||||
|
||||
// 2
|
||||
database2, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database2, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree2, err := NewTree(Config{database2, 256, DefaultThresholdNLeafs,
|
||||
HashFunctionBlake2b})
|
||||
@@ -878,7 +876,7 @@ func TestDbgStats(t *testing.T) {
|
||||
c.Assert(len(invalids), qt.Equals, 0)
|
||||
|
||||
// 3
|
||||
database3, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database3, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree3, err := NewTree(Config{database3, 256, DefaultThresholdNLeafs,
|
||||
HashFunctionBlake2b})
|
||||
@@ -914,8 +912,7 @@ func TestLoadVT(t *testing.T) {
|
||||
|
||||
nLeafs := 1024
|
||||
|
||||
database, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
database := memdb.New()
|
||||
tree, err := NewTree(Config{database, 256, DefaultThresholdNLeafs,
|
||||
HashFunctionPoseidon})
|
||||
c.Assert(err, qt.IsNil)
|
||||
@@ -932,9 +929,7 @@ func TestLoadVT(t *testing.T) {
|
||||
c.Assert(err, qt.IsNil)
|
||||
c.Check(len(invalids), qt.Equals, 0)
|
||||
|
||||
rTx := tree.db.ReadTx()
|
||||
defer rTx.Discard()
|
||||
vt, err := tree.loadVT(rTx)
|
||||
vt, err := tree.loadVT()
|
||||
c.Assert(err, qt.IsNil)
|
||||
_, err = vt.computeHashes()
|
||||
c.Assert(err, qt.IsNil)
|
||||
@@ -951,7 +946,7 @@ func TestAddKeysWithEmptyValues(t *testing.T) {
|
||||
|
||||
nLeafs := 1024
|
||||
|
||||
database, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree, err := NewTree(Config{database, 256, DefaultThresholdNLeafs,
|
||||
HashFunctionPoseidon})
|
||||
@@ -973,7 +968,7 @@ func TestAddKeysWithEmptyValues(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
database2, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database2, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree2, err := NewTree(Config{database2, 256, DefaultThresholdNLeafs,
|
||||
HashFunctionPoseidon})
|
||||
@@ -988,7 +983,7 @@ func TestAddKeysWithEmptyValues(t *testing.T) {
|
||||
checkRoots(c, tree, tree2)
|
||||
|
||||
// use tree3 to add nil value array
|
||||
database3, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database3, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree3, err := NewTree(Config{database3, 256, DefaultThresholdNLeafs,
|
||||
HashFunctionPoseidon})
|
||||
@@ -1038,7 +1033,7 @@ func TestAddBatchThresholdInDisk(t *testing.T) {
|
||||
// customize thresholdNLeafs for the test
|
||||
testThresholdNLeafs := 1024
|
||||
|
||||
database1, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database1, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree1, err := NewTree(Config{database1, 256, testThresholdNLeafs,
|
||||
HashFunctionBlake2b})
|
||||
@@ -1106,13 +1101,13 @@ func TestAddBatchThresholdInDisk(t *testing.T) {
|
||||
}
|
||||
|
||||
func initTestUpFromSubRoots(c *qt.C) (*Tree, *Tree) {
|
||||
database1, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database1, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree1, err := NewTree(Config{database1, 256, DefaultThresholdNLeafs,
|
||||
HashFunctionBlake2b})
|
||||
c.Assert(err, qt.IsNil)
|
||||
|
||||
database2, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database2, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree2, err := NewTree(Config{database2, 256, DefaultThresholdNLeafs,
|
||||
HashFunctionBlake2b})
|
||||
|
||||
@@ -7,12 +7,12 @@ import (
|
||||
|
||||
qt "github.com/frankban/quicktest"
|
||||
"go.vocdoni.io/dvote/db"
|
||||
"go.vocdoni.io/dvote/db/badgerdb"
|
||||
"go.vocdoni.io/dvote/db/pebbledb"
|
||||
)
|
||||
|
||||
func TestCircomVerifierProof(t *testing.T) {
|
||||
c := qt.New(t)
|
||||
database, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree, err := NewTree(Config{Database: database, MaxLevels: 4,
|
||||
HashFunction: HashFunctionPoseidon})
|
||||
|
||||
42
go.mod
42
go.mod
@@ -1,10 +1,42 @@
|
||||
module github.com/vocdoni/arbo
|
||||
|
||||
go 1.16
|
||||
go 1.23.0
|
||||
|
||||
toolchain go1.23.1
|
||||
|
||||
require (
|
||||
github.com/frankban/quicktest v1.13.0
|
||||
github.com/iden3/go-iden3-crypto v0.0.12
|
||||
go.vocdoni.io/dvote v1.0.4-0.20211025120558-83c64f440044
|
||||
golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871
|
||||
github.com/frankban/quicktest v1.14.6
|
||||
github.com/iden3/go-iden3-crypto v0.0.17
|
||||
go.vocdoni.io/dvote v1.10.2-0.20241024102542-c1ce6d744bc5
|
||||
golang.org/x/crypto v0.28.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/DataDog/zstd v1.5.2 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/cockroachdb/errors v1.11.3 // indirect
|
||||
github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce // indirect
|
||||
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect
|
||||
github.com/cockroachdb/pebble v1.1.2 // indirect
|
||||
github.com/cockroachdb/redact v1.1.5 // indirect
|
||||
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect
|
||||
github.com/getsentry/sentry-go v0.27.0 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
github.com/klauspost/compress v1.17.9 // indirect
|
||||
github.com/kr/pretty v0.3.1 // indirect
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/prometheus/client_golang v1.19.1 // indirect
|
||||
github.com/prometheus/client_model v0.6.1 // indirect
|
||||
github.com/prometheus/common v0.55.0 // indirect
|
||||
github.com/prometheus/procfs v0.15.1 // indirect
|
||||
github.com/rogpeppe/go-internal v1.11.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect
|
||||
golang.org/x/sys v0.26.0 // indirect
|
||||
golang.org/x/text v0.19.0 // indirect
|
||||
google.golang.org/protobuf v1.34.2 // indirect
|
||||
)
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
|
||||
qt "github.com/frankban/quicktest"
|
||||
"go.vocdoni.io/dvote/db"
|
||||
"go.vocdoni.io/dvote/db/badgerdb"
|
||||
"go.vocdoni.io/dvote/db/pebbledb"
|
||||
)
|
||||
|
||||
func checkRoots(c *qt.C, tree1, tree2 *Tree) {
|
||||
@@ -88,13 +88,13 @@ func TestReadTreeDBG(t *testing.T) {
|
||||
|
||||
c := qt.New(t)
|
||||
|
||||
database1, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database1, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree1, err := NewTree(Config{Database: database1, MaxLevels: 100,
|
||||
HashFunction: HashFunctionBlake2b})
|
||||
c.Assert(err, qt.IsNil)
|
||||
|
||||
database2, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database2, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree2, err := NewTree(Config{Database: database2, MaxLevels: 100,
|
||||
HashFunction: HashFunctionBlake2b})
|
||||
|
||||
295
memdb/memdb.go
Normal file
295
memdb/memdb.go
Normal file
@@ -0,0 +1,295 @@
|
||||
package memdb
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"sort"
|
||||
"sync"
|
||||
|
||||
"go.vocdoni.io/dvote/db"
|
||||
)
|
||||
|
||||
// MemoryDB is an in-memory implementation of the db.Database interface.
|
||||
type MemoryDB struct {
|
||||
mu sync.RWMutex
|
||||
store map[string][]byte
|
||||
}
|
||||
|
||||
// New creates a new MemoryDB instance.
|
||||
func New() *MemoryDB {
|
||||
return &MemoryDB{
|
||||
store: make(map[string][]byte),
|
||||
}
|
||||
}
|
||||
|
||||
// Close closes the database. For in-memory DB, it's a no-op.
|
||||
func (m *MemoryDB) Close() error {
|
||||
// No resources to release for in-memory DB
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get retrieves the value for the given key. If the key does not exist, returns ErrKeyNotFound.
|
||||
func (m *MemoryDB) Get(key []byte) ([]byte, error) {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
|
||||
val, exists := m.store[string(key)]
|
||||
if !exists {
|
||||
return nil, db.ErrKeyNotFound
|
||||
}
|
||||
// Return a copy to prevent external modification
|
||||
return append([]byte(nil), val...), nil
|
||||
}
|
||||
|
||||
// Iterate calls the callback with all key-value pairs in the database whose key starts with prefix.
|
||||
// The iteration is ordered lexicographically by key.
|
||||
func (m *MemoryDB) Iterate(prefix []byte, callback func(key, value []byte) bool) error {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
|
||||
var keys []string
|
||||
for k := range m.store {
|
||||
if bytes.HasPrefix([]byte(k), prefix) {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
}
|
||||
sort.Strings(keys) // Lexicographical order
|
||||
|
||||
for _, k := range keys {
|
||||
v := m.store[k]
|
||||
// Make copies to prevent external modification
|
||||
keyCopy := []byte(k)
|
||||
valCopy := append([]byte(nil), v...)
|
||||
cont := callback(keyCopy, valCopy)
|
||||
if !cont {
|
||||
break
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// WriteTx creates a new write transaction.
|
||||
func (m *MemoryDB) WriteTx() db.WriteTx {
|
||||
return &memoryWriteTx{
|
||||
db: m,
|
||||
sets: make(map[string][]byte),
|
||||
deletes: make(map[string]struct{}),
|
||||
active: true,
|
||||
}
|
||||
}
|
||||
|
||||
// Compact is a no-op for in-memory DB.
|
||||
func (m *MemoryDB) Compact() error {
|
||||
// No compaction needed for in-memory DB
|
||||
return nil
|
||||
}
|
||||
|
||||
// memoryWriteTx implements the db.WriteTx interface.
|
||||
type memoryWriteTx struct {
|
||||
db *MemoryDB
|
||||
sets map[string][]byte
|
||||
deletes map[string]struct{}
|
||||
mu sync.Mutex
|
||||
active bool
|
||||
}
|
||||
|
||||
// ensureActive checks if the transaction is still active.
|
||||
func (tx *memoryWriteTx) ensureActive() error {
|
||||
tx.mu.Lock()
|
||||
defer tx.mu.Unlock()
|
||||
if !tx.active {
|
||||
return errors.New("transaction is no longer active")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get retrieves the value for the given key within the transaction context.
|
||||
func (tx *memoryWriteTx) Get(key []byte) ([]byte, error) {
|
||||
if err := tx.ensureActive(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Check pending deletes first
|
||||
if _, deleted := tx.deletes[string(key)]; deleted {
|
||||
return nil, db.ErrKeyNotFound
|
||||
}
|
||||
|
||||
// Check pending sets
|
||||
if val, exists := tx.sets[string(key)]; exists {
|
||||
return append([]byte(nil), val...), nil
|
||||
}
|
||||
|
||||
// Fallback to the main DB
|
||||
return tx.db.Get(key)
|
||||
}
|
||||
|
||||
// Iterate iterates over the key-value pairs within the transaction context.
|
||||
func (tx *memoryWriteTx) Iterate(prefix []byte, callback func(key, value []byte) bool) error {
|
||||
if err := tx.ensureActive(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tx.db.mu.RLock()
|
||||
defer tx.db.mu.RUnlock()
|
||||
|
||||
var keys []string
|
||||
for k := range tx.db.store {
|
||||
if bytes.HasPrefix([]byte(k), prefix) {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
}
|
||||
sort.Strings(keys) // Lexicographical order
|
||||
|
||||
for _, k := range keys {
|
||||
if _, deleted := tx.deletes[k]; deleted {
|
||||
continue
|
||||
}
|
||||
if val, exists := tx.sets[k]; exists {
|
||||
// Use the value from the transaction's pending sets
|
||||
keyCopy := []byte(k)
|
||||
valCopy := append([]byte(nil), val...)
|
||||
cont := callback(keyCopy, valCopy)
|
||||
if !cont {
|
||||
break
|
||||
}
|
||||
} else {
|
||||
// Use the value from the main DB
|
||||
v := tx.db.store[k]
|
||||
keyCopy := []byte(k)
|
||||
valCopy := append([]byte(nil), v...)
|
||||
cont := callback(keyCopy, valCopy)
|
||||
if !cont {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Also include any new keys set in the transaction that weren't in the main DB
|
||||
var newKeys []string
|
||||
for k := range tx.sets {
|
||||
if !bytes.HasPrefix([]byte(k), prefix) {
|
||||
continue
|
||||
}
|
||||
if _, exists := tx.db.store[k]; !exists {
|
||||
newKeys = append(newKeys, k)
|
||||
}
|
||||
}
|
||||
sort.Strings(newKeys)
|
||||
for _, k := range newKeys {
|
||||
val := tx.sets[k]
|
||||
keyCopy := []byte(k)
|
||||
valCopy := append([]byte(nil), val...)
|
||||
cont := callback(keyCopy, valCopy)
|
||||
if !cont {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Set adds or updates a key-value pair in the transaction.
|
||||
func (tx *memoryWriteTx) Set(key, value []byte) error {
|
||||
if err := tx.ensureActive(); err != nil {
|
||||
return err
|
||||
}
|
||||
tx.mu.Lock()
|
||||
defer tx.mu.Unlock()
|
||||
|
||||
// Optional: Check for transaction size limits here
|
||||
// For simplicity, we assume no size limits
|
||||
|
||||
tx.sets[string(key)] = append([]byte(nil), value...)
|
||||
delete(tx.deletes, string(key))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Delete removes a key from the transaction.
|
||||
func (tx *memoryWriteTx) Delete(key []byte) error {
|
||||
if err := tx.ensureActive(); err != nil {
|
||||
return err
|
||||
}
|
||||
tx.mu.Lock()
|
||||
defer tx.mu.Unlock()
|
||||
|
||||
delete(tx.sets, string(key))
|
||||
tx.deletes[string(key)] = struct{}{}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Apply copies the key-values from the source WriteTx into this transaction.
|
||||
func (tx *memoryWriteTx) Apply(source db.WriteTx) error {
|
||||
if err := tx.ensureActive(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sourceTx, ok := source.(*memoryWriteTx)
|
||||
if !ok {
|
||||
return errors.New("unsupported WriteTx type")
|
||||
}
|
||||
|
||||
sourceTx.mu.Lock()
|
||||
defer sourceTx.mu.Unlock()
|
||||
|
||||
tx.mu.Lock()
|
||||
defer tx.mu.Unlock()
|
||||
|
||||
for k, v := range sourceTx.sets {
|
||||
tx.sets[k] = append([]byte(nil), v...)
|
||||
delete(tx.deletes, k)
|
||||
}
|
||||
|
||||
for k := range sourceTx.deletes {
|
||||
delete(tx.sets, k)
|
||||
tx.deletes[k] = struct{}{}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Commit applies all pending changes to the main DB.
|
||||
func (tx *memoryWriteTx) Commit() error {
|
||||
if err := tx.ensureActive(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tx.db.mu.Lock()
|
||||
defer tx.db.mu.Unlock()
|
||||
|
||||
tx.mu.Lock()
|
||||
defer tx.mu.Unlock()
|
||||
|
||||
// Apply sets
|
||||
for k, v := range tx.sets {
|
||||
tx.db.store[k] = append([]byte(nil), v...)
|
||||
}
|
||||
|
||||
// Apply deletes
|
||||
for k := range tx.deletes {
|
||||
delete(tx.db.store, k)
|
||||
}
|
||||
|
||||
tx.active = false
|
||||
return nil
|
||||
}
|
||||
|
||||
// Discard aborts the transaction, discarding all pending changes.
|
||||
func (tx *memoryWriteTx) Discard() {
|
||||
tx.mu.Lock()
|
||||
defer tx.mu.Unlock()
|
||||
tx.active = false
|
||||
// Clear pending changes
|
||||
tx.sets = nil
|
||||
tx.deletes = nil
|
||||
}
|
||||
|
||||
// Unwrap allows unwrapping the WriteTx if needed.
|
||||
func (tx *memoryWriteTx) Unwrap() db.WriteTx {
|
||||
return tx
|
||||
}
|
||||
|
||||
// Ensure that MemoryDB implements db.Database and memoryWriteTx implements db.WriteTx.
|
||||
var (
|
||||
_ db.Database = (*MemoryDB)(nil)
|
||||
_ db.WriteTx = (*memoryWriteTx)(nil)
|
||||
)
|
||||
@@ -9,12 +9,12 @@ import (
|
||||
qt "github.com/frankban/quicktest"
|
||||
"github.com/vocdoni/arbo"
|
||||
"go.vocdoni.io/dvote/db"
|
||||
"go.vocdoni.io/dvote/db/badgerdb"
|
||||
"go.vocdoni.io/dvote/db/pebbledb"
|
||||
)
|
||||
|
||||
func TestGenerator(t *testing.T) {
|
||||
c := qt.New(t)
|
||||
database, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree, err := arbo.NewTree(arbo.Config{Database: database, MaxLevels: 4,
|
||||
HashFunction: arbo.HashFunctionPoseidon})
|
||||
|
||||
68
tree.go
68
tree.go
@@ -160,13 +160,11 @@ func NewTreeWithTx(wTx db.WriteTx, cfg Config) (*Tree, error) {
|
||||
|
||||
// Root returns the root of the Tree
|
||||
func (t *Tree) Root() ([]byte, error) {
|
||||
rTx := t.db.ReadTx()
|
||||
defer rTx.Discard()
|
||||
return t.RootWithTx(rTx)
|
||||
return t.RootWithTx(t.db)
|
||||
}
|
||||
|
||||
// RootWithTx returns the root of the Tree using the given db.ReadTx
|
||||
func (t *Tree) RootWithTx(rTx db.ReadTx) ([]byte, error) {
|
||||
func (t *Tree) RootWithTx(rTx db.Reader) ([]byte, error) {
|
||||
// if snapshotRoot is defined, means that the tree is a snapshot, and
|
||||
// the root is not obtained from the db, but from the snapshotRoot
|
||||
// parameter
|
||||
@@ -429,7 +427,7 @@ func (t *Tree) upFromSubRoots(wTx db.WriteTx, subRoots [][]byte) ([]byte, error)
|
||||
return t.upFromSubRoots(wTx, newSubRoots)
|
||||
}
|
||||
|
||||
func (t *Tree) getSubRootsAtLevel(rTx db.ReadTx, root []byte, l int) ([][]byte, error) {
|
||||
func (t *Tree) getSubRootsAtLevel(rTx db.Reader, root []byte, l int) ([][]byte, error) {
|
||||
// go at level l and return each node key, where each node key is the
|
||||
// subRoot of the subTree that starts there
|
||||
|
||||
@@ -448,7 +446,7 @@ func (t *Tree) getSubRootsAtLevel(rTx db.ReadTx, root []byte, l int) ([][]byte,
|
||||
}
|
||||
|
||||
func (t *Tree) addBatchInMemory(wTx db.WriteTx, keys, values [][]byte) ([]Invalid, error) {
|
||||
vt, err := t.loadVT(wTx)
|
||||
vt, err := t.loadVT()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -491,11 +489,11 @@ func (t *Tree) addBatchInMemory(wTx db.WriteTx, keys, values [][]byte) ([]Invali
|
||||
|
||||
// loadVT loads a new virtual tree (vt) from the current Tree, which contains
|
||||
// the same leafs.
|
||||
func (t *Tree) loadVT(rTx db.ReadTx) (vt, error) {
|
||||
func (t *Tree) loadVT() (vt, error) {
|
||||
vt := newVT(t.maxLevels, t.hashFunction)
|
||||
vt.params.dbg = t.dbg
|
||||
var callbackErr error
|
||||
err := t.IterateWithStopWithTx(rTx, nil, func(_ int, k, v []byte) bool {
|
||||
err := t.IterateWithStopWithTx(t.db, nil, func(_ int, k, v []byte) bool {
|
||||
if v[0] != PrefixValueLeaf {
|
||||
return false
|
||||
}
|
||||
@@ -639,7 +637,7 @@ func (t *Tree) add(wTx db.WriteTx, root []byte, fromLvl int, k, v []byte) ([]byt
|
||||
}
|
||||
|
||||
// down goes down to the leaf recursively
|
||||
func (t *Tree) down(rTx db.ReadTx, newKey, currKey []byte, siblings [][]byte,
|
||||
func (t *Tree) down(rTx db.Reader, newKey, currKey []byte, siblings [][]byte,
|
||||
path []bool, currLvl int, getLeaf bool) (
|
||||
[]byte, []byte, [][]byte, error) {
|
||||
if currLvl > t.maxLevels {
|
||||
@@ -932,15 +930,12 @@ func (t *Tree) UpdateWithTx(wTx db.WriteTx, k, v []byte) error {
|
||||
// returned, together with the packed siblings of the proof, and a boolean
|
||||
// parameter that indicates if the proof is of existence (true) or not (false).
|
||||
func (t *Tree) GenProof(k []byte) ([]byte, []byte, []byte, bool, error) {
|
||||
rTx := t.db.ReadTx()
|
||||
defer rTx.Discard()
|
||||
|
||||
return t.GenProofWithTx(rTx, k)
|
||||
return t.GenProofWithTx(t.db, k)
|
||||
}
|
||||
|
||||
// GenProofWithTx does the same than the GenProof method, but allowing to pass
|
||||
// the db.ReadTx that is used.
|
||||
func (t *Tree) GenProofWithTx(rTx db.ReadTx, k []byte) ([]byte, []byte, []byte, bool, error) {
|
||||
func (t *Tree) GenProofWithTx(rTx db.Reader, k []byte) ([]byte, []byte, []byte, bool, error) {
|
||||
keyPath, err := keyPathFromKey(t.maxLevels, k)
|
||||
if err != nil {
|
||||
return nil, nil, nil, false, err
|
||||
@@ -1067,17 +1062,14 @@ func bytesToBitmap(b []byte) []bool {
|
||||
// will be placed the data found in the tree in the leaf that was on the path
|
||||
// going to the input key.
|
||||
func (t *Tree) Get(k []byte) ([]byte, []byte, error) {
|
||||
rTx := t.db.ReadTx()
|
||||
defer rTx.Discard()
|
||||
|
||||
return t.GetWithTx(rTx, k)
|
||||
return t.GetWithTx(t.db, k)
|
||||
}
|
||||
|
||||
// GetWithTx does the same than the Get method, but allowing to pass the
|
||||
// db.ReadTx that is used. If the key is not found, will return the error
|
||||
// ErrKeyNotFound, and in the leafK & leafV parameters will be placed the data
|
||||
// found in the tree in the leaf that was on the path going to the input key.
|
||||
func (t *Tree) GetWithTx(rTx db.ReadTx, k []byte) ([]byte, []byte, error) {
|
||||
func (t *Tree) GetWithTx(rTx db.Reader, k []byte) ([]byte, []byte, error) {
|
||||
keyPath, err := keyPathFromKey(t.maxLevels, k)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
@@ -1159,15 +1151,12 @@ func (t *Tree) setNLeafs(wTx db.WriteTx, nLeafs int) error {
|
||||
|
||||
// GetNLeafs returns the number of Leafs of the Tree.
|
||||
func (t *Tree) GetNLeafs() (int, error) {
|
||||
rTx := t.db.ReadTx()
|
||||
defer rTx.Discard()
|
||||
|
||||
return t.GetNLeafsWithTx(rTx)
|
||||
return t.GetNLeafsWithTx(t.db)
|
||||
}
|
||||
|
||||
// GetNLeafsWithTx does the same than the GetNLeafs method, but allowing to
|
||||
// pass the db.ReadTx that is used.
|
||||
func (t *Tree) GetNLeafsWithTx(rTx db.ReadTx) (int, error) {
|
||||
func (t *Tree) GetNLeafsWithTx(rTx db.Reader) (int, error) {
|
||||
b, err := rTx.Get(dbKeyNLeafs)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
@@ -1220,8 +1209,7 @@ func (t *Tree) Snapshot(fromRoot []byte) (*Tree, error) {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
rTx := t.db.ReadTx()
|
||||
defer rTx.Discard()
|
||||
rTx := t.db
|
||||
// check that the root exists in the db
|
||||
if !bytes.Equal(fromRoot, t.emptyHash) {
|
||||
if _, err := rTx.Get(fromRoot); err == ErrKeyNotFound {
|
||||
@@ -1246,15 +1234,12 @@ func (t *Tree) Snapshot(fromRoot []byte) (*Tree, error) {
|
||||
// Iterate iterates through the full Tree, executing the given function on each
|
||||
// node of the Tree.
|
||||
func (t *Tree) Iterate(fromRoot []byte, f func([]byte, []byte)) error {
|
||||
rTx := t.db.ReadTx()
|
||||
defer rTx.Discard()
|
||||
|
||||
return t.IterateWithTx(rTx, fromRoot, f)
|
||||
return t.IterateWithTx(t.db, fromRoot, f)
|
||||
}
|
||||
|
||||
// IterateWithTx does the same than the Iterate method, but allowing to pass
|
||||
// the db.ReadTx that is used.
|
||||
func (t *Tree) IterateWithTx(rTx db.ReadTx, fromRoot []byte, f func([]byte, []byte)) error {
|
||||
func (t *Tree) IterateWithTx(rTx db.Reader, fromRoot []byte, f func([]byte, []byte)) error {
|
||||
// allow to define which root to use
|
||||
if fromRoot == nil {
|
||||
var err error
|
||||
@@ -1270,23 +1255,20 @@ func (t *Tree) IterateWithTx(rTx db.ReadTx, fromRoot []byte, f func([]byte, []by
|
||||
// level, and a boolean parameter used by the passed function, is to indicate to
|
||||
// stop iterating on the branch when the method returns 'true'.
|
||||
func (t *Tree) IterateWithStop(fromRoot []byte, f func(int, []byte, []byte) bool) error {
|
||||
rTx := t.db.ReadTx()
|
||||
defer rTx.Discard()
|
||||
|
||||
// allow to define which root to use
|
||||
if fromRoot == nil {
|
||||
var err error
|
||||
fromRoot, err = t.RootWithTx(rTx)
|
||||
fromRoot, err = t.RootWithTx(t.db)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return t.iterWithStop(rTx, fromRoot, 0, f)
|
||||
return t.iterWithStop(t.db, fromRoot, 0, f)
|
||||
}
|
||||
|
||||
// IterateWithStopWithTx does the same than the IterateWithStop method, but
|
||||
// allowing to pass the db.ReadTx that is used.
|
||||
func (t *Tree) IterateWithStopWithTx(rTx db.ReadTx, fromRoot []byte,
|
||||
func (t *Tree) IterateWithStopWithTx(rTx db.Reader, fromRoot []byte,
|
||||
f func(int, []byte, []byte) bool) error {
|
||||
// allow to define which root to use
|
||||
if fromRoot == nil {
|
||||
@@ -1299,7 +1281,7 @@ func (t *Tree) IterateWithStopWithTx(rTx db.ReadTx, fromRoot []byte,
|
||||
return t.iterWithStop(rTx, fromRoot, 0, f)
|
||||
}
|
||||
|
||||
func (t *Tree) iterWithStop(rTx db.ReadTx, k []byte, currLevel int,
|
||||
func (t *Tree) iterWithStop(rTx db.Reader, k []byte, currLevel int,
|
||||
f func(int, []byte, []byte) bool) error {
|
||||
var v []byte
|
||||
var err error
|
||||
@@ -1336,7 +1318,7 @@ func (t *Tree) iterWithStop(rTx db.ReadTx, k []byte, currLevel int,
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *Tree) iter(rTx db.ReadTx, k []byte, f func([]byte, []byte)) error {
|
||||
func (t *Tree) iter(rTx db.Reader, k []byte, f func([]byte, []byte)) error {
|
||||
f2 := func(currLvl int, k, v []byte) bool {
|
||||
f(k, v)
|
||||
return false
|
||||
@@ -1484,20 +1466,16 @@ func (t *Tree) GraphvizFirstNLevels(w io.Writer, fromRoot []byte, untilLvl int)
|
||||
fmt.Fprintf(w, `digraph hierarchy {
|
||||
node [fontname=Monospace,fontsize=10,shape=box]
|
||||
`)
|
||||
|
||||
rTx := t.db.ReadTx()
|
||||
defer rTx.Discard()
|
||||
|
||||
if fromRoot == nil {
|
||||
var err error
|
||||
fromRoot, err = t.RootWithTx(rTx)
|
||||
fromRoot, err = t.RootWithTx(t.db)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
nEmpties := 0
|
||||
err := t.iterWithStop(rTx, fromRoot, 0, func(currLvl int, k, v []byte) bool {
|
||||
err := t.iterWithStop(t.db, fromRoot, 0, func(currLvl int, k, v []byte) bool {
|
||||
if currLvl == untilLvl {
|
||||
return true // to stop the iter from going down
|
||||
}
|
||||
|
||||
49
tree_test.go
49
tree_test.go
@@ -12,7 +12,6 @@ import (
|
||||
|
||||
qt "github.com/frankban/quicktest"
|
||||
"go.vocdoni.io/dvote/db"
|
||||
"go.vocdoni.io/dvote/db/badgerdb"
|
||||
"go.vocdoni.io/dvote/db/pebbledb"
|
||||
)
|
||||
|
||||
@@ -26,7 +25,7 @@ func checkRootBIString(c *qt.C, tree *Tree, expected string) {
|
||||
func TestDBTx(t *testing.T) {
|
||||
c := qt.New(t)
|
||||
|
||||
dbBadger, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
dbBadger, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
testDBTx(c, dbBadger)
|
||||
|
||||
@@ -72,7 +71,7 @@ func TestAddTestVectors(t *testing.T) {
|
||||
}
|
||||
|
||||
func testAdd(c *qt.C, hashFunc HashFunction, testVectors []string) {
|
||||
database, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree, err := NewTree(Config{Database: database, MaxLevels: 256,
|
||||
HashFunction: hashFunc})
|
||||
@@ -105,7 +104,7 @@ func testAdd(c *qt.C, hashFunc HashFunction, testVectors []string) {
|
||||
|
||||
func TestAddBatch(t *testing.T) {
|
||||
c := qt.New(t)
|
||||
database, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree, err := NewTree(Config{Database: database, MaxLevels: 256,
|
||||
HashFunction: HashFunctionPoseidon})
|
||||
@@ -124,7 +123,7 @@ func TestAddBatch(t *testing.T) {
|
||||
checkRootBIString(c, tree,
|
||||
"296519252211642170490407814696803112091039265640052570497930797516015811235")
|
||||
|
||||
database, err = badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database, err = pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree2, err := NewTree(Config{Database: database, MaxLevels: 256,
|
||||
HashFunction: HashFunctionPoseidon})
|
||||
@@ -148,7 +147,7 @@ func TestAddBatch(t *testing.T) {
|
||||
|
||||
func TestAddDifferentOrder(t *testing.T) {
|
||||
c := qt.New(t)
|
||||
database1, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database1, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree1, err := NewTree(Config{Database: database1, MaxLevels: 256,
|
||||
HashFunction: HashFunctionPoseidon})
|
||||
@@ -164,7 +163,7 @@ func TestAddDifferentOrder(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
database2, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database2, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree2, err := NewTree(Config{Database: database2, MaxLevels: 256,
|
||||
HashFunction: HashFunctionPoseidon})
|
||||
@@ -190,7 +189,7 @@ func TestAddDifferentOrder(t *testing.T) {
|
||||
|
||||
func TestAddRepeatedIndex(t *testing.T) {
|
||||
c := qt.New(t)
|
||||
database, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree, err := NewTree(Config{Database: database, MaxLevels: 256,
|
||||
HashFunction: HashFunctionPoseidon})
|
||||
@@ -209,7 +208,7 @@ func TestAddRepeatedIndex(t *testing.T) {
|
||||
|
||||
func TestUpdate(t *testing.T) {
|
||||
c := qt.New(t)
|
||||
database, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree, err := NewTree(Config{Database: database, MaxLevels: 256,
|
||||
HashFunction: HashFunctionPoseidon})
|
||||
@@ -263,7 +262,7 @@ func TestUpdate(t *testing.T) {
|
||||
|
||||
func TestAux(t *testing.T) { // TODO split in proper tests
|
||||
c := qt.New(t)
|
||||
database, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree, err := NewTree(Config{Database: database, MaxLevels: 256,
|
||||
HashFunction: HashFunctionPoseidon})
|
||||
@@ -303,7 +302,7 @@ func TestAux(t *testing.T) { // TODO split in proper tests
|
||||
|
||||
func TestGet(t *testing.T) {
|
||||
c := qt.New(t)
|
||||
database, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree, err := NewTree(Config{Database: database, MaxLevels: 256,
|
||||
HashFunction: HashFunctionPoseidon})
|
||||
@@ -428,7 +427,7 @@ func TestPackAndUnpackSiblings(t *testing.T) {
|
||||
|
||||
func TestGenProofAndVerify(t *testing.T) {
|
||||
c := qt.New(t)
|
||||
database, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree, err := NewTree(Config{Database: database, MaxLevels: 256,
|
||||
HashFunction: HashFunctionPoseidon})
|
||||
@@ -469,7 +468,7 @@ func TestDumpAndImportDumpInFile(t *testing.T) {
|
||||
|
||||
func testDumpAndImportDump(t *testing.T, inFile bool) {
|
||||
c := qt.New(t)
|
||||
database1, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database1, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree1, err := NewTree(Config{Database: database1, MaxLevels: 256,
|
||||
HashFunction: HashFunctionPoseidon})
|
||||
@@ -498,7 +497,7 @@ func testDumpAndImportDump(t *testing.T, inFile bool) {
|
||||
c.Assert(err, qt.IsNil)
|
||||
}
|
||||
|
||||
database2, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database2, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree2, err := NewTree(Config{Database: database2, MaxLevels: 256,
|
||||
HashFunction: HashFunctionPoseidon})
|
||||
@@ -526,7 +525,7 @@ func testDumpAndImportDump(t *testing.T, inFile bool) {
|
||||
|
||||
func TestRWMutex(t *testing.T) {
|
||||
c := qt.New(t)
|
||||
database, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree, err := NewTree(Config{Database: database, MaxLevels: 256,
|
||||
HashFunction: HashFunctionPoseidon})
|
||||
@@ -559,7 +558,7 @@ func TestRWMutex(t *testing.T) {
|
||||
// TODO UPDATE
|
||||
// func TestSetGetNLeafs(t *testing.T) {
|
||||
// c := qt.New(t)
|
||||
// database, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
// database, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
// c.Assert(err, qt.IsNil)
|
||||
// tree, err := NewTree(database, 100, HashFunctionPoseidon)
|
||||
// c.Assert(err, qt.IsNil)
|
||||
@@ -610,13 +609,13 @@ func TestRWMutex(t *testing.T) {
|
||||
func TestAddBatchFullyUsed(t *testing.T) {
|
||||
c := qt.New(t)
|
||||
|
||||
database1, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database1, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree1, err := NewTree(Config{Database: database1, MaxLevels: 4,
|
||||
HashFunction: HashFunctionPoseidon})
|
||||
c.Assert(err, qt.IsNil)
|
||||
|
||||
database2, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database2, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree2, err := NewTree(Config{Database: database2, MaxLevels: 4,
|
||||
HashFunction: HashFunctionPoseidon})
|
||||
@@ -671,7 +670,7 @@ func TestAddBatchFullyUsed(t *testing.T) {
|
||||
|
||||
func TestSetRoot(t *testing.T) {
|
||||
c := qt.New(t)
|
||||
database, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree, err := NewTree(Config{Database: database, MaxLevels: 256,
|
||||
HashFunction: HashFunctionPoseidon})
|
||||
@@ -728,7 +727,7 @@ func TestSetRoot(t *testing.T) {
|
||||
|
||||
func TestSnapshot(t *testing.T) {
|
||||
c := qt.New(t)
|
||||
database, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree, err := NewTree(Config{Database: database, MaxLevels: 256,
|
||||
HashFunction: HashFunctionPoseidon})
|
||||
@@ -779,7 +778,7 @@ func TestSnapshot(t *testing.T) {
|
||||
func TestGetFromSnapshotExpectArboErrKeyNotFound(t *testing.T) {
|
||||
c := qt.New(t)
|
||||
|
||||
database, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree, err := NewTree(Config{Database: database, MaxLevels: 256,
|
||||
HashFunction: HashFunctionPoseidon})
|
||||
@@ -800,7 +799,7 @@ func TestGetFromSnapshotExpectArboErrKeyNotFound(t *testing.T) {
|
||||
|
||||
func TestKeyLen(t *testing.T) {
|
||||
c := qt.New(t)
|
||||
database, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
// maxLevels is 100, keyPath length = ceil(maxLevels/8) = 13
|
||||
maxLevels := 100
|
||||
@@ -835,7 +834,7 @@ func TestKeyLen(t *testing.T) {
|
||||
// expect errors when adding a key bigger than maximum capacity of the
|
||||
// tree: ceil(maxLevels/8)
|
||||
maxLevels = 32
|
||||
database, err = badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database, err = pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree, err = NewTree(Config{Database: database, MaxLevels: maxLevels,
|
||||
HashFunction: HashFunctionBlake2b})
|
||||
@@ -906,7 +905,7 @@ func TestKeyLen(t *testing.T) {
|
||||
func TestKeyLenBiggerThan32(t *testing.T) {
|
||||
c := qt.New(t)
|
||||
maxLevels := 264
|
||||
database, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree, err := NewTree(Config{Database: database, MaxLevels: maxLevels,
|
||||
HashFunction: HashFunctionBlake2b})
|
||||
@@ -949,7 +948,7 @@ func BenchmarkAdd(b *testing.B) {
|
||||
|
||||
func benchmarkAdd(b *testing.B, hashFunc HashFunction, ks, vs [][]byte) {
|
||||
c := qt.New(b)
|
||||
database, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree, err := NewTree(Config{Database: database, MaxLevels: 140,
|
||||
HashFunction: hashFunc})
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
|
||||
qt "github.com/frankban/quicktest"
|
||||
"go.vocdoni.io/dvote/db"
|
||||
"go.vocdoni.io/dvote/db/badgerdb"
|
||||
"go.vocdoni.io/dvote/db/pebbledb"
|
||||
)
|
||||
|
||||
// testVirtualTree adds the given key-values and tests the vt root against the
|
||||
@@ -17,7 +17,7 @@ func testVirtualTree(c *qt.C, maxLevels int, keys, values [][]byte) {
|
||||
c.Assert(len(keys), qt.Equals, len(values))
|
||||
|
||||
// normal tree, to have an expected root value
|
||||
database, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree, err := NewTree(Config{Database: database, MaxLevels: maxLevels,
|
||||
HashFunction: HashFunctionSha256})
|
||||
@@ -123,7 +123,7 @@ func TestVirtualTreeAddBatch(t *testing.T) {
|
||||
}
|
||||
|
||||
// normal tree, to have an expected root value
|
||||
database, err := badgerdb.New(db.Options{Path: c.TempDir()})
|
||||
database, err := pebbledb.New(db.Options{Path: c.TempDir()})
|
||||
c.Assert(err, qt.IsNil)
|
||||
tree, err := NewTree(Config{Database: database, MaxLevels: maxLevels,
|
||||
HashFunction: HashFunctionBlake2b})
|
||||
|
||||
Reference in New Issue
Block a user