Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bug(dot/state): delete previous previous finalised trie from BlockState.tries #2341

Merged
merged 16 commits into from
Mar 8, 2022
21 changes: 15 additions & 6 deletions dot/state/block_finalisation.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,6 @@ func (bs *BlockState) GetHighestFinalisedHeader() (*types.Header, error) {
func (bs *BlockState) SetFinalisedHash(hash common.Hash, round, setID uint64) error {
bs.Lock()
defer bs.Unlock()

has, _ := bs.HasHeader(hash)
if !has {
return fmt.Errorf("cannot finalise unknown block %s", hash)
Expand All @@ -136,10 +135,6 @@ func (bs *BlockState) SetFinalisedHash(hash common.Hash, round, setID uint64) er
return fmt.Errorf("failed to set highest round and set ID: %w", err)
}

if err := bs.handleFinalisedBlock(hash); err != nil {
return fmt.Errorf("failed to set number->hash mapping on finalisation: %w", err)
}

if round > 0 {
bs.notifyFinalized(hash, round, setID)
}
Expand Down Expand Up @@ -176,6 +171,21 @@ func (bs *BlockState) SetFinalisedHash(hash common.Hash, round, setID uint64) er
),
)

if !bs.lastFinalised.Equal(hash) {
defer func(lastFinalised common.Hash) {
qdm12 marked this conversation as resolved.
Show resolved Hide resolved
lastFinalisedHeader, err := bs.GetHeader(lastFinalised)
if err != nil {
logger.Debugf("unable to retrieve header for last finalised block, hash: %s, err: %s", bs.lastFinalised, err)
}
stateRootTrie := bs.tries.get(lastFinalisedHeader.StateRoot)
if stateRootTrie != nil {
bs.tries.delete(lastFinalisedHeader.StateRoot)
} else {
logger.Errorf("unable to find trie with stateroot hash: %s", lastFinalisedHeader.StateRoot)
}
}(bs.lastFinalised)
}

bs.lastFinalised = hash
return nil
}
Expand Down Expand Up @@ -243,7 +253,6 @@ func (bs *BlockState) handleFinalisedBlock(curr common.Hash) error {

logger.Tracef("cleaned out finalised block from memory; block number %s with hash %s", block.Header.Number, hash)
}

return batch.Flush()
}

Expand Down
29 changes: 8 additions & 21 deletions dot/state/block_finalisation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"github.com/ChainSafe/gossamer/dot/types"
"github.com/ChainSafe/gossamer/lib/common"
"github.com/ChainSafe/gossamer/lib/trie"
"github.com/golang/mock/gomock"

"github.com/stretchr/testify/require"
)
Expand Down Expand Up @@ -64,16 +63,7 @@ func TestHighestRoundAndSetID(t *testing.T) {
}

func TestBlockState_SetFinalisedHash(t *testing.T) {
ctrl := gomock.NewController(t)

triesGauge := NewMockGauge(ctrl)
triesGauge.EXPECT().Set(0.00)
tries := &Tries{
rootToTrie: make(map[common.Hash]*trie.Trie),
triesGauge: triesGauge,
}

bs := newTestBlockState(t, testGenesisHeader, tries)
bs := newTestBlockState(t, testGenesisHeader, newTriesEmpty())
h, err := bs.GetFinalisedHash(0, 0)
require.NoError(t, err)
require.Equal(t, testGenesisHeader.Hash(), h)
Expand All @@ -84,10 +74,13 @@ func TestBlockState_SetFinalisedHash(t *testing.T) {
require.NotNil(t, di)
err = digest.Add(*di)
require.NoError(t, err)

someStateRoot := common.Hash{1, 1}
header := &types.Header{
ParentHash: testGenesisHeader.Hash(),
Number: big.NewInt(1),
Digest: digest,
StateRoot: someStateRoot,
}

testhash := header.Hash()
Expand All @@ -100,6 +93,9 @@ func TestBlockState_SetFinalisedHash(t *testing.T) {
})
require.NoError(t, err)

// set tries with some state root
bs.tries.softSet(someStateRoot, trie.NewEmptyTrie())

err = bs.SetFinalisedHash(testhash, 1, 1)
require.NoError(t, err)

Expand All @@ -109,16 +105,7 @@ func TestBlockState_SetFinalisedHash(t *testing.T) {
}

func TestSetFinalisedHash_setFirstSlotOnFinalisation(t *testing.T) {
ctrl := gomock.NewController(t)

triesGauge := NewMockGauge(ctrl)
triesGauge.EXPECT().Set(0.00).Times(2)
tries := &Tries{
rootToTrie: make(map[common.Hash]*trie.Trie),
triesGauge: triesGauge,
}

bs := newTestBlockState(t, testGenesisHeader, tries)
bs := newTestBlockState(t, testGenesisHeader, newTriesEmpty())
firstSlot := uint64(42069)

digest := types.NewDigest()
Expand Down
25 changes: 2 additions & 23 deletions dot/state/block_notify_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,8 @@ import (
"time"

"github.com/ChainSafe/gossamer/dot/types"
"github.com/ChainSafe/gossamer/lib/common"
"github.com/ChainSafe/gossamer/lib/runtime"
runtimemocks "github.com/ChainSafe/gossamer/lib/runtime/mocks"
"github.com/ChainSafe/gossamer/lib/trie"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/require"
)

Expand Down Expand Up @@ -47,16 +44,7 @@ func TestFreeImportedBlockNotifierChannel(t *testing.T) {
}

func TestFinalizedChannel(t *testing.T) {
ctrl := gomock.NewController(t)

triesGauge := NewMockGauge(ctrl)
triesGauge.EXPECT().Set(0.00).Times(3)
tries := &Tries{
rootToTrie: make(map[common.Hash]*trie.Trie),
triesGauge: triesGauge,
}

bs := newTestBlockState(t, testGenesisHeader, tries)
bs := newTestBlockState(t, testGenesisHeader, newTriesEmpty())

ch := bs.GetFinalisedNotifierChannel()

Expand Down Expand Up @@ -111,16 +99,7 @@ func TestImportChannel_Multi(t *testing.T) {
}

func TestFinalizedChannel_Multi(t *testing.T) {
ctrl := gomock.NewController(t)

triesGauge := NewMockGauge(ctrl)
triesGauge.EXPECT().Set(0.00)
tries := &Tries{
rootToTrie: make(map[common.Hash]*trie.Trie),
triesGauge: triesGauge,
}

bs := newTestBlockState(t, testGenesisHeader, tries)
bs := newTestBlockState(t, testGenesisHeader, newTriesEmpty())

num := 5
chs := make([]chan *types.FinalisationInfo, num)
Expand Down
2 changes: 1 addition & 1 deletion dot/state/block_race_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func TestConcurrencySetHeader(t *testing.T) {
dbs[i] = NewInMemoryDB(t)
}

tries := (*Tries)(nil) // not used in this test
tries := newTriesEmpty() // not used in this test
timwu20 marked this conversation as resolved.
Show resolved Hide resolved

pend := new(sync.WaitGroup)
pend.Add(threads)
Expand Down
26 changes: 8 additions & 18 deletions dot/state/block_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ func newTestBlockState(t *testing.T, header *types.Header, tries *Tries) *BlockS

bs, err := NewBlockStateFromGenesis(db, tries, header, telemetryMock)
require.NoError(t, err)

tr := trie.NewEmptyTrie()
err = tr.Load(bs.db, header.StateRoot)
require.NoError(t, err)
bs.tries.softSet(header.StateRoot, tr)
qdm12 marked this conversation as resolved.
Show resolved Hide resolved

return bs
}

Expand Down Expand Up @@ -262,16 +268,7 @@ func TestAddBlock_BlockNumberToHash(t *testing.T) {
}

func TestFinalization_DeleteBlock(t *testing.T) {
ctrl := gomock.NewController(t)

triesGauge := NewMockGauge(ctrl)
triesGauge.EXPECT().Set(0.00).Times(5)
tries := &Tries{
rootToTrie: make(map[common.Hash]*trie.Trie),
triesGauge: triesGauge,
}

bs := newTestBlockState(t, testGenesisHeader, tries)
bs := newTestBlockState(t, testGenesisHeader, newTriesEmpty())
AddBlocksToState(t, bs, 5, false)

btBefore := bs.bt.DeepCopy()
Expand Down Expand Up @@ -482,14 +479,7 @@ func TestAddBlockToBlockTree(t *testing.T) {
}

func TestNumberIsFinalised(t *testing.T) {
ctrl := gomock.NewController(t)

triesGauge := NewMockGauge(ctrl)
triesGauge.EXPECT().Set(0.00).Times(2)
tries := &Tries{
rootToTrie: make(map[common.Hash]*trie.Trie),
triesGauge: triesGauge,
}
qdm12 marked this conversation as resolved.
Show resolved Hide resolved
tries := newTriesEmpty()

bs := newTestBlockState(t, testGenesisHeader, tries)
fin, err := bs.NumberIsFinalised(big.NewInt(0))
Expand Down
5 changes: 4 additions & 1 deletion dot/state/helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ import (

func newTriesEmpty() *Tries {
return &Tries{
rootToTrie: make(map[common.Hash]*trie.Trie),
rootToTrie: make(map[common.Hash]*trie.Trie),
triesGauge: triesGauge,
setCounter: setCounter,
deleteCounter: deleteCounter,
}
}

Expand Down
37 changes: 3 additions & 34 deletions dot/state/storage_notify_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,12 @@ import (

"github.com/ChainSafe/chaindb"
"github.com/ChainSafe/gossamer/lib/common"
"github.com/ChainSafe/gossamer/lib/trie"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
)

func TestStorageState_RegisterStorageObserver(t *testing.T) {
ctrl := gomock.NewController(t)

triesGauge := NewMockGauge(ctrl)
triesGauge.EXPECT().Inc().Times(2)
tries := &Tries{
rootToTrie: make(map[common.Hash]*trie.Trie),
triesGauge: triesGauge,
}

ss := newTestStorageState(t, tries)
ss := newTestStorageState(t, newTriesEmpty())

ts, err := ss.TrieState(nil)
require.NoError(t, err)
Expand Down Expand Up @@ -64,16 +53,7 @@ func TestStorageState_RegisterStorageObserver(t *testing.T) {
}

func TestStorageState_RegisterStorageObserver_Multi(t *testing.T) {
ctrl := gomock.NewController(t)

triesGauge := NewMockGauge(ctrl)
triesGauge.EXPECT().Inc().Times(2)
tries := &Tries{
rootToTrie: make(map[common.Hash]*trie.Trie),
triesGauge: triesGauge,
}

ss := newTestStorageState(t, tries)
ss := newTestStorageState(t, newTriesEmpty())
ts, err := ss.TrieState(nil)
require.NoError(t, err)

Expand Down Expand Up @@ -125,18 +105,7 @@ func TestStorageState_RegisterStorageObserver_Multi(t *testing.T) {

func TestStorageState_RegisterStorageObserver_Multi_Filter(t *testing.T) {
t.Skip() // this seems to fail often on CI
ctrl := gomock.NewController(t)

triesGauge := NewMockGauge(ctrl)
// TODO restrict those mock calls once test is fixed.
triesGauge.EXPECT().Inc().AnyTimes()
triesGauge.EXPECT().Set(gomock.Any()).AnyTimes()
tries := &Tries{
rootToTrie: make(map[common.Hash]*trie.Trie),
triesGauge: triesGauge,
}

ss := newTestStorageState(t, tries)
ss := newTestStorageState(t, newTriesEmpty())
ts, err := ss.TrieState(nil)
require.NoError(t, err)

Expand Down
Loading