From 4346856c6be3be7e6a9f43eabedf2d60cc489d6a Mon Sep 17 00:00:00 2001 From: zakir <80246097+zakir-code@users.noreply.github.com> Date: Tue, 21 Jan 2025 14:39:39 +0800 Subject: [PATCH] test: crosschain origin token (#932) --- app/init.go | 10 +++--- client/client_test.go | 4 +-- contract/crosschain_precompile.go | 9 +++++ precompiles/crosschain/contract_test.go | 9 +++-- precompiles/crosschain/crosschain_test.go | 33 +++++++++++++++++++ testutil/helpers/base_suite.go | 2 +- .../helpers/crosschain_precompile_suite.go | 6 ++++ x/crosschain/keeper/bridge_call_out.go | 8 ++--- x/crosschain/keeper/outgoing_tx.go | 2 +- x/erc20/keeper/genesis.go | 7 ---- 10 files changed, 66 insertions(+), 24 deletions(-) diff --git a/app/init.go b/app/init.go index aeb29707..25c028ec 100644 --- a/app/init.go +++ b/app/init.go @@ -10,7 +10,6 @@ import ( "github.com/pundiai/fx-core/v8/app/keepers" "github.com/pundiai/fx-core/v8/contract" fxtypes "github.com/pundiai/fx-core/v8/types" - ethtypes "github.com/pundiai/fx-core/v8/x/eth/types" ) func initChainer(ctx sdk.Context, keepers keepers.AppKeepers) error { @@ -26,11 +25,12 @@ func initChainer(ctx sdk.Context, keepers keepers.AppKeepers) error { return err } - bridgeDenoms := []contract.BridgeDenoms{ - { - ChainName: contract.MustStrToByte32(ethtypes.ModuleName), + bridgeDenoms := make([]contract.BridgeDenoms, 0) + for _, chainName := range fxtypes.GetSupportChains() { + bridgeDenoms = append(bridgeDenoms, contract.BridgeDenoms{ + ChainName: contract.MustStrToByte32(chainName), Denoms: []common.Hash{contract.MustStrToByte32(fxtypes.DefaultDenom)}, - }, + }) } acc := keepers.AccountKeeper.GetModuleAddress(evmtypes.ModuleName) diff --git a/client/client_test.go b/client/client_test.go index e2ae30b8..62d53e46 100644 --- a/client/client_test.go +++ b/client/client_test.go @@ -189,7 +189,7 @@ func (suite *rpcTestSuite) TestClient_Tx() { // 0. initAccount // 1.fee_collector + 2.distribution + 3.bonded_tokens_pool + 4.not_bonded_tokens_pool + 5.gov + 6.mint + 7.autytypes.NewModuleAddress(crosschain) // 8.evm 9.0x..1001 10.0x..1002 11.erc20 12.warp-token-contract - suite.Equal(authtypes.NewBaseAccount(toAddress, nil, uint64(21+i), 0), account) + suite.Equal(authtypes.NewBaseAccount(toAddress, nil, uint64(20+i), 0), account) } ethPrivKey := suite.GetPrivKeyByIndex(hd2.EthSecp256k1Type, 0) @@ -224,7 +224,7 @@ func (suite *rpcTestSuite) TestClient_Tx() { account, err := cli.QueryAccount(ethAddress.String()) suite.Require().NoError(err) - suite.Equal(authtypes.NewBaseAccount(ethAddress, nil, uint64(24), 0), account) + suite.Equal(authtypes.NewBaseAccount(ethAddress, nil, uint64(23), 0), account) } for i := 0; i < len(clients); i++ { diff --git a/contract/crosschain_precompile.go b/contract/crosschain_precompile.go index 43e2d404..d2e8b773 100644 --- a/contract/crosschain_precompile.go +++ b/contract/crosschain_precompile.go @@ -75,3 +75,12 @@ func (k CrosschainPrecompileKeeper) ExecuteClaim(ctx context.Context, from commo } return unpackRetIsOk(k.abi, "executeClaim", res) } + +func (k CrosschainPrecompileKeeper) Crosschain(ctx context.Context, value *big.Int, from common.Address, args CrosschainArgs) (*evmtypes.MsgEthereumTxResponse, error) { + res, err := k.ApplyContract(ctx, from, k.contractAddr, value, k.abi, "crossChain", + args.Token, args.Receipt, args.Amount, args.Fee, args.Target, args.Memo) + if err != nil { + return nil, err + } + return unpackRetIsOk(k.abi, "crossChain", res) +} diff --git a/precompiles/crosschain/contract_test.go b/precompiles/crosschain/contract_test.go index 436e7437..015aaa83 100644 --- a/precompiles/crosschain/contract_test.go +++ b/precompiles/crosschain/contract_test.go @@ -92,17 +92,20 @@ func (suite *CrosschainPrecompileTestSuite) SetOracle(online bool) crosschaintyp return oracle } -func (suite *CrosschainPrecompileTestSuite) AddBridgeToken(symbolOrAddr string, isNative bool) common.Address { +func (suite *CrosschainPrecompileTestSuite) AddBridgeToken(symbolOrAddr string, isNativeOrOrigin bool) common.Address { keeper := suite.App.Erc20Keeper var erc20Token erc20types.ERC20Token var err error - if isNative { + if isNativeOrOrigin { erc20Token, err = keeper.RegisterNativeCoin(suite.Ctx, symbolOrAddr, symbolOrAddr, 18) } else { erc20Token, err = keeper.RegisterNativeERC20(suite.Ctx, common.HexToAddress(symbolOrAddr)) } suite.Require().NoError(err) - err = keeper.AddBridgeToken(suite.Ctx, erc20Token.Denom, suite.chainName, erc20Token.Erc20Address, isNative) + if symbolOrAddr == fxtypes.DefaultSymbol { + isNativeOrOrigin = false + } + err = keeper.AddBridgeToken(suite.Ctx, erc20Token.Denom, suite.chainName, helpers.GenExternalAddr(suite.chainName), isNativeOrOrigin) suite.Require().NoError(err) return common.HexToAddress(erc20Token.Erc20Address) } diff --git a/precompiles/crosschain/crosschain_test.go b/precompiles/crosschain/crosschain_test.go index adbfbfb4..764a06ef 100644 --- a/precompiles/crosschain/crosschain_test.go +++ b/precompiles/crosschain/crosschain_test.go @@ -1,11 +1,18 @@ package crosschain_test import ( + "math/big" "testing" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/require" + "github.com/pundiai/fx-core/v8/contract" "github.com/pundiai/fx-core/v8/precompiles/crosschain" + "github.com/pundiai/fx-core/v8/testutil/helpers" + fxtypes "github.com/pundiai/fx-core/v8/types" + ethtypes "github.com/pundiai/fx-core/v8/x/eth/types" ) func TestCrosschainABI(t *testing.T) { @@ -16,3 +23,29 @@ func TestCrosschainABI(t *testing.T) { require.Len(t, crosschainABI.Event.Inputs, 8) } + +func (suite *CrosschainPrecompileTestSuite) TestContract_Crosschain() { + suite.AddBridgeToken(fxtypes.DefaultSymbol, true) + + suite.App.CrosschainKeepers.GetKeeper(suite.chainName). + SetLastObservedBlockHeight(suite.Ctx, 100, 100) + + balance := suite.Balance(suite.signer.AccAddress()) + + txResponse := suite.Crosschain(suite.Ctx, big.NewInt(2), suite.signer.Address(), + contract.CrosschainArgs{ + Token: common.Address{}, + Receipt: helpers.GenExternalAddr(suite.chainName), + Amount: big.NewInt(1), + Fee: big.NewInt(1), + Target: contract.MustStrToByte32(suite.chainName), + Memo: "", + }, + ) + suite.NotNil(txResponse) + suite.Len(txResponse.Logs, 1) + + transferCoin := helpers.NewStakingCoin(2, 0) + suite.AssertBalance(suite.signer.AccAddress(), balance.Sub(transferCoin)...) + suite.AssertBalance(authtypes.NewModuleAddress(ethtypes.ModuleName), transferCoin) +} diff --git a/testutil/helpers/base_suite.go b/testutil/helpers/base_suite.go index 3b466f09..7c5f22a5 100644 --- a/testutil/helpers/base_suite.go +++ b/testutil/helpers/base_suite.go @@ -180,7 +180,7 @@ func (s *BaseSuite) Balance(acc sdk.AccAddress) sdk.Coins { func (s *BaseSuite) AssertBalance(addr sdk.AccAddress, expBal ...sdk.Coin) { balances := s.App.BankKeeper.GetAllBalances(s.Ctx, addr) for _, bal := range expBal { - s.Equal(bal.Amount, balances.AmountOf(bal.Denom), bal.Denom) + s.Equal(bal.Amount.String(), balances.AmountOf(bal.Denom).String(), bal.Denom) } } diff --git a/testutil/helpers/crosschain_precompile_suite.go b/testutil/helpers/crosschain_precompile_suite.go index ce675109..a362ea43 100644 --- a/testutil/helpers/crosschain_precompile_suite.go +++ b/testutil/helpers/crosschain_precompile_suite.go @@ -69,3 +69,9 @@ func (s CrosschainPrecompileSuite) ExecuteClaim(ctx context.Context, from common s.requireError(err) return res } + +func (s CrosschainPrecompileSuite) Crosschain(ctx context.Context, value *big.Int, from common.Address, args contract.CrosschainArgs) *evmtypes.MsgEthereumTxResponse { + res, err := s.CrosschainPrecompileKeeper.Crosschain(ctx, value, from, args) + s.requireError(err) + return res +} diff --git a/x/crosschain/keeper/bridge_call_out.go b/x/crosschain/keeper/bridge_call_out.go index db5387cf..38dd740b 100644 --- a/x/crosschain/keeper/bridge_call_out.go +++ b/x/crosschain/keeper/bridge_call_out.go @@ -242,12 +242,10 @@ func (k Keeper) CrosschainBaseCoin(ctx sdk.Context, caller contract.Caller, from if originToken { return k.erc20Keeper.SetCache(ctx, types.NewIBCTransferKey(fxTarget.IBCChannel, sequence), amount.Amount) } - } else { - if _, err := k.BuildOutgoingTxBatch(ctx, caller, from, receipt, amount, fee); err != nil { - return err - } + return nil } - return nil + _, err := k.BuildOutgoingTxBatch(ctx, caller, from, receipt, amount, fee) + return err } func (k Keeper) IBCTransfer(ctx sdk.Context, from sdk.AccAddress, to string, amount sdk.Coin, channel, memo string) (uint64, error) { diff --git a/x/crosschain/keeper/outgoing_tx.go b/x/crosschain/keeper/outgoing_tx.go index ef52fc60..cdfb8703 100644 --- a/x/crosschain/keeper/outgoing_tx.go +++ b/x/crosschain/keeper/outgoing_tx.go @@ -19,7 +19,7 @@ func (k Keeper) BuildOutgoingTxBatch(ctx sdk.Context, caller contract.Caller, se bridgeFeeQuoteKeeper := contract.NewBridgeFeeQuoteKeeper(caller) quoteInfos, err := bridgeFeeQuoteKeeper.GetDefaultOracleQuote(ctx, contract.MustStrToByte32(k.moduleName), contract.MustStrToByte32(fee.Denom)) if err != nil { - return 0, err + return 0, types.ErrInvalid.Wrapf("failed to get bridge fee quote: %s", err.Error()) } var quoteInfo *contract.IBridgeFeeQuoteQuoteInfo for _, quote := range quoteInfos { diff --git a/x/erc20/keeper/genesis.go b/x/erc20/keeper/genesis.go index 3692c08b..75bad2c6 100644 --- a/x/erc20/keeper/genesis.go +++ b/x/erc20/keeper/genesis.go @@ -4,7 +4,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - fxtypes "github.com/pundiai/fx-core/v8/types" "github.com/pundiai/fx-core/v8/x/erc20/types" ) @@ -19,12 +18,6 @@ func (k Keeper) InitGenesis(ctx sdk.Context, data types.GenesisState) error { // NOTE: shouldn't occur return sdkerrors.ErrNotFound.Wrapf("module account %s", types.ModuleName) } - - metadata := fxtypes.NewDefaultMetadata() - _, err := k.RegisterNativeCoin(ctx, metadata.Name, metadata.Symbol, fxtypes.DenomUnit) - if err != nil { - return sdkerrors.ErrLogic.Wrapf("failed to register native coin: %s", err.Error()) - } return nil }