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

fix: Fix bug and add test case #2168

Merged
merged 5 commits into from
Aug 23, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
166 changes: 152 additions & 14 deletions tests/e2e/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,20 +84,21 @@
type TestConfigType string

const (
DefaultTestCfg TestConfigType = "default"
ChangeoverTestCfg TestConfigType = "changeover"
DemocracyTestCfg TestConfigType = "democracy"
DemocracyRewardTestCfg TestConfigType = "democracy-reward"
SlashThrottleTestCfg TestConfigType = "slash-throttling"
MulticonsumerTestCfg TestConfigType = "multi-consumer"
ConsumerMisbehaviourTestCfg TestConfigType = "consumer-misbehaviour"
CompatibilityTestCfg TestConfigType = "compatibility"
SmallMaxValidatorsTestCfg TestConfigType = "small-max-validators"
InactiveProviderValsTestCfg TestConfigType = "inactive-provider-vals"
GovTestCfg TestConfigType = "gov"
InactiveValsGovTestCfg TestConfigType = "inactive-vals-gov"
InactiveValsMintTestCfg TestConfigType = "inactive-vals-mint"
MintTestCfg TestConfigType = "mint"
DefaultTestCfg TestConfigType = "default"
ChangeoverTestCfg TestConfigType = "changeover"
DemocracyTestCfg TestConfigType = "democracy"
DemocracyRewardTestCfg TestConfigType = "democracy-reward"
SlashThrottleTestCfg TestConfigType = "slash-throttling"
MulticonsumerTestCfg TestConfigType = "multi-consumer"
ConsumerMisbehaviourTestCfg TestConfigType = "consumer-misbehaviour"
CompatibilityTestCfg TestConfigType = "compatibility"
SmallMaxValidatorsTestCfg TestConfigType = "small-max-validators"
InactiveProviderValsTestCfg TestConfigType = "inactive-provider-vals"
GovTestCfg TestConfigType = "gov"
InactiveValsGovTestCfg TestConfigType = "inactive-vals-gov"
InactiveValsMintTestCfg TestConfigType = "inactive-vals-mint"
MintTestCfg TestConfigType = "mint"
InactiveValsExtraValsTestCfg TestConfigType = "inactive-vals-extra-vals"
)

type TestConfig struct {
Expand Down Expand Up @@ -205,6 +206,8 @@
testCfg = InactiveValsMintTestConfig()
case MintTestCfg:
testCfg = MintTestConfig()
case InactiveValsExtraValsTestCfg:
testCfg = InactiveValsExtraValsTestConfig()
default:
panic(fmt.Sprintf("Invalid test config: %s", cfgType))
}
Expand Down Expand Up @@ -610,6 +613,25 @@
return tr
}

func InactiveValsExtraValsTestConfig() TestConfig {
tr := InactiveProviderValsTestConfig()

// set the MaxProviderConsensusValidators param to 4
proviConfig := tr.chainConfigs[ChainID("provi")]
proviConfig.GenesisChanges += " | .app_state.provider.params.max_provider_consensus_validators = \"4\""
// set max validators to 5
proviConfig.GenesisChanges += " | .app_state.staking.params.max_validators = \"5\""
tr.chainConfigs[ChainID("provi")] = proviConfig

// add the extra validators to the validator config
extraVals := GetExtraValidatorConfigs()
for valId, val := range extraVals {
tr.validatorConfigs[valId] = val
}
Comment on lines +628 to +630

Check warning

Code scanning / CodeQL

Iteration over map Warning test

Iteration over map may be a possible source of non-determinism

return tr
}

func SmallMaxValidatorsTestConfig() TestConfig {
cfg := DefaultTestConfig()

Expand Down Expand Up @@ -1274,3 +1296,119 @@
}
return hermesConfig
}

// GetExtraValidatorConfigs returns a map of extra validator configurations.
// These are configurations that are not part of the default configurations,
// for cases where more validators are needed.
// Commented out fields are fields that can be set, but are not necessary for the test
// they are used in so far.
// These are left as guidance to fill out as they become relevant in the future.
func GetExtraValidatorConfigs() map[ValidatorID]ValidatorConfig {
return map[ValidatorID]ValidatorConfig{
ValidatorID("david"): {
Mnemonic: "save arm pill nothing riot park analyst fever couple use reform hotel involve captain ride spell cricket spoil admit proud file renew below add",
DelAddress: "cosmos1jv9j37zakskecthedez2xuvkd7aj4v96u6wm57",
// DelAddressOnConsumer: "consumer1dkas8mu4kyhl5jrh4nzvm65qz588hy9qahzgv6",
ValoperAddress: "cosmosvaloper1jv9j37zakskecthedez2xuvkd7aj4v96ew6wcd",
// ValoperAddressOnConsumer: "consumervaloper1dkas8mu4kyhl5jrh4nzvm65qz588hy9qj0phzw",
ValconsAddress: "cosmosvalcons1vde2tkme0336durkp7qlehyw2v0r2rgm5lfcw5",
ValconsAddressOnConsumer: "consumervalcons1vde2tkme0336durkp7qlehyw2v0r2rgmmxnal5",
PrivValidatorKey: `{
"address": "6372A5DB797C63A6F0760F81FCDC8E531E350D1B",
"pub_key": {
"type": "tendermint/PubKeyEd25519",
"value": "JFt8aKr1AnubC23rVEUza0pl3DQC0VdC6jUlnkjCh5o="
},
"priv_key": {
"type": "tendermint/PrivKeyEd25519",
"value": "mBErI1aFTt2VHNiWkb14mEfSIfUU6PHndJCKaJ2XjkwkW3xoqvUCe5sLbetURTNrSmXcNALRV0LqNSWeSMKHmg=="
}
}`,
NodeKey: `{"priv_key":{"type":"tendermint/PrivKeyEd25519","value":"LJQ/VDAYtEEaJC3NA32fZ2oLLm9akLeLVnBlJ2WOYEMLohbwfac0x42Qh23E/ByEMliSjfGvLFQZIYzRqwJcLA=="}}`,
IpSuffix: "7",

// // consumer chain assigned key
// ConsumerMnemonic: "grunt list hour endless observe better spoil penalty lab duck only layer vague fantasy satoshi record demise topple space shaft solar practice donor sphere",
// ConsumerDelAddress: "consumer1q90l6j6lzzgt460ehjj56azknlt5yrd44y2uke",
// ConsumerDelAddressOnProvider: "cosmos1q90l6j6lzzgt460ehjj56azknlt5yrd4s38n97",
// ConsumerValoperAddress: "consumervaloper1q90l6j6lzzgt460ehjj56azknlt5yrd46ufrcd",
// ConsumerValoperAddressOnProvider: "cosmosvaloper1q90l6j6lzzgt460ehjj56azknlt5yrd449nxfd",
// ConsumerValconsAddress: "consumervalcons1uuec3cjxajv5te08p220usrjhkfhg9wyref26m",
// ConsumerValconsAddressOnProvider: "cosmosvalcons1uuec3cjxajv5te08p220usrjhkfhg9wyvqn0tm",
// ConsumerValPubKey: `{"@type":"/cosmos.crypto.ed25519.PubKey","key":"QlG+iYe6AyYpvY1z9RNJKCVlH14Q/qSz4EjGdGCru3o="}`,
// ConsumerPrivValidatorKey: `{"address":"E73388E246EC9945E5E70A94FE4072BD937415C4","pub_key":{"type":"tendermint/PubKeyEd25519","value":"QlG+iYe6AyYpvY1z9RNJKCVlH14Q/qSz4EjGdGCru3o="},"priv_key":{"type":"tendermint/PrivKeyEd25519","value":"OFR4w+FC6EMw5fAGTrHVexyPrjzQ7QfqgZOMgVf0izlCUb6Jh7oDJim9jXP1E0koJWUfXhD+pLPgSMZ0YKu7eg=="}}`,
// ConsumerNodeKey: `{"priv_key":{"type":"tendermint/PrivKeyEd25519","value":"uhPCqnL2KE8m/8OFNLQ5bN3CJr6mds+xfBi0E4umT/s2uWiJhet+vbYx88DHSdof3gGFNTIzAIxSppscBKX96w=="}}`,
// UseConsumerKey: false,
},
ValidatorID("eve"): {
Mnemonic: "board lava muffin daughter frozen chimney chest whale give subject inquiry forward alter gasp busy flee wire ecology invite code comic cloth shoot pen",
DelAddress: "cosmos1p56m290cgys4396e3f8p4kj9lrzwak7zemg45t",
// DelAddressOnConsumer: "consumer1dkas8mu4kyhl5jrh4nzvm65qz588hy9qahzgv6",
ValoperAddress: "cosmosvaloper1p56m290cgys4396e3f8p4kj9lrzwak7zu0uqcc",
// ValoperAddressOnConsumer: "consumervaloper1dkas8mu4kyhl5jrh4nzvm65qz588hy9qj0phzw",
ValconsAddress: "cosmosvalcons1dqvy6lz440hj4zxjske5knsyx60ac5estqx6k2",
ValconsAddressOnConsumer: "consumervalcons1dqvy6lz440hj4zxjske5knsyx60ac5esyeul82",
PrivValidatorKey: `{
"address": "68184D7C55ABEF2A88D285B34B4E04369FDC5330",
"pub_key": {
"type": "tendermint/PubKeyEd25519",
"value": "QbLLxm/mNHfS9WWXTxvt30D2xeC7/HRrMrZJIVOtj9s="
},
"priv_key": {
"type": "tendermint/PrivKeyEd25519",
"value": "LDPp4B9/Q18yZBJv2zXMnCA+NB9wvaM3XAkWLuCvbaFBssvGb+Y0d9L1ZZdPG+3fQPbF4Lv8dGsytkkhU62P2w=="
}
}`,
NodeKey: `{"priv_key":{"type":"tendermint/PrivKeyEd25519","value":"eyDlEXWWP5KwD2IKZeJ/bvf8jT+pVsXYVjpV2HfP+GEjngJe2dNbuuNqtC6L7SFcp5/W2aOIKsslASqv+Oai9Q=="}}`,
IpSuffix: "8",

// // consumer chain assigned key
// ConsumerMnemonic: "grunt list hour endless observe better spoil penalty lab duck only layer vague fantasy satoshi record demise topple space shaft solar practice donor sphere",
// ConsumerDelAddress: "consumer1q90l6j6lzzgt460ehjj56azknlt5yrd44y2uke",
// ConsumerDelAddressOnProvider: "cosmos1q90l6j6lzzgt460ehjj56azknlt5yrd4s38n97",
// ConsumerValoperAddress: "consumervaloper1q90l6j6lzzgt460ehjj56azknlt5yrd46ufrcd",
// ConsumerValoperAddressOnProvider: "cosmosvaloper1q90l6j6lzzgt460ehjj56azknlt5yrd449nxfd",
// ConsumerValconsAddress: "consumervalcons1uuec3cjxajv5te08p220usrjhkfhg9wyref26m",
// ConsumerValconsAddressOnProvider: "cosmosvalcons1uuec3cjxajv5te08p220usrjhkfhg9wyvqn0tm",
// ConsumerValPubKey: `{"@type":"/cosmos.crypto.ed25519.PubKey","key":"QlG+iYe6AyYpvY1z9RNJKCVlH14Q/qSz4EjGdGCru3o="}`,
// ConsumerPrivValidatorKey: `{"address":"E73388E246EC9945E5E70A94FE4072BD937415C4","pub_key":{"type":"tendermint/PubKeyEd25519","value":"QlG+iYe6AyYpvY1z9RNJKCVlH14Q/qSz4EjGdGCru3o="},"priv_key":{"type":"tendermint/PrivKeyEd25519","value":"OFR4w+FC6EMw5fAGTrHVexyPrjzQ7QfqgZOMgVf0izlCUb6Jh7oDJim9jXP1E0koJWUfXhD+pLPgSMZ0YKu7eg=="}}`,
// ConsumerNodeKey: `{"priv_key":{"type":"tendermint/PrivKeyEd25519","value":"uhPCqnL2KE8m/8OFNLQ5bN3CJr6mds+xfBi0E4umT/s2uWiJhet+vbYx88DHSdof3gGFNTIzAIxSppscBKX96w=="}}`,
// UseConsumerKey: false,
},
ValidatorID("fred"): {
Mnemonic: "squeeze runway ivory cause throw diagram camp cricket clutch lens venture panel explain transfer dove notice nest twist plate van paddle rude summer give",
DelAddress: "cosmos13s90cyesdm2292pn8mnzmjm0ez3nd7jaw32tdq",
// // DelAddressOnConsumer: "consumer1dkas8mu4kyhl5jrh4nzvm65qz588hy9qahzgv6",
ValoperAddress: "cosmosvaloper13s90cyesdm2292pn8mnzmjm0ez3nd7jat977pn",
// // ValoperAddressOnConsumer: "consumervaloper1dkas8mu4kyhl5jrh4nzvm65qz588hy9qj0phzw",
ValconsAddress: "cosmosvalcons1xvuktnaz3rvwmldw7ktv7lcn2xf7l252wmsv5e",
ValconsAddressOnConsumer: "consumervalcons1xvuktnaz3rvwmldw7ktv7lcn2xf7l252pz2f9e",
PrivValidatorKey: `{
"address": "333965CFA288D8EDFDAEF596CF7F135193EFAA8A",
"pub_key": {
"type": "tendermint/PubKeyEd25519",
"value": "nC7g+8/y3NNx7D6Ae970H9954JeqX7SyAxNHh5GnJGs="
},
"priv_key": {
"type": "tendermint/PrivKeyEd25519",
"value": "otxstGMSCO0T4CU/Ouxxaam+HUFoL9ArKmMqvSaaCaCcLuD7z/Lc03HsPoB73vQf33ngl6pftLIDE0eHkackaw=="
}
}`,
NodeKey: `{"priv_key":{"type":"tendermint/PrivKeyEd25519","value":"oeJWEaFbLHIgZEbCeVDeYKDqM23fv3j/FobYdhIffQYN2X9MUvBlkhi4Uz6dLQ+vSfZIZb2x2vPcgJsCUpLGnQ=="}}`,
IpSuffix: "9",

// // consumer chain assigned key
// ConsumerMnemonic: "grunt list hour endless observe better spoil penalty lab duck only layer vague fantasy satoshi record demise topple space shaft solar practice donor sphere",
// ConsumerDelAddress: "consumer1q90l6j6lzzgt460ehjj56azknlt5yrd44y2uke",
// ConsumerDelAddressOnProvider: "cosmos1q90l6j6lzzgt460ehjj56azknlt5yrd4s38n97",
// ConsumerValoperAddress: "consumervaloper1q90l6j6lzzgt460ehjj56azknlt5yrd46ufrcd",
// ConsumerValoperAddressOnProvider: "cosmosvaloper1q90l6j6lzzgt460ehjj56azknlt5yrd449nxfd",
// ConsumerValconsAddress: "consumervalcons1uuec3cjxajv5te08p220usrjhkfhg9wyref26m",
// ConsumerValconsAddressOnProvider: "cosmosvalcons1uuec3cjxajv5te08p220usrjhkfhg9wyvqn0tm",
// ConsumerValPubKey: `{"@type":"/cosmos.crypto.ed25519.PubKey","key":"QlG+iYe6AyYpvY1z9RNJKCVlH14Q/qSz4EjGdGCru3o="}`,
// ConsumerPrivValidatorKey: `{"address":"E73388E246EC9945E5E70A94FE4072BD937415C4","pub_key":{"type":"tendermint/PubKeyEd25519","value":"QlG+iYe6AyYpvY1z9RNJKCVlH14Q/qSz4EjGdGCru3o="},"priv_key":{"type":"tendermint/PrivKeyEd25519","value":"OFR4w+FC6EMw5fAGTrHVexyPrjzQ7QfqgZOMgVf0izlCUb6Jh7oDJim9jXP1E0koJWUfXhD+pLPgSMZ0YKu7eg=="}}`,
// ConsumerNodeKey: `{"priv_key":{"type":"tendermint/PrivKeyEd25519","value":"uhPCqnL2KE8m/8OFNLQ5bN3CJr6mds+xfBi0E4umT/s2uWiJhet+vbYx88DHSdof3gGFNTIzAIxSppscBKX96w=="}}`,
// UseConsumerKey: false,
},
}
}
6 changes: 6 additions & 0 deletions tests/e2e/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,12 @@ var stepChoices = map[string]StepChoice{
description: "test minting without inactive validators as a sanity check",
testConfig: MintTestCfg,
},
"inactive-vals-outside-max-validators": {
name: "inactive-vals-outside-max-validators",
steps: stepsInactiveValsTopNReproduce(),
description: "tests the behaviour of inactive validators with a top N = 100 chain and when max_validators is smaller than the total number of validators",
testConfig: InactiveValsExtraValsTestCfg,
},
}

func getTestCaseUsageString() string {
Expand Down
138 changes: 138 additions & 0 deletions tests/e2e/steps.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
package main

import (
"strconv"

gov "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types"
)

type Step struct {
Action interface{}
State State
Expand Down Expand Up @@ -138,3 +145,134 @@ var consumerDoubleDowntimeSteps = concatSteps(
stepsRedelegate("consu"),
stepsDoubleDowntime("consu"),
)

func stepsInactiveValsTopNReproduce() []Step {
alice_power := uint(30)
bob_power := uint(29)
carol_power := uint(20)
david_power := uint(10)
eve_power := uint(7)
fred_power := uint(4)

return []Step{
{
Action: StartChainAction{
Chain: ChainID("provi"),
Validators: []StartChainValidator{
{Id: ValidatorID("alice"), Stake: alice_power * 1000000, Allocation: 10000000000},
{Id: ValidatorID("bob"), Stake: bob_power * 1000000, Allocation: 10000000000},
{Id: ValidatorID("carol"), Stake: carol_power * 1000000, Allocation: 10000000000},
{Id: ValidatorID("david"), Stake: david_power * 1000000, Allocation: 10000000000},
{Id: ValidatorID("eve"), Stake: eve_power * 1000000, Allocation: 10000000000},
{Id: ValidatorID("fred"), Stake: fred_power * 1000000, Allocation: 10000000000},
},
},
State: State{
ChainID("provi"): ChainState{
ValPowers: &map[ValidatorID]uint{
ValidatorID("alice"): alice_power,
ValidatorID("bob"): bob_power,
ValidatorID("carol"): carol_power,
ValidatorID("david"): david_power,
ValidatorID("eve"): 0, // max provider consensus validators is 4, so eve and fred are at 0 power
ValidatorID("fred"): 0,
},
StakedTokens: &map[ValidatorID]uint{
ValidatorID("alice"): alice_power * 1000000,
ValidatorID("bob"): bob_power * 1000000,
ValidatorID("carol"): carol_power * 1000000,
ValidatorID("david"): david_power * 1000000,
ValidatorID("eve"): eve_power * 1000000,
ValidatorID("fred"): fred_power * 1000000,
},
},
},
},
{
Action: SubmitConsumerAdditionProposalAction{
Chain: ChainID("provi"),
From: ValidatorID("alice"),
Deposit: 10000001,
ConsumerChain: ChainID("consu"),
SpawnTime: 0,
InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 1},
TopN: 100,
AllowInactiveVals: false,
},
State: State{
ChainID("provi"): ChainState{
Proposals: &map[uint]Proposal{
1: ConsumerAdditionProposal{
Deposit: 10000001,
Chain: ChainID("consu"),
SpawnTime: 0,
InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 1},
Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_VOTING_PERIOD)),
},
},
},
},
},
{
Action: VoteGovProposalAction{
Chain: ChainID("provi"),
From: []ValidatorID{ValidatorID("alice"), ValidatorID("bob"), ValidatorID("carol"), ValidatorID("david"), ValidatorID("eve")},
Vote: []string{"yes", "yes", "yes", "yes", "yes"},
PropNumber: 1,
},
State: State{
ChainID("provi"): ChainState{
Proposals: &map[uint]Proposal{
1: ConsumerAdditionProposal{
Deposit: 10000001,
Chain: ChainID("consu"),
SpawnTime: 0,
InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 1},
Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_PASSED)),
},
},
HasToValidate: &map[ValidatorID][]ChainID{
ValidatorID("alice"): {"consu"},
ValidatorID("bob"): {"consu"},
ValidatorID("carol"): {"consu"},
ValidatorID("david"): {"consu"},
ValidatorID("eve"): {},
ValidatorID("fred"): {},
},
},
},
},
{
Action: StartConsumerChainAction{
ConsumerChain: ChainID("consu"),
ProviderChain: ChainID("provi"),
Validators: []StartChainValidator{
{Id: ValidatorID("alice"), Stake: alice_power * 1000000, Allocation: 10000000000},
{Id: ValidatorID("bob"), Stake: bob_power * 1000000, Allocation: 10000000000},
{Id: ValidatorID("carol"), Stake: carol_power * 1000000, Allocation: 10000000000},
{Id: ValidatorID("david"), Stake: david_power * 1000000, Allocation: 10000000000},
{Id: ValidatorID("eve"), Stake: eve_power * 1000000, Allocation: 10000000000},
{Id: ValidatorID("fred"), Stake: fred_power * 1000000, Allocation: 10000000000},
},
// For consumers that're launching with the provider being on an earlier version
// of ICS before the soft opt-out threshold was introduced, we need to set the
// soft opt-out threshold to 0.05 in the consumer genesis to ensure that the
// consumer binary doesn't panic. Sdk requires that all params are set to valid
// values from the genesis file.
GenesisChanges: ".app_state.ccvconsumer.params.soft_opt_out_threshold = \"0.05\"",
},
State: State{
ChainID("consu"): ChainState{
ValPowers: &map[ValidatorID]uint{
ValidatorID("alice"): alice_power,
ValidatorID("bob"): bob_power,
ValidatorID("carol"): carol_power,
ValidatorID("david"): david_power,
ValidatorID("eve"): 0,
ValidatorID("fred"): 0,
},
},
},
},
}
}
13 changes: 12 additions & 1 deletion tests/integration/partial_set_security_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package integration

import (
"slices"
"sort"
"testing"

"cosmossdk.io/math"
Expand Down Expand Up @@ -119,9 +120,19 @@ func TestMinStake(t *testing.T) {
lastVals, err := providerKeeper.GetLastBondedValidators(s.providerChain.GetContext())
s.Require().NoError(err)

// Assuming tc.stakedTokens is defined somewhere in your test case
// Create a copy of the tc.stakedTokens slice
sortedTokens := make([]int64, len(tc.stakedTokens))
copy(sortedTokens, tc.stakedTokens)

// Sort the copied slice in descending order
sort.Slice(sortedTokens, func(i, j int) bool {
return sortedTokens[i] > sortedTokens[j]
})

for i, val := range lastVals {
// check that the initial state was set correctly
require.Equal(s.T(), math.NewInt(tc.stakedTokens[i]), val.Tokens)
require.Equal(s.T(), math.NewInt(sortedTokens[i]), val.Tokens)
}

// check the validator set on the consumer chain is the original one
Expand Down
Loading
Loading