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

Consumer Unbonding As Param #410

Merged
merged 7 commits into from
Oct 28, 2022
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions proto/interchain_security/ccv/consumer/v1/consumer.proto
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ message Params {
// This param is a part of the cosmos sdk staking module. In the case of
// a ccv enabled consumer chain, the ccv module acts as the staking module.
int64 historical_entries = 8;

// Unbonding period for the consumer,
// which should be smaller than that of the provider in general.
google.protobuf.Duration unbonding_period = 9
[(gogoproto.nullable) = false, (gogoproto.stdduration) = true];
}

// LastTransmissionBlockHeight is the last time validator holding
Expand Down
15 changes: 9 additions & 6 deletions tests/difference/core/driver/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,7 @@ func (b *Builder) createConsumerGenesis(tmConfig *ibctesting.TendermintConfig) *
consumertypes.DefaultTransferTimeoutPeriod,
consumertypes.DefaultConsumerRedistributeFrac,
consumertypes.DefaultHistoricalEntries,
consumertypes.DefaultConsumerUnbondingPeriod,
)
return consumertypes.NewInitialGenesisState(providerClient, providerConsState, valUpdates, consumertypes.SlashRequests{}, params)
}
Expand Down Expand Up @@ -516,9 +517,7 @@ func (b *Builder) doIBCHandshake() {

// Configure and create the consumer Client
tmConfig := b.path.EndpointB.ClientConfig.(*ibctesting.TendermintConfig)
// TODO: This is intentionally set to unbonding period for P (provider)
// TODO: Not sure why it breaks without this.
tmConfig.UnbondingPeriod = b.initState.UnbondingP
tmConfig.UnbondingPeriod = b.initState.UnbondingC
tmConfig.TrustingPeriod = b.initState.Trusting
tmConfig.MaxClockDrift = b.initState.MaxClockDrift
err = b.path.EndpointB.CreateClient()
Expand Down Expand Up @@ -696,12 +695,12 @@ func (b *Builder) build() {
// Create a simulated network link link
b.createLink()

// Set the unbonding time on the consumer to the model value
b.consumerKeeper().SetUnbondingPeriod(b.ctx(C), b.initState.UnbondingC)

// Establish connection, channel
b.doIBCHandshake()

// Set the unbonding time on the consumer to the model value
b.consumerKeeper().SetUnbondingTime(b.ctx(C), b.initState.UnbondingC)

// Send an empty VSC packet from the provider to the consumer to finish
// the handshake. This is necessary because the model starts from a
// completely initialized state, with a completed handshake.
Expand Down Expand Up @@ -756,6 +755,10 @@ func (b *Builder) build() {
b.updateClient(b.chainID(C))
}

// The state of the data returned is equivalent to the state of two chains
// after a full handshake, but the precise order of steps used to reach the
// state does not necessarily mimic the order of steps that happen in a
// live scenario.
func GetZeroState(suite *suite.Suite, initState InitState) (
*ibctesting.Path, []sdk.ValAddress, int64, int64) {
b := Builder{initState: initState, suite: suite}
Expand Down
3 changes: 1 addition & 2 deletions tests/e2e/channel_init.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,7 @@ func (suite *CCVTestSuite) TestConsumerGenesis() {
providerChannel := suite.path.EndpointA.ChannelID
suite.Require().Equal(providerChannel, restartGenesis.ProviderChannelId)
maturityTime := consumerKeeper.GetPacketMaturityTime(suite.consumerChain.GetContext(), 1)
unbondingPeriod, found := consumerKeeper.GetUnbondingTime(suite.consumerCtx())
suite.Require().True(found)
unbondingPeriod := consumerKeeper.GetUnbondingPeriod(suite.consumerCtx())
suite.Require().Equal(uint64(origTime.Add(unbondingPeriod).UnixNano()), maturityTime, "maturity time is not set correctly in genesis")

suite.Require().NotPanics(func() {
Expand Down
6 changes: 2 additions & 4 deletions tests/e2e/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,7 @@ func relayAllCommittedPackets(
func incrementTimeByUnbondingPeriod(s *CCVTestSuite, chainType ChainType) {
// Get unboding period from staking keeper
providerUnbondingPeriod := s.providerApp.GetStakingKeeper().UnbondingTime(s.providerCtx())
consumerUnbondingPeriod, found := s.consumerApp.GetConsumerKeeper().GetUnbondingTime(s.consumerCtx())
s.Require().True(found)
consumerUnbondingPeriod := s.consumerApp.GetConsumerKeeper().GetUnbondingPeriod(s.consumerCtx())
expectedUnbondingPeriod := utils.ComputeConsumerUnbondingPeriod(providerUnbondingPeriod)
s.Require().Equal(expectedUnbondingPeriod+24*time.Hour, providerUnbondingPeriod, "unexpected provider unbonding period")
s.Require().Equal(expectedUnbondingPeriod, consumerUnbondingPeriod, "unexpected consumer unbonding period")
Expand Down Expand Up @@ -330,8 +329,7 @@ func (suite *CCVTestSuite) commitSlashPacket(ctx sdk.Context, packetData ccv.Sla
// incrementTimeBy increments the overall time by jumpPeriod
func incrementTimeBy(s *CCVTestSuite, jumpPeriod time.Duration) {
// Get unboding period from staking keeper
consumerUnbondingPeriod, found := s.consumerApp.GetConsumerKeeper().GetUnbondingTime(s.consumerChain.GetContext())
s.Require().True(found)
consumerUnbondingPeriod := s.consumerApp.GetConsumerKeeper().GetUnbondingPeriod(s.consumerChain.GetContext())
split := 1
trustingPeriodFraction := s.providerApp.GetProviderKeeper().GetTrustingPeriodFraction(s.providerCtx())
if jumpPeriod > consumerUnbondingPeriod/time.Duration(trustingPeriodFraction) {
Expand Down
3 changes: 1 addition & 2 deletions tests/e2e/valset_update.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,7 @@ func (suite *CCVTestSuite) TestSendVSCMaturedPackets() {
suite.Require().True(ack.Success(), "OnRecvVSCPacket did not return a Success Acknowledgment")

// increase time such that first two packets are unbonded but third is not.
unbondingPeriod, found := consumerKeeper.GetUnbondingTime(suite.consumerChain.GetContext())
suite.Require().True(found)
unbondingPeriod := consumerKeeper.GetUnbondingPeriod(suite.consumerChain.GetContext())
// increase time
incrementTimeBy(suite, unbondingPeriod-time.Hour)

Expand Down
3 changes: 0 additions & 3 deletions testutil/keeper/expectations.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@ func GetMocksForCreateConsumerClient(ctx sdk.Context, mocks *MockedKeepers,
expectedChainID string, expectedLatestHeight clienttypes.Height) []*gomock.Call {

expectations := []*gomock.Call{
mocks.MockStakingKeeper.EXPECT().UnbondingTime(ctx).Return(time.Hour).Times(
1, // called once in CreateConsumerClient
),

mocks.MockClientKeeper.EXPECT().CreateClient(
ctx,
Expand Down
18 changes: 0 additions & 18 deletions x/ccv/consumer/keeper/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"github.com/cosmos/interchain-security/x/ccv/consumer/types"
consumertypes "github.com/cosmos/interchain-security/x/ccv/consumer/types"
ccv "github.com/cosmos/interchain-security/x/ccv/types"
utils "github.com/cosmos/interchain-security/x/ccv/utils"

abci "github.com/tendermint/tendermint/abci/types"
tmtypes "github.com/tendermint/tendermint/types"
Expand Down Expand Up @@ -45,10 +44,6 @@ func (k Keeper) InitGenesis(ctx sdk.Context, state *consumertypes.GenesisState)
panic(err)
}

// Set the unbonding period: use the unbonding period on the provider to
shaspitz marked this conversation as resolved.
Show resolved Hide resolved
// compute the unbonding period on the consumer
unbondingTime := utils.ComputeConsumerUnbondingPeriod(state.ProviderClientState.UnbondingPeriod)
shaspitz marked this conversation as resolved.
Show resolved Hide resolved
k.SetUnbondingTime(ctx, unbondingTime)
// Set default value for valset update ID
k.SetHeightValsetUpdateID(ctx, uint64(ctx.BlockHeight()), uint64(0))
// set provider client id.
Expand Down Expand Up @@ -77,19 +72,6 @@ func (k Keeper) InitGenesis(ctx sdk.Context, state *consumertypes.GenesisState)
panic("initial validator set does not match last consensus state of the provider client")
}

// Set the unbonding period: use the unbonding period on the provider to
// compute the unbonding period on the consumer
clientState, ok := k.clientKeeper.GetClientState(ctx, state.ProviderClientId)
if !ok {
panic("client state for provider client not found. MUST run IBC genesis before CCV consumer genesis")
}
tmClientState, ok := clientState.(*ibctmtypes.ClientState)
if !ok {
panic(fmt.Sprintf("client state has wrong type. expected: %T, got: %T", &ibctmtypes.ClientState{}, clientState))
}
unbondingTime := utils.ComputeConsumerUnbondingPeriod(tmClientState.UnbondingPeriod)
k.SetUnbondingTime(ctx, unbondingTime)

// set height to valset update id mapping
for _, h2v := range state.HeightToValsetUpdateId {
k.SetHeightValsetUpdateID(ctx, h2v.Height, h2v.ValsetUpdateId)
Expand Down
13 changes: 6 additions & 7 deletions x/ccv/consumer/keeper/genesis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ func TestInitGenesis(t *testing.T) {
consumertypes.DefaultTransferTimeoutPeriod,
consumertypes.DefaultConsumerRedistributeFrac,
consumertypes.DefaultHistoricalEntries,
consumertypes.DefaultConsumerUnbondingPeriod,
)

testCases := []struct {
Expand All @@ -81,9 +82,8 @@ func TestInitGenesis(t *testing.T) {
require.Equal(t, gs.Params, ck.GetParams(ctx))
require.Equal(t, ccv.ConsumerPortID, ck.GetPort(ctx))

ubdTime, found := ck.GetUnbondingTime(ctx)
require.True(t, found)
require.Equal(t, gs.ProviderClientState.UnbondingPeriod, ubdTime)
ubdPeriod := ck.GetUnbondingPeriod(ctx)
require.Equal(t, consumertypes.DefaultConsumerUnbondingPeriod, ubdPeriod)

require.Zero(t, ck.GetHeightValsetUpdateID(ctx, uint64(ctx.BlockHeight())))

Expand All @@ -97,7 +97,6 @@ func TestInitGenesis(t *testing.T) {
gomock.InOrder(
expectGetCapabilityMock(ctx, mocks),
expectLatestConsensusStateMock(ctx, mocks, clientID, validator),
expectGetClientStateMock(ctx, mocks, "", clientID),
)
},
genesis: consumertypes.NewRestartGenesisState(clientID, channelID,
Expand All @@ -111,9 +110,8 @@ func TestInitGenesis(t *testing.T) {
require.Equal(t, gs.Params, ck.GetParams(ctx))
require.Equal(t, ccv.ConsumerPortID, ck.GetPort(ctx))

ubdTime, found := ck.GetUnbondingTime(ctx)
require.True(t, found)
require.Equal(t, testutil.GetClientState("").UnbondingPeriod, ubdTime)
ubdPeriod := ck.GetUnbondingPeriod(ctx)
require.Equal(t, consumertypes.DefaultConsumerUnbondingPeriod, ubdPeriod)

// export states to genesis
require.Equal(t, matPacket.VscId, ck.GetHeightValsetUpdateID(ctx, uint64(0)))
Expand Down Expand Up @@ -169,6 +167,7 @@ func TestExportGenesis(t *testing.T) {
consumertypes.DefaultTransferTimeoutPeriod,
consumertypes.DefaultConsumerRedistributeFrac,
consumertypes.DefaultHistoricalEntries,
consumertypes.DefaultConsumerUnbondingPeriod,
)

// create a single validator
Expand Down
25 changes: 0 additions & 25 deletions x/ccv/consumer/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package keeper
import (
"encoding/binary"
"fmt"
"time"

"github.com/cosmos/cosmos-sdk/codec"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
Expand Down Expand Up @@ -136,30 +135,6 @@ func (k Keeper) ClaimCapability(ctx sdk.Context, cap *capabilitytypes.Capability
return k.scopedKeeper.ClaimCapability(ctx, cap, name)
}

// SetUnbondingTime sets the unbonding period of the consumer chain
func (k Keeper) SetUnbondingTime(ctx sdk.Context, unbondingTime time.Duration) {
store := ctx.KVStore(k.storeKey)
timeBytes := make([]byte, 8)
binary.BigEndian.PutUint64(timeBytes, uint64(unbondingTime.Nanoseconds()))
store.Set(types.UnbondingTimeKey(), timeBytes)
}

// GetUnbondingTime gets the unbonding period of the consumer chain
func (k Keeper) GetUnbondingTime(ctx sdk.Context) (time.Duration, bool) {
store := ctx.KVStore(k.storeKey)
bz := store.Get(types.UnbondingTimeKey())
if bz == nil {
return 0, false
}
return time.Duration(binary.BigEndian.Uint64(bz)), true
}

// DeleteUnbondingTime deletes the unbonding period of the consumer chain
func (k Keeper) DeleteUnbondingTime(ctx sdk.Context) {
store := ctx.KVStore(k.storeKey)
store.Delete(types.UnbondingTimeKey())
}

// SetProviderClientID sets the clientID for the client to the provider.
// Set in InitGenesis
func (k Keeper) SetProviderClientID(ctx sdk.Context, clientID string) {
Expand Down
17 changes: 9 additions & 8 deletions x/ccv/consumer/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
conntypes "github.com/cosmos/ibc-go/v3/modules/core/03-connection/types"
testkeeper "github.com/cosmos/interchain-security/testutil/keeper"
"github.com/cosmos/interchain-security/x/ccv/consumer/types"
consumertypes "github.com/cosmos/interchain-security/x/ccv/consumer/types"
ccv "github.com/cosmos/interchain-security/x/ccv/types"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/require"
Expand All @@ -17,19 +18,19 @@ import (
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
)

// TestUnbondingTime tests getter and setter functionality for the unbonding period of a consumer chain
// TestUnbondingTime tests the getter and setter for the unbonding period of a consumer chain,
func TestUnbondingTime(t *testing.T) {

consumerKeeper, ctx, ctrl, _ := testkeeper.GetConsumerKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t))
defer ctrl.Finish()
consumerKeeper.SetParams(ctx, consumertypes.DefaultParams())

_, ok := consumerKeeper.GetUnbondingTime(ctx)
require.False(t, ok)
unbondingPeriod := time.Hour * 24 * 7 * 3
consumerKeeper.SetUnbondingTime(ctx, unbondingPeriod)
storedUnbondingPeriod, ok := consumerKeeper.GetUnbondingTime(ctx)
require.True(t, ok)
require.Equal(t, storedUnbondingPeriod, unbondingPeriod)
ubdTime := consumerKeeper.GetUnbondingPeriod(ctx)
require.Equal(t, consumertypes.DefaultConsumerUnbondingPeriod, ubdTime)

consumerKeeper.SetUnbondingPeriod(ctx, time.Hour*24*10)
storedUnbondingPeriod := consumerKeeper.GetUnbondingPeriod(ctx)
require.Equal(t, time.Hour*24*10, storedUnbondingPeriod)
}
shaspitz marked this conversation as resolved.
Show resolved Hide resolved

// TestProviderClientID tests getter and setter functionality for the client ID stored on consumer keeper
Expand Down
12 changes: 12 additions & 0 deletions x/ccv/consumer/keeper/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ func (k Keeper) GetParams(ctx sdk.Context) types.Params {
k.GetTransferTimeoutPeriod(ctx),
k.GetConsumerRedistributionFrac(ctx),
k.GetHistoricalEntries(ctx),
k.GetUnbondingPeriod(ctx),
)
}

Expand Down Expand Up @@ -94,3 +95,14 @@ func (k Keeper) GetHistoricalEntries(ctx sdk.Context) int64 {
k.paramStore.Get(ctx, types.KeyHistoricalEntries, &n)
return n
}

// Only used to set an unbonding period in diff tests
func (k Keeper) SetUnbondingPeriod(ctx sdk.Context, period time.Duration) {
k.paramStore.Set(ctx, types.KeyConsumerUnbondingPeriod, period)
}

func (k Keeper) GetUnbondingPeriod(ctx sdk.Context) time.Duration {
var period time.Duration
k.paramStore.Get(ctx, types.KeyConsumerUnbondingPeriod, &period)
return period
}
4 changes: 3 additions & 1 deletion x/ccv/consumer/keeper/params_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,15 @@ func TestParams(t *testing.T) {
consumertypes.DefaultTransferTimeoutPeriod,
consumertypes.DefaultConsumerRedistributeFrac,
consumertypes.DefaultHistoricalEntries,
consumertypes.DefaultConsumerUnbondingPeriod,
) // these are the default params, IBC suite independently sets enabled=true

params := consumerKeeper.GetParams(ctx)
require.Equal(t, expParams, params)

newParams := types.NewParams(false, 1000,
"channel-2", "cosmos19pe9pg5dv9k5fzgzmsrgnw9rl9asf7ddwhu7lm", 7*24*time.Hour, 25*time.Hour, "0.5", 500)
"channel-2", "cosmos19pe9pg5dv9k5fzgzmsrgnw9rl9asf7ddwhu7lm",
7*24*time.Hour, 25*time.Hour, "0.5", 500, 24*21*time.Hour)
consumerKeeper.SetParams(ctx, newParams)
params = consumerKeeper.GetParams(ctx)
require.Equal(t, newParams, params)
Expand Down
6 changes: 1 addition & 5 deletions x/ccv/consumer/keeper/relay.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,7 @@ func (k Keeper) OnRecvVSCPacket(ctx sdk.Context, packet channeltypes.Packet, new
}

// Save maturity time and packet
unbondingPeriod, found := k.GetUnbondingTime(ctx)
if !found {
panic("the unbonding period is not set on the consumer chain")
}
maturityTime := ctx.BlockTime().Add(unbondingPeriod)
maturityTime := ctx.BlockTime().Add(k.GetUnbondingPeriod(ctx))
k.SetPacketMaturityTime(ctx, newChanges.ValsetUpdateId, uint64(maturityTime.UnixNano()))

// set height to VSC id mapping
Expand Down
11 changes: 7 additions & 4 deletions x/ccv/consumer/keeper/relay_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
channeltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types"
host "github.com/cosmos/ibc-go/v3/modules/core/24-host"
testkeeper "github.com/cosmos/interchain-security/testutil/keeper"
consumertypes "github.com/cosmos/interchain-security/x/ccv/consumer/types"
"github.com/cosmos/interchain-security/x/ccv/types"
ccv "github.com/cosmos/interchain-security/x/ccv/types"
"github.com/golang/mock/gomock"
Expand Down Expand Up @@ -114,7 +115,11 @@ func TestOnRecvVSCPacket(t *testing.T) {

// Set channel to provider, still in context of consumer chain
consumerKeeper.SetProviderChannel(ctx, consumerCCVChannelID)
consumerKeeper.SetUnbondingTime(ctx, 100*time.Hour)

// Set module params with custom unbonding period
moduleParams := consumertypes.DefaultParams()
moduleParams.UnbondingPeriod = 100 * time.Hour
consumerKeeper.SetParams(ctx, moduleParams)

for _, tc := range testCases {
ack := consumerKeeper.OnRecvVSCPacket(ctx, tc.packet, tc.newChanges)
Expand All @@ -138,9 +143,7 @@ func TestOnRecvVSCPacket(t *testing.T) {
})
require.Equal(t, tc.expectedPendingChanges, *actualPendingChanges, "pending changes not equal to expected changes after successful packet receive. case: %s", tc.name)

unbondingPeriod, found := consumerKeeper.GetUnbondingTime(ctx)
require.True(t, found)
expectedTime := uint64(ctx.BlockTime().Add(unbondingPeriod).UnixNano())
expectedTime := uint64(ctx.BlockTime().Add(consumerKeeper.GetUnbondingPeriod(ctx)).UnixNano())
maturityTime := consumerKeeper.GetPacketMaturityTime(ctx, tc.newChanges.ValsetUpdateId)
require.Equal(t, expectedTime, maturityTime, "packet maturity time has unexpected value for case: %s", tc.name)
}
Expand Down
8 changes: 2 additions & 6 deletions x/ccv/consumer/keeper/validators.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,13 +111,9 @@ func (k Keeper) MaxValidators(sdk.Context) uint32 {
panic("unimplemented on CCV keeper")
}

// UnbondingTime returns consumer unbonding time
// UnbondingTime returns consumer unbonding period, satisfying the staking keeper interface
func (k Keeper) UnbondingTime(ctx sdk.Context) time.Duration {
unbondingTime, found := k.GetUnbondingTime(ctx)
if !found {
panic("the consumer unbonding period is not set")
}
return unbondingTime
return k.GetUnbondingPeriod(ctx)
}

// GetHistoricalInfo gets the historical info at a given height
Expand Down
Loading