-
Notifications
You must be signed in to change notification settings - Fork 323
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
test: add integration test for the ibc tokenfilter #1474
Changes from 2 commits
bc30840
b3265aa
1afd56f
d37325c
0615c05
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,230 @@ | ||
package tokenfilter | ||
|
||
import ( | ||
"encoding/json" | ||
"testing" | ||
"time" | ||
|
||
"cosmossdk.io/math" | ||
"github.com/celestiaorg/celestia-app/app" | ||
"github.com/celestiaorg/celestia-app/app/encoding" | ||
codectypes "github.com/cosmos/cosmos-sdk/codec/types" | ||
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" | ||
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" | ||
"github.com/ethereum/go-ethereum/common" | ||
|
||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" | ||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" | ||
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" | ||
ibctesting "github.com/cosmos/ibc-go/v6/testing" | ||
"github.com/stretchr/testify/require" | ||
abci "github.com/tendermint/tendermint/abci/types" | ||
"github.com/tendermint/tendermint/crypto" | ||
"github.com/tendermint/tendermint/libs/log" | ||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types" | ||
tmtypes "github.com/tendermint/tendermint/types" | ||
dbm "github.com/tendermint/tm-db" | ||
|
||
"github.com/cosmos/ibc-go/v6/testing/mock" | ||
"github.com/cosmos/ibc-go/v6/testing/simapp" | ||
) | ||
|
||
// 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. | ||
// | ||
// Time management is handled by the Coordinator in order to ensure synchrony between chains. | ||
// Each update of any chain increments the block header time for all chains by 5 seconds. | ||
// | ||
// NOTE: to use a custom sender privkey and account for testing purposes, replace and modify this | ||
// constructor function. | ||
// | ||
// CONTRACT: Validator 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 *ibctesting.Coordinator, chainID string, valSet *tmtypes.ValidatorSet, signers map[string]tmtypes.PrivValidator) *ibctesting.TestChain { | ||
genAccs := []authtypes.GenesisAccount{} | ||
genBals := []banktypes.Balance{} | ||
senderAccs := []ibctesting.SenderAccount{} | ||
|
||
// generate genesis accounts | ||
for i := 0; i < ibctesting.MaxAccounts; i++ { | ||
senderPrivKey := secp256k1.GenPrivKey() | ||
acc := authtypes.NewBaseAccount(senderPrivKey.PubKey().Address().Bytes(), senderPrivKey.PubKey(), uint64(i), 0) | ||
amount, ok := sdk.NewIntFromString("10000000000000000000") | ||
require.True(t, ok) | ||
|
||
// add sender account | ||
balance := banktypes.Balance{ | ||
Address: acc.GetAddress().String(), | ||
Coins: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, amount)), | ||
} | ||
|
||
genAccs = append(genAccs, acc) | ||
genBals = append(genBals, balance) | ||
|
||
senderAcc := ibctesting.SenderAccount{ | ||
SenderAccount: acc, | ||
SenderPrivKey: senderPrivKey, | ||
} | ||
|
||
senderAccs = append(senderAccs, senderAcc) | ||
} | ||
|
||
app := SetupWithGenesisValSet(t, valSet, genAccs, chainID, sdk.DefaultPowerReduction, genBals...) | ||
|
||
// create current header and call begin block | ||
header := tmproto.Header{ | ||
ChainID: chainID, | ||
Height: 1, | ||
Time: coord.CurrentTime.UTC(), | ||
} | ||
|
||
txConfig := app.GetTxConfig() | ||
|
||
// create an account to send transactions from | ||
chain := &ibctesting.TestChain{ | ||
T: t, | ||
Coordinator: coord, | ||
ChainID: chainID, | ||
App: app, | ||
CurrentHeader: header, | ||
QueryServer: app.GetIBCKeeper(), | ||
TxConfig: txConfig, | ||
Codec: app.AppCodec(), | ||
Vals: valSet, | ||
NextVals: valSet, | ||
Signers: signers, | ||
SenderPrivKey: senderAccs[0].SenderPrivKey, | ||
SenderAccount: senderAccs[0].SenderAccount, | ||
SenderAccounts: senderAccs, | ||
} | ||
|
||
coord.CommitBlock(chain) | ||
|
||
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 | ||
cmwaters marked this conversation as resolved.
Show resolved
Hide resolved
|
||
func NewTestChain(t *testing.T, coord *ibctesting.Coordinator, chainID string) *ibctesting.TestChain { | ||
// generate validators private/public key | ||
cmwaters marked this conversation as resolved.
Show resolved
Hide resolved
|
||
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) | ||
|
||
return NewTestChainWithValSet(t, coord, chainID, valSet, signersByAddress) | ||
} | ||
|
||
// SetupWithGenesisValSet initializes a new SimApp with a validator set and genesis accounts | ||
// 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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [non blocking question]
does this depend on the power reduction passed? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think so. Honestly I'm not sure. I didn't write it and it doesn't really affect the test |
||
// account. A Nop logger is set in SimApp. | ||
func SetupWithGenesisValSet(t testing.TB, valSet *tmtypes.ValidatorSet, genAccs []authtypes.GenesisAccount, chainID string, powerReduction math.Int, balances ...banktypes.Balance) ibctesting.TestingApp { | ||
db := dbm.NewMemDB() | ||
encCdc := encoding.MakeConfig(app.ModuleEncodingRegisters...) | ||
genesisState := app.NewDefaultGenesisState(encCdc.Codec) | ||
app := app.New( | ||
log.NewNopLogger(), db, nil, true, map[int64]bool{}, app.DefaultNodeHome, 5, encCdc, simapp.EmptyAppOptions{}, | ||
) | ||
|
||
// set genesis accounts | ||
authGenesis := authtypes.NewGenesisState(authtypes.DefaultParams(), 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.TokensFromConsensusPower(1, powerReduction) | ||
|
||
for _, val := range valSet.Validators { | ||
pk, err := cryptocodec.FromTmPubKeyInterface(val.PubKey) | ||
require.NoError(t, err) | ||
pkAny, err := codectypes.NewAnyWithValue(pk) | ||
require.NoError(t, err) | ||
evmAddress := common.HexToAddress(crypto.CRandHex(common.AddressLength)) | ||
validator := stakingtypes.Validator{ | ||
OperatorAddress: sdk.ValAddress(val.Address).String(), | ||
ConsensusPubkey: pkAny, | ||
Jailed: false, | ||
Status: stakingtypes.Bonded, | ||
Tokens: bondAmt, | ||
DelegatorShares: sdk.OneDec(), | ||
Description: stakingtypes.Description{}, | ||
UnbondingHeight: int64(0), | ||
UnbondingTime: time.Unix(0, 0).UTC(), | ||
Commission: stakingtypes.NewCommission(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec()), | ||
MinSelfDelegation: sdk.ZeroInt(), | ||
EvmAddress: evmAddress.Hex(), | ||
} | ||
|
||
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) | ||
|
||
bondDenom := stakingGenesis.Params.BondDenom | ||
|
||
// add bonded amount to bonded pool module account | ||
balances = append(balances, banktypes.Balance{ | ||
Address: authtypes.NewModuleAddress(stakingtypes.BondedPoolName).String(), | ||
Coins: sdk.Coins{sdk.NewCoin(bondDenom, bondAmt.Mul(sdk.NewInt(int64(len(valSet.Validators)))))}, | ||
}) | ||
|
||
// set validators and delegations | ||
stakingGenesis = *stakingtypes.NewGenesisState(stakingGenesis.Params, validators, delegations) | ||
genesisState[stakingtypes.ModuleName] = app.AppCodec().MustMarshalJSON(&stakingGenesis) | ||
|
||
// update total supply | ||
bankGenesis := banktypes.NewGenesisState(banktypes.DefaultGenesisState().Params, balances, sdk.NewCoins(), []banktypes.Metadata{}) | ||
genesisState[banktypes.ModuleName] = app.AppCodec().MustMarshalJSON(bankGenesis) | ||
|
||
stateBytes, err := json.MarshalIndent(genesisState, "", " ") | ||
require.NoError(t, err) | ||
|
||
// init chain will set the validator set and initialize the genesis accounts | ||
app.InitChain( | ||
abci.RequestInitChain{ | ||
ChainId: chainID, | ||
Validators: []abci.ValidatorUpdate{}, | ||
AppStateBytes: stateBytes, | ||
}, | ||
) | ||
|
||
// commit genesis changes | ||
app.Commit() | ||
app.BeginBlock( | ||
abci.RequestBeginBlock{ | ||
Header: tmproto.Header{ | ||
ChainID: chainID, | ||
Height: app.LastBlockHeight() + 1, | ||
AppHash: app.LastCommitID().Hash, | ||
ValidatorsHash: valSet.Hash(), | ||
NextValidatorsHash: valSet.Hash(), | ||
}, | ||
}, | ||
) | ||
|
||
return app | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[question] I'm not sure how this comment is applicable to the line below. Should the comment be moved?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I can cut it out. This entire setup.go page is copy pasted from IBC's testing framework just FYI. Predominantly because our
staking.Validator
requires anEvmAddress
.