-
Notifications
You must be signed in to change notification settings - Fork 116
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
Key assignment adds iteration on MsgCreateValidator
#603
Comments
The loop iterates over all validators, which is the source of the problem. It does this because it is looking for a consumer address matching the new validator's address in an index with keys like To solve this we could create a second index with keys like |
We should also look into whether is possible to have a single index with keys like |
I think it works and is simple 👍
I think this also works, and this could replace the current |
Hi, the main is updated. If we change the index, from
|
Changing the index from
|
I see, in the above second call, when iterate the db to find the
|
the
|
Why can't we delete the old key-value? |
we can do all in one migration, i just feel it is secure if we still keep the old data for a bit longer ? |
Just chiming in; it could be worthwhile to explore what cosmos-sdk collections bring us with regards to this issue. If this turns out to be too much trouble, let's consider using a collection if applicable and refactor this it in a later ICS version?
I'm not sure keeping old data adds to security. |
Big thanks to @MSalopek for this migration free solution ! just check with trying each consumer ChainID ( for each chainID, if |
A note from today's dev session. It seems that the iterations discussed above can be refactored such that the store key is calculated and simply accessed via e.g. // ValidatorConsensusKeyInUse is called when a new validator is created
// in the x/staking module of cosmos-sdk. In case it panics, the TX aborts
// and thus, the validator is not created. See AfterValidatorCreated hook.
func ValidatorConsensusKeyInUse(k *Keeper, ctx sdk.Context, valAddr sdk.ValAddress) bool {
// Get the validator being added in the staking module.
val, found := k.stakingKeeper.GetValidator(ctx, valAddr)
if !found {
// Abort TX, do NOT allow validator to be created
panic("did not find newly created validator in staking module")
}
// Get the consensus address of the validator being added
consensusAddr, err := val.GetConsAddr()
if err != nil {
// Abort TX, do NOT allow validator to be created
panic("could not get validator cons addr ")
}
consuChains := k.GetAllConsumerChains(ctx)
for _, consumerChain := range consuChains {
if _, found := k.GetValidatorByConsumerAddr(
ctx,
consumerChain.ChainId,
providertypes.NewConsumerConsAddress(consensusAddr)); found {
return true
}
}
return false
} Additionally, a delete operation can be performed on the entire store subtree. e.g.
Not sure about the delete, but by intuition I'd wager it can be done like that. |
@MSalopek @yaruwangway It's not easy to iterate over all consumer chains as // GetAllConsumerChains gets all of the consumer chains, for which the provider module
// created IBC clients. Consumer chains with created clients are also referred to as registered. and consumer keys can be assigned for every chain, even those that are not yet registered, i.e., func (msg MsgAssignConsumerKey) ValidateBasic() error {
if strings.TrimSpace(msg.ChainId) == "" {
return ErrBlankConsumerChainID
}
// It is possible to assign keys for consumer chains that are not yet approved.
// This can only be done by a signing validator, but it is still sensible
// to limit the chainID size to prevent abuse.
// TODO: In future, a mechanism will be added to limit assigning keys to chains
// which are approved or pending approval, only.
if 128 < len(msg.ChainId) {
return ErrBlankConsumerChainID
} |
@jtremback , "It can't just iterate over all chainIds and try to get the consumerAddress for each one because there could consumerAddress stored for chainIds that have not been created yet." what does this mean ? cc @MSalopek |
@yaruwangway It means that you can create a consumer key for a chain that is not yet registered (the gov proposal has not passed and the clientID is unknown). |
@mpoke // TODO: In future, a mechanism will be added to limit assigning keys to chains
// which are approved or pending approval, only |
Sure. Please open a separate issue though. |
just to clarify some edge cases :
thanks! |
Problem
Due to the key assignment protocol, when creating a new validator in the staking module (via the
MsgCreateValidator
message), the code iterates over all consumer keys which have been assigned in order to check if the validator being added is, or was, a consumer chain validator. This can be used as an attack vector.Closing criteria
Figure out a way to get rid of this check.
Problem details
The ICS code implements the
AfterValidatorCreated
staking hook, which is called when a new validator is created. This hook iterates over all assigned consumer addresses, i.e.,interchain-security/x/ccv/provider/keeper/hooks.go
Line 79 in 3e339ea
TODOs
The text was updated successfully, but these errors were encountered: