-
Notifications
You must be signed in to change notification settings - Fork 138
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
simplify consumer addition and removal propsal handling #460
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,20 +20,9 @@ import ( | |
) | ||
|
||
// HandleConsumerAdditionProposal will receive the consumer chain's client state from the proposal. | ||
// If the spawn time has already passed, then set the consumer chain. Otherwise store the client | ||
// as a pending client, and set once spawn time has passed. | ||
// | ||
// Note: This method implements SpawnConsumerChainProposalHandler in spec. | ||
// See: https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/methods.md#ccv-pcf-spccprop1 | ||
// Spec tag: [CCV-PCF-SPCCPROP.1] | ||
// The proposal is stored into state and if spawn time has passed the client will be created set in the next BeginBlocker. | ||
func (k Keeper) HandleConsumerAdditionProposal(ctx sdk.Context, p *types.ConsumerAdditionProposal) error { | ||
if !ctx.BlockTime().Before(p.SpawnTime) { | ||
// lockUbdOnTimeout is set to be false, regardless of what the proposal says, until we can specify and test issues around this use case more thoroughly | ||
return k.CreateConsumerClient(ctx, p.ChainId, p.InitialHeight, false) | ||
} | ||
|
||
err := k.SetPendingConsumerAdditionProp(ctx, p) | ||
if err != nil { | ||
if err := k.SetPendingConsumerAdditionProp(ctx, p); err != nil { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should be a little careful about the error semantics because the err is used in the gov module when the proposal is submitted. See #463 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure what you mean? The behaviour is the same with regards to error handling. |
||
return err | ||
} | ||
|
||
|
@@ -99,16 +88,8 @@ func (k Keeper) CreateConsumerClient(ctx sdk.Context, chainID string, | |
|
||
// HandleConsumerRemovalProposal stops a consumer chain and released the outstanding unbonding operations. | ||
// If the stop time hasn't already passed, it stores the proposal as a pending proposal. | ||
// | ||
// This method implements StopConsumerChainProposalHandler from spec. | ||
// See: https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/methods.md#ccv-pcf-stccprop1 | ||
// Spec tag: [CCV-PCF-STCCPROP.1] | ||
// If the stop time has passed the proposal will be executed in BeginBlocker. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could consolidate comments on 90-91
|
||
func (k Keeper) HandleConsumerRemovalProposal(ctx sdk.Context, p *types.ConsumerRemovalProposal) error { | ||
|
||
if !ctx.BlockTime().Before(p.StopTime) { | ||
return k.StopConsumerChain(ctx, p.ChainId, false, true) | ||
} | ||
|
||
k.SetPendingConsumerRemovalProp(ctx, p.ChainId, p.StopTime) | ||
return nil | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,15 +29,15 @@ import ( | |
// Tests the HandleConsumerAdditionProposal method against the SpawnConsumerChainProposalHandler spec. | ||
// See: https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/methods.md#ccv-pcf-spccprop1 | ||
// Spec tag: [CCV-PCF-SPCCPROP.1] | ||
// | ||
// NOTE: immediate handling of proposals is not necessary - all proposals are executed in BeginBlock. | ||
func TestHandleConsumerAdditionProposal(t *testing.T) { | ||
|
||
type testCase struct { | ||
description string | ||
prop *providertypes.ConsumerAdditionProposal | ||
// Time when prop is handled | ||
blockTime time.Time | ||
// Whether it's expected that the spawn time has passed and client should be created | ||
expCreatedClient bool | ||
} | ||
|
||
// Snapshot times asserted in tests | ||
|
@@ -46,7 +46,7 @@ func TestHandleConsumerAdditionProposal(t *testing.T) { | |
|
||
tests := []testCase{ | ||
{ | ||
description: "ctx block time is after proposal's spawn time, expected that client is created", | ||
description: "ctx block time is after proposal's spawn time, expected that client is persisted as pending - execution is in BeginBlocker", | ||
prop: providertypes.NewConsumerAdditionProposal( | ||
"title", | ||
"description", | ||
|
@@ -56,8 +56,7 @@ func TestHandleConsumerAdditionProposal(t *testing.T) { | |
[]byte("bin_hash"), | ||
now, // Spawn time | ||
).(*providertypes.ConsumerAdditionProposal), | ||
blockTime: hourFromNow, | ||
expCreatedClient: true, | ||
blockTime: hourFromNow, | ||
}, | ||
{ | ||
description: `ctx block time is before proposal's spawn time, | ||
|
@@ -71,41 +70,29 @@ func TestHandleConsumerAdditionProposal(t *testing.T) { | |
[]byte("bin_hash"), | ||
hourFromNow, // Spawn time | ||
).(*types.ConsumerAdditionProposal), | ||
blockTime: now, | ||
expCreatedClient: false, | ||
blockTime: now, | ||
}, | ||
} | ||
|
||
for _, tc := range tests { | ||
// Common setup | ||
keeperParams := testkeeper.NewInMemKeeperParams(t) | ||
providerKeeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, keeperParams) | ||
providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, keeperParams) | ||
providerKeeper.SetParams(ctx, providertypes.DefaultParams()) | ||
ctx = ctx.WithBlockTime(tc.blockTime) | ||
|
||
if tc.expCreatedClient { | ||
// Mock calls are only asserted if we expect a client to be created. | ||
gomock.InOrder( | ||
testkeeper.GetMocksForCreateConsumerClient(ctx, &mocks, "chainID", clienttypes.NewHeight(2, 3))..., | ||
) | ||
} | ||
|
||
tc.prop.LockUnbondingOnTimeout = false // Full functionality not implemented yet. | ||
|
||
err := providerKeeper.HandleConsumerAdditionProposal(ctx, tc.prop) | ||
require.NoError(t, err) | ||
|
||
if tc.expCreatedClient { | ||
testCreatedConsumerClient(t, ctx, providerKeeper, tc.prop.ChainId, "clientID") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similiar to another comment, an equivalent check should probably be tested
|
||
} else { | ||
// check that stored pending prop is exactly the same as the initially instantiated prop | ||
gotProposal, found := providerKeeper.GetPendingConsumerAdditionProp(ctx, tc.prop.SpawnTime, tc.prop.ChainId) | ||
require.True(t, found) | ||
require.Equal(t, *tc.prop, gotProposal) | ||
// double check that a client for this chain does not exist | ||
_, found = providerKeeper.GetConsumerClientId(ctx, tc.prop.ChainId) | ||
require.False(t, found) | ||
} | ||
// check that stored pending prop is exactly the same as the initially instantiated prop | ||
gotProposal, found := providerKeeper.GetPendingConsumerAdditionProp(ctx, tc.prop.SpawnTime, tc.prop.ChainId) | ||
require.True(t, found) | ||
require.Equal(t, *tc.prop, gotProposal) | ||
// double check that a client for this chain does not exist | ||
_, found = providerKeeper.GetConsumerClientId(ctx, tc.prop.ChainId) | ||
require.False(t, found) | ||
ctrl.Finish() | ||
} | ||
} | ||
|
@@ -311,6 +298,8 @@ func TestPendingConsumerAdditionPropOrder(t *testing.T) { | |
// | ||
// See: https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/methods.md#ccv-pcf-stccprop1 | ||
// Spec tag: [CCV-PCF-STCCPROP.1] | ||
// | ||
// NOTE: immediate handling of proposals is not necessary - all proposals are executed in BeginBlock. | ||
func TestHandleConsumerRemovalProposal(t *testing.T) { | ||
|
||
type testCase struct { | ||
|
@@ -319,8 +308,6 @@ func TestHandleConsumerRemovalProposal(t *testing.T) { | |
prop *types.ConsumerRemovalProposal | ||
// Time when prop is handled | ||
blockTime time.Time | ||
// Whether consumer chain should have been stopped | ||
expStop bool | ||
} | ||
|
||
// Snapshot times asserted in tests | ||
|
@@ -337,7 +324,6 @@ func TestHandleConsumerRemovalProposal(t *testing.T) { | |
now, | ||
).(*providertypes.ConsumerRemovalProposal), | ||
blockTime: hourFromNow, // After stop time. | ||
expStop: true, | ||
}, | ||
{ | ||
description: "valid proposal: stop time has not yet been reached", | ||
|
@@ -348,39 +334,23 @@ func TestHandleConsumerRemovalProposal(t *testing.T) { | |
hourFromNow, | ||
).(*providertypes.ConsumerRemovalProposal), | ||
blockTime: now, // Before proposal's stop time | ||
expStop: false, | ||
}, | ||
} | ||
|
||
for _, tc := range tests { | ||
|
||
// Common setup | ||
keeperParams := testkeeper.NewInMemKeeperParams(t) | ||
providerKeeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, keeperParams) | ||
providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, keeperParams) | ||
providerKeeper.SetParams(ctx, providertypes.DefaultParams()) | ||
ctx = ctx.WithBlockTime(tc.blockTime) | ||
|
||
// Mock expectations and setup for stopping the consumer chain, if applicable | ||
if tc.expStop { | ||
testkeeper.SetupForStoppingConsumerChain(t, ctx, &providerKeeper, mocks) | ||
} | ||
// Note: when expStop is false, no mocks are setup, | ||
// meaning no external keeper methods are allowed to be called. | ||
|
||
err := providerKeeper.HandleConsumerRemovalProposal(ctx, tc.prop) | ||
require.NoError(t, err) | ||
|
||
if tc.expStop { | ||
// Expect no pending proposal to exist | ||
found := providerKeeper.GetPendingConsumerRemovalProp(ctx, tc.prop.ChainId, tc.prop.StopTime) | ||
require.False(t, found) | ||
|
||
testProviderStateIsCleaned(t, ctx, providerKeeper, tc.prop.ChainId, "channelID") | ||
Comment on lines
-375
to
-378
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In replacing these lines we want to maintain the same amount of coverage. Here the proposal actually was processed so
to check the same thing. |
||
} else { | ||
// Proposal should be stored as pending | ||
found := providerKeeper.GetPendingConsumerRemovalProp(ctx, tc.prop.ChainId, tc.prop.StopTime) | ||
require.True(t, found) | ||
} | ||
// Proposal should be stored as pending | ||
found := providerKeeper.GetPendingConsumerRemovalProp(ctx, tc.prop.ChainId, tc.prop.StopTime) | ||
require.True(t, found) | ||
|
||
// Assert mock calls from setup function | ||
ctrl.Finish() | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.