Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ibctesting: custom voting power reduction for testing #939

Merged
merged 13 commits into from
Mar 11, 2022
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ Ref: https://keepachangelog.com/en/1.0.0/
* (core) [\#709](https://github.com/cosmos/ibc-go/pull/709) Replace github.com/pkg/errors with stdlib errors

### API Breaking


* (testing) [\#939](https://github.com/cosmos/ibc-go/pull/939) Support custom power reduction for testing.
* (channel) [\#848](https://github.com/cosmos/ibc-go/pull/848) Added `ChannelId` to MsgChannelOpenInitResponse
* (testing) [\#813](https://github.com/cosmos/ibc-go/pull/813) The `ack` argument to the testing function `RelayPacket` has been removed as it is no longer needed.
* (testing) [\#774](https://github.com/cosmos/ibc-go/pull/774) Added `ChainID` arg to `SetupWithGenesisValSet` on the testing app. `Coordinator` generated ChainIDs now starts at index 1
Expand Down
34 changes: 25 additions & 9 deletions testing/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,16 +58,20 @@ func SetupTestingApp() (TestingApp, map[string]json.RawMessage) {
// that also act as delegators. For simplicity, each validator is bonded with a delegation
// of one consensus engine unit (10^6) in the default token of the simapp from first genesis
// account. A Nop logger is set in SimApp.
func SetupWithGenesisValSet(t *testing.T, valSet *tmtypes.ValidatorSet, genAccs []authtypes.GenesisAccount, chainID string, balances ...banktypes.Balance) TestingApp {
func SetupWithGenesisValSet(t *testing.T, valSet *tmtypes.ValidatorSet, genAccs []authtypes.GenesisAccount, chainID string, powerReduction sdk.Int, balances ...banktypes.Balance) TestingApp {
app, genesisState := DefaultTestingAppInit()

// set genesis accounts
authGenesis := authtypes.NewGenesisState(authtypes.DefaultParams(), genAccs)
var authGenesis *authtypes.GenesisState
app.AppCodec().MustUnmarshalJSON(genesisState[authtypes.ModuleName], authGenesis)

authGenesis = authtypes.NewGenesisState(authGenesis.Params, genAccs)
genesisState[authtypes.ModuleName] = app.AppCodec().MustMarshalJSON(authGenesis)

validators := make([]stakingtypes.Validator, 0, len(valSet.Validators))
delegations := make([]stakingtypes.Delegation, 0, len(valSet.Validators))

bondAmt := sdk.NewInt(1000000)
bondAmt := sdk.TokensFromConsensusPower(1, powerReduction)
fedekunze marked this conversation as resolved.
Show resolved Hide resolved

for _, val := range valSet.Validators {
pk, err := cryptocodec.FromTmPubKeyInterface(val.PubKey)
Expand All @@ -87,24 +91,36 @@ func SetupWithGenesisValSet(t *testing.T, valSet *tmtypes.ValidatorSet, genAccs
Commission: stakingtypes.NewCommission(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec()),
MinSelfDelegation: sdk.ZeroInt(),
}

validators = append(validators, validator)
delegations = append(delegations, stakingtypes.NewDelegation(genAccs[0].GetAddress(), val.Address.Bytes(), sdk.OneDec()))
}

// set validators and delegations
var stakingGenesis stakingtypes.GenesisState
app.AppCodec().MustUnmarshalJSON(genesisState[stakingtypes.ModuleName], &stakingGenesis)

stakingGenesis.Validators = validators
stakingGenesis.Delegations = delegations
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I realize this is branching off old behaviour, but this assumes the external users don't want to specify their own validator set. Maybe we should only add validators/delegators if these fields are empty after DefaultTestingAppInit

We could expose a helper function to do all this validator creation functionality. One argument could be the power reduction. Then we can modify the existing code to check if the validators/delegators are empty, if so then we call the default validator creation function


bondDenom := stakingGenesis.Params.BondDenom

// set validators and delegations
genesisState[stakingtypes.ModuleName] = app.AppCodec().MustMarshalJSON(&stakingGenesis)

totalSupply := sdk.NewCoins()

// add bonded amount to bonded pool module account
balances = append(balances, banktypes.Balance{
Address: authtypes.NewModuleAddress(stakingtypes.BondedPoolName).String(),
Coins: sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, bondAmt.Mul(sdk.NewInt(int64(len(valSet.Validators)))))},
Coins: sdk.Coins{sdk.NewCoin(bondDenom, bondAmt.Mul(sdk.NewInt(int64(len(valSet.Validators)))))},
})

// set validators and delegations
stakingGenesis := stakingtypes.NewGenesisState(stakingtypes.DefaultParams(), validators, delegations)
genesisState[stakingtypes.ModuleName] = app.AppCodec().MustMarshalJSON(stakingGenesis)

// update total supply
bankGenesis := banktypes.NewGenesisState(banktypes.DefaultGenesisState().Params, balances, totalSupply, []banktypes.Metadata{})
var bankGenesis *banktypes.GenesisState
app.AppCodec().MustUnmarshalJSON(genesisState[banktypes.ModuleName], bankGenesis)

bankGenesis = banktypes.NewGenesisState(bankGenesis.Params, balances, totalSupply, []banktypes.Metadata{})
genesisState[banktypes.ModuleName] = app.AppCodec().MustMarshalJSON(bankGenesis)

stateBytes, err := json.MarshalIndent(genesisState, "", " ")
Expand Down
60 changes: 27 additions & 33 deletions testing/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,7 @@ import (
"github.com/cosmos/ibc-go/v3/testing/simapp"
)

var (
MaxAccounts = 10
)
var MaxAccounts = 10

type SenderAccount struct {
SenderPrivKey cryptotypes.PrivKey
Expand All @@ -51,7 +49,7 @@ type SenderAccount struct {
// is used for delivering transactions through the application state.
// NOTE: the actual application uses an empty chain-id for ease of testing.
type TestChain struct {
t *testing.T
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

had to make this public in order to support the custom test chain from a new constructor

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you point me to the issue? Not sure I follow

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough

*testing.T

Coordinator *Coordinator
App TestingApp
Expand Down Expand Up @@ -88,7 +86,6 @@ type TestChain struct {
// 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 @@ -116,7 +113,7 @@ func NewTestChainWithValSet(t *testing.T, coord *Coordinator, chainID string, va
senderAccs = append(senderAccs, senderAcc)
}

app := SetupWithGenesisValSet(t, valSet, genAccs, chainID, genBals...)
app := SetupWithGenesisValSet(t, valSet, genAccs, chainID, sdk.DefaultPowerReduction, genBals...)

// create current header and call begin block
header := tmproto.Header{
Expand All @@ -129,7 +126,7 @@ func NewTestChainWithValSet(t *testing.T, coord *Coordinator, chainID string, va

// create an account to send transactions from
chain := &TestChain{
t: t,
T: t,
Coordinator: coord,
ChainID: chainID,
App: app,
Expand Down Expand Up @@ -191,7 +188,7 @@ func (chain *TestChain) GetContext() sdk.Context {
// their own SimApp.
func (chain *TestChain) GetSimApp() *simapp.SimApp {
app, ok := chain.App.(*simapp.SimApp)
require.True(chain.t, ok)
require.True(chain.T, ok)

return app
}
Expand All @@ -213,10 +210,10 @@ func (chain *TestChain) QueryProofAtHeight(key []byte, height int64) ([]byte, cl
})

merkleProof, err := commitmenttypes.ConvertProofs(res.ProofOps)
require.NoError(chain.t, err)
require.NoError(chain.T, err)

proof, err := chain.App.AppCodec().Marshal(&merkleProof)
require.NoError(chain.t, err)
require.NoError(chain.T, err)

revision := clienttypes.ParseChainID(chain.ChainID)

Expand All @@ -237,10 +234,10 @@ func (chain *TestChain) QueryUpgradeProof(key []byte, height uint64) ([]byte, cl
})

merkleProof, err := commitmenttypes.ConvertProofs(res.ProofOps)
require.NoError(chain.t, err)
require.NoError(chain.T, err)

proof, err := chain.App.AppCodec().Marshal(&merkleProof)
require.NoError(chain.t, err)
require.NoError(chain.T, err)

revision := clienttypes.ParseChainID(chain.ChainID)

Expand Down Expand Up @@ -300,7 +297,7 @@ func (chain *TestChain) SendMsgs(msgs ...sdk.Msg) (*sdk.Result, error) {
chain.Coordinator.UpdateTimeForChain(chain)

_, r, err := simapp.SignAndDeliver(
chain.t,
chain.T,
chain.TxConfig,
chain.App.GetBaseApp(),
chain.GetContext().BlockHeader(),
Expand Down Expand Up @@ -329,7 +326,7 @@ func (chain *TestChain) SendMsgs(msgs ...sdk.Msg) (*sdk.Result, error) {
// expected to exist otherwise testing will fail.
func (chain *TestChain) GetClientState(clientID string) exported.ClientState {
clientState, found := chain.App.GetIBCKeeper().ClientKeeper.GetClientState(chain.GetContext(), clientID)
require.True(chain.t, found)
require.True(chain.T, found)

return clientState
}
Expand Down Expand Up @@ -361,7 +358,7 @@ func (chain *TestChain) GetValsAtHeight(height int64) (*tmtypes.ValidatorSet, bo
// acknowledgement does not exist then testing will fail.
func (chain *TestChain) GetAcknowledgement(packet exported.PacketI) []byte {
ack, found := chain.App.GetIBCKeeper().ChannelKeeper.GetPacketAcknowledgement(chain.GetContext(), packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence())
require.True(chain.t, found)
require.True(chain.T, found)

return ack
}
Expand Down Expand Up @@ -436,7 +433,8 @@ func (chain *TestChain) CreateTMClientHeader(chainID string, blockHeight int64,
valSet *tmproto.ValidatorSet
trustedVals *tmproto.ValidatorSet
)
require.NotNil(chain.t, tmValSet)
require.NotNil(chain.T, tmValSet)
require.NotNil(chain.T, tmTrustedVals)

vsetHash := tmValSet.Hash()

Expand All @@ -461,25 +459,21 @@ func (chain *TestChain) CreateTMClientHeader(chainID string, blockHeight int64,
voteSet := tmtypes.NewVoteSet(chainID, blockHeight, 1, tmproto.PrecommitType, tmValSet)

commit, err := tmtypes.MakeCommit(blockID, blockHeight, 1, voteSet, signers, timestamp)
require.NoError(chain.t, err)
require.NoError(chain.T, err)

signedHeader := &tmproto.SignedHeader{
Header: tmHeader.ToProto(),
Commit: commit.ToProto(),
}

if tmValSet != nil {
valSet, err = tmValSet.ToProto()
if err != nil {
panic(err)
}
valSet, err = tmValSet.ToProto()
if err != nil {
panic(err)
}

if tmTrustedVals != nil {
trustedVals, err = tmTrustedVals.ToProto()
if err != nil {
panic(err)
}
trustedVals, err = tmTrustedVals.ToProto()
if err != nil {
panic(err)
}

// The trusted fields may be nil. They may be filled before relaying messages to a client.
Expand Down Expand Up @@ -533,11 +527,11 @@ func (chain *TestChain) CreatePortCapability(scopedKeeper capabilitykeeper.Scope
if !ok {
// create capability using the IBC capability keeper
cap, err := chain.App.GetScopedIBCKeeper().NewCapability(chain.GetContext(), host.PortPath(portID))
require.NoError(chain.t, err)
require.NoError(chain.T, err)

// claim capability using the scopedKeeper
err = scopedKeeper.ClaimCapability(chain.GetContext(), cap, host.PortPath(portID))
require.NoError(chain.t, err)
require.NoError(chain.T, err)
}

chain.App.Commit()
Expand All @@ -549,7 +543,7 @@ func (chain *TestChain) CreatePortCapability(scopedKeeper capabilitykeeper.Scope
// exist, otherwise testing will fail.
func (chain *TestChain) GetPortCapability(portID string) *capabilitytypes.Capability {
cap, ok := chain.App.GetScopedIBCKeeper().GetCapability(chain.GetContext(), host.PortPath(portID))
require.True(chain.t, ok)
require.True(chain.T, ok)

return cap
}
Expand All @@ -563,9 +557,9 @@ func (chain *TestChain) CreateChannelCapability(scopedKeeper capabilitykeeper.Sc
_, ok := chain.App.GetScopedIBCKeeper().GetCapability(chain.GetContext(), capName)
if !ok {
cap, err := chain.App.GetScopedIBCKeeper().NewCapability(chain.GetContext(), capName)
require.NoError(chain.t, err)
require.NoError(chain.T, err)
err = scopedKeeper.ClaimCapability(chain.GetContext(), cap, capName)
require.NoError(chain.t, err)
require.NoError(chain.T, err)
}

chain.App.Commit()
Expand All @@ -577,7 +571,7 @@ func (chain *TestChain) CreateChannelCapability(scopedKeeper capabilitykeeper.Sc
// The capability must exist, otherwise testing will fail.
func (chain *TestChain) GetChannelCapability(portID, channelID string) *capabilitytypes.Capability {
cap, ok := chain.App.GetScopedIBCKeeper().GetCapability(chain.GetContext(), host.ChannelCapabilityPath(portID, channelID))
require.True(chain.t, ok)
require.True(chain.T, ok)

return cap
}
44 changes: 19 additions & 25 deletions testing/coordinator.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ var (
// Coordinator is a testing struct which contains N TestChain's. It handles keeping all chains
// in sync with regards to time.
type Coordinator struct {
t *testing.T
*testing.T

CurrentTime time.Time
Chains map[string]*TestChain
Expand All @@ -29,7 +29,7 @@ type Coordinator struct {
func NewCoordinator(t *testing.T, n int) *Coordinator {
chains := make(map[string]*TestChain)
coord := &Coordinator{
t: t,
T: t,
CurrentTime: globalStartTime,
}

Expand Down Expand Up @@ -84,10 +84,10 @@ func (coord *Coordinator) Setup(path *Path) {
// caller does not anticipate any errors.
func (coord *Coordinator) SetupClients(path *Path) {
err := path.EndpointA.CreateClient()
require.NoError(coord.t, err)
require.NoError(coord.T, err)

err = path.EndpointB.CreateClient()
require.NoError(coord.t, err)
require.NoError(coord.T, err)
}

// SetupClientConnections is a helper function to create clients and the appropriate
Expand All @@ -105,19 +105,20 @@ func (coord *Coordinator) SetupConnections(path *Path) {
// successfully opened otherwise testing will fail.
func (coord *Coordinator) CreateConnections(path *Path) {
err := path.EndpointA.ConnOpenInit()
require.NoError(coord.t, err)
require.NoError(coord.T, err)

err = path.EndpointB.ConnOpenTry()
require.NoError(coord.t, err)
require.NoError(coord.T, err)

err = path.EndpointA.ConnOpenAck()
require.NoError(coord.t, err)
require.NoError(coord.T, err)

err = path.EndpointB.ConnOpenConfirm()
require.NoError(coord.t, err)
require.NoError(coord.T, err)

// ensure counterparty is up to date
path.EndpointA.UpdateClient()
err = path.EndpointA.UpdateClient()
require.NoError(coord.T, err)
}

// CreateMockChannels constructs and executes channel handshake messages to create OPEN
Expand Down Expand Up @@ -146,26 +147,27 @@ func (coord *Coordinator) CreateTransferChannels(path *Path) {
// opened otherwise testing will fail.
func (coord *Coordinator) CreateChannels(path *Path) {
err := path.EndpointA.ChanOpenInit()
require.NoError(coord.t, err)
require.NoError(coord.T, err)

err = path.EndpointB.ChanOpenTry()
require.NoError(coord.t, err)
require.NoError(coord.T, err)

err = path.EndpointA.ChanOpenAck()
require.NoError(coord.t, err)
require.NoError(coord.T, err)

err = path.EndpointB.ChanOpenConfirm()
require.NoError(coord.t, err)
require.NoError(coord.T, err)

// ensure counterparty is up to date
path.EndpointA.UpdateClient()
err = path.EndpointA.UpdateClient()
require.NoError(coord.T, err)
}

// GetChain returns the TestChain using the given chainID and returns an error if it does
// not exist.
func (coord *Coordinator) GetChain(chainID string) *TestChain {
chain, found := coord.Chains[chainID]
require.True(coord.t, found, fmt.Sprintf("%s chain does not exist", chainID))
require.True(coord.T, found, fmt.Sprintf("%s chain does not exist", chainID))
return chain
}

Expand Down Expand Up @@ -210,11 +212,7 @@ func (coord *Coordinator) ConnOpenInitOnBothChains(path *Path) error {
return err
}

if err := path.EndpointB.UpdateClient(); err != nil {
return err
}

return nil
return path.EndpointB.UpdateClient()
}

// ChanOpenInitOnBothChains initializes a channel on the source chain and counterparty chain
Expand All @@ -235,9 +233,5 @@ func (coord *Coordinator) ChanOpenInitOnBothChains(path *Path) error {
return err
}

if err := path.EndpointB.UpdateClient(); err != nil {
return err
}

return nil
return path.EndpointB.UpdateClient()
}
Loading