mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-12-24 15:25:18 +00:00
test(e2e): add tests for cosmos coin conversion (#1612)
* add e2e test for cosmos coin conversion * add e2e test for eip712 signing of converts * update kvtool
This commit is contained in:
parent
528be6350e
commit
a1f1f0d957
4
.gitignore
vendored
4
.gitignore
vendored
@ -37,3 +37,7 @@ build/bin
|
|||||||
# Ignore build dirs
|
# Ignore build dirs
|
||||||
build/darwin
|
build/darwin
|
||||||
build/linux
|
build/linux
|
||||||
|
|
||||||
|
# Go workspace files
|
||||||
|
go.work
|
||||||
|
go.work.sum
|
||||||
|
244
tests/e2e/e2e_convert_cosmos_coins_test.go
Normal file
244
tests/e2e/e2e_convert_cosmos_coins_test.go
Normal file
@ -0,0 +1,244 @@
|
|||||||
|
package e2e_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"math/big"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
sdkerrors "cosmossdk.io/errors"
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
txtypes "github.com/cosmos/cosmos-sdk/types/tx"
|
||||||
|
"github.com/ethereum/go-ethereum"
|
||||||
|
"github.com/kava-labs/kava/tests/e2e/testutil"
|
||||||
|
"github.com/kava-labs/kava/tests/util"
|
||||||
|
evmutiltypes "github.com/kava-labs/kava/x/evmutil/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
func setupConvertToCoinTest(
|
||||||
|
suite *IntegrationTestSuite, accountName string,
|
||||||
|
) (denom string, initialFunds sdk.Coins, user *testutil.SigningAccount) {
|
||||||
|
// we expect a denom to be registered to the allowed denoms param
|
||||||
|
// and for the funded account to have a balance for that denom
|
||||||
|
params, err := suite.Kava.Evmutil.Params(context.Background(), &evmutiltypes.QueryParamsRequest{})
|
||||||
|
suite.NoError(err)
|
||||||
|
suite.GreaterOrEqual(
|
||||||
|
len(params.Params.AllowedCosmosDenoms), 1,
|
||||||
|
"kava chain expected to have at least one AllowedCosmosDenom for ERC20 conversion",
|
||||||
|
)
|
||||||
|
|
||||||
|
tokenInfo := params.Params.AllowedCosmosDenoms[0]
|
||||||
|
denom = tokenInfo.CosmosDenom
|
||||||
|
initialFunds = sdk.NewCoins(
|
||||||
|
sdk.NewInt64Coin(suite.Kava.StakingDenom, 1e6), // gas money
|
||||||
|
sdk.NewInt64Coin(denom, 1e10), // conversion-enabled cosmos coin
|
||||||
|
)
|
||||||
|
|
||||||
|
user = suite.Kava.NewFundedAccount(accountName, initialFunds)
|
||||||
|
|
||||||
|
return denom, initialFunds, user
|
||||||
|
}
|
||||||
|
|
||||||
|
func (suite *IntegrationTestSuite) TestConvertCosmosCoinsToFromERC20() {
|
||||||
|
denom, initialFunds, user := setupConvertToCoinTest(suite, "cosmo-coin-converter")
|
||||||
|
|
||||||
|
fee := sdk.NewCoins(ukava(7500))
|
||||||
|
convertAmount := int64(5e9)
|
||||||
|
initialModuleBalance := suite.Kava.GetModuleBalances(evmutiltypes.ModuleName).AmountOf(denom)
|
||||||
|
|
||||||
|
///////////////////////////////
|
||||||
|
// CONVERT COSMOS COIN -> ERC20
|
||||||
|
///////////////////////////////
|
||||||
|
convertToErc20Msg := evmutiltypes.NewMsgConvertCosmosCoinToERC20(
|
||||||
|
user.SdkAddress.String(),
|
||||||
|
user.EvmAddress.Hex(),
|
||||||
|
sdk.NewInt64Coin(denom, convertAmount),
|
||||||
|
)
|
||||||
|
tx := util.KavaMsgRequest{
|
||||||
|
Msgs: []sdk.Msg{&convertToErc20Msg},
|
||||||
|
GasLimit: 2e6,
|
||||||
|
FeeAmount: fee,
|
||||||
|
Data: "converting sdk coin to erc20",
|
||||||
|
}
|
||||||
|
res := user.SignAndBroadcastKavaTx(tx)
|
||||||
|
suite.NoError(res.Err)
|
||||||
|
|
||||||
|
// query for the deployed contract
|
||||||
|
deployedContracts, err := suite.Kava.Evmutil.DeployedCosmosCoinContracts(
|
||||||
|
context.Background(),
|
||||||
|
&evmutiltypes.QueryDeployedCosmosCoinContractsRequest{CosmosDenoms: []string{denom}},
|
||||||
|
)
|
||||||
|
suite.NoError(err)
|
||||||
|
suite.Len(deployedContracts.DeployedCosmosCoinContracts, 1)
|
||||||
|
|
||||||
|
contractAddress := deployedContracts.DeployedCosmosCoinContracts[0].Address
|
||||||
|
|
||||||
|
// check erc20 balance
|
||||||
|
bz, err := suite.Kava.EvmClient.CallContract(context.Background(), ethereum.CallMsg{
|
||||||
|
To: &contractAddress.Address,
|
||||||
|
Data: util.BuildErc20BalanceOfCallData(user.EvmAddress),
|
||||||
|
}, nil)
|
||||||
|
suite.NoError(err)
|
||||||
|
erc20Balance := new(big.Int).SetBytes(bz)
|
||||||
|
suite.BigIntsEqual(big.NewInt(convertAmount), erc20Balance, "unexpected erc20 balance post-convert")
|
||||||
|
|
||||||
|
// check cosmos coin is deducted from account
|
||||||
|
expectedFunds := initialFunds.AmountOf(denom).SubRaw(convertAmount)
|
||||||
|
balance := suite.Kava.QuerySdkForBalances(user.SdkAddress).AmountOf(denom)
|
||||||
|
suite.Equal(expectedFunds, balance)
|
||||||
|
|
||||||
|
// check that module account has sdk coins
|
||||||
|
expectedModuleBalance := initialModuleBalance.AddRaw(convertAmount)
|
||||||
|
actualModuleBalance := suite.Kava.GetModuleBalances(evmutiltypes.ModuleName).AmountOf(denom)
|
||||||
|
suite.Equal(expectedModuleBalance, actualModuleBalance)
|
||||||
|
|
||||||
|
///////////////////////////////
|
||||||
|
// CONVERT ERC20 -> COSMOS COIN
|
||||||
|
///////////////////////////////
|
||||||
|
convertFromErc20Msg := evmutiltypes.NewMsgConvertCosmosCoinFromERC20(
|
||||||
|
user.EvmAddress.Hex(),
|
||||||
|
user.SdkAddress.String(),
|
||||||
|
sdk.NewInt64Coin(denom, convertAmount),
|
||||||
|
)
|
||||||
|
|
||||||
|
tx = util.KavaMsgRequest{
|
||||||
|
Msgs: []sdk.Msg{&convertFromErc20Msg},
|
||||||
|
GasLimit: 2e5,
|
||||||
|
FeeAmount: fee,
|
||||||
|
Data: "converting erc20 to cosmos coin",
|
||||||
|
}
|
||||||
|
res = user.SignAndBroadcastKavaTx(tx)
|
||||||
|
suite.NoError(res.Err)
|
||||||
|
|
||||||
|
// check erc20 balance
|
||||||
|
bz, err = suite.Kava.EvmClient.CallContract(context.Background(), ethereum.CallMsg{
|
||||||
|
To: &contractAddress.Address,
|
||||||
|
Data: util.BuildErc20BalanceOfCallData(user.EvmAddress),
|
||||||
|
}, nil)
|
||||||
|
suite.NoError(err)
|
||||||
|
erc20Balance = new(big.Int).SetBytes(bz)
|
||||||
|
suite.BigIntsEqual(big.NewInt(0), erc20Balance, "expected all erc20 to be converted back")
|
||||||
|
|
||||||
|
// check cosmos coin is added back to account
|
||||||
|
expectedFunds = initialFunds.AmountOf(denom)
|
||||||
|
balance = suite.Kava.QuerySdkForBalances(user.SdkAddress).AmountOf(denom)
|
||||||
|
suite.Equal(expectedFunds, balance)
|
||||||
|
|
||||||
|
// check that module account has sdk coins deducted
|
||||||
|
actualModuleBalance = suite.Kava.GetModuleBalances(evmutiltypes.ModuleName).AmountOf(denom)
|
||||||
|
suite.Equal(initialModuleBalance, actualModuleBalance)
|
||||||
|
}
|
||||||
|
|
||||||
|
// like the above, but confirming we can sign the messages with eip712
|
||||||
|
func (suite *IntegrationTestSuite) TestEIP712ConvertCosmosCoinsToFromERC20() {
|
||||||
|
denom, initialFunds, user := setupConvertToCoinTest(suite, "cosmo-coin-converter-eip712")
|
||||||
|
|
||||||
|
convertAmount := int64(5e9)
|
||||||
|
initialModuleBalance := suite.Kava.GetModuleBalances(evmutiltypes.ModuleName).AmountOf(denom)
|
||||||
|
|
||||||
|
///////////////////////////////
|
||||||
|
// CONVERT COSMOS COIN -> ERC20
|
||||||
|
///////////////////////////////
|
||||||
|
convertToErc20Msg := evmutiltypes.NewMsgConvertCosmosCoinToERC20(
|
||||||
|
user.SdkAddress.String(),
|
||||||
|
user.EvmAddress.Hex(),
|
||||||
|
sdk.NewInt64Coin(denom, convertAmount),
|
||||||
|
)
|
||||||
|
tx := suite.NewEip712TxBuilder(
|
||||||
|
user,
|
||||||
|
suite.Kava,
|
||||||
|
2e6,
|
||||||
|
sdk.NewCoins(ukava(1e4)),
|
||||||
|
[]sdk.Msg{&convertToErc20Msg},
|
||||||
|
"this is a memo",
|
||||||
|
).GetTx()
|
||||||
|
txBytes, err := suite.Kava.EncodingConfig.TxConfig.TxEncoder()(tx)
|
||||||
|
suite.NoError(err)
|
||||||
|
|
||||||
|
// submit the eip712 message to the chain.
|
||||||
|
res, err := suite.Kava.Tx.BroadcastTx(context.Background(), &txtypes.BroadcastTxRequest{
|
||||||
|
TxBytes: txBytes,
|
||||||
|
Mode: txtypes.BroadcastMode_BROADCAST_MODE_SYNC,
|
||||||
|
})
|
||||||
|
suite.NoError(err)
|
||||||
|
suite.Equal(sdkerrors.SuccessABCICode, res.TxResponse.Code)
|
||||||
|
|
||||||
|
_, err = util.WaitForSdkTxCommit(suite.Kava.Tx, res.TxResponse.TxHash, 6*time.Second)
|
||||||
|
suite.NoError(err)
|
||||||
|
|
||||||
|
// query for the deployed contract
|
||||||
|
deployedContracts, err := suite.Kava.Evmutil.DeployedCosmosCoinContracts(
|
||||||
|
context.Background(),
|
||||||
|
&evmutiltypes.QueryDeployedCosmosCoinContractsRequest{CosmosDenoms: []string{denom}},
|
||||||
|
)
|
||||||
|
suite.NoError(err)
|
||||||
|
suite.Len(deployedContracts.DeployedCosmosCoinContracts, 1)
|
||||||
|
|
||||||
|
contractAddress := deployedContracts.DeployedCosmosCoinContracts[0].Address
|
||||||
|
|
||||||
|
// check erc20 balance
|
||||||
|
bz, err := suite.Kava.EvmClient.CallContract(context.Background(), ethereum.CallMsg{
|
||||||
|
To: &contractAddress.Address,
|
||||||
|
Data: util.BuildErc20BalanceOfCallData(user.EvmAddress),
|
||||||
|
}, nil)
|
||||||
|
suite.NoError(err)
|
||||||
|
erc20Balance := new(big.Int).SetBytes(bz)
|
||||||
|
suite.BigIntsEqual(big.NewInt(convertAmount), erc20Balance, "unexpected erc20 balance post-convert")
|
||||||
|
|
||||||
|
// check cosmos coin is deducted from account
|
||||||
|
expectedFunds := initialFunds.AmountOf(denom).SubRaw(convertAmount)
|
||||||
|
balance := suite.Kava.QuerySdkForBalances(user.SdkAddress).AmountOf(denom)
|
||||||
|
suite.Equal(expectedFunds, balance)
|
||||||
|
|
||||||
|
// check that module account has sdk coins
|
||||||
|
expectedModuleBalance := initialModuleBalance.AddRaw(convertAmount)
|
||||||
|
actualModuleBalance := suite.Kava.GetModuleBalances(evmutiltypes.ModuleName).AmountOf(denom)
|
||||||
|
suite.Equal(expectedModuleBalance, actualModuleBalance)
|
||||||
|
|
||||||
|
///////////////////////////////
|
||||||
|
// CONVERT ERC20 -> COSMOS COIN
|
||||||
|
///////////////////////////////
|
||||||
|
convertFromErc20Msg := evmutiltypes.NewMsgConvertCosmosCoinFromERC20(
|
||||||
|
user.EvmAddress.Hex(),
|
||||||
|
user.SdkAddress.String(),
|
||||||
|
sdk.NewInt64Coin(denom, convertAmount),
|
||||||
|
)
|
||||||
|
tx = suite.NewEip712TxBuilder(
|
||||||
|
user,
|
||||||
|
suite.Kava,
|
||||||
|
2e5,
|
||||||
|
sdk.NewCoins(ukava(1e4)),
|
||||||
|
[]sdk.Msg{&convertFromErc20Msg},
|
||||||
|
"",
|
||||||
|
).GetTx()
|
||||||
|
txBytes, err = suite.Kava.EncodingConfig.TxConfig.TxEncoder()(tx)
|
||||||
|
suite.NoError(err)
|
||||||
|
|
||||||
|
// submit the eip712 message to the chain
|
||||||
|
res, err = suite.Kava.Tx.BroadcastTx(context.Background(), &txtypes.BroadcastTxRequest{
|
||||||
|
TxBytes: txBytes,
|
||||||
|
Mode: txtypes.BroadcastMode_BROADCAST_MODE_SYNC,
|
||||||
|
})
|
||||||
|
suite.NoError(err)
|
||||||
|
suite.Equal(sdkerrors.SuccessABCICode, res.TxResponse.Code)
|
||||||
|
|
||||||
|
_, err = util.WaitForSdkTxCommit(suite.Kava.Tx, res.TxResponse.TxHash, 6*time.Second)
|
||||||
|
suite.NoError(err)
|
||||||
|
|
||||||
|
// check erc20 balance
|
||||||
|
bz, err = suite.Kava.EvmClient.CallContract(context.Background(), ethereum.CallMsg{
|
||||||
|
To: &contractAddress.Address,
|
||||||
|
Data: util.BuildErc20BalanceOfCallData(user.EvmAddress),
|
||||||
|
}, nil)
|
||||||
|
suite.NoError(err)
|
||||||
|
erc20Balance = new(big.Int).SetBytes(bz)
|
||||||
|
suite.BigIntsEqual(big.NewInt(0), erc20Balance, "expected all erc20 to be converted back")
|
||||||
|
|
||||||
|
// check cosmos coin is added back to account
|
||||||
|
expectedFunds = initialFunds.AmountOf(denom)
|
||||||
|
balance = suite.Kava.QuerySdkForBalances(user.SdkAddress).AmountOf(denom)
|
||||||
|
suite.Equal(expectedFunds, balance)
|
||||||
|
|
||||||
|
// check that module account has sdk coins deducted
|
||||||
|
actualModuleBalance = suite.Kava.GetModuleBalances(evmutiltypes.ModuleName).AmountOf(denom)
|
||||||
|
suite.Equal(initialModuleBalance, actualModuleBalance)
|
||||||
|
}
|
@ -5,7 +5,7 @@ import "fmt"
|
|||||||
// TestUpgradeHandler can be used to run tests post-upgrade. If an upgrade is enabled, all tests
|
// TestUpgradeHandler can be used to run tests post-upgrade. If an upgrade is enabled, all tests
|
||||||
// are run against the upgraded chain. However, this file is a good place to consolidate all
|
// are run against the upgraded chain. However, this file is a good place to consolidate all
|
||||||
// acceptance tests for a given set of upgrade handlers.
|
// acceptance tests for a given set of upgrade handlers.
|
||||||
func (suite IntegrationTestSuite) TestUpgradeHandler() {
|
func (suite *IntegrationTestSuite) TestUpgradeHandler() {
|
||||||
suite.SkipIfUpgradeDisabled()
|
suite.SkipIfUpgradeDisabled()
|
||||||
fmt.Println("An upgrade has run!")
|
fmt.Println("An upgrade has run!")
|
||||||
suite.True(true)
|
suite.True(true)
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit ea6bd5386c80d372c52f0801ff91923eb0dab56f
|
Subproject commit 98d25c9b659eaee465c72198f387268ce763400c
|
@ -22,6 +22,7 @@ import (
|
|||||||
"github.com/kava-labs/kava/tests/util"
|
"github.com/kava-labs/kava/tests/util"
|
||||||
communitytypes "github.com/kava-labs/kava/x/community/types"
|
communitytypes "github.com/kava-labs/kava/x/community/types"
|
||||||
earntypes "github.com/kava-labs/kava/x/earn/types"
|
earntypes "github.com/kava-labs/kava/x/earn/types"
|
||||||
|
evmutiltypes "github.com/kava-labs/kava/x/evmutil/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Chain wraps query clients & accounts for a network
|
// Chain wraps query clients & accounts for a network
|
||||||
@ -42,6 +43,7 @@ type Chain struct {
|
|||||||
Community communitytypes.QueryClient
|
Community communitytypes.QueryClient
|
||||||
Earn earntypes.QueryClient
|
Earn earntypes.QueryClient
|
||||||
Evm evmtypes.QueryClient
|
Evm evmtypes.QueryClient
|
||||||
|
Evmutil evmutiltypes.QueryClient
|
||||||
Tm tmservice.ServiceClient
|
Tm tmservice.ServiceClient
|
||||||
Tx txtypes.ServiceClient
|
Tx txtypes.ServiceClient
|
||||||
}
|
}
|
||||||
@ -75,6 +77,7 @@ func NewChain(t *testing.T, details *runner.ChainDetails, fundedAccountMnemonic
|
|||||||
chain.Community = communitytypes.NewQueryClient(grpcConn)
|
chain.Community = communitytypes.NewQueryClient(grpcConn)
|
||||||
chain.Earn = earntypes.NewQueryClient(grpcConn)
|
chain.Earn = earntypes.NewQueryClient(grpcConn)
|
||||||
chain.Evm = evmtypes.NewQueryClient(grpcConn)
|
chain.Evm = evmtypes.NewQueryClient(grpcConn)
|
||||||
|
chain.Evmutil = evmutiltypes.NewQueryClient(grpcConn)
|
||||||
chain.Tm = tmservice.NewServiceClient(grpcConn)
|
chain.Tm = tmservice.NewServiceClient(grpcConn)
|
||||||
chain.Tx = txtypes.NewServiceClient(grpcConn)
|
chain.Tx = txtypes.NewServiceClient(grpcConn)
|
||||||
|
|
||||||
@ -114,3 +117,9 @@ func (chain *Chain) QuerySdkForBalances(addr sdk.AccAddress) sdk.Coins {
|
|||||||
require.NoError(chain.t, err)
|
require.NoError(chain.t, err)
|
||||||
return res.Balances
|
return res.Balances
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user