-
Notifications
You must be signed in to change notification settings - Fork 292
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test: add integration test for the ibc tokenfilter (#1474)
Closes: #1249 Adds a test suite under `testing/tokenfilter` that does the following: - ensures that native celestia tokens can be sent out from celestia and can return - ensures that other chains can't send tokens to celestia chains and that their balance is unaffected.
- Loading branch information
Showing
4 changed files
with
399 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,229 @@ | ||
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() | ||
|
||
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. | ||
func NewTestChain(t *testing.T, coord *ibctesting.Coordinator, chainID string) *ibctesting.TestChain { | ||
var ( | ||
validatorsPerChain = 4 | ||
validators []*tmtypes.Validator | ||
signersByAddress = make(map[string]tmtypes.PrivValidator, validatorsPerChain) | ||
) | ||
|
||
// generate validators private/public key | ||
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 | ||
// 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 | ||
} |
Oops, something went wrong.