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

Key assignment #515

Merged
merged 64 commits into from
Dec 7, 2022
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
f83c731
add MsgAssignConsumerKey
mpoke Nov 23, 2022
084ef62
add MsgAssignConsumerKey
mpoke Nov 23, 2022
ebd0398
fix package name
mpoke Nov 23, 2022
020f285
add keys
mpoke Nov 23, 2022
75bf2a1
add keeper methods for key assignment
mpoke Nov 23, 2022
ac30f74
handle MsgAssignConsumerKey
mpoke Nov 23, 2022
6707ac9
map addresses in slash requests
mpoke Nov 23, 2022
26ff35a
prune old consumer addresses
mpoke Nov 23, 2022
6974766
move AssignConsumerKey logic to keeper
mpoke Nov 23, 2022
35bb100
update consumer initial valset
mpoke Nov 23, 2022
09fd054
add ApplyKeyAssignmentToValUpdates
mpoke Nov 23, 2022
098a4e6
fix client creation
mpoke Nov 23, 2022
f8cd226
do not check init valset on consumer
mpoke Nov 23, 2022
533c6cf
clean state on val removal
mpoke Nov 23, 2022
3091bd1
fix TestAssignConsensusKeyForConsumerChain
mpoke Nov 23, 2022
b85e87c
delete on val removal
mpoke Nov 23, 2022
595c3eb
remove reverse mapping on val removal
mpoke Nov 23, 2022
1c2e696
remove pending key assignment in EndBlock
mpoke Nov 23, 2022
f5be337
add query endpoints
jtremback Nov 23, 2022
40b3bc9
Refactor AssignConsumerKey for clarity (IMO)
jtremback Nov 23, 2022
19cc625
finish key assignment genesis code- untested
jtremback Nov 23, 2022
3270302
FIxed mocks compile issue - not sure if it works right though.
jtremback Nov 23, 2022
87fff1b
add test for init and export genesis
jtremback Nov 24, 2022
d7f3be4
set after get in AssignConsumerKey
mpoke Nov 24, 2022
4a4dce2
enable AssignConsumerKey to be called twice
mpoke Nov 24, 2022
a621b9b
remove key assignment on chain removal
mpoke Nov 24, 2022
cf1bc61
apply some review comments
mpoke Nov 24, 2022
86c5979
fix bug: two validator with same consumer key
mpoke Nov 24, 2022
c050cc8
rename key: ConsumerValidatorsByVscIDBytePrefix -> ConsumerAddrsToPru…
mpoke Nov 24, 2022
605d562
PendingKeyAssignment -> KeyAssignmentReplacements
mpoke Nov 24, 2022
0c9f620
msg.ProviderAddr is a validator addr
mpoke Nov 24, 2022
f0ae261
fix: key assignment genesis tests (#517)
sainoe Nov 24, 2022
d64f7a6
add key assignment CRUD operations unit tests (#516)
MSalopek Nov 24, 2022
9e84264
improve KeyAssignmentReplacement set and get
mpoke Nov 25, 2022
5872f93
remove ApplyKeyAssignmentToInitialValset (redundant)
mpoke Nov 25, 2022
c396b3f
add invariant to docstring of AppendConsumerAddrsToPrune
mpoke Nov 25, 2022
e772dfb
fix address conversion
mpoke Nov 25, 2022
7fbbc76
Merge branch 'main' into marius/key-assignment
mpoke Nov 25, 2022
6d8cd10
adding e2e tests
mpoke Nov 25, 2022
aca9578
fix linter
mpoke Nov 25, 2022
8641273
add queries; setup integration tests (#519)
MSalopek Nov 28, 2022
eb7ff69
Adds some very basic random testing and unit tests (#522)
danwt Nov 28, 2022
5820c66
Enable key assignment testing for all e2e tests (#524)
mpoke Nov 28, 2022
7616700
Merge branch 'main' into marius/key-assignment
jtremback Nov 28, 2022
a1f592a
Merge branch 'main' into marius/key-assignment
danwt Dec 1, 2022
0568ce8
adding ADR
mpoke Dec 1, 2022
561c567
Merge branch 'marius/key-assignment' of github.com:cosmos/interchain-…
mpoke Dec 1, 2022
0d3123f
move handler.go outside client/
mpoke Dec 2, 2022
1bec53f
replace [][]byte with AddressList
mpoke Dec 2, 2022
23d4b54
remove IterateAllConsumerAddrsToPrune; not needed
mpoke Dec 2, 2022
0c29fb4
apply review suggestions
mpoke Dec 2, 2022
bb4e1ea
fix merge conflicts
mpoke Dec 2, 2022
637fc55
fix linter
mpoke Dec 2, 2022
ca05578
Danwt/key assignment slash test (#545)
danwt Dec 2, 2022
f1f5ed4
Merge branch 'main' into marius/key-assignment
danwt Dec 5, 2022
0fe2305
Fixes #503 prevents two key assignment key overlap security issues (#…
danwt Dec 5, 2022
a519d12
Bump AssignConsumerKey comment
Dec 6, 2022
a833334
Merge branch 'main' into marius/key-assignment
danwt Dec 6, 2022
da08407
improve comments for iterators
mpoke Dec 6, 2022
ab43903
Masa/key assignment integration tests amend (#548)
MSalopek Dec 6, 2022
f87973d
remove node_modules
mpoke Dec 7, 2022
26ddbf6
fix comment
mpoke Dec 7, 2022
6e0ca7f
fix merge conflicts
mpoke Dec 7, 2022
530cdcb
Merge branch 'main' into marius/key-assignment
mpoke Dec 7, 2022
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
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ require (
github.com/golang/mock v1.6.0
github.com/oxyno-zeta/gomock-extra-matcher v1.1.0
github.com/regen-network/cosmos-proto v0.3.1
github.com/spf13/pflag v1.0.5
)

require (
Expand Down Expand Up @@ -114,7 +115,6 @@ require (
github.com/sasha-s/go-deadlock v0.3.1 // indirect
github.com/spf13/afero v1.8.2 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.13.0 // indirect
github.com/subosito/gotenv v1.4.1 // indirect
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect
Expand Down
34 changes: 34 additions & 0 deletions proto/interchain_security/ccv/provider/v1/genesis.proto
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import "interchain_security/ccv/v1/ccv.proto";
import "interchain_security/ccv/provider/v1/provider.proto";
import "interchain_security/ccv/consumer/v1/consumer.proto";
import "interchain_security/ccv/consumer/v1/genesis.proto";
import "tendermint/crypto/keys.proto";


// GenesisState defines the CCV provider chain genesis state
Expand Down Expand Up @@ -36,6 +37,15 @@ message GenesisState {
[ (gogoproto.nullable) = false ];
Params params = 8
[ (gogoproto.nullable) = false ];
// empty for a new chain
repeated ValidatorConsumerPubKey validator_consumer_pubkeys = 9
[ (gogoproto.nullable) = false ];
// empty for a new chain
repeated ValidatorByConsumerAddr validators_by_consumer_addr = 10
[ (gogoproto.nullable) = false ];
// empty for a new chain
repeated ConsumerAddrsToPrune consumer_addrs_to_prune = 11
[ (gogoproto.nullable) = false ];
}

// consumer chain
Expand Down Expand Up @@ -76,3 +86,27 @@ message ValsetUpdateIdToHeight {
uint64 valset_update_id = 1;
uint64 height = 2;
}

// Used to serialize the ValidatorConsumerPubKey index from key assignment
// ValidatorConsumerPubKey: (chainID, providerAddr consAddr) -> consumerKey tmprotocrypto.PublicKey
message ValidatorConsumerPubKey {
string chain_id = 1;
bytes provider_addr = 2;
tendermint.crypto.PublicKey consumer_key = 3;
}

// Used to serialize the ValidatorConsumerAddr index from key assignment
// ValidatorByConsumerAddr: (chainID, consumerAddr consAddr) -> providerAddr consAddr
message ValidatorByConsumerAddr {
string chain_id = 1;
bytes consumer_addr = 2;
bytes provider_addr = 3;
}

// Used to serialize the ConsumerAddrsToPrune index from key assignment
// ConsumerAddrsToPrune: (chainID, vscID uint64) -> consumerAddrsToPrune [][]byte
message ConsumerAddrsToPrune {
string chain_id = 1;
uint64 vsc_id = 2;
repeated bytes consumer_addrs = 3;
}
5 changes: 5 additions & 0 deletions proto/interchain_security/ccv/provider/v1/provider.proto
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,8 @@ message ConsumerRemovalProposals {
// proposals waiting for stop_time to pass
repeated ConsumerRemovalProposal pending = 1;
}

// AddressList contains a list of consensus addresses
message AddressList {
repeated bytes addresses = 1;
}
44 changes: 44 additions & 0 deletions proto/interchain_security/ccv/provider/v1/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,20 @@ service Query {
option (google.api.http).get =
"/interchain_security/ccv/provider/consumer_chain_stop_proposals";
}

// QueryValidatorConsumerAddr queries the address
// assigned by a validator for a consumer chain.
rpc QueryValidatorConsumerAddr(QueryValidatorConsumerAddrRequest)
returns (QueryValidatorConsumerAddrResponse) {
option (google.api.http).get = "/interchain_security/ccv/provider/validator_consumer_addr";
}

// QueryProviderAddr returns the provider chain validator
// given a consumer chain validator address
rpc QueryValidatorProviderAddr(QueryValidatorProviderAddrRequest)
returns (QueryValidatorProviderAddrResponse) {
option (google.api.http).get = "/interchain_security/ccv/provider/validator_provider_addr";
}
}

message QueryConsumerGenesisRequest { string chain_id = 1; }
Expand Down Expand Up @@ -68,3 +82,33 @@ message Chain {
string chain_id = 1;
string client_id = 2;
}

message QueryValidatorConsumerAddrRequest {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
// The id of the consumer chain
string chain_id = 1;
// The consensus address of the validator on the provider chain
string provider_address = 2
[ (gogoproto.moretags) = "yaml:\"address\"" ];
}

message QueryValidatorConsumerAddrResponse {
// The address of the validator on the consumer chain
string consumer_address = 1;
}

message QueryValidatorProviderAddrRequest {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
// The id of the provider chain
string chain_id = 1;
// The consensus address of the validator on the consumer chain
string consumer_address = 2
[ (gogoproto.moretags) = "yaml:\"address\"" ];
}

message QueryValidatorProviderAddrResponse {
// The address of the validator on the provider chain
string provider_address = 1;
}
29 changes: 29 additions & 0 deletions proto/interchain_security/ccv/provider/v1/tx.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
syntax = "proto3";
package interchain_security.ccv.provider.v1;

option go_package = "github.com/cosmos/interchain-security/x/ccv/provider/types";

import "google/api/annotations.proto";
import "gogoproto/gogo.proto";
import "cosmos_proto/cosmos.proto";
import "google/protobuf/any.proto";

// Msg defines the Msg service.
service Msg {
rpc AssignConsumerKey(MsgAssignConsumerKey) returns (MsgAssignConsumerKeyResponse);
}

message MsgAssignConsumerKey {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
// The chain id of the consumer chain to assign a consensus public key to
string chain_id = 1;
// The validator address on the provider
string provider_addr = 2
[ (gogoproto.moretags) = "yaml:\"address\"" ];
// The consensus public key to use on the consumer
google.protobuf.Any consumer_key = 3
[ (cosmos_proto.accepts_interface) = "cosmos.crypto.PubKey" ];
}

message MsgAssignConsumerKeyResponse {}
15 changes: 15 additions & 0 deletions testutil/keeper/mocks.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 0 additions & 36 deletions x/ccv/consumer/keeper/genesis.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
package keeper

import (
"bytes"
"fmt"

sdk "github.com/cosmos/cosmos-sdk/types"
ibctmtypes "github.com/cosmos/ibc-go/v3/modules/light-clients/07-tendermint/types"
consumertypes "github.com/cosmos/interchain-security/x/ccv/consumer/types"
ccv "github.com/cosmos/interchain-security/x/ccv/types"

abci "github.com/tendermint/tendermint/abci/types"
tmtypes "github.com/tendermint/tendermint/types"
)

// InitGenesis initializes the CCV consumer state and binds to PortID.
Expand Down Expand Up @@ -56,12 +53,6 @@ func (k Keeper) InitGenesis(ctx sdk.Context, state *consumertypes.GenesisState)
k.SetHeightValsetUpdateID(ctx, uint64(ctx.BlockHeight()), uint64(0))

} else {
// verify genesis initial valset against the latest consensus state
// IBC genesis MUST run before CCV consumer genesis
if err := k.verifyGenesisInitValset(ctx, state); err != nil {
panic(err)
}

// chain restarts with the CCV channel established
if state.ProviderChannelId != "" {
// set provider channel ID
Expand Down Expand Up @@ -197,30 +188,3 @@ func (k Keeper) ExportGenesis(ctx sdk.Context) (genesis *consumertypes.GenesisSt

return
}

// verifyGenesisInitValset verifies the latest consensus state on provider client matches
// the initial validator set of restarted chain thus
func (k Keeper) verifyGenesisInitValset(ctx sdk.Context, genState *consumertypes.GenesisState) error {

consState, ok := k.clientKeeper.GetLatestClientConsensusState(ctx, genState.ProviderClientId)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand why the whole function was removed.

Does it make sense to maybe check if the client consensus state does indeed exist?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is something that should be addressed by validation.

if !ok {
return fmt.Errorf("consensus state for provider client not found. MUST run IBC genesis before CCV consumer genesis")
}
tmConsState, ok := consState.(*ibctmtypes.ConsensusState)
if !ok {
return fmt.Errorf(fmt.Sprintf("consensus state has wrong type. expected: %T, got: %T", &ibctmtypes.ConsensusState{}, consState))
}

// ensure that initial validator set is same as initial consensus state on provider client.
// this will be verified by provider module on channel handshake.
vals, err := tmtypes.PB2TM.ValidatorUpdates(genState.InitialValSet)
if err != nil {
return err
}
valSet := tmtypes.NewValidatorSet(vals)

if !bytes.Equal(tmConsState.NextValidatorsHash, valSet.Hash()) {
return fmt.Errorf("initial validator set does not match last consensus state of the provider client")
}
return nil
}
14 changes: 0 additions & 14 deletions x/ccv/consumer/types/genesis.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
package types

import (
"bytes"

sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
ibctmtypes "github.com/cosmos/ibc-go/v3/modules/light-clients/07-tendermint/types"
ccv "github.com/cosmos/interchain-security/x/ccv/types"

abci "github.com/tendermint/tendermint/abci/types"
tmtypes "github.com/tendermint/tendermint/types"
)

// NewInitialGenesisState returns a consumer GenesisState for a completely new consumer chain.
Expand Down Expand Up @@ -114,17 +111,6 @@ func (gs GenesisState) Validate() error {
if gs.LastTransmissionBlockHeight.Height != 0 {
return sdkerrors.Wrap(ccv.ErrInvalidGenesis, "last transmission block height must be empty for new chain")
}

// ensure that initial validator set is same as initial consensus state on provider client.
// this will be verified by provider module on channel handshake.
vals, err := tmtypes.PB2TM.ValidatorUpdates(gs.InitialValSet)
if err != nil {
return sdkerrors.Wrap(err, "could not convert val updates to validator set")
}
valSet := tmtypes.NewValidatorSet(vals)
if !bytes.Equal(gs.ProviderConsensusState.NextValidatorsHash, valSet.Hash()) {
return sdkerrors.Wrap(ccv.ErrInvalidGenesis, "initial validators does not hash to NextValidatorsHash on provider client")
}
} else {
// NOTE: For restart genesis, we will verify initial validator set in InitGenesis.
if gs.ProviderClientId == "" {
Expand Down
36 changes: 36 additions & 0 deletions x/ccv/provider/client/cli/flags.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package cli

import (
flag "github.com/spf13/pflag"
)

const (
FlagConsumerChainId = "validator"
FlagAddressValidator = "validator"
FlagConsumerPubKey = "pubkey"
FlagNodeID = "node-id"
FlagIP = "ip"
)

// common flagsets to add to various functions
var (
fsValidator = flag.NewFlagSet("", flag.ContinueOnError)
)

func init() {
fsValidator.String(FlagAddressValidator, "", "The Bech32 address of the validator")
}

// FlagSetPublicKey Returns the flagset for Public Key related operations.
func FlagSetPublicKey() *flag.FlagSet {
fs := flag.NewFlagSet("", flag.ContinueOnError)
fs.String(FlagConsumerPubKey, "", "The Protobuf JSON encoded public key to use for the consumer chain")
return fs
}

// FlagSetPublicKey Returns the flagset for Public Key related operations.
func FlagSetConsumerChainId() *flag.FlagSet {
fs := flag.NewFlagSet("", flag.ContinueOnError)
fs.String(FlagConsumerChainId, "", "The chainId of the consumer chain")
return fs
}
Loading