Skip to content

Commit

Permalink
CVCH Implement KeepRecent Tests for increase and decrease
Browse files Browse the repository at this point in the history
  • Loading branch information
chillyvee committed Apr 20, 2022
1 parent 92e8214 commit a3d7b9d
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 41 deletions.
83 changes: 49 additions & 34 deletions store/rootmulti/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ type Store struct {
traceContext types.TraceContext
traceContextMutex sync.Mutex

cleanHouseHeight int64 // CVCH: -1 Unstarted; 0 Finished; +# Current Height we are pruning down from
cleanHouseAmount int64 // CVCH: Positive Integer of blocks to prune @ Each pruning-interval
cleanHouseFinished bool // CVCH: true at false, then turn off when cleanHouse is complete
histPruneHeight int64 // CVCH: -1 Unstarted; 0 Finished; +# Current Height we are pruning down from
histPruneAmount int64 // CVCH: Positive Integer of blocks to prune @ Each pruning-interval
histPruneFinished bool // CVCH: true at start, then falsewhen histPrune is complete

interBlockCache types.MultiStorePersistentCache

Expand Down Expand Up @@ -84,9 +84,9 @@ func NewStore(db dbm.DB) *Store {
listeners: make(map[types.StoreKey][]types.WriteListener),
removalMap: make(map[types.StoreKey]bool),

cleanHouseHeight: -1, // CVCH
cleanHouseAmount: 10, // CVCH
cleanHouseFinished: false, // CVCH
histPruneHeight: -1, // CVCH
histPruneAmount: 10, // CVCH
histPruneFinished: false, // CVCH
}
}

Expand Down Expand Up @@ -396,50 +396,62 @@ func (rs *Store) LastCommitID() types.CommitID {
// Example 1: KeepRecent = 100 is changed to KeepRecent = 50, leaving the oldest 50 blocks unpruned after restart.
// Example 2: KeepEvery = 100 is changed to KeepRecent = 50, leaving the old "Every" heights in the DB.
func (rs *Store) addPruneHistorical(previousHeight int64) {
debuginfo := false // show debug info

// Clean Historical is already finished
if rs.cleanHouseFinished {
if rs.histPruneFinished {
return
}

// Avoid cleaning historical too early in the blockchain lifecycle
// Avoid historical pruning too early in the blockchain lifecycle
// Only consider cleaning historical heights if current height > KeepRecent)
if previousHeight < int64(rs.pruningOpts.KeepRecent) {
fmt.Printf("**CVCH Too Early: %d !> %d\n", previousHeight, rs.pruningOpts.KeepRecent)
fmt.Printf("**CVCH Early Finished!!\n")
rs.cleanHouseFinished = true // Since we have started below the KeepRecent height, cleanHouse is unnecessary
if debuginfo {
fmt.Printf("**CVCH Too Early: %d !> %d\n", previousHeight, rs.pruningOpts.KeepRecent)
fmt.Printf("**CVCH Early Finished!!\n")
}
rs.histPruneFinished = true // Since we have started below the KeepRecent height, histPrune is unnecessary
return
}

// Debug
fmt.Printf("**CVCH Run : %d > %d\n", previousHeight, rs.pruningOpts.KeepRecent)
fmt.Printf("**CVCH cHH : %d\n", rs.cleanHouseHeight)
if debuginfo {
fmt.Printf("**CVCH Run : %d > %d\n", previousHeight, rs.pruningOpts.KeepRecent)
fmt.Printf("**CVCH cHH : %d\n", rs.histPruneHeight)
}

// Start from current height, then move towards 0 since more recent blocks are more likely to be present)
// Remove all previous blocks older than KeepRecent
// NOTE: SNAPSHOTS MUST be within KeepRecent (Must KeepRecent > snapshot-keep-recent * snapshot-interval (a multiple of pruning-keep-every in older cosmos-sdk versions, or within keep-recent for newer cosmos-sdk versions)

// Clean Historical hasn't been set up yet
if rs.cleanHouseHeight == -1 {
rs.cleanHouseHeight = previousHeight - int64(rs.pruningOpts.KeepRecent) // We are not concerned about duplicate height removals
fmt.Printf("**CVCH Init cleanHouseHeight = %d\n", rs.cleanHouseHeight)
}

fmt.Printf("**PH CVCH Starting: cleanHouseHeight %d\n", rs.cleanHouseHeight)
// Determine starting and ending heights to clean
var cleanOffset int64
for cleanOffset = 0; cleanOffset < rs.cleanHouseAmount; cleanOffset++ {
fmt.Printf("**PH CVCH Add %d\n", rs.cleanHouseHeight)
rs.pruneHeights = append(rs.pruneHeights, rs.cleanHouseHeight)

rs.cleanHouseHeight-- // Reduce cleanHouseHeight for next time through the loop
if rs.cleanHouseHeight < 1 {
fmt.Printf("\t\t**PH CVCH **COMPLETE** cHH:%d\n", rs.cleanHouseHeight)
fmt.Printf("**CVCH Finished!!\n")
rs.cleanHouseFinished = true
if rs.histPruneHeight == -1 {
rs.histPruneHeight = previousHeight - int64(rs.pruningOpts.KeepRecent) // We are not concerned about duplicate height removals
if debuginfo {
fmt.Printf("**CVCH Init histPruneHeight = %d\n", rs.histPruneHeight)
}
}

if debuginfo {
fmt.Printf("**PH CVCH Starting: histPruneHeight %d\n", rs.histPruneHeight)
}
// Determine starting and ending heights to prune
var histCtr int64
for histCtr = 0; histCtr < rs.histPruneAmount; histCtr++ {
if debuginfo {
fmt.Printf("**PH CVCH Add %d\n", rs.histPruneHeight)
}
rs.pruneHeights = append(rs.pruneHeights, rs.histPruneHeight)

rs.histPruneHeight-- // Reduce histPruneHeight for next time through the loop
if rs.histPruneHeight < 1 {
if debuginfo {
fmt.Printf("**CVCH Finished!!\n")
}
rs.histPruneFinished = true
break // do not remove heights below 1
}
}
fmt.Printf("**PH CVCH Resulting: cleanHouseHeight %d\n", rs.cleanHouseHeight)
}

// Commit implements Committer/CommitStore.
Expand Down Expand Up @@ -478,14 +490,14 @@ func (rs *Store) Commit() types.CommitID {
// be pruned, where pruneHeight = (commitHeight - 1) - KeepRecent.
if rs.pruningOpts.Interval > 0 && int64(rs.pruningOpts.KeepRecent) < previousHeight {
pruneHeight := previousHeight - int64(rs.pruningOpts.KeepRecent)
fmt.Printf("**CVCH PH.Future Add pruneHeight %d (previousHeight %d)\n", pruneHeight, previousHeight)
//fmt.Printf("**CVCH PH.Future Add pruneHeight %d (previousHeight %d)\n", pruneHeight, previousHeight)
rs.pruneHeights = append(rs.pruneHeights, pruneHeight)
}

// If the next version will be a pruning interval, pre-append any historical prunes.
// This early addtion makes testing in the existing framework easy
if rs.pruningOpts.Interval > 0 && (version+1)%int64(rs.pruningOpts.Interval) == 0 {
rs.addPruneHistorical(previousHeight) // CVCH: Add additional block heights for clean house pruning
rs.addPruneHistorical(previousHeight) // CVCH: Add additional block heights for historical pruning
}

// Execute batch prune if the current height is a pruning interval height
Expand All @@ -504,6 +516,7 @@ func (rs *Store) Commit() types.CommitID {
// pruneStores will batch delete a list of heights from each mounted sub-store.
// Afterwards, pruneHeights is reset.
func (rs *Store) pruneStores() {
debuginfo := false // show debug info - Helpful to see which heights are pruned
if len(rs.pruneHeights) == 0 {
return
}
Expand All @@ -514,7 +527,9 @@ func (rs *Store) pruneStores() {
// it to get the underlying IAVL store.
store = rs.GetCommitKVStore(key)

fmt.Printf("**PH DV %s => %v\n", key, rs.pruneHeights)
if debuginfo {
fmt.Printf("**pruneStores Key: %s Heights: %v\n", key, rs.pruneHeights)
}
if err := store.(*iavl.Store).DeleteVersions(rs.pruneHeights...); err != nil {
if errCause := errors.Cause(err); errCause != nil && errCause != iavltree.ErrVersionDoesNotExist {
panic(err)
Expand Down
91 changes: 84 additions & 7 deletions store/rootmulti/store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -555,15 +555,15 @@ func TestMultiStore_PruningHistoricalEarlyFinish(t *testing.T) {
}

// Should already be flagged complete since we started at zero height
require.Equal(t, ms.cleanHouseFinished, true)
require.Equal(t, ms.histPruneFinished, true)
}

// Confirm that historical pruning starts and completes
func TestMultiStore_PruningHistorical(t *testing.T) {
// Confirm that decreasing the KeepRecent setting from 100->10 prunes the new offset
func TestMultiStore_PruningHistoricalDecrease(t *testing.T) {
debuginfo := false // Show debug logs?

if debuginfo {
fmt.Println("TestMultiStore_PruningHistorical")
fmt.Println("TestMultiStore_PruningHistoricalReduce")
}

// Create DB
Expand All @@ -581,7 +581,7 @@ func TestMultiStore_PruningHistorical(t *testing.T) {
// Next pruneHeight 60, historicalPrune queue height = 59, previousHeight = 58, previousHeight(58) - keepRecent(10) = 48
historicMarker := int64(48)

// "restart" + CHANGE PruningOptions (to a lower KeepRecent), Check for historical prune
// Simulate Reconfig + "Restart" + CHANGE PruningOptions (to a lower KeepRecent), Check for historical prune
if debuginfo {
fmt.Printf("Restart with new PruneingOptions\n")
}
Expand All @@ -600,7 +600,7 @@ func TestMultiStore_PruningHistorical(t *testing.T) {
if debuginfo {
fmt.Printf("Historic Prune Loop %d\n", i)
}
require.Equal(t, false, ms.cleanHouseFinished) // Should not be done pruning at the beginning of this loop
require.Equal(t, false, ms.histPruneFinished) // Should not be done pruning at the beginning of this loop

// This commit should queue a lot of historical prunes
ms.Commit()
Expand All @@ -619,7 +619,7 @@ func TestMultiStore_PruningHistorical(t *testing.T) {
}

// Historic Prune - Should be complete
require.Equal(t, true, ms.cleanHouseFinished)
require.Equal(t, true, ms.histPruneFinished)

// Run some extra commits to see if the program dies
for i := int64(0); i < 10; i++ {
Expand All @@ -632,6 +632,83 @@ func TestMultiStore_PruningHistorical(t *testing.T) {
require.Equal(t, targetHeights, ms.pruneHeights)
}

// Confirm that increasing the KeepRecent setting from 10->30 prunes the new offset
func TestMultiStore_PruningHistoricalIncrease(t *testing.T) {
debuginfo := false // Show debug logs?

if debuginfo {
fmt.Println("TestMultiStore_PruningHistoricalIncrease")
}

// Create DB
db := dbm.NewMemDB()
ms := newMultiStoreWithMounts(db, types.PruningOptions{KeepRecent: 10, Interval: 5})
require.NoError(t, ms.LoadLatestVersion())

// Add enough heights to start pruning after increase
targetHeights := []int64{45, 46}
for i := int64(0); i < 57; i++ {
ms.Commit()
}
require.Equal(t, true, ms.histPruneFinished) // Should not be done pruning at the beginning of this loop
ph, err := getPruningHeights(ms.db)
require.Equal(t, targetHeights, ph) // Should have some pruneHeights due to low KeepRecent

// Next pruneHeight 60, historicalPrune queue height = 59, previousHeight = 58, previousHeight(58) - keepRecent(30) = 28
historicMarker := int64(28)

// Simulate Reconfig + "Restart" + CHANGE PruningOptions (to a lower KeepRecent), Check for historical prune
if debuginfo {
fmt.Printf("Restart with new PruneingOptions\n")
}
ms = newMultiStoreWithMounts(db, types.PruningOptions{KeepRecent: 30, Interval: 10})
err = ms.LoadLatestVersion()
require.NoError(t, err)
ph, err = getPruningHeights(ms.db)
require.Equal(t, targetHeights, ph) // Should have some pruneHeights due to low KeepRecent
ms.Commit() // Boring commit

// commit until all historic heights have been pruned
// Loop 0: Prune Heights: 19-28
// Loop 1: Prune Heights: 9-18
// Loop 2: Prune Heights: 1- 8
for i := 0; i < 3; i++ {
if debuginfo {
fmt.Printf("Historic Prune Loop %d\n", i)
}
require.Equal(t, false, ms.histPruneFinished) // Should not be done pruning at the beginning of this loop

// This commit should queue a lot of historical prunes
ms.Commit()
for h := historicMarker; h > historicMarker-10 && h > 0; h-- {
require.Contains(t, ms.pruneHeights, h) // Expect each historicalHeight to be queued for prune
}
historicMarker -= 10

// Run another series of dummy commits until the next historical height queue
for dummy := int64(0); dummy < 9; dummy++ {
if debuginfo {
fmt.Printf("\tBoring Commit Height %d\n", ms.lastCommitInfo.GetVersion()+1)
}
ms.Commit()
}
}

// Historic Prune - Should be complete
require.Equal(t, true, ms.histPruneFinished)

// Run some extra commits to see if the program dies
for i := int64(0); i < 10; i++ {
if debuginfo {
fmt.Printf("\tExtra Commit Height %d\n", ms.lastCommitInfo.GetVersion()+1)
}
ms.Commit()
}

targetHeights = []int64{60, 61, 62, 63, 64, 65, 66, 67}
require.Equal(t, targetHeights, ms.pruneHeights)
}

func TestSetInitialVersion(t *testing.T) {
db := dbm.NewMemDB()
multi := newMultiStoreWithMounts(db, types.PruneNothing)
Expand Down

0 comments on commit a3d7b9d

Please sign in to comment.