Skip to content

Commit

Permalink
added a test illustrating the problem
Browse files Browse the repository at this point in the history
  • Loading branch information
ivan-gavran committed Nov 24, 2022
1 parent 6c0d718 commit 9294f74
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 0 deletions.
45 changes: 45 additions & 0 deletions x/ccv/provider/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,51 @@ func TestMaturedUnbondingOps(t *testing.T) {
}
}

func TestChainIdsToRemove(t *testing.T) {
providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t))
defer ctrl.Finish()

// in the first scenario, chains D and E are expired (their expected time is smaller than the reference time)
// This indeed happens as expected because the chainID of the chain which is not expired is alphabetically
// after "D" and "E"
tc_active_first_alphabetically := []struct {
chainID string
expected uint64
}{
{expected: 1, chainID: "D"},
{expected: 1, chainID: "E"},
{expected: 5, chainID: "F"},
}
referenceTime := 2

for _, test := range tc_active_first_alphabetically {
providerKeeper.SetInitTimeoutTimestamp(ctx, test.chainID, test.expected)
}
to_remove := providerKeeper.GetChainIdsToRemove(ctx, uint64(referenceTime))

require.Equal(t, []string{"D", "E"}, to_remove)

// in the second scenario, we add another chain with id "A" (so, alphabetically before all existing chains)
// and we increase the reference time so that "A" is only chain that should not expired.
// However, none of them expires (because the function breaks prematurely as soon as the first non-expired
// chain is found)
tc_active_last_alphabetically := []struct {
chainID string
expected uint64
}{
{expected: 10, chainID: "A"},
}

for _, test := range tc_active_last_alphabetically {
providerKeeper.SetInitTimeoutTimestamp(ctx, test.chainID, test.expected)
}
referenceTime = 6
to_remove = providerKeeper.GetChainIdsToRemove(ctx, uint64(referenceTime))

require.Equal(t, []string{"D", "E", "F"}, to_remove)

}

func TestInitTimeoutTimestamp(t *testing.T) {
providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t))
defer ctrl.Finish()
Expand Down
17 changes: 17 additions & 0 deletions x/ccv/provider/keeper/relay.go
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,22 @@ func (k Keeper) HandleSlashPacket(ctx sdk.Context, chainID string, data ccv.Slas
return true, nil
}

func (k Keeper) GetChainIdsToRemove(ctx sdk.Context, referenceTime uint64) []string {
var chainIdsToRemove []string
k.IterateInitTimeoutTimestamp(ctx, func(chainID string, ts uint64) bool {
if referenceTime > ts {
// initTimeout expired
chainIdsToRemove = append(chainIdsToRemove, chainID)
// continue to iterate through all timed out consumers
return true
}
// break iteration since the timeout timestamps are in order
return false
})

return chainIdsToRemove
}

// EndBlockCIS contains the EndBlock logic needed for
// the Consumer Chain Removal sub-protocol
func (k Keeper) EndBlockCCR(ctx sdk.Context) {
Expand All @@ -324,6 +340,7 @@ func (k Keeper) EndBlockCCR(ctx sdk.Context) {
// break iteration since the timeout timestamps are in order
return false
})

// remove consumers that timed out
for _, chainID := range chainIdsToRemove {
// stop the consumer chain and unlock the unbonding.
Expand Down

0 comments on commit 9294f74

Please sign in to comment.