Skip to content

Commit

Permalink
Create test chain with multiple validators (cosmos#942)
Browse files Browse the repository at this point in the history
* testing: adding multiple sender accounts for testing puproses

* fix genesis setup (cosmos#936)

* Update testing/chain.go

Co-authored-by: colin axnér <[email protected]>

* refactor: code hygiene

* Update testing/chain.go

Co-authored-by: Aditya <[email protected]>

* multi validator commit taken from @Saione

* add function to pass custom valset

* add changelog

Co-authored-by: Sean King <[email protected]>
Co-authored-by: Sean King <[email protected]>
Co-authored-by: colin axnér <[email protected]>
  • Loading branch information
4 people authored Feb 17, 2022
1 parent 20dd5ca commit 98f4d3a
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 14 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ Ref: https://keepachangelog.com/en/1.0.0/

### Improvements

* (testing) [\#942](https://github.com/cosmos/ibc-go/pull/942) `NewTestChain` will create 4 validators in validator set by default. A new constructor function `NewTestChainWithValSet` is provided for test writers who want custom control over the validator set of test chains.
* (testing) [\#904](https://github.com/cosmos/ibc-go/pull/904) Add `ParsePacketFromEvents` function to the testing package. Useful when sending/relaying packets via the testing package.
* (testing) [\#893](https://github.com/cosmos/ibc-go/pull/893) Support custom private keys for testing.
* (testing) [\#810](https://github.com/cosmos/ibc-go/pull/810) Additional testing function added to `Endpoint` type called `RecvPacketWithResult`. Performs the same functionality as the existing `RecvPacket` function but also returns the message result. `path.RelayPacket` no longer uses the provided acknowledgement argument and instead obtains the acknowledgement via MsgRecvPacket events.
Expand Down
54 changes: 40 additions & 14 deletions testing/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@ type TestChain struct {
SenderAccounts []SenderAccount
}

// NewTestChain initializes a new TestChain instance with a single validator set using a
// generated secp256k1 Tendermint private key. It also creates a sender BaseAccount to be used for
// delivering transactions.
// NewTestChainWithValSet initializes a new TestChain instance with the given validator set
// and signer array. It also initializes 10 Sender accounts with a balance of 10000000000000000000 coins of
// bond denom to use for tests.
//
// The first block height is committed to state in order to allow for client creations on
// counterparty chains. The TestChain will return with a block height starting at 2.
Expand All @@ -84,17 +84,11 @@ type TestChain struct {
//
// NOTE: to use a custom sender privkey and account for testing purposes, replace and modify this
// constructor function.
func NewTestChain(t *testing.T, coord *Coordinator, chainID string) *TestChain {
// generate validator private/public key
privVal := mock.NewPV()
pubKey, err := privVal.GetPubKey()
require.NoError(t, err)

// create validator set with single validator
validator := tmtypes.NewValidator(pubKey, 1)
valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator})
signers := []tmtypes.PrivValidator{privVal}

//
// CONTRACT: Validator and signer array must be provided in the order expected by Tendermint.
// i.e. sorted first by power and then lexicographically by address.
func NewTestChainWithValSet(t *testing.T, coord *Coordinator, chainID string, valSet *tmtypes.ValidatorSet, signers []tmtypes.PrivValidator) *TestChain {

genAccs := []authtypes.GenesisAccount{}
genBals := []banktypes.Balance{}
senderAccs := []SenderAccount{}
Expand Down Expand Up @@ -155,6 +149,38 @@ func NewTestChain(t *testing.T, coord *Coordinator, chainID string) *TestChain {
return chain
}

// NewTestChain initializes a new test chain with a default of 4 validators
// Use this function if the tests do not need custom control over the validator set
func NewTestChain(t *testing.T, coord *Coordinator, chainID string) *TestChain {
// generate validators private/public key
var (
validatorsPerChain = 4
validators []*tmtypes.Validator
signersByAddress = make(map[string]tmtypes.PrivValidator, validatorsPerChain)
)

for i := 0; i < validatorsPerChain; i++ {
privVal := mock.NewPV()
pubKey, err := privVal.GetPubKey()
require.NoError(t, err)
validators = append(validators, tmtypes.NewValidator(pubKey, 1))
signersByAddress[pubKey.Address().String()] = privVal
}

// construct validator set;
// Note that the validators are sorted by voting power
// or, if equal, by address lexical order
valSet := tmtypes.NewValidatorSet(validators)

// create signers indexed by the valSet validators's order
signers := []tmtypes.PrivValidator{}
for _, val := range valSet.Validators {
signers = append(signers, signersByAddress[val.PubKey.Address().String()])
}

return NewTestChainWithValSet(t, coord, chainID, valSet, signers)
}

// GetContext returns the current context for the application.
func (chain *TestChain) GetContext() sdk.Context {
return chain.App.GetBaseApp().NewContext(false, chain.CurrentHeader)
Expand Down

0 comments on commit 98f4d3a

Please sign in to comment.