mirror of
https://github.com/arnaucube/hermez-node.git
synced 2026-02-07 03:16:45 +01:00
StateDB intermediate state reset when opening DB
StateDB intermediate state reset when opening DB to force getting always last Checkpoint at last BatchNum, avoiding inconsistent intermediate state.
This commit is contained in:
@@ -75,6 +75,12 @@ func NewStateDB(path string, withMT bool, nLevels int) (*StateDB, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// make reset (get checkpoint) at currentBatch
|
||||||
|
err = sdb.Reset(sdb.currentBatch)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
return sdb, nil
|
return sdb, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,7 +107,10 @@ func (s *StateDB) setCurrentBatch() error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
tx.Put(KeyCurrentBatch, s.currentBatch.Bytes())
|
err = tx.Put(KeyCurrentBatch, s.currentBatch.Bytes())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if err := tx.Commit(); err != nil {
|
if err := tx.Commit(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -153,11 +162,6 @@ func (s *StateDB) DeleteCheckpoint(batchNum common.BatchNum) error {
|
|||||||
// those checkpoints will remain in the storage, and eventually will be
|
// those checkpoints will remain in the storage, and eventually will be
|
||||||
// deleted when MakeCheckpoint overwrites them.
|
// deleted when MakeCheckpoint overwrites them.
|
||||||
func (s *StateDB) Reset(batchNum common.BatchNum) error {
|
func (s *StateDB) Reset(batchNum common.BatchNum) error {
|
||||||
if batchNum == 0 {
|
|
||||||
s.idx = 0
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
checkpointPath := s.path + PathBatchNum + strconv.Itoa(int(batchNum))
|
checkpointPath := s.path + PathBatchNum + strconv.Itoa(int(batchNum))
|
||||||
currentPath := s.path + PathCurrent
|
currentPath := s.path + PathCurrent
|
||||||
|
|
||||||
@@ -166,6 +170,18 @@ func (s *StateDB) Reset(batchNum common.BatchNum) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if batchNum == 0 {
|
||||||
|
// if batchNum == 0, open the new fresh 'current'
|
||||||
|
sto, err := pebble.NewPebbleStorage(currentPath, false)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
s.db = sto
|
||||||
|
s.idx = 0
|
||||||
|
s.currentBatch = batchNum
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// copy 'BatchNumX' to 'current'
|
// copy 'BatchNumX' to 'current'
|
||||||
cmd := exec.Command("cp", "-r", checkpointPath, currentPath) //nolint:gosec
|
cmd := exec.Command("cp", "-r", checkpointPath, currentPath) //nolint:gosec
|
||||||
err = cmd.Run()
|
err = cmd.Run()
|
||||||
@@ -191,12 +207,14 @@ func (s *StateDB) Reset(batchNum common.BatchNum) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if s.mt != nil {
|
||||||
// open the MT for the current s.db
|
// open the MT for the current s.db
|
||||||
mt, err := merkletree.NewMerkleTree(s.db, s.mt.MaxLevels())
|
mt, err := merkletree.NewMerkleTree(s.db, s.mt.MaxLevels())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
s.mt = mt
|
s.mt = mt
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -255,8 +273,14 @@ func createAccountInTreeDB(sto db.Storage, mt *merkletree.MerkleTree, idx common
|
|||||||
return nil, ErrAccountAlreadyExists
|
return nil, ErrAccountAlreadyExists
|
||||||
}
|
}
|
||||||
|
|
||||||
tx.Put(v.Bytes(), accountBytes[:])
|
err = tx.Put(v.Bytes(), accountBytes[:])
|
||||||
tx.Put(idx.Bytes(), v.Bytes())
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
err = tx.Put(idx.Bytes(), v.Bytes())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
if err := tx.Commit(); err != nil {
|
if err := tx.Commit(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -295,8 +319,14 @@ func updateAccountInTreeDB(sto db.Storage, mt *merkletree.MerkleTree, idx common
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
tx.Put(v.Bytes(), accountBytes[:])
|
err = tx.Put(v.Bytes(), accountBytes[:])
|
||||||
tx.Put(idx.Bytes(), v.Bytes())
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
err = tx.Put(idx.Bytes(), v.Bytes())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
if err := tx.Commit(); err != nil {
|
if err := tx.Commit(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -34,6 +34,87 @@ func newAccount(t *testing.T, i int) *common.Account {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestNewStateDBIntermediateState(t *testing.T) {
|
||||||
|
dir, err := ioutil.TempDir("", "tmpdb")
|
||||||
|
require.Nil(t, err)
|
||||||
|
|
||||||
|
sdb, err := NewStateDB(dir, false, 0)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
// test values
|
||||||
|
k0 := []byte("testkey0")
|
||||||
|
k1 := []byte("testkey1")
|
||||||
|
v0 := []byte("testvalue0")
|
||||||
|
v1 := []byte("testvalue1")
|
||||||
|
|
||||||
|
// store some data
|
||||||
|
tx, err := sdb.db.NewTx()
|
||||||
|
assert.Nil(t, err)
|
||||||
|
err = tx.Put(k0, v0)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
err = tx.Commit()
|
||||||
|
assert.Nil(t, err)
|
||||||
|
v, err := sdb.db.Get(k0)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, v0, v)
|
||||||
|
|
||||||
|
// call NewStateDB which should get the db at the last checkpoint state
|
||||||
|
// executing a Reset (discarding the last 'testkey0'&'testvalue0' data)
|
||||||
|
sdb, err = NewStateDB(dir, false, 0)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
v, err = sdb.db.Get(k0)
|
||||||
|
assert.NotNil(t, err)
|
||||||
|
assert.Equal(t, db.ErrNotFound, err)
|
||||||
|
assert.Nil(t, v)
|
||||||
|
|
||||||
|
// store the same data from the beginning that has ben lost since last NewStateDB
|
||||||
|
tx, err = sdb.db.NewTx()
|
||||||
|
assert.Nil(t, err)
|
||||||
|
err = tx.Put(k0, v0)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
err = tx.Commit()
|
||||||
|
assert.Nil(t, err)
|
||||||
|
v, err = sdb.db.Get(k0)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, v0, v)
|
||||||
|
|
||||||
|
// make checkpoints with the current state
|
||||||
|
bn, err := sdb.GetCurrentBatch()
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, common.BatchNum(0), bn)
|
||||||
|
err = sdb.MakeCheckpoint()
|
||||||
|
assert.Nil(t, err)
|
||||||
|
bn, err = sdb.GetCurrentBatch()
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, common.BatchNum(1), bn)
|
||||||
|
|
||||||
|
// write more data
|
||||||
|
tx, err = sdb.db.NewTx()
|
||||||
|
assert.Nil(t, err)
|
||||||
|
err = tx.Put(k1, v1)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
err = tx.Commit()
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
v, err = sdb.db.Get(k1)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, v1, v)
|
||||||
|
|
||||||
|
// call NewStateDB which should get the db at the last checkpoint state
|
||||||
|
// executing a Reset (discarding the last 'testkey1'&'testvalue1' data)
|
||||||
|
sdb, err = NewStateDB(dir, false, 0)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
v, err = sdb.db.Get(k0)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, v0, v)
|
||||||
|
|
||||||
|
v, err = sdb.db.Get(k1)
|
||||||
|
assert.NotNil(t, err)
|
||||||
|
assert.Equal(t, db.ErrNotFound, err)
|
||||||
|
assert.Nil(t, v)
|
||||||
|
}
|
||||||
|
|
||||||
func TestStateDBWithoutMT(t *testing.T) {
|
func TestStateDBWithoutMT(t *testing.T) {
|
||||||
dir, err := ioutil.TempDir("", "tmpdb")
|
dir, err := ioutil.TempDir("", "tmpdb")
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|||||||
@@ -322,7 +322,10 @@ func (s *StateDB) setIdx(idx common.Idx) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
tx.Put(keyidx, idx.Bytes())
|
err = tx.Put(keyidx, idx.Bytes())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if err := tx.Commit(); err != nil {
|
if err := tx.Commit(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
2
go.mod
2
go.mod
@@ -9,7 +9,7 @@ require (
|
|||||||
github.com/gobuffalo/packr/v2 v2.8.0
|
github.com/gobuffalo/packr/v2 v2.8.0
|
||||||
github.com/iden3/go-iden3-core v0.0.8
|
github.com/iden3/go-iden3-core v0.0.8
|
||||||
github.com/iden3/go-iden3-crypto v0.0.6-0.20200823174058-e04ca5764a15
|
github.com/iden3/go-iden3-crypto v0.0.6-0.20200823174058-e04ca5764a15
|
||||||
github.com/iden3/go-merkletree v0.0.0-20200825093552-a4b68208bb41
|
github.com/iden3/go-merkletree v0.0.0-20200902123354-eeb949f8c334
|
||||||
github.com/jinzhu/gorm v1.9.15
|
github.com/jinzhu/gorm v1.9.15
|
||||||
github.com/jmoiron/sqlx v1.2.0
|
github.com/jmoiron/sqlx v1.2.0
|
||||||
github.com/lib/pq v1.8.0
|
github.com/lib/pq v1.8.0
|
||||||
|
|||||||
2
go.sum
2
go.sum
@@ -308,6 +308,8 @@ github.com/iden3/go-merkletree v0.0.0-20200819092443-dc656fdd32fc h1:VnRP7JCp5TJ
|
|||||||
github.com/iden3/go-merkletree v0.0.0-20200819092443-dc656fdd32fc/go.mod h1:MRe6i0mi2oDVUzgBIHsNRE6XAg8EBuqIQZMsd+do+dU=
|
github.com/iden3/go-merkletree v0.0.0-20200819092443-dc656fdd32fc/go.mod h1:MRe6i0mi2oDVUzgBIHsNRE6XAg8EBuqIQZMsd+do+dU=
|
||||||
github.com/iden3/go-merkletree v0.0.0-20200825093552-a4b68208bb41 h1:mCOMMQ/YmL9ST9kk7ifT961chESkB2GFFEp8osF0Jw8=
|
github.com/iden3/go-merkletree v0.0.0-20200825093552-a4b68208bb41 h1:mCOMMQ/YmL9ST9kk7ifT961chESkB2GFFEp8osF0Jw8=
|
||||||
github.com/iden3/go-merkletree v0.0.0-20200825093552-a4b68208bb41/go.mod h1:MRe6i0mi2oDVUzgBIHsNRE6XAg8EBuqIQZMsd+do+dU=
|
github.com/iden3/go-merkletree v0.0.0-20200825093552-a4b68208bb41/go.mod h1:MRe6i0mi2oDVUzgBIHsNRE6XAg8EBuqIQZMsd+do+dU=
|
||||||
|
github.com/iden3/go-merkletree v0.0.0-20200902123354-eeb949f8c334 h1:FQngDJKiwM6i4kHlVFvSpJa9sO+QvZ7C+GqoPWe+5BI=
|
||||||
|
github.com/iden3/go-merkletree v0.0.0-20200902123354-eeb949f8c334/go.mod h1:MRe6i0mi2oDVUzgBIHsNRE6XAg8EBuqIQZMsd+do+dU=
|
||||||
github.com/iden3/go-wasm3 v0.0.1/go.mod h1:j+TcAB94Dfrjlu5kJt83h2OqAU+oyNUTwNZnQyII1sI=
|
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/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=
|
github.com/influxdata/influxdb v1.2.3-0.20180221223340-01288bdb0883/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY=
|
||||||
|
|||||||
Reference in New Issue
Block a user