-
Notifications
You must be signed in to change notification settings - Fork 134
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
feat!: Allow validators outside the active set to validate on consumer chains #1878
Changes from 22 commits
0fcb57b
c0d8581
b88cfb5
2e5a91a
2cddff5
acdf06a
48f4085
5ccdb18
48a1aba
66139cc
c11e65d
d21cf9a
87742aa
fb1a8e5
b632aca
519a329
0285039
9e58c13
134d840
70a6bf1
1265836
affd10f
5ea92ea
617b515
9822bbf
b29b867
9b5e578
bfb83ab
a7de72a
faff1a7
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 |
---|---|---|
@@ -1,6 +1,7 @@ | ||
package app | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"io" | ||
stdlog "log" | ||
|
@@ -86,7 +87,6 @@ import ( | |
"github.com/cosmos/cosmos-sdk/x/slashing" | ||
slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper" | ||
slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" | ||
"github.com/cosmos/cosmos-sdk/x/staking" | ||
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" | ||
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" | ||
"github.com/cosmos/cosmos-sdk/x/upgrade" | ||
|
@@ -107,6 +107,11 @@ import ( | |
ibcproviderclient "github.com/cosmos/interchain-security/v4/x/ccv/provider/client" | ||
ibcproviderkeeper "github.com/cosmos/interchain-security/v4/x/ccv/provider/keeper" | ||
providertypes "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" | ||
|
||
wrapped_genutil "github.com/cosmos/interchain-security/v4/x/ccv/wrapped_genutil" | ||
wrapped_staking "github.com/cosmos/interchain-security/v4/x/ccv/wrapped_staking" | ||
Comment on lines
+111
to
+112
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. Consider renaming The current names |
||
|
||
sdkmoduletypes "github.com/cosmos/cosmos-sdk/types/module" | ||
) | ||
|
||
const ( | ||
|
@@ -129,7 +134,8 @@ var ( | |
genutil.NewAppModuleBasic(genutiltypes.DefaultMessageValidator), | ||
bank.AppModuleBasic{}, | ||
capability.AppModuleBasic{}, | ||
staking.AppModuleBasic{}, | ||
// staking.AppModuleBasic{}, | ||
p-offtermatt marked this conversation as resolved.
Show resolved
Hide resolved
|
||
wrapped_staking.AppModuleBasic{}, | ||
mint.AppModuleBasic{}, | ||
distr.AppModuleBasic{}, | ||
gov.NewAppModuleBasic( | ||
|
@@ -498,7 +504,7 @@ func New( | |
// NOTE: Any module instantiated in the module manager that is later modified | ||
// must be passed by reference here. | ||
app.MM = module.NewManager( | ||
genutil.NewAppModule( | ||
wrapped_genutil.NewAppModule( | ||
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. Genutil and staking need to be wrapped, because they send validator updates to CometBFT and we need to filter those. |
||
app.AccountKeeper, | ||
app.StakingKeeper, | ||
app.BaseApp.DeliverTx, | ||
|
@@ -513,7 +519,8 @@ func New( | |
mint.NewAppModule(appCodec, app.MintKeeper, app.AccountKeeper, nil, app.GetSubspace(minttypes.ModuleName)), | ||
slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper, app.GetSubspace(slashingtypes.ModuleName)), | ||
distr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper, app.GetSubspace(distrtypes.ModuleName)), | ||
staking.NewAppModule(appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper, app.GetSubspace(stakingtypes.ModuleName)), | ||
// staking.NewAppModule(appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper, app.GetSubspace(stakingtypes.ModuleName)), | ||
p-offtermatt marked this conversation as resolved.
Show resolved
Hide resolved
|
||
wrapped_staking.NewAppModule(appCodec, *app.StakingKeeper, app.AccountKeeper, app.BankKeeper, app.GetSubspace(stakingtypes.ModuleName)), | ||
upgrade.NewAppModule(&app.UpgradeKeeper), | ||
evidence.NewAppModule(app.EvidenceKeeper), | ||
ibc.NewAppModule(app.IBCKeeper), | ||
|
@@ -608,7 +615,8 @@ func New( | |
capability.NewAppModule(appCodec, *app.CapabilityKeeper, false), | ||
gov.NewAppModule(appCodec, app.GovKeeper, app.AccountKeeper, app.BankKeeper, app.GetSubspace(govtypes.ModuleName)), | ||
mint.NewAppModule(appCodec, app.MintKeeper, app.AccountKeeper, nil, app.GetSubspace(minttypes.ModuleName)), | ||
staking.NewAppModule(appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper, app.GetSubspace(stakingtypes.ModuleName)), | ||
// staking.NewAppModule(appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper, app.GetSubspace(stakingtypes.ModuleName)), | ||
p-offtermatt marked this conversation as resolved.
Show resolved
Hide resolved
|
||
wrapped_staking.NewAppModule(appCodec, *app.StakingKeeper, app.AccountKeeper, app.BankKeeper, app.GetSubspace(stakingtypes.ModuleName)), | ||
distr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper, app.GetSubspace(distrtypes.ModuleName)), | ||
slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper, app.GetSubspace(slashingtypes.ModuleName)), | ||
params.NewAppModule(app.ParamsKeeper), | ||
|
@@ -721,7 +729,45 @@ func (app *App) InitChainer(ctx sdk.Context, req abci.RequestInitChain) abci.Res | |
|
||
app.UpgradeKeeper.SetModuleVersionMap(ctx, app.MM.GetVersionMap()) | ||
|
||
return app.MM.InitGenesis(ctx, app.appCodec, genesisState) | ||
return InitGenesis(app.MM, ctx, app.appCodec, genesisState) | ||
} | ||
|
||
// InitGenesis performs init genesis functionality for modules. Exactly one | ||
// module must return a non-empty validator set update to correctly initialize | ||
// the chain. | ||
func InitGenesis(m *sdkmoduletypes.Manager, ctx sdk.Context, cdc codec.JSONCodec, genesisData map[string]json.RawMessage) abci.ResponseInitChain { | ||
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. Why do we need this function here? How is it different from the original call to |
||
var validatorUpdates []abci.ValidatorUpdate | ||
ctx.Logger().Info("initializing blockchain state from genesis.json") | ||
for _, moduleName := range m.OrderInitGenesis { | ||
if genesisData[moduleName] == nil { | ||
continue | ||
} | ||
|
||
if module, ok := m.Modules[moduleName].(sdkmoduletypes.HasGenesis); ok { | ||
ctx.Logger().Debug("running initialization for module", "module", moduleName) | ||
|
||
moduleValUpdates := module.InitGenesis(ctx, cdc, genesisData[moduleName]) | ||
|
||
// use these validator updates if provided, the module manager assumes | ||
// only one module will update the validator set | ||
if len(moduleValUpdates) > 0 { | ||
fmt.Println("val updates by module", moduleName) | ||
if len(validatorUpdates) > 0 { | ||
panic("validator InitGenesis updates already set by a previous module") | ||
} | ||
validatorUpdates = moduleValUpdates | ||
} | ||
} | ||
} | ||
|
||
// a chain must initialize with a non-empty validator set | ||
if len(validatorUpdates) == 0 { | ||
panic(fmt.Sprintf("validator set is empty after InitGenesis, please ensure at least one validator is initialized with a delegation greater than or equal to the DefaultPowerReduction (%d)", sdk.DefaultPowerReduction)) | ||
} | ||
|
||
return abci.ResponseInitChain{ | ||
Validators: validatorUpdates, | ||
} | ||
} | ||
|
||
// LoadHeight loads a particular height | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -212,6 +212,10 @@ message Params { | |
|
||
// The number of blocks that comprise an epoch. | ||
int64 blocks_per_epoch = 10; | ||
|
||
// The maximal number of validators that will be passed | ||
// to the consensus engine on the provider. | ||
int64 max_provider_consensus_validators = 11; | ||
Comment on lines
+216
to
+218
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. Tip Codebase Verification The search results indicate that the field
Analysis chainEnsure the new field Scripts executedThe following scripts were executed for the analysis: Script: #!/bin/bash
# Description: Verify that the new field is used in the consensus engine configuration.
# Test: Search for the usage of `max_provider_consensus_validators`. Expect: Configurations or validations that use this field.
rg --type go $'max_provider_consensus_validators'
Length of output: 407 Script: #!/bin/bash
# Description: Verify that the new field is documented and validated in the consensus engine configuration.
# Test: Search for documentation related to `max_provider_consensus_validators`.
rg --type go --type md --type proto 'max_provider_consensus_validators'
# Test: Search for validation logic related to `max_provider_consensus_validators`.
rg --type go 'validate.*max_provider_consensus_validators'
Length of output: 162 Script: #!/bin/bash
# Description: Verify that the new field is documented and validated in the consensus engine configuration.
# Test: Search for documentation related to `max_provider_consensus_validators`.
rg --type go --type md --type 'proto' 'max_provider_consensus_validators'
# Test: Search for validation logic related to `max_provider_consensus_validators`.
rg --type go 'validate.*max_provider_consensus_validators'
Length of output: 162 Script: #!/bin/bash
# Description: Verify that the new field is documented and validated in the consensus engine configuration.
# Test: Search for documentation related to `max_provider_consensus_validators`.
rg --type go --type md --glob '**/*.proto' 'max_provider_consensus_validators'
# Test: Search for validation logic related to `max_provider_consensus_validators`.
rg --type go 'validate.*max_provider_consensus_validators'
Length of output: 244 |
||
} | ||
|
||
// SlashAcks contains cons addresses of consumer chain validators | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -328,22 +328,22 @@ func (tr TestConfig) getRewards(chain ChainID, modelState Rewards) Rewards { | |
|
||
func (tr TestConfig) getReward(chain ChainID, validator ValidatorID, blockHeight uint, isNativeDenom bool) float64 { | ||
valCfg := tr.validatorConfigs[validator] | ||
delAddresss := valCfg.DelAddress | ||
delAddress := valCfg.DelAddress | ||
if chain != ChainID("provi") { | ||
// use binary with Bech32Prefix set to ConsumerAccountPrefix | ||
if valCfg.UseConsumerKey { | ||
delAddresss = valCfg.ConsumerDelAddress | ||
delAddress = valCfg.ConsumerDelAddress | ||
} else { | ||
// use the same address as on the provider but with different prefix | ||
delAddresss = valCfg.DelAddressOnConsumer | ||
delAddress = valCfg.DelAddressOnConsumer | ||
Comment on lines
+331
to
+338
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. Refactor to improve address handling logic. The logic for determining the delegate address based on the chain type is repeated multiple times throughout the file. Consider abstracting this logic into a helper function to reduce code duplication and improve maintainability. - if chain != ChainID("provi") {
- // use binary with Bech32Prefix set to ConsumerAccountPrefix
- if valCfg.UseConsumerKey {
- delAddress = valCfg.ConsumerDelAddress
- } else {
- // use the same address as on the provider but with different prefix
- delAddress = valCfg.DelAddressOnConsumer
- }
- }
+ delAddress = getDelegateAddress(chain, valCfg) And then define
|
||
} | ||
} | ||
|
||
//#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. | ||
bz, err := exec.Command("docker", "exec", tr.containerConfig.InstanceName, tr.chainConfigs[chain].BinaryName, | ||
|
||
"query", "distribution", "rewards", | ||
delAddresss, | ||
delAddress, | ||
|
||
`--height`, fmt.Sprint(blockHeight), | ||
`--node`, tr.getQueryNode(chain), | ||
|
@@ -358,6 +358,11 @@ func (tr TestConfig) getReward(chain ChainID, validator ValidatorID, blockHeight | |
denomCondition = `total.#(denom=="stake").amount` | ||
} | ||
|
||
if *verbose { | ||
log.Println("Getting reward for chain: ", chain, " validator: ", validator, " block: ", blockHeight) | ||
log.Println("Reward response: ", string(bz)) | ||
} | ||
Comment on lines
+361
to
+364
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. Ensure verbose logging is controlled by a flag. The verbose logging within the - if *verbose {
- log.Println("Getting reward for chain: ", chain, " validator: ", validator, " block: ", blockHeight)
- log.Println("Reward response: ", string(bz))
- }
+ if tr.verbose {
+ log.Println("Getting reward for chain: ", chain, " validator: ", validator, " block: ", blockHeight)
+ log.Println("Reward response: ", string(bz))
+ } Ensure that
|
||
|
||
return gjson.Get(string(bz), denomCondition).Float() | ||
} | ||
|
||
|
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.
We need to find better naming for these two modules.