Skip to content

Commit

Permalink
adding e2e tests
Browse files Browse the repository at this point in the history
  • Loading branch information
mpoke committed Nov 25, 2022
1 parent 7fbbc76 commit 6d8cd10
Show file tree
Hide file tree
Showing 5 changed files with 272 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
255 changes: 255 additions & 0 deletions tests/e2e/key_assignment.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,255 @@
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()
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 6d8cd10

Please sign in to comment.