mirror of
https://github.com/arnaucube/hermez-node.git
synced 2026-02-07 11:26:44 +01:00
Replace cp -r in StateDB by checkpoints, Resolve #93
This commit is contained in:
@@ -4,10 +4,10 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/hermeznetwork/hermez-node/common"
|
"github.com/hermeznetwork/hermez-node/common"
|
||||||
|
"github.com/hermeznetwork/hermez-node/log"
|
||||||
"github.com/iden3/go-merkletree"
|
"github.com/iden3/go-merkletree"
|
||||||
"github.com/iden3/go-merkletree/db"
|
"github.com/iden3/go-merkletree/db"
|
||||||
"github.com/iden3/go-merkletree/db/pebble"
|
"github.com/iden3/go-merkletree/db/pebble"
|
||||||
@@ -103,7 +103,7 @@ func NewStateDB(path string, typ TypeStateDB, nLevels int) (*StateDB, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// make reset (get checkpoint) at currentBatch
|
// make reset (get checkpoint) at currentBatch
|
||||||
err = sdb.Reset(sdb.currentBatch)
|
err = sdb.reset(sdb.currentBatch, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -162,6 +162,8 @@ func (s *StateDB) MakeCheckpoint() error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
} else if err != nil && !os.IsNotExist(err) {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// execute Checkpoint
|
// execute Checkpoint
|
||||||
@@ -184,14 +186,59 @@ func (s *StateDB) DeleteCheckpoint(batchNum common.BatchNum) error {
|
|||||||
return os.RemoveAll(checkpointPath)
|
return os.RemoveAll(checkpointPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func pebbleMakeCheckpoint(source, dest string) error {
|
||||||
|
// Remove dest folder (if it exists) before doing the checkpoint
|
||||||
|
if _, err := os.Stat(dest); !os.IsNotExist(err) {
|
||||||
|
err := os.RemoveAll(dest)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else if err != nil && !os.IsNotExist(err) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
sto, err := pebble.NewPebbleStorage(source, false)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
errClose := sto.Pebble().Close()
|
||||||
|
if errClose != nil {
|
||||||
|
log.Errorw("Pebble.Close", "err", errClose)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// execute Checkpoint
|
||||||
|
err = sto.Pebble().Checkpoint(dest)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Reset resets the StateDB to the checkpoint at the given batchNum. Reset
|
// Reset resets the StateDB to the checkpoint at the given batchNum. Reset
|
||||||
// does not delete the checkpoints between old current and the new current,
|
// does not delete the checkpoints between old current and the new current,
|
||||||
// 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 {
|
||||||
|
return s.reset(batchNum, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// reset resets the StateDB to the checkpoint at the given batchNum. Reset
|
||||||
|
// does not delete the checkpoints between old current and the new current,
|
||||||
|
// those checkpoints will remain in the storage, and eventually will be
|
||||||
|
// deleted when MakeCheckpoint overwrites them. `closeCurrent` will close the
|
||||||
|
// currently opened db before doing the reset.
|
||||||
|
func (s *StateDB) reset(batchNum common.BatchNum, closeCurrent bool) error {
|
||||||
checkpointPath := s.path + PathBatchNum + strconv.Itoa(int(batchNum))
|
checkpointPath := s.path + PathBatchNum + strconv.Itoa(int(batchNum))
|
||||||
currentPath := s.path + PathCurrent
|
currentPath := s.path + PathCurrent
|
||||||
|
|
||||||
|
if closeCurrent {
|
||||||
|
if err := s.db.Pebble().Close(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
// remove 'current'
|
// remove 'current'
|
||||||
err := os.RemoveAll(currentPath)
|
err := os.RemoveAll(currentPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -210,8 +257,7 @@ func (s *StateDB) Reset(batchNum common.BatchNum) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// copy 'BatchNumX' to 'current'
|
// copy 'BatchNumX' to 'current'
|
||||||
cmd := exec.Command("cp", "-r", checkpointPath, currentPath) //nolint:gosec
|
err = pebbleMakeCheckpoint(checkpointPath, currentPath)
|
||||||
err = cmd.Run()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -431,20 +477,21 @@ func (l *LocalStateDB) Reset(batchNum common.BatchNum, fromSynchronizer bool) er
|
|||||||
return fmt.Errorf("Checkpoint not exist in Synchronizer")
|
return fmt.Errorf("Checkpoint not exist in Synchronizer")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := l.db.Pebble().Close(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
// remove 'current'
|
// remove 'current'
|
||||||
err := os.RemoveAll(currentPath)
|
err := os.RemoveAll(currentPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// copy synchronizer'BatchNumX' to 'current'
|
// copy synchronizer'BatchNumX' to 'current'
|
||||||
cmd := exec.Command("cp", "-r", synchronizerCheckpointPath, currentPath) //nolint:gosec
|
err = pebbleMakeCheckpoint(synchronizerCheckpointPath, currentPath)
|
||||||
err = cmd.Run()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// copy synchronizer-'BatchNumX' to 'BatchNumX'
|
// copy synchronizer'BatchNumX' to 'BatchNumX'
|
||||||
cmd = exec.Command("cp", "-r", synchronizerCheckpointPath, checkpointPath) //nolint:gosec
|
err = pebbleMakeCheckpoint(synchronizerCheckpointPath, checkpointPath)
|
||||||
err = cmd.Run()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -471,5 +518,5 @@ func (l *LocalStateDB) Reset(batchNum common.BatchNum, fromSynchronizer bool) er
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
// use checkpoint from LocalStateDB
|
// use checkpoint from LocalStateDB
|
||||||
return l.StateDB.Reset(batchNum)
|
return l.StateDB.reset(batchNum, true)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user