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

test: add integration test for the ibc tokenfilter #1474

Merged
merged 5 commits into from
Mar 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ import (
qgbmodule "github.com/celestiaorg/celestia-app/x/qgb"
qgbmodulekeeper "github.com/celestiaorg/celestia-app/x/qgb/keeper"
qgbmoduletypes "github.com/celestiaorg/celestia-app/x/qgb/types"
ibctestingtypes "github.com/cosmos/ibc-go/v6/testing/types"
)

const (
Expand Down Expand Up @@ -577,6 +578,31 @@ func (app *App) ModuleAccountAddrs() map[string]bool {
return modAccAddrs
}

// GetBaseApp implements the TestingApp interface.
func (app *App) GetBaseApp() *baseapp.BaseApp {
return app.BaseApp
}

// GetStakingKeeper implements the TestingApp interface.
func (app *App) GetStakingKeeper() ibctestingtypes.StakingKeeper {
return app.StakingKeeper
}

// GetIBCKeeper implements the TestingApp interface.
func (app *App) GetIBCKeeper() *ibckeeper.Keeper {
return app.IBCKeeper
}

// GetScopedIBCKeeper implements the TestingApp interface.
func (app *App) GetScopedIBCKeeper() capabilitykeeper.ScopedKeeper {
return app.ScopedIBCKeeper
}

// GetTxConfig implements the TestingApp interface.
func (app *App) GetTxConfig() client.TxConfig {
return app.txConfig
}

// LegacyAmino returns SimApp's amino codec.
//
// NOTE: This is solely to be used for testing purposes as it may be desirable
Expand Down
7 changes: 7 additions & 0 deletions app/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package app

import (
"encoding/json"

"github.com/cosmos/cosmos-sdk/codec"
)

// The genesis state of the blockchain is represented here as a map of raw json
Expand All @@ -12,3 +14,8 @@ import (
// the ModuleBasicManager which populates json from each BasicModule
// object provided to it during init.
type GenesisState map[string]json.RawMessage

// NewDefaultGenesisState generates the default state for the application.
func NewDefaultGenesisState(cdc codec.JSONCodec) GenesisState {
return ModuleBasics.DefaultGenesis(cdc)
}
229 changes: 229 additions & 0 deletions testing/tokenfilter/setup.go
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
Copy link
Member

Choose a reason for hiding this comment

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

[non blocking question]

For simplicity, each validator is bonded with a delegation
// of one consensus engine unit (10^6)

does this depend on the power reduction passed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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
}
Loading