Skip to content

Commit

Permalink
feat: improve bridge call (#325)
Browse files Browse the repository at this point in the history
  • Loading branch information
zakir-code authored Apr 7, 2024
1 parent 6f9bf7b commit 977673c
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 109 deletions.
38 changes: 23 additions & 15 deletions x/crosschain/keeper/bridge_call_out.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,34 +15,42 @@ import (

func (k Keeper) AddOutgoingBridgeCall(ctx sdk.Context, msg *types.MsgBridgeCall) (*types.OutgoingBridgeCall, error) {
params := k.GetParams(ctx)
batchTimeout := k.CalExternalTimeoutHeight(ctx, params, params.ExternalBatchTimeout)
if batchTimeout <= 0 {
bridgeCallTimeout := k.CalExternalTimeoutHeight(ctx, params, params.BridgeCallTimeout)
if bridgeCallTimeout <= 0 {
return nil, errorsmod.Wrap(types.ErrInvalid, "bridge call timeout height")
}

oracleSet := k.GetLatestOracleSet(ctx)
if oracleSet == nil {
return nil, errorsmod.Wrap(types.ErrInvalid, "no oracle set")
}

nextID := k.autoIncrementID(ctx, types.KeyLastBridgeCallID)

senderAddr := sdk.MustAccAddressFromBech32(msg.Sender)
outCall := &types.OutgoingBridgeCall{
Nonce: nextID,
Timeout: batchTimeout,
Sender: fxtypes.AddressToStr(senderAddr.Bytes(), k.moduleName),
Receiver: msg.Receiver,
To: msg.To,
Asset: msg.Asset,
Message: msg.Message,
Value: msg.Value,
GasLimit: msg.GasLimit,
bridgeCall := &types.OutgoingBridgeCall{
Nonce: nextID,
Timeout: bridgeCallTimeout,
Sender: fxtypes.AddressToStr(senderAddr.Bytes(), k.moduleName),
Receiver: msg.Receiver,
To: msg.To,
Asset: msg.Asset,
Message: msg.Message,
Value: msg.Value,
GasLimit: msg.GasLimit,
OracleSetNonce: oracleSet.Nonce,
BlockHeight: uint64(ctx.BlockHeight()),
}
k.SetOutgoingBridgeCall(ctx, outCall)
k.SetOutgoingBridgeCall(ctx, bridgeCall)

ctx.EventManager().EmitEvent(sdk.NewEvent(
types.EventTypeBridgeCall,
sdk.NewAttribute(sdk.AttributeKeyModule, k.moduleName),
sdk.NewAttribute(types.AttributeKeyBridgeCallNonce, fmt.Sprint(outCall.Nonce)),
sdk.NewAttribute(sdk.AttributeKeySender, bridgeCall.Sender),
sdk.NewAttribute(types.AttributeKeyBridgeCallNonce, fmt.Sprint(bridgeCall.Nonce)),
))

return outCall, nil
return bridgeCall, nil
}

func (k Keeper) SetOutgoingBridgeCall(ctx sdk.Context, out *types.OutgoingBridgeCall) {
Expand Down
1 change: 1 addition & 0 deletions x/crosschain/keeper/bridge_call_out_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (

func (suite *KeeperTestSuite) TestKeeper_BridgeCallRefund() {
suite.bondedOracle()
suite.Commit()

bridgeToken := helpers.GenerateAddress()
bridgeTokenStr := fxtypes.AddressToStr(bridgeToken.Bytes(), suite.chainName)
Expand Down
94 changes: 0 additions & 94 deletions x/evm/precompiles/crosschain/bridge_call_test.go
Original file line number Diff line number Diff line change
@@ -1,21 +1,10 @@
package crosschain_test

import (
"encoding/hex"
"fmt"
"math/big"
"testing"

sdkmath "cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/ethereum/go-ethereum/common"
evmtypes "github.com/evmos/ethermint/x/evm/types"
"github.com/stretchr/testify/require"
tmrand "github.com/tendermint/tendermint/libs/rand"

"github.com/functionx/fx-core/v7/contract"
"github.com/functionx/fx-core/v7/testutil/helpers"
erc20types "github.com/functionx/fx-core/v7/x/erc20/types"
"github.com/functionx/fx-core/v7/x/evm/precompiles/crosschain"
)

Expand All @@ -27,86 +16,3 @@ func TestBridgeCallABI(t *testing.T) {
require.Equal(t, 7, len(crosschain.BridgeCallMethod.Inputs))
require.Equal(t, 1, len(crosschain.BridgeCallMethod.Outputs))
}

func (suite *PrecompileTestSuite) TestBridgeCall() {
testCases := []struct {
name string
malleate func(tokenPair *erc20types.TokenPair, randMint *big.Int, moduleName string) []byte
error func(args []string) string
result bool
}{
{
name: "pass",
malleate: func(tokenPair *erc20types.TokenPair, randMint *big.Int, moduleName string) []byte {
asset, err := contract.PackERC20AssetWithType([]common.Address{tokenPair.GetERC20Contract()}, []*big.Int{randMint})
suite.NoError(err)
assetBytes, err := hex.DecodeString(asset)
suite.NoError(err)

data, err := crosschain.GetABI().Pack(
"bridgeCall",
moduleName,
big.NewInt(1000),
helpers.GenerateAddress(),
helpers.GenerateAddress(),
[]byte{},
big.NewInt(0),
assetBytes,
)
suite.Require().NoError(err)
return data
},
error: func(args []string) string {
return ""
},
result: true,
},
}

for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.name), func() {
suite.SetupTest() // reset
signer := suite.RandSigner()
// token pair
md := suite.GenerateCrossChainDenoms()
moduleName := md.RandModule()

// deploy fip20 external
fip20External, err := suite.app.Erc20Keeper.DeployUpgradableToken(suite.ctx, signer.Address(), "Test token", "TEST", 18)
suite.Require().NoError(err)
// token pair
pair, err := suite.app.Erc20Keeper.RegisterNativeERC20(suite.ctx, fip20External, md.GetMetadata().DenomUnits[0].Aliases...)
suite.Require().NoError(err)

randMint := big.NewInt(int64(tmrand.Uint32() + 10))
suite.MintLockNativeTokenToModule(md.GetMetadata(), sdkmath.NewIntFromBigInt(randMint))

coin := sdk.NewCoin(pair.GetDenom(), sdkmath.NewIntFromBigInt(randMint))
helpers.AddTestAddr(suite.app, suite.ctx, signer.AccAddress().Bytes(), sdk.NewCoins(coin))
suite.MintERC20Token(signer, pair.GetERC20Contract(), suite.app.Erc20Keeper.ModuleAddress(), randMint)

_, err = suite.app.Erc20Keeper.ConvertCoin(sdk.WrapSDKContext(suite.ctx), &erc20types.MsgConvertCoin{
Coin: coin,
Receiver: signer.Address().Hex(),
Sender: signer.AccAddress().String(),
})
suite.Require().NoError(err)
suite.CrossChainKeepers()[moduleName].SetLastObservedBlockHeight(suite.ctx, 100, uint64(suite.ctx.BlockHeight()))

packData := tc.malleate(pair, randMint, moduleName)

tx, err := suite.PackEthereumTx(signer, crosschain.GetAddress(), big.NewInt(0), packData)
var res *evmtypes.MsgEthereumTxResponse
if err == nil {
res, err = suite.app.EvmKeeper.EthereumTx(sdk.WrapSDKContext(suite.ctx), tx)
}
// check result
if tc.result {
suite.Require().NoError(err)
suite.Require().False(res.Failed(), res.VmError)
} else {
suite.Require().Error(err)
}
})
}
}

0 comments on commit 977673c

Please sign in to comment.