2023-03-07 22:37:45 +00:00
|
|
|
package testutil
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
2023-06-06 16:40:17 +00:00
|
|
|
"math/big"
|
2023-03-07 22:37:45 +00:00
|
|
|
"testing"
|
|
|
|
|
2023-06-06 21:51:42 +00:00
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
|
2023-03-07 22:37:45 +00:00
|
|
|
"github.com/cosmos/cosmos-sdk/client/grpc/tmservice"
|
|
|
|
"github.com/cosmos/cosmos-sdk/crypto/hd"
|
|
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
|
|
txtypes "github.com/cosmos/cosmos-sdk/types/tx"
|
|
|
|
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
|
|
|
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
2023-06-06 21:51:42 +00:00
|
|
|
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
|
|
|
|
|
2023-06-06 16:40:17 +00:00
|
|
|
"github.com/ethereum/go-ethereum"
|
2023-04-03 16:58:45 +00:00
|
|
|
"github.com/ethereum/go-ethereum/common"
|
2023-03-07 22:37:45 +00:00
|
|
|
"github.com/ethereum/go-ethereum/ethclient"
|
2023-06-06 21:51:42 +00:00
|
|
|
|
2023-04-06 17:51:13 +00:00
|
|
|
evmtypes "github.com/evmos/ethermint/x/evm/types"
|
2023-03-07 22:37:45 +00:00
|
|
|
|
|
|
|
"github.com/kava-labs/kava/app"
|
|
|
|
kavaparams "github.com/kava-labs/kava/app/params"
|
|
|
|
"github.com/kava-labs/kava/tests/e2e/runner"
|
|
|
|
"github.com/kava-labs/kava/tests/util"
|
2023-06-06 21:51:42 +00:00
|
|
|
committeetypes "github.com/kava-labs/kava/x/committee/types"
|
2023-03-28 22:32:36 +00:00
|
|
|
communitytypes "github.com/kava-labs/kava/x/community/types"
|
|
|
|
earntypes "github.com/kava-labs/kava/x/earn/types"
|
2023-06-05 20:22:23 +00:00
|
|
|
evmutiltypes "github.com/kava-labs/kava/x/evmutil/types"
|
2023-03-07 22:37:45 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// Chain wraps query clients & accounts for a network
|
|
|
|
type Chain struct {
|
2023-04-06 17:51:13 +00:00
|
|
|
accounts map[string]*SigningAccount
|
|
|
|
t *testing.T
|
2023-03-07 22:37:45 +00:00
|
|
|
|
2023-03-17 18:30:23 +00:00
|
|
|
StakingDenom string
|
|
|
|
ChainId string
|
2023-03-07 22:37:45 +00:00
|
|
|
|
2023-04-03 16:58:45 +00:00
|
|
|
EvmClient *ethclient.Client
|
|
|
|
ContractAddrs map[string]common.Address
|
2023-03-28 22:32:36 +00:00
|
|
|
|
2023-04-06 17:51:13 +00:00
|
|
|
EncodingConfig kavaparams.EncodingConfig
|
|
|
|
|
2023-03-07 22:37:45 +00:00
|
|
|
Auth authtypes.QueryClient
|
|
|
|
Bank banktypes.QueryClient
|
2023-06-06 21:51:42 +00:00
|
|
|
Committee committeetypes.QueryClient
|
2023-03-28 22:32:36 +00:00
|
|
|
Community communitytypes.QueryClient
|
|
|
|
Earn earntypes.QueryClient
|
2023-04-06 17:51:13 +00:00
|
|
|
Evm evmtypes.QueryClient
|
2023-06-05 20:22:23 +00:00
|
|
|
Evmutil evmutiltypes.QueryClient
|
2023-03-07 22:37:45 +00:00
|
|
|
Tm tmservice.ServiceClient
|
|
|
|
Tx txtypes.ServiceClient
|
2023-06-06 21:51:42 +00:00
|
|
|
Upgrade upgradetypes.QueryClient
|
2023-03-07 22:37:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// NewChain creates the query clients & signing account management for a chain run on a set of ports.
|
|
|
|
// A signing client for the fundedAccountMnemonic is initialized. This account is referred to in the
|
|
|
|
// code as "whale" and it is used to supply funds to all new accounts.
|
|
|
|
func NewChain(t *testing.T, details *runner.ChainDetails, fundedAccountMnemonic string) (*Chain, error) {
|
2023-03-17 18:30:23 +00:00
|
|
|
chain := &Chain{
|
2023-04-03 16:58:45 +00:00
|
|
|
t: t,
|
|
|
|
StakingDenom: details.StakingDenom,
|
|
|
|
ChainId: details.ChainId,
|
|
|
|
ContractAddrs: make(map[string]common.Address),
|
2023-03-17 18:30:23 +00:00
|
|
|
}
|
2023-04-06 17:51:13 +00:00
|
|
|
chain.EncodingConfig = app.MakeEncodingConfig()
|
2023-03-07 22:37:45 +00:00
|
|
|
|
2023-06-20 16:29:25 +00:00
|
|
|
grpcConn, err := details.GrpcConn()
|
2023-03-07 22:37:45 +00:00
|
|
|
if err != nil {
|
|
|
|
return chain, err
|
|
|
|
}
|
|
|
|
|
2023-06-20 16:29:25 +00:00
|
|
|
chain.EvmClient, err = details.EvmClient()
|
2023-03-07 22:37:45 +00:00
|
|
|
if err != nil {
|
|
|
|
return chain, err
|
|
|
|
}
|
|
|
|
|
|
|
|
chain.Auth = authtypes.NewQueryClient(grpcConn)
|
|
|
|
chain.Bank = banktypes.NewQueryClient(grpcConn)
|
2023-06-06 21:51:42 +00:00
|
|
|
chain.Committee = committeetypes.NewQueryClient(grpcConn)
|
2023-03-28 22:32:36 +00:00
|
|
|
chain.Community = communitytypes.NewQueryClient(grpcConn)
|
|
|
|
chain.Earn = earntypes.NewQueryClient(grpcConn)
|
2023-04-06 17:51:13 +00:00
|
|
|
chain.Evm = evmtypes.NewQueryClient(grpcConn)
|
2023-06-05 20:22:23 +00:00
|
|
|
chain.Evmutil = evmutiltypes.NewQueryClient(grpcConn)
|
2023-03-07 22:37:45 +00:00
|
|
|
chain.Tm = tmservice.NewServiceClient(grpcConn)
|
|
|
|
chain.Tx = txtypes.NewServiceClient(grpcConn)
|
2023-06-06 21:51:42 +00:00
|
|
|
chain.Upgrade = upgradetypes.NewQueryClient(grpcConn)
|
2023-03-07 22:37:45 +00:00
|
|
|
|
|
|
|
// initialize accounts map
|
|
|
|
chain.accounts = make(map[string]*SigningAccount)
|
|
|
|
// setup the signing account for the initially funded account (used to fund all other accounts)
|
|
|
|
whale := chain.AddNewSigningAccount(
|
|
|
|
FundedAccountName,
|
|
|
|
hd.CreateHDPath(Bip44CoinType, 0, 0),
|
2023-03-17 18:30:23 +00:00
|
|
|
chain.ChainId,
|
2023-03-07 22:37:45 +00:00
|
|
|
fundedAccountMnemonic,
|
|
|
|
)
|
|
|
|
|
|
|
|
// check that funded account is actually funded.
|
2023-06-06 21:51:42 +00:00
|
|
|
fmt.Printf("[%s] account used for funding (%s) address: %s\n", chain.ChainId, FundedAccountName, whale.SdkAddress)
|
2023-03-07 22:37:45 +00:00
|
|
|
whaleFunds := chain.QuerySdkForBalances(whale.SdkAddress)
|
|
|
|
if whaleFunds.IsZero() {
|
|
|
|
chain.t.Fatal("funded account mnemonic is for account with no funds")
|
|
|
|
}
|
|
|
|
|
|
|
|
return chain, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Shutdown performs closes all the account request channels for this chain.
|
|
|
|
func (chain *Chain) Shutdown() {
|
|
|
|
// close all account request channels
|
|
|
|
for _, a := range chain.accounts {
|
|
|
|
close(a.sdkReqChan)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// QuerySdkForBalances gets the balance of a particular address on this Chain.
|
|
|
|
func (chain *Chain) QuerySdkForBalances(addr sdk.AccAddress) sdk.Coins {
|
|
|
|
res, err := chain.Bank.AllBalances(context.Background(), &banktypes.QueryAllBalancesRequest{
|
|
|
|
Address: addr.String(),
|
|
|
|
})
|
|
|
|
require.NoError(chain.t, err)
|
|
|
|
return res.Balances
|
|
|
|
}
|
2023-06-05 20:22:23 +00:00
|
|
|
|
|
|
|
// GetModuleBalances returns the balance of a requested module account
|
|
|
|
func (chain *Chain) GetModuleBalances(moduleName string) sdk.Coins {
|
|
|
|
addr := authtypes.NewModuleAddress(moduleName)
|
|
|
|
return chain.QuerySdkForBalances(addr)
|
|
|
|
}
|
2023-06-06 16:40:17 +00:00
|
|
|
|
|
|
|
func (chain *Chain) GetErc20Balance(contract, address common.Address) *big.Int {
|
|
|
|
resData, err := chain.EvmClient.CallContract(context.Background(), ethereum.CallMsg{
|
|
|
|
To: &contract,
|
|
|
|
Data: util.BuildErc20BalanceOfCallData(address),
|
|
|
|
}, nil)
|
|
|
|
require.NoError(chain.t, err)
|
|
|
|
|
|
|
|
return new(big.Int).SetBytes(resData)
|
|
|
|
}
|