Skip to content

Commit

Permalink
additional tests
Browse files Browse the repository at this point in the history
  • Loading branch information
stana-miric committed Nov 21, 2024
1 parent 9fa5ec3 commit 973dbee
Show file tree
Hide file tree
Showing 2 changed files with 277 additions and 1 deletion.
216 changes: 216 additions & 0 deletions x/ccv/provider/keeper/infraction_parameters_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
package keeper_test

import (
"testing"
"time"

"cosmossdk.io/math"
testkeeper "github.com/cosmos/interchain-security/v6/testutil/keeper"
providertypes "github.com/cosmos/interchain-security/v6/x/ccv/provider/types"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/require"
)

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

consumerID := "consumer1"
initialParams := providertypes.InfractionParameters{
DoubleSign: &providertypes.SlashJailParameters{
JailDuration: 1000 * time.Second,
SlashFraction: math.LegacyNewDecWithPrec(4, 1),
},
Downtime: &providertypes.SlashJailParameters{
JailDuration: 500 * time.Second,
SlashFraction: math.LegacyNewDec(0),
},
}

// Set initial infraction parameters
require.NoError(t, k.SetInfractionParameters(ctx, consumerID, initialParams))

// Queue identical parameters
require.NoError(t, k.UpdateQueuedInfractionParams(ctx, consumerID, initialParams))

// Verify queue is empty
hasQueued := k.HasQueuedInfractionParameters(ctx, consumerID)
require.False(t, hasQueued)
}

func TestUpdateQueuedInfractionParams_UpdateDifferentItem(t *testing.T) {
k, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t))
defer ctrl.Finish()

mocks.MockStakingKeeper.EXPECT().UnbondingTime(ctx).Return(time.Second, nil).AnyTimes()

consumerID := "consumer2"
initialParams := providertypes.InfractionParameters{
DoubleSign: &providertypes.SlashJailParameters{
JailDuration: 1000 * time.Second,
SlashFraction: math.LegacyNewDecWithPrec(4, 1),
},
Downtime: &providertypes.SlashJailParameters{
JailDuration: 500 * time.Second,
SlashFraction: math.LegacyNewDec(0),
},
}
newParams := providertypes.InfractionParameters{
DoubleSign: &providertypes.SlashJailParameters{
JailDuration: 2000 * time.Second,
SlashFraction: math.LegacyNewDecWithPrec(5, 1),
},
Downtime: &providertypes.SlashJailParameters{
JailDuration: 1000 * time.Second,
SlashFraction: math.LegacyNewDec(1),
},
}

// Set initial infraction parameters
require.NoError(t, k.SetInfractionParameters(ctx, consumerID, initialParams))

// Queue different parameters
require.NoError(t, k.UpdateQueuedInfractionParams(ctx, consumerID, newParams))

// Verify queue has updated parameters
queuedParams, err := k.GetQueuedInfractionParameters(ctx, consumerID)
require.NoError(t, err)
require.Equal(t, newParams, queuedParams)
}

func TestUpdateQueuedInfractionParams_OnlyLastItemInQueue(t *testing.T) {
k, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t))
defer ctrl.Finish()

mocks.MockStakingKeeper.EXPECT().UnbondingTime(ctx).Return(time.Second, nil).AnyTimes()

initialParams := providertypes.InfractionParameters{
DoubleSign: &providertypes.SlashJailParameters{
JailDuration: 1000 * time.Second,
SlashFraction: math.LegacyNewDecWithPrec(4, 1),
},
Downtime: &providertypes.SlashJailParameters{
JailDuration: 500 * time.Second,
SlashFraction: math.LegacyNewDec(0),
},
}

consumerID := "consumer3"
paramsList := []providertypes.InfractionParameters{
{
DoubleSign: &providertypes.SlashJailParameters{
JailDuration: 1000 * time.Second,
SlashFraction: math.LegacyNewDecWithPrec(4, 1),
},
Downtime: &providertypes.SlashJailParameters{
JailDuration: 500 * time.Second,
SlashFraction: math.LegacyNewDec(0),
},
},
{
DoubleSign: &providertypes.SlashJailParameters{
JailDuration: 1500 * time.Second,
SlashFraction: math.LegacyNewDecWithPrec(3, 1),
},
Downtime: &providertypes.SlashJailParameters{
JailDuration: 600 * time.Second,
SlashFraction: math.LegacyNewDec(0),
},
},
}

// Set initial infraction parameters
require.NoError(t, k.SetInfractionParameters(ctx, consumerID, initialParams))

// Queue multiple parameters
for _, params := range paramsList {
require.NoError(t, k.UpdateQueuedInfractionParams(ctx, consumerID, params))
}

// Verify only the last one is kept in the queue
queuedParams, err := k.GetQueuedInfractionParameters(ctx, consumerID)
require.NoError(t, err)
require.Equal(t, paramsList[len(paramsList)-1], queuedParams)
}

func TestBeginBlockUpdateInfractionParameters_MixedTiming(t *testing.T) {
keeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t))
defer ctrl.Finish()

unbondingTime := time.Second
mocks.MockStakingKeeper.EXPECT().UnbondingTime(gomock.Any()).Return(unbondingTime, nil).AnyTimes()

// Define old and new InfractionParameters
oldInfractionParams := providertypes.InfractionParameters{
DoubleSign: &providertypes.SlashJailParameters{
JailDuration: 1000 * time.Second,
SlashFraction: math.LegacyNewDecWithPrec(4, 1), // 0.4
},
Downtime: &providertypes.SlashJailParameters{
JailDuration: 500 * time.Second,
SlashFraction: math.LegacyNewDec(0),
},
}
newInfractionParams := providertypes.InfractionParameters{
DoubleSign: &providertypes.SlashJailParameters{
JailDuration: 1200 * time.Second,
SlashFraction: math.LegacyNewDecWithPrec(5, 1), // 0.5
},
Downtime: &providertypes.SlashJailParameters{
JailDuration: 600 * time.Second,
SlashFraction: math.LegacyNewDecWithPrec(1, 1), // 0.1
},
}

// Define consumers
consumerIds := []string{"consumer1", "consumer2", "consumer3", "consumer4"}

// Set old infraction parameters for all consumers
for _, consumerId := range consumerIds {
err := keeper.SetInfractionParameters(ctx, consumerId, oldInfractionParams)
require.NoError(t, err)
}

// Create contexts for different time scenarios
currentTime := ctx.BlockTime()
ctxWithTimeBefore := ctx.WithBlockTime(currentTime.Add(-2 * unbondingTime))
ctxWithTimeAfter := ctx.WithBlockTime(currentTime.Add(2 * unbondingTime))

// Queue updates for consumers
err := keeper.UpdateQueuedInfractionParams(ctxWithTimeBefore, "consumer1", newInfractionParams)
require.NoError(t, err)
err = keeper.UpdateQueuedInfractionParams(ctxWithTimeBefore, "consumer2", newInfractionParams)
require.NoError(t, err)
err = keeper.UpdateQueuedInfractionParams(ctxWithTimeAfter, "consumer3", newInfractionParams)
require.NoError(t, err)
err = keeper.UpdateQueuedInfractionParams(ctxWithTimeAfter, "consumer4", newInfractionParams)
require.NoError(t, err)

// Call BeginBlockUpdateInfractionParameters with current context
err = keeper.BeginBlockUpdateInfractionParameters(ctx)
require.NoError(t, err)

// Confirm queue state
require.True(t, keeper.HasQueuedInfractionParameters(ctx, "consumer3"))
require.True(t, keeper.HasQueuedInfractionParameters(ctx, "consumer4"))
require.False(t, keeper.HasQueuedInfractionParameters(ctx, "consumer1"))
require.False(t, keeper.HasQueuedInfractionParameters(ctx, "consumer2"))

// Confirm infraction parameters are updated for consumer1 and consumer2
params1, err := keeper.GetInfractionParameters(ctx, "consumer1")
require.NoError(t, err)
require.Equal(t, params1, newInfractionParams)

params2, err := keeper.GetInfractionParameters(ctx, "consumer2")
require.NoError(t, err)
require.Equal(t, params2, newInfractionParams)

// Confirm infraction parameters are not updated for consumer3 and consumer4
params3, err := keeper.GetInfractionParameters(ctx, "consumer3")
require.NoError(t, err)
require.Equal(t, params3, oldInfractionParams)

params4, err := keeper.GetInfractionParameters(ctx, "consumer4")
require.NoError(t, err)
require.Equal(t, params4, oldInfractionParams)
}
62 changes: 61 additions & 1 deletion x/ccv/provider/keeper/msg_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import (
"testing"
"time"

"cosmossdk.io/math"
"github.com/cosmos/ibc-go/v8/modules/core/02-client/types"
"github.com/golang/mock/gomock"

"github.com/stretchr/testify/require"

Expand All @@ -16,9 +18,12 @@ import (
)

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

mocks.MockSlashingKeeper.EXPECT().DowntimeJailDuration(gomock.Any()).Return(time.Second*600, nil).AnyTimes()
mocks.MockSlashingKeeper.EXPECT().SlashFractionDoubleSign(gomock.Any()).Return(math.LegacyNewDec(0), nil).AnyTimes()

msgServer := providerkeeper.NewMsgServerImpl(&providerKeeper)

consumerMetadata := providertypes.ConsumerMetadata{
Expand All @@ -41,6 +46,11 @@ func TestCreateConsumer(t *testing.T) {
require.Equal(t, "submitter", ownerAddress)
phase := providerKeeper.GetConsumerPhase(ctx, "0")
require.Equal(t, providertypes.CONSUMER_PHASE_REGISTERED, phase)
infractionParam, err := providerKeeper.GetInfractionParameters(ctx, response.ConsumerId)
require.NoError(t, err)
expectedInfractionParameters, err := providertypes.DefaultConsumerInfractionParameters(ctx, mocks.MockSlashingKeeper)
require.NoError(t, err)
require.Equal(t, expectedInfractionParameters, infractionParam)

consumerMetadata = providertypes.ConsumerMetadata{
Name: "chain name",
Expand Down Expand Up @@ -69,6 +79,11 @@ func TestUpdateConsumer(t *testing.T) {
providerKeeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t))
defer ctrl.Finish()

mocks.MockSlashingKeeper.EXPECT().DowntimeJailDuration(gomock.Any()).Return(time.Second*600, nil).AnyTimes()
mocks.MockSlashingKeeper.EXPECT().SlashFractionDoubleSign(gomock.Any()).Return(math.LegacyNewDec(0), nil).AnyTimes()
unbondingTime := 2 * time.Second
mocks.MockStakingKeeper.EXPECT().UnbondingTime(gomock.Any()).Return(unbondingTime, nil).AnyTimes()

msgServer := providerkeeper.NewMsgServerImpl(&providerKeeper)

// try to update a non-existing (i.e., no consumer id exists)
Expand Down Expand Up @@ -142,6 +157,16 @@ func TestUpdateConsumer(t *testing.T) {
expectedInitializationParameters := testkeeper.GetTestInitializationParameters()
expectedInitializationParameters.InitialHeight.RevisionNumber = 1
expectedPowerShapingParameters := testkeeper.GetTestPowerShapingParameters()
expectedInfractionParameters := providertypes.InfractionParameters{
DoubleSign: &providertypes.SlashJailParameters{
JailDuration: 1000 * time.Second,
SlashFraction: math.LegacyNewDecWithPrec(4, 1), // 0.4
},
Downtime: &providertypes.SlashJailParameters{
JailDuration: 500 * time.Second,
SlashFraction: math.LegacyNewDec(0),
},
}

expectedOwnerAddress := "cosmos1dkas8mu4kyhl5jrh4nzvm65qz588hy9qcz08la"
expectedChainId = "updatedChainId-1"
Expand All @@ -151,6 +176,7 @@ func TestUpdateConsumer(t *testing.T) {
Metadata: &expectedConsumerMetadata,
InitializationParameters: &expectedInitializationParameters,
PowerShapingParameters: &expectedPowerShapingParameters,
InfractionParameters: &expectedInfractionParameters,
NewChainId: expectedChainId,
})
require.NoError(t, err)
Expand All @@ -175,6 +201,11 @@ func TestUpdateConsumer(t *testing.T) {
require.NoError(t, err)
require.Equal(t, expectedPowerShapingParameters, actualPowerShapingParameters)

// assert that infraction parameters were updated
actualInfractionParameters, err := providerKeeper.GetInfractionParameters(ctx, consumerId)
require.NoError(t, err)
require.Equal(t, expectedInfractionParameters, actualInfractionParameters)

// assert that the chain id has been updated
actualChainId, err := providerKeeper.GetConsumerChainId(ctx, consumerId)
require.NoError(t, err)
Expand Down Expand Up @@ -282,6 +313,35 @@ func TestUpdateConsumer(t *testing.T) {
require.NoError(t, err)
require.Equal(t, expectedPowerShapingParameters, actualPowerShapingParameters)

// assert that we can update the infraction parameters of a launched chain
providerKeeper.SetConsumerPhase(ctx, consumerId, providertypes.CONSUMER_PHASE_LAUNCHED)
newExpectedInfractionParameters := providertypes.InfractionParameters{
DoubleSign: &providertypes.SlashJailParameters{
JailDuration: 2000 * time.Second,
SlashFraction: math.LegacyNewDecWithPrec(6, 1), // 0.6
},
Downtime: &providertypes.SlashJailParameters{
JailDuration: 1000 * time.Second,
SlashFraction: math.LegacyNewDecWithPrec(2, 1),
},
}
_, err = msgServer.UpdateConsumer(ctx,
&providertypes.MsgUpdateConsumer{
Owner: expectedOwnerAddress, ConsumerId: consumerId,
Metadata: nil,
InitializationParameters: nil,
PowerShapingParameters: nil,
InfractionParameters: &newExpectedInfractionParameters,
})
require.NoError(t, err)
// infraction parameters are queued and not updated yet to newExpectedInfractionParameters since the chain is launched
require.Equal(t, expectedInfractionParameters, actualInfractionParameters)
// trigger update of queud infraction params after unbonding time is passed
providerKeeper.BeginBlockUpdateInfractionParameters(ctx.WithBlockTime(ctx.BlockTime().Add(2 * unbondingTime)))
actualInfractionParameters, err = providerKeeper.GetInfractionParameters(ctx, consumerId)
require.NoError(t, err)
require.Equal(t, newExpectedInfractionParameters, actualInfractionParameters)

// assert that if we call `MsgUpdateConsumer` with a spawn time of zero on an initialized chain, the chain
// will not be scheduled to launch and will move back to its Registered phase
providerKeeper.SetConsumerPhase(ctx, consumerId, providertypes.CONSUMER_PHASE_INITIALIZED)
Expand Down

0 comments on commit 973dbee

Please sign in to comment.