Delete old checkpoints in stateDB automatically

Introduce a constructor parameter for the StateDB called `keep`, which tells
how many checkpoints to keep.  When doing a new checkpoint, if the number of
existing checkpoints exeeds `keep`, the oldest ones will be deleted.
This commit is contained in:
Eduard S
2020-12-23 18:06:36 +01:00
parent 35d598f564
commit 2205fcadbc
17 changed files with 192 additions and 64 deletions

View File

@@ -46,7 +46,7 @@ func TestNewStateDBIntermediateState(t *testing.T) {
defer assert.NoError(t, os.RemoveAll(dir))
chainID := uint16(0)
sdb, err := NewStateDB(dir, TypeTxSelector, 0, chainID)
sdb, err := NewStateDB(dir, 128, TypeTxSelector, 0, chainID)
assert.NoError(t, err)
// test values
@@ -68,7 +68,7 @@ func TestNewStateDBIntermediateState(t *testing.T) {
// 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, TypeTxSelector, 0, chainID)
sdb, err = NewStateDB(dir, 128, TypeTxSelector, 0, chainID)
assert.NoError(t, err)
v, err = sdb.db.Get(k0)
assert.NotNil(t, err)
@@ -110,7 +110,7 @@ func TestNewStateDBIntermediateState(t *testing.T) {
// 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, TypeTxSelector, 0, chainID)
sdb, err = NewStateDB(dir, 128, TypeTxSelector, 0, chainID)
assert.NoError(t, err)
v, err = sdb.db.Get(k0)
@@ -129,7 +129,7 @@ func TestStateDBWithoutMT(t *testing.T) {
defer assert.NoError(t, os.RemoveAll(dir))
chainID := uint16(0)
sdb, err := NewStateDB(dir, TypeTxSelector, 0, chainID)
sdb, err := NewStateDB(dir, 128, TypeTxSelector, 0, chainID)
assert.NoError(t, err)
// create test accounts
@@ -184,7 +184,7 @@ func TestStateDBWithMT(t *testing.T) {
defer assert.NoError(t, os.RemoveAll(dir))
chainID := uint16(0)
sdb, err := NewStateDB(dir, TypeSynchronizer, 32, chainID)
sdb, err := NewStateDB(dir, 128, TypeSynchronizer, 32, chainID)
assert.NoError(t, err)
// create test accounts
@@ -237,7 +237,7 @@ func TestCheckpoints(t *testing.T) {
defer assert.NoError(t, os.RemoveAll(dir))
chainID := uint16(0)
sdb, err := NewStateDB(dir, TypeSynchronizer, 32, chainID)
sdb, err := NewStateDB(dir, 128, TypeSynchronizer, 32, chainID)
assert.NoError(t, err)
// create test accounts
@@ -291,20 +291,20 @@ func TestCheckpoints(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, common.BatchNum(4), cb)
err = sdb.DeleteCheckpoint(common.BatchNum(9))
err = sdb.DeleteCheckpoint(common.BatchNum(1))
assert.NoError(t, err)
err = sdb.DeleteCheckpoint(common.BatchNum(10))
err = sdb.DeleteCheckpoint(common.BatchNum(2))
assert.NoError(t, err)
err = sdb.DeleteCheckpoint(common.BatchNum(9)) // does not exist, should return err
err = sdb.DeleteCheckpoint(common.BatchNum(1)) // does not exist, should return err
assert.NotNil(t, err)
err = sdb.DeleteCheckpoint(common.BatchNum(11)) // does not exist, should return err
err = sdb.DeleteCheckpoint(common.BatchNum(2)) // does not exist, should return err
assert.NotNil(t, err)
// Create a LocalStateDB from the initial StateDB
dirLocal, err := ioutil.TempDir("", "ldb")
require.NoError(t, err)
defer assert.NoError(t, os.RemoveAll(dirLocal))
ldb, err := NewLocalStateDB(dirLocal, sdb, TypeBatchBuilder, 32)
ldb, err := NewLocalStateDB(dirLocal, 128, sdb, TypeBatchBuilder, 32)
assert.NoError(t, err)
// get checkpoint 4 from sdb (StateDB) to ldb (LocalStateDB)
@@ -325,7 +325,7 @@ func TestCheckpoints(t *testing.T) {
dirLocal2, err := ioutil.TempDir("", "ldb2")
require.NoError(t, err)
defer assert.NoError(t, os.RemoveAll(dirLocal2))
ldb2, err := NewLocalStateDB(dirLocal2, sdb, TypeBatchBuilder, 32)
ldb2, err := NewLocalStateDB(dirLocal2, 128, sdb, TypeBatchBuilder, 32)
assert.NoError(t, err)
// get checkpoint 4 from sdb (StateDB) to ldb (LocalStateDB)
@@ -355,7 +355,7 @@ func TestStateDBGetAccounts(t *testing.T) {
require.NoError(t, err)
chainID := uint16(0)
sdb, err := NewStateDB(dir, TypeTxSelector, 0, chainID)
sdb, err := NewStateDB(dir, 128, TypeTxSelector, 0, chainID)
assert.NoError(t, err)
// create test accounts
@@ -403,7 +403,7 @@ func TestCheckAccountsTreeTestVectors(t *testing.T) {
defer assert.NoError(t, os.RemoveAll(dir))
chainID := uint16(0)
sdb, err := NewStateDB(dir, TypeSynchronizer, 32, chainID)
sdb, err := NewStateDB(dir, 128, TypeSynchronizer, 32, chainID)
require.NoError(t, err)
ay0 := new(big.Int).Sub(new(big.Int).Exp(big.NewInt(2), big.NewInt(253), nil), big.NewInt(1))
@@ -469,3 +469,56 @@ func TestCheckAccountsTreeTestVectors(t *testing.T) {
// root value generated by js version:
assert.Equal(t, "17298264051379321456969039521810887093935433569451713402227686942080129181291", sdb.mt.Root().BigInt().String())
}
func TestListCheckpoints(t *testing.T) {
dir, err := ioutil.TempDir("", "tmpdb")
require.NoError(t, err)
defer assert.NoError(t, os.RemoveAll(dir))
chainID := uint16(0)
sdb, err := NewStateDB(dir, 128, TypeSynchronizer, 32, chainID)
require.NoError(t, err)
numCheckpoints := 16
// do checkpoints
for i := 0; i < numCheckpoints; i++ {
err = sdb.MakeCheckpoint()
require.NoError(t, err)
}
list, err := sdb.listCheckpoints()
require.NoError(t, err)
assert.Equal(t, numCheckpoints, len(list))
assert.Equal(t, 1, list[0])
assert.Equal(t, numCheckpoints, list[len(list)-1])
numReset := 10
err = sdb.Reset(common.BatchNum(numReset))
require.NoError(t, err)
list, err = sdb.listCheckpoints()
require.NoError(t, err)
assert.Equal(t, numReset, len(list))
assert.Equal(t, 1, list[0])
assert.Equal(t, numReset, list[len(list)-1])
}
func TestDeleteOldCheckpoints(t *testing.T) {
dir, err := ioutil.TempDir("", "tmpdb")
require.NoError(t, err)
defer assert.NoError(t, os.RemoveAll(dir))
chainID := uint16(0)
keep := 16
sdb, err := NewStateDB(dir, keep, TypeSynchronizer, 32, chainID)
require.NoError(t, err)
numCheckpoints := 32
// do checkpoints and check that we never have more than `keep`
// checkpoints
for i := 0; i < numCheckpoints; i++ {
err = sdb.MakeCheckpoint()
require.NoError(t, err)
checkpoints, err := sdb.listCheckpoints()
require.NoError(t, err)
assert.LessOrEqual(t, len(checkpoints), keep)
}
}