Skip to content
This repository has been archived by the owner on Jan 4, 2023. It is now read-only.

Commit

Permalink
IS-873: rollback GV and P-Rep list
Browse files Browse the repository at this point in the history
- rollbac kGV and P-Rep list when process ROLLBACK
- do not execute GV and P-Rep garbage collection while initilization
- add test case for ClaimBackupInfo
  • Loading branch information
eunsoopark committed Nov 19, 2019
1 parent a19f67e commit 8305d2e
Show file tree
Hide file tree
Showing 11 changed files with 276 additions and 162 deletions.
32 changes: 29 additions & 3 deletions core/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ func (ctx *Context) UpdateGovernanceVariable(gvList []*IISSGovernanceVariable) {
deleteOld := false
deleteIndex := -1
for i := gvLen - 1; i >= 0 ; i-- {
if ctx.GV[i].BlockHeight < ctx.DB.getCalcDoneBH() {
if ctx.GV[i].BlockHeight <= ctx.DB.getPrevCalcDoneBH() {
if deleteOld {
// delete from management DB
bucket.Delete(ctx.GV[i].ID())
Expand Down Expand Up @@ -393,7 +393,7 @@ func (ctx *Context) UpdatePRep(prepList []*PRep) {
deleteOld := false
deleteIndex := -1
for i := prepLen - 1; i >= 0 ; i-- {
if ctx.PRep[i].BlockHeight < ctx.DB.getCalcDoneBH() {
if ctx.PRep[i].BlockHeight <= ctx.DB.getPrevCalcDoneBH() {
if deleteOld {
// delete from management DB
bucket.Delete(ctx.PRep[i].ID())
Expand Down Expand Up @@ -475,6 +475,32 @@ func (ctx *Context) UpdatePRepCandidate(iissDB db.Database) {
}
}

func (ctx *Context) RollbackManagementDB(blockHeight uint64) {
// Rollback Governance Variable
bucket, _ := ctx.DB.management.GetBucket(db.PrefixGovernanceVariable)
gvLen := len(ctx.GV)
for i := gvLen - 1; i >= 0 ; i-- {
if ctx.GV[i].BlockHeight > blockHeight {
// delete from management DB
bucket.Delete(ctx.GV[i].ID())
// delete from memory
ctx.GV = ctx.GV[:i]
}
}

// Rollback Main/Sub P-Rep list
bucket, _ = ctx.DB.management.GetBucket(db.PrefixPRep)
prepLen := len(ctx.PRep)
for i := prepLen - 1; i >= 0 ; i-- {
if ctx.PRep[i].BlockHeight > blockHeight {
// delete from management DB
bucket.Delete(ctx.PRep[i].ID())
// delete from memory
ctx.PRep = ctx.PRep[:i]
}
}
}

func (ctx *Context) Print() {
log.Printf("============================================================================")
log.Printf("Print context values\n")
Expand Down Expand Up @@ -510,7 +536,7 @@ func NewContext(dbPath string, dbType string, dbName string, dbCount int) (*Cont
}

// read Governance variable
ctx.GV, err = LoadGovernanceVariable(mngDB, ctx.DB.getCalcDoneBH())
ctx.GV, err = LoadGovernanceVariable(mngDB)
if err != nil {
log.Printf("Failed to load GV structure\n")
return nil, err
Expand Down
117 changes: 74 additions & 43 deletions core/context_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,44 +57,46 @@ func TestContext_NewContext(t *testing.T) {
assert.NotNil(t, ctx.PRepCandidates)
}

func TestContext_UpdateGovernanceVariable(t *testing.T) {
func TestContext_GovernanceVariable(t *testing.T) {
const (
ctxBlockHeight uint64 = 100
ctxBlockHeight1 uint64 = 50
ctxBlockHeight2 uint64 = 100
)
ctx := initTest(1)
defer finalizeTest(ctx)

bucket, _ := ctx.DB.management.GetBucket(db.PrefixGovernanceVariable)

// Set Block height
blockHash := make([]byte, BlockHashSize)
copy(blockHash, []byte(string(ctxBlockHeight)))
ctx.DB.setCalcDoneBH(ctxBlockHeight)
// Set Block height of CalcDone and PrevCalcDone
ctx.DB.setCalcDoneBH(ctxBlockHeight1)

// Insert initial GV
gv := new(GovernanceVariable)
gv.BlockHeight = ctxBlockHeight - 20
gv.RewardRep = *common.NewHexIntFromUint64(ctxBlockHeight - 20)
gv.BlockHeight = ctxBlockHeight1 - 20
gv.RewardRep = *common.NewHexIntFromUint64(ctxBlockHeight1 - 20)
ctx.GV = append(ctx.GV, gv)
value, _ := gv.Bytes()
bucket.Set(gv.ID(), value)

gv = new(GovernanceVariable)
gv.BlockHeight = ctxBlockHeight - 10
gv.RewardRep = *common.NewHexIntFromUint64(ctxBlockHeight - 10)
gv.BlockHeight = ctxBlockHeight1
gv.RewardRep = *common.NewHexIntFromUint64(ctxBlockHeight1)
ctx.GV = append(ctx.GV, gv)
value, _ = gv.Bytes()
bucket.Set(gv.ID(), value)

// Set Block height of CalcDone and PrevCalcDone
ctx.DB.setCalcDoneBH(ctxBlockHeight2)

// make IISSGovernanceVariable list
gvList := make([]*IISSGovernanceVariable, 0)
iissGV := new(IISSGovernanceVariable)
iissGV.BlockHeight = ctxBlockHeight + 10
iissGV.RewardRep = ctxBlockHeight + 10
iissGV.BlockHeight = ctxBlockHeight2 - 20
iissGV.RewardRep = ctxBlockHeight2 - 20
gvList = append(gvList, iissGV)
iissGV = new(IISSGovernanceVariable)
iissGV.BlockHeight = ctxBlockHeight + 20
iissGV.RewardRep = ctxBlockHeight + 20
iissGV.BlockHeight = ctxBlockHeight2
iissGV.RewardRep = ctxBlockHeight2
gvList = append(gvList, iissGV)

// update GV
Expand All @@ -103,71 +105,85 @@ func TestContext_UpdateGovernanceVariable(t *testing.T) {
// check - len
assert.Equal(t, len(gvList) + 1, len(ctx.GV))

// check - values

// In memory
assert.Equal(t, ctxBlockHeight - 10, ctx.GV[0].BlockHeight)
assert.Equal(t, ctxBlockHeight1, ctx.GV[0].BlockHeight)
// In DB
bs, _ := bucket.Get(ctx.GV[0].ID())
assert.NotNil(t, bs)
gv.SetBytes(bs)
assert.Equal(t, 0, ctx.GV[0].RewardRep.Cmp(&gv.RewardRep.Int))

// In memory
assert.Equal(t, ctxBlockHeight + 10, ctx.GV[1].BlockHeight)
assert.Equal(t, ctxBlockHeight2 - 20, ctx.GV[1].BlockHeight)
// In DB
bs, _ = bucket.Get(ctx.GV[1].ID())
assert.NotNil(t, bs)
gv.SetBytes(bs)
assert.Equal(t, 0, ctx.GV[1].RewardRep.Cmp(&gv.RewardRep.Int))

// In memory
assert.Equal(t, ctxBlockHeight + 20, ctx.GV[2].BlockHeight)
assert.Equal(t, ctxBlockHeight2, ctx.GV[2].BlockHeight)
// In DB
bs, _ = bucket.Get(ctx.GV[2].ID())
assert.NotNil(t, bs)
gv.SetBytes(bs)
assert.Equal(t, 0, ctx.GV[2].RewardRep.Cmp(&gv.RewardRep.Int))

// test rollback
ctx.RollbackManagementDB(ctxBlockHeight1)

// check - len
assert.Equal(t, 1, len(ctx.GV))

// In memory
assert.Equal(t, ctxBlockHeight1, ctx.GV[0].BlockHeight)
// In DB
bs, _ = bucket.Get(ctx.GV[0].ID())
assert.NotNil(t, bs)
gv.SetBytes(bs)
assert.Equal(t, 0, ctx.GV[0].RewardRep.Cmp(&gv.RewardRep.Int))
}

func TestContext_UpdatePRep(t *testing.T) {
func TestContext_PRep(t *testing.T) {
const (
ctxBlockHeight uint64 = 100
ctxBlockHeight1 uint64 = 50
ctxBlockHeight2 uint64 = 100
)
ctx := initTest(1)
defer finalizeTest(ctx)

bucket, _ := ctx.DB.management.GetBucket(db.PrefixPRep)

// Set Block height
blockHash := make([]byte, BlockHashSize)
copy(blockHash, []byte(string(ctxBlockHeight)))
ctx.DB.setCalcDoneBH(ctxBlockHeight)
ctx.DB.setCalcDoneBH(ctxBlockHeight1)

// Insert initial PRep
pRep := new(PRep)
pRep.BlockHeight = ctxBlockHeight - 20
pRep.TotalDelegation = *common.NewHexIntFromUint64(ctxBlockHeight - 20)
pRep.BlockHeight = ctxBlockHeight1 - 20
pRep.TotalDelegation = *common.NewHexIntFromUint64(ctxBlockHeight1 - 20)
ctx.PRep = append(ctx.PRep, pRep)
value, _ := pRep.Bytes()
bucket.Set(pRep.ID(), value)

pRep = new(PRep)
pRep.BlockHeight = ctxBlockHeight - 10
pRep.TotalDelegation = *common.NewHexIntFromUint64(ctxBlockHeight - 10)
pRep.BlockHeight = ctxBlockHeight1
pRep.TotalDelegation = *common.NewHexIntFromUint64(ctxBlockHeight1)
ctx.PRep = append(ctx.PRep, pRep)
value, _ = pRep.Bytes()
bucket.Set(pRep.ID(), value)

// Set Block height
ctx.DB.setCalcDoneBH(ctxBlockHeight1)

// make IISS list
prepList := make([]*PRep, 0)
pRep = new(PRep)
pRep.BlockHeight = ctxBlockHeight + 10
pRep.TotalDelegation = *common.NewHexIntFromUint64(ctxBlockHeight + 10)
pRep.BlockHeight = ctxBlockHeight2 - 20
pRep.TotalDelegation = *common.NewHexIntFromUint64(ctxBlockHeight1 - 20)
prepList = append(prepList, pRep)
pRep = new(PRep)
pRep.BlockHeight = ctxBlockHeight + 20
pRep.TotalDelegation = *common.NewHexIntFromUint64(ctxBlockHeight + 20)
pRep.BlockHeight = ctxBlockHeight2
pRep.TotalDelegation = *common.NewHexIntFromUint64(ctxBlockHeight2)
prepList = append(prepList, pRep)

// update PRep
Expand All @@ -179,28 +195,43 @@ func TestContext_UpdatePRep(t *testing.T) {
// check - values

// In memory
assert.Equal(t, ctxBlockHeight - 10, ctx.PRep[0].BlockHeight)
assert.Equal(t, ctxBlockHeight1, ctx.PRep[0].BlockHeight)
// In DB
bs, _ := bucket.Get(ctx.PRep[0].ID())
assert.NotNil(t, bs)
pRep.SetBytes(bs)
assert.Equal(t, 0, ctx.PRep[0].TotalDelegation.Cmp(&pRep.TotalDelegation.Int))

// In memory
assert.Equal(t, ctxBlockHeight + 10, ctx.PRep[1].BlockHeight)
assert.Equal(t, ctxBlockHeight2 - 20, ctx.PRep[1].BlockHeight)
// In DB
bs, _ = bucket.Get(ctx.PRep[1].ID())
assert.NotNil(t, bs)
pRep.SetBytes(bs)
assert.Equal(t, 0, ctx.PRep[1].TotalDelegation.Cmp(&pRep.TotalDelegation.Int))

// In memory
assert.Equal(t, ctxBlockHeight + 20, ctx.PRep[2].BlockHeight)
assert.Equal(t, ctxBlockHeight2, ctx.PRep[2].BlockHeight)
// In DB
bs, _ = bucket.Get(ctx.PRep[2].ID())
assert.NotNil(t, bs)
pRep.SetBytes(bs)
assert.Equal(t, 0, ctx.PRep[2].TotalDelegation.Cmp(&pRep.TotalDelegation.Int))

// rollback
ctx.RollbackManagementDB(ctxBlockHeight1)

// check - len
assert.Equal(t, 1, len(ctx.PRep))

// In memory
assert.Equal(t, ctxBlockHeight1, ctx.PRep[0].BlockHeight)
// In DB
bs, _ = bucket.Get(ctx.PRep[0].ID())
assert.NotNil(t, bs)
pRep.SetBytes(bs)
assert.Equal(t, 0, ctx.PRep[0].TotalDelegation.Cmp(&pRep.TotalDelegation.Int))

}

func TestContext_UpdatePRepCandidate(t *testing.T) {
Expand Down Expand Up @@ -413,11 +444,11 @@ func TestContext_ResetAccountDB(t *testing.T) {
qDB := ctx.DB.getCalculateDB(ia.Address)
bucket, _ := qDB.GetBucket(db.PrefixIScore)
err := bucket.Set(ia.ID(), ia.Bytes())
assert.Nil(t, err)
assert.NoError(t, err)

blockHeight := uint64(1000)
err = ctx.DB.resetAccountDB(blockHeight)
assert.Nil(t, err)
assert.NoError(t, err)

// same query DB
assert.Equal(t, qDBList, ctx.DB.getQueryDBList())
Expand All @@ -430,15 +461,15 @@ func TestContext_ResetAccountDB(t *testing.T) {
for i := 0; i < ctx.DB.info.DBCount; i++ {
backupName := fmt.Sprintf(BackupDBNameFormat, blockHeight, i+1)
stat, err := os.Stat(filepath.Join(ctx.DB.info.DBRoot, backupName))
assert.Nil(t, err)
assert.NoError(t, err)
assert.True(t, stat.IsDir())
}
// check ia value in backup DB
backupName := fmt.Sprintf(BackupDBNameFormat, blockHeight, ctx.DB.getAccountDBIndex(ia.Address) + 1)
backupDB := db.Open(ctx.DB.info.DBRoot, ctx.DB.info.DBType, backupName)
bucket, _ = backupDB.GetBucket(db.PrefixIScore)
bs, err := bucket.Get(ia.ID())
assert.Nil(t, err)
assert.NoError(t, err)
assert.NotNil(t, bs)
assert.Equal(t, ia.Bytes(), bs)
backupDB.Close()
Expand Down Expand Up @@ -501,7 +532,7 @@ func TestContext_RollbackAccountDB(t *testing.T) {
qDB := ctx.DB.getQueryDB(ia.Address)
bucket, _ := qDB.GetBucket(db.PrefixIScore)
err = bucket.Set(ia.ID(), ia.Bytes())
assert.Nil(t, err)
assert.NoError(t, err)

// emulate calculation process
prevBlockHeight := uint64(5)
Expand All @@ -517,7 +548,7 @@ func TestContext_RollbackAccountDB(t *testing.T) {

// reset account DB to make backup account DB
err = ctx.DB.resetAccountDB(blockHeight)
assert.Nil(t, err)
assert.NoError(t, err)
WriteCalculationResult(crDB, blockHeight, nil, nil)
ctx.DB.setCalcDoneBH(blockHeight)
ctx.DB.writeToDB()
Expand All @@ -536,15 +567,15 @@ func TestContext_RollbackAccountDB(t *testing.T) {
// backup account DB remains
backupName := fmt.Sprintf(BackupDBNameFormat, blockHeight, 1)
stat, err := os.Stat(filepath.Join(ctx.DB.info.DBRoot, backupName))
assert.Nil(t, err)
assert.NoError(t, err)
assert.True(t, stat.IsDir())

// check block height and block hash
assert.Equal(t, blockHeight, ctx.DB.getCalcDoneBH())

// valid Rollback
err = ctx.DB.rollbackAccountDB(0)
assert.Nil(t, err)
assert.NoError(t, err)

// backup account DB was deleted
backupName = fmt.Sprintf(BackupDBNameFormat, blockHeight, 1)
Expand Down
2 changes: 1 addition & 1 deletion core/db_account_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func TestDBAccount_NewIScoreAccountFromBytes(t *testing.T) {

iaNew, err := NewIScoreAccountFromBytes(ia.Bytes())

assert.Nil(t, err)
assert.NoError(t, err)

assert.Equal(t, 0, ia.IScore.Cmp(&iaNew.IScore.Int))
assert.Equal(t, ia.BlockHeight, iaNew.BlockHeight)
Expand Down
18 changes: 9 additions & 9 deletions core/db_calculate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@ func TestDBCalculate_BytesAndSetBytes(t *testing.T) {
var calcResultNew CalculationResult

bs, err := calculationResult.Bytes()
assert.Nil(t, err)
assert.NoError(t, err)
err = calcResultNew.SetBytes(bs)
assert.Nil(t, err)
assert.NoError(t, err)
bsNew, err := calcResultNew.Bytes()
assert.Nil(t, err)
assert.NoError(t, err)

assert.Equal(t, calculationResult.Success, calcResultNew.Success)
assert.Equal(t, 0, calculationResult.IScore.Cmp(&calcResultNew.IScore.Int))
Expand All @@ -54,11 +54,11 @@ func TestDBCalculate_NewClaimFromBytes(t *testing.T) {
calculationResult := makeCalcResult()

bs, err := calculationResult.Bytes()
assert.Nil(t, err)
assert.NoError(t, err)
calcResultNew, err := NewCalculationResultFromBytes(bs)
assert.Nil(t, err)
assert.NoError(t, err)
bsNew, err := calcResultNew.Bytes()
assert.Nil(t, err)
assert.NoError(t, err)

assert.Equal(t, calculationResult.Success, calcResultNew.Success)
assert.Equal(t, 0, calculationResult.IScore.Cmp(&calcResultNew.IScore.Int))
Expand All @@ -81,12 +81,12 @@ func TestDBCalculate_CalculationResult(t *testing.T) {
WriteCalculationResult(crDB, calcBlockHeight, stats, stateHash)

bucket, err := crDB.GetBucket(db.PrefixCalcResult)
assert.Nil(t, err)
assert.NoError(t, err)
bs, err := bucket.Get(common.Uint64ToBytes(calcBlockHeight))
assert.Nil(t, err)
assert.NoError(t, err)

err = calculationResult.SetBytes(bs)
assert.Nil(t, err)
assert.NoError(t, err)

assert.True(t, calculationResult.Success)
assert.Equal(t, 0, calculationResult.IScore.Cmp(&stats.TotalReward.Int))
Expand Down
Loading

0 comments on commit 8305d2e

Please sign in to comment.