Skip to content

Commit

Permalink
Squashed commit of the following:
Browse files Browse the repository at this point in the history
commit aca9578
Author: mpoke <[email protected]>
Date:   Fri Nov 25 14:50:45 2022 +0100

    fix linter

commit 6d8cd10
Author: mpoke <[email protected]>
Date:   Fri Nov 25 14:46:11 2022 +0100

    adding e2e tests

commit 7fbbc76
Merge: e772dfb 095a076
Author: Marius Poke <[email protected]>
Date:   Fri Nov 25 12:04:15 2022 +0100

    Merge branch 'main' into marius/key-assignment

commit e772dfb
Author: mpoke <[email protected]>
Date:   Fri Nov 25 11:47:25 2022 +0100

    fix address conversion

commit 095a076
Author: Shawn Marshall-Spitzbart <[email protected]>
Date:   Wed Nov 23 11:12:48 2022 -0800

    Multi-consumer capable e2e tests (#475)

    * changes

    * mas

    * Update README.md

    * Update README.md

    * sorry for the friday night emails

    * Update instance_test.go

    * wip

    * wip

    * wip

    * wip

    * wip

    * wip

    * wip

    * wip

    * works

    * Update generic_setup.go

    * Update setup.go

    * smol

    * small

    * path to ccv chan setup

    * todos

    * Update setup.go

    * Create debug_test.go

    * democ

    * Update debug_test.go

    * setup all ccv channels

    * bump to main

    * another bump, missed one

    * fix after merge main

    * fixes

    * Update slashing.go

    * expired client tests

    * checks

    * fixed the stuff

    * smol

    * changes

    * updates

    * cleans

    * clean

    * todo

    * fixes

    * cleans

    * Update slashing.go

    * Update slashing.go

    Co-authored-by: Jehan <[email protected]>
  • Loading branch information
Daniel committed Nov 25, 2022
1 parent 30083cc commit c8787bc
Show file tree
Hide file tree
Showing 5 changed files with 273 additions and 6 deletions.
1 change: 1 addition & 0 deletions tests/e2e/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ E2e tests are categorized into files as follows:
- `stop_consumer.go` - e2e tests for the _Consumer Chain Removal_ sub-protocol
- `normal_operations.go` - e2e tests for _normal operations_ of ICS enabled chains
- `expired_client.go` - e2e tests for testing expired clients
- `key_assignment.go` - e2e tests for testing key assignment
- `instance_test.go` - ties the e2e test structure into golang's standard test mechanism, with appropriate definitions for concrete app types and setup callback

To run the e2e tests defined in this repo on any arbitrary consumer and provider implementation, copy the pattern exemplified in `instance_test.go` and `specific_setup.go`
19 changes: 14 additions & 5 deletions tests/e2e/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,25 +189,34 @@ func relayAllCommittedPackets(
srcPortID string,
srcChannelID string,
expectedPackets int,
msgAndArgs ...interface{},
) {
// check that the packets are committed in state
commitments := srcChain.App.GetIBCKeeper().ChannelKeeper.GetAllPacketCommitmentsAtChannel(
srcChain.GetContext(),
srcPortID,
srcChannelID,
)
s.Require().Equal(expectedPackets, len(commitments),
"actual number of packet commitments does not match expectation")
s.Require().Equal(
expectedPackets,
len(commitments),
fmt.Sprintf("actual number of packet commitments does not match expectation; %s", msgAndArgs...),
)

// relay all packets from srcChain to counterparty
for _, commitment := range commitments {
// - get packets
packet, found := srcChain.GetSentPacket(commitment.Sequence, srcChannelID)
s.Require().True(found, "did not find sent packet")

s.Require().True(
found,
fmt.Sprintf("did not find sent packet; %s", msgAndArgs...),
)
// - relay the packet
err := path.RelayPacket(packet)
s.Require().NoError(err)
s.Require().NoError(
err,
fmt.Sprintf("error while relaying packets; %s", msgAndArgs...),
)
}
}

Expand Down
256 changes: 256 additions & 0 deletions tests/e2e/key_assignment.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,256 @@
package e2e

import (
sdk "github.com/cosmos/cosmos-sdk/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
"github.com/cosmos/ibc-go/v3/testing/mock"
providerkeeper "github.com/cosmos/interchain-security/x/ccv/provider/keeper"
ccv "github.com/cosmos/interchain-security/x/ccv/types"
tmencoding "github.com/tendermint/tendermint/crypto/encoding"
tmprotocrypto "github.com/tendermint/tendermint/proto/tendermint/crypto"
)

func (s *CCVTestSuite) TestKeyAssignment() {
testCases := []struct {
name string
assignFunc func(*providerkeeper.Keeper) error
expError bool
expPacketCount int
}{
{
"assignment during channel init", func(pk *providerkeeper.Keeper) error {
// key assignment
validator, consumerKey := generateNewConsumerKey(s, 0)
err := pk.AssignConsumerKey(s.providerCtx(), s.consumerChain.ChainID, validator, consumerKey)
if err != nil {
return err
}

// check that a VSCPacket is queued
s.providerChain.NextBlock()
pendingPackets := pk.GetPendingPackets(s.providerCtx(), s.consumerChain.ChainID)
s.Require().Len(pendingPackets, 1)

// establish CCV channel
s.SetupCCVChannel(s.path)

return nil
}, false, 2,
},
{
"assignment after channel init", func(pk *providerkeeper.Keeper) error {
// establish CCV channel
s.SetupCCVChannel(s.path)

// key assignment
validator, consumerKey := generateNewConsumerKey(s, 0)
err := pk.AssignConsumerKey(s.providerCtx(), s.consumerChain.ChainID, validator, consumerKey)
if err != nil {
return err
}
s.providerChain.NextBlock()

return nil
}, false, 2,
},
{
"assignment with power change", func(pk *providerkeeper.Keeper) error {
// establish CCV channel
s.SetupCCVChannel(s.path)

// key assignment
validator, consumerKey := generateNewConsumerKey(s, 0)
err := pk.AssignConsumerKey(s.providerCtx(), s.consumerChain.ChainID, validator, consumerKey)
if err != nil {
return err
}

// Bond some tokens on provider to change validator powers
bondAmt := sdk.NewInt(1000000)
delAddr := s.providerChain.SenderAccount.GetAddress()
delegate(s, delAddr, bondAmt)

s.providerChain.NextBlock()

return nil
}, false, 2,
},
{
"double same-key assignment in same block", func(pk *providerkeeper.Keeper) error {
// establish CCV channel
s.SetupCCVChannel(s.path)

// key assignment
validator, consumerKey := generateNewConsumerKey(s, 0)
err := pk.AssignConsumerKey(s.providerCtx(), s.consumerChain.ChainID, validator, consumerKey)
if err != nil {
return err
}

// same key assignment
err = pk.AssignConsumerKey(s.providerCtx(), s.consumerChain.ChainID, validator, consumerKey)
if err != nil {
return err
}
s.providerChain.NextBlock()

return nil
}, true, 2,
},
{
"double key assignment in same block", func(pk *providerkeeper.Keeper) error {
// establish CCV channel
s.SetupCCVChannel(s.path)

// key assignment
validator, consumerKey := generateNewConsumerKey(s, 0)
err := pk.AssignConsumerKey(s.providerCtx(), s.consumerChain.ChainID, validator, consumerKey)
if err != nil {
return err
}

// same key assignment
validator, consumerKey = generateNewConsumerKey(s, 0)
err = pk.AssignConsumerKey(s.providerCtx(), s.consumerChain.ChainID, validator, consumerKey)
if err != nil {
return err
}
s.providerChain.NextBlock()

return nil
}, false, 2,
},
{
"double same-key assignment in different blocks", func(pk *providerkeeper.Keeper) error {
// establish CCV channel
s.SetupCCVChannel(s.path)

// key assignment
validator, consumerKey := generateNewConsumerKey(s, 0)
err := pk.AssignConsumerKey(s.providerCtx(), s.consumerChain.ChainID, validator, consumerKey)
if err != nil {
return err
}
s.providerChain.NextBlock()

// same key assignment
err = pk.AssignConsumerKey(s.providerCtx(), s.consumerChain.ChainID, validator, consumerKey)
if err != nil {
return err
}
s.providerChain.NextBlock()

return nil
}, true, 2,
},
{
"double key assignment in different blocks", func(pk *providerkeeper.Keeper) error {
// establish CCV channel
s.SetupCCVChannel(s.path)

// key assignment
validator, consumerKey := generateNewConsumerKey(s, 0)
err := pk.AssignConsumerKey(s.providerCtx(), s.consumerChain.ChainID, validator, consumerKey)
if err != nil {
return err
}
s.providerChain.NextBlock()

// same key assignment
validator, consumerKey = generateNewConsumerKey(s, 0)
err = pk.AssignConsumerKey(s.providerCtx(), s.consumerChain.ChainID, validator, consumerKey)
if err != nil {
return err
}
s.providerChain.NextBlock()

return nil
}, false, 3,
},
// TODO: this test should pass if we manage to change the client update mode to sequential
// {
// "key assignment for all validators in the same block", func(pk *providerkeeper.Keeper) error {
// // establish CCV channel
// s.SetupCCVChannel(s.path)

// // key assignment
// for i, _ := range s.providerChain.Vals.Validators {
// validator, consumerKey := generateNewConsumerKey(s, i)
// err := pk.AssignConsumerKey(s.providerCtx(), s.consumerChain.ChainID, validator, consumerKey)
// if err != nil {
// return err
// }
// }
// // vscPakcketData := pk.GetPendingPackets(s.providerCtx(), s.consumerChain.ChainID)
// // s.Require().Len(vscPakcketData, 1)
// // s.Require().Len(vscPakcketData[0].ValidatorUpdates, 2*len(s.providerChain.Vals.Validators))

// s.providerChain.NextBlock()

// return nil
// }, false, 2,
// },
}
for i, tc := range testCases {
providerKeeper := s.providerApp.GetProviderKeeper()

err := tc.assignFunc(&providerKeeper)
if tc.expError {
s.Require().Error(err, "test: "+tc.name)
} else {
s.Require().NoError(err, "test: "+tc.name)
}

if !tc.expError {
// Bond some tokens on provider to change validator powers
bondAmt := sdk.NewInt(1000000)
delAddr := s.providerChain.SenderAccount.GetAddress()
delegate(s, delAddr, bondAmt)

// Send CCV packet to consumer
s.providerChain.NextBlock()

// Relay all VSC packets from provider to consumer
relayAllCommittedPackets(
s,
s.providerChain,
s.path,
ccv.ProviderPortID,
s.path.EndpointB.ChannelID,
tc.expPacketCount,
"test: "+tc.name,
)

// update clients
err := s.path.EndpointA.UpdateClient()
s.Require().NoError(err)
err = s.path.EndpointB.UpdateClient()
s.Require().NoError(err)
}

if i+1 < len(testCases) {
// reset suite to reset provider client
s.SetupTest()
}
}
}

// generateNewConsumerKey generate new consumer key for the validator with valIndex
func generateNewConsumerKey(s *CCVTestSuite, valIndex int) (stakingtypes.Validator, tmprotocrypto.PublicKey) {
// get validator
s.Require().Less(valIndex, len(s.providerChain.Vals.Validators))
_, valAddr := s.getValByIdx(valIndex)
validator := s.getVal(s.providerCtx(), valAddr)

// generate new PrivValidator
privVal := mock.NewPV()
tmPubKey, err := privVal.GetPubKey()
s.Require().NoError(err)
pubKey, err := tmencoding.PubKeyToProto(tmPubKey)
s.Require().NoError(err)

// add Signer to the consumer chain
s.consumerChain.Signers[tmPubKey.Address().String()] = privVal

return validator, pubKey
}
2 changes: 1 addition & 1 deletion x/ccv/provider/keeper/key_assignment.go
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ func (k Keeper) AssignConsumerKey(
if _, found := k.GetValidatorByConsumerAddr(ctx, chainID, consumerAddr); found {
// mapping already exists; return error
return sdkerrors.Wrapf(
types.ErrInvalidConsumerConsensusPubKey, "consumer key already exists",
types.ErrConsumerKeyExists, "consumer key already exists",
)
}

Expand Down
1 change: 1 addition & 0 deletions x/ccv/provider/types/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ var (
ErrConsumerKeyNotFound = sdkerrors.Register(ModuleName, 7, "consumer key not found")
ErrNoValidatorConsumerAddress = sdkerrors.Register(ModuleName, 8, "error getting validator consumer address")
ErrNoValidatorProviderAddress = sdkerrors.Register(ModuleName, 9, "error getting validator provider address")
ErrConsumerKeyExists = sdkerrors.Register(ModuleName, 10, "consumer consensus public key already exists")
)

0 comments on commit c8787bc

Please sign in to comment.