diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c9f0c55b35..90f8e4b0af4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -63,6 +63,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. diff --git a/testing/chain.go b/testing/chain.go index 86717501c6a..89e5b5cb308 100644 --- a/testing/chain.go +++ b/testing/chain.go @@ -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. @@ -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{} @@ -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)