Skip to content

Commit

Permalink
fix(store): pruning height returns zero when store is not in prune mode
Browse files Browse the repository at this point in the history
  • Loading branch information
b00f committed Jul 21, 2024
1 parent 18a084b commit 986d6d9
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 23 deletions.
2 changes: 1 addition & 1 deletion store/mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -299,5 +299,5 @@ func (*MockStore) IsPruned() bool {
}

func (*MockStore) PruningHeight() uint32 {
return 1
return 0
}
29 changes: 16 additions & 13 deletions store/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -415,11 +415,26 @@ func (s *store) IsBanned(addr crypto.Address) bool {
return s.config.BannedAddrs[addr]
}

// IsPruned indicates that store is in prune mode.
// IsPruned returns true if the store is in prune mode, otherwise false.
func (s *store) IsPruned() bool {
return s.isPruned
}

// PruningHeight returns the height at which blocks will be pruned if the store is in prune mode.
// If the store is not in prune mode, it returns 0.
func (s *store) PruningHeight() uint32 {
s.lk.RLock()
defer s.lk.RUnlock()

if !s.isPruned {
return 0
}

// TODO: it can be optimized (and safer?) by keeping the last block height in memory.
cert := s.lastCertificate()
return cert.Height() - s.config.RetentionBlocks()

Check failure on line 435 in store/store.go

View workflow job for this annotation

GitHub Actions / linting

return with no blank line before (nlreturn)

Check failure on line 435 in store/store.go

View workflow job for this annotation

GitHub Actions / build-linux

return with no blank line before (nlreturn)
}

// Prune iterates over all blocks from the pruning height to the genesis block and prunes them.
// The pruning height is `LastBlockHeight - RetentionBlocks`.
// The callback function is called after each block is pruned and can cancel the process.
Expand Down Expand Up @@ -487,15 +502,3 @@ func (s *store) pruneBlock(blockHeight uint32) (bool, error) {

return true, nil
}

func (s *store) PruningHeight() uint32 {
s.lk.RLock()
defer s.lk.RUnlock()

cert := s.lastCertificate()
if cert == nil {
return 0
}

return cert.Height() - s.config.RetentionBlocks()
}
35 changes: 32 additions & 3 deletions store/store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ func setup(t *testing.T, config *Config) *testData {
s, err := NewStore(config)
require.NoError(t, err)
assert.False(t, s.IsPruned(), "empty store should not be in prune mode")
assert.Zero(t, s.PruningHeight(), "pruning height should be zero for an empty store")

td := &testData{
TestSuite: ts,
Expand All @@ -65,6 +66,7 @@ func TestReopenStore(t *testing.T) {
store, _ := NewStore(td.store.config)

assert.False(t, store.IsPruned())
assert.Zero(t, store.PruningHeight())
assert.Equal(t, uint32(10), store.LastCertificate().Height())
}

Expand Down Expand Up @@ -297,7 +299,6 @@ func TestPrune(t *testing.T) {
// Store doesn't have blocks for one day
err := td.store.Prune(cb)
assert.NoError(t, err)
assert.False(t, td.store.isPruned)

assert.Zero(t, totalPruned)
assert.Zero(t, lastPruningHeight)
Expand Down Expand Up @@ -330,9 +331,10 @@ func TestPrune(t *testing.T) {
td.store.config.TxCacheWindow = 1
s, err := NewStore(td.store.config)
require.NoError(t, err)
assert.True(t, s.IsPruned(), "store should be in prune mode")

td.store = s.(*store)

assert.True(t, td.store.IsPruned(), "store should be in prune mode")
assert.Equal(t, uint32(8), td.store.PruningHeight())
})

t.Run("Commit new block", func(t *testing.T) {
Expand All @@ -344,5 +346,32 @@ func TestPrune(t *testing.T) {
cBlk, err := td.store.Block(9)
assert.Error(t, err)
assert.Nil(t, cBlk)

assert.Equal(t, uint32(9), td.store.PruningHeight())
})
}

func TestCancelPrune(t *testing.T) {
conf := testConfig()
conf.RetentionDays = 1
td := setup(t, conf)

hits := uint32(0)
cb := func(pruned bool, pruningHeight uint32) bool {

Check failure on line 360 in store/store_test.go

View workflow job for this annotation

GitHub Actions / linting

unused-parameter: parameter 'pruned' seems to be unused, consider removing or renaming it as _ (revive)

Check failure on line 360 in store/store_test.go

View workflow job for this annotation

GitHub Actions / build-linux

unused-parameter: parameter 'pruned' seems to be unused, consider removing or renaming it as _ (revive)
hits++

return true // Cancel pruning
}

t.Run("Cancel Pruning database", func(t *testing.T) {
blk, cert := td.GenerateTestBlock(blockPerDay + 7)
td.store.SaveBlock(blk, cert)
err := td.store.WriteBatch()
require.NoError(t, err)

err = td.store.Prune(cb)
assert.NoError(t, err)

assert.Equal(t, uint32(1), hits)
})
}
7 changes: 1 addition & 6 deletions www/grpc/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,6 @@ func (s *blockchainServer) GetBlockchainInfo(_ context.Context,
cv = append(cv, s.validatorToProto(v))
}

pruningHeight := uint32(0)
if s.state.IsPruned() {
pruningHeight = s.state.PruningHeight()
}

return &pactus.GetBlockchainInfoResponse{
LastBlockHeight: s.state.LastBlockHeight(),
LastBlockHash: s.state.LastBlockHash().String(),
Expand All @@ -46,7 +41,7 @@ func (s *blockchainServer) GetBlockchainInfo(_ context.Context,
TotalPower: s.state.TotalPower(),
CommitteePower: s.state.CommitteePower(),
IsPruned: s.state.IsPruned(),
PruningHeight: pruningHeight,
PruningHeight: s.state.PruningHeight(),
LastBlockTime: s.state.LastBlockTime().Unix(),
CommitteeValidators: cv,
}, nil
Expand Down
2 changes: 2 additions & 0 deletions www/grpc/blockchain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ func TestGetBlockchainInfo(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, td.mockState.TestStore.LastHeight, res.LastBlockHeight)
assert.NotEmpty(t, res.LastBlockHash)
assert.Zero(t, res.PruningHeight)
assert.False(t, res.IsPruned)
})

assert.Nil(t, conn.Close(), "Error closing connection")
Expand Down

0 comments on commit 986d6d9

Please sign in to comment.