From 98f4d3af3d9ea8f345c03031deec3162d21d5c45 Mon Sep 17 00:00:00 2001 From: Aditya Date: Thu, 17 Feb 2022 16:41:15 +0100 Subject: [PATCH] Create test chain with multiple validators (#942) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * testing: adding multiple sender accounts for testing puproses * fix genesis setup (#936) * Update testing/chain.go Co-authored-by: colin axnér <25233464+colin-axner@users.noreply.github.com> * refactor: code hygiene * Update testing/chain.go Co-authored-by: Aditya * multi validator commit taken from @saione * add function to pass custom valset * add changelog Co-authored-by: Sean King Co-authored-by: Sean King Co-authored-by: colin axnér <25233464+colin-axner@users.noreply.github.com> --- CHANGELOG.md | 1 + testing/chain.go | 54 +++++++++++++++++++++++++++++++++++------------- 2 files changed, 41 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e9a2790b7c..86cde220706 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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. 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)