Skip to content

Commit

Permalink
refactor: restructure bridge call logic for improved readability
Browse files Browse the repository at this point in the history
  • Loading branch information
zakir-code committed Jan 9, 2025
1 parent 9020cc4 commit 0a3ae7e
Show file tree
Hide file tree
Showing 10 changed files with 194 additions and 205 deletions.
4 changes: 2 additions & 2 deletions x/crosschain/keeper/attestation_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ func (k Keeper) ExecuteClaim(ctx sdk.Context, eventNonce uint64) (preExecuteErr,
case *types.MsgSendToFxClaim:
executeErr = k.SendToFxExecuted(cacheCtx, claim)
case *types.MsgBridgeCallClaim:
executeErr = k.BridgeCallHandler(cacheCtx, claim)
executeErr = k.BridgeCallExecuted(cacheCtx, claim)
case *types.MsgBridgeCallResultClaim:
executeErr = k.BridgeCallResultHandler(cacheCtx, claim)
executeErr = k.BridgeCallResultExecuted(cacheCtx, claim)
default:
executeErr = sdkerrors.ErrInvalidRequest.Wrapf("invalid claim type: %s", claim.GetType())
}
Expand Down
15 changes: 0 additions & 15 deletions x/crosschain/keeper/bridge_account.go

This file was deleted.

22 changes: 8 additions & 14 deletions x/crosschain/keeper/bridge_call_in.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (
"github.com/pundiai/fx-core/v8/x/crosschain/types"
)

func (k Keeper) BridgeCallHandler(ctx sdk.Context, msg *types.MsgBridgeCallClaim) error {
func (k Keeper) BridgeCallExecuted(ctx sdk.Context, msg *types.MsgBridgeCallClaim) error {
k.CreateBridgeAccount(ctx, msg.TxOrigin)
if senderAccount := k.ak.GetAccount(ctx, msg.GetSenderAddr().Bytes()); senderAccount != nil {
if _, ok := senderAccount.(sdk.ModuleAccountI); ok {
Expand All @@ -41,7 +41,7 @@ func (k Keeper) BridgeCallHandler(ctx sdk.Context, msg *types.MsgBridgeCallClaim
baseCoins = baseCoins.Add(baseCoin)
}

if err := k.handlerBridgeCallInFee(ctx, msg.GetSenderAddr(), msg.QuoteId.BigInt(), msg.GasLimit.BigInt()); err != nil {
if err := k.HandlerBridgeCallInFee(ctx, msg.GetSenderAddr(), msg.QuoteId.BigInt(), msg.GasLimit.BigInt()); err != nil {
return err
}

Expand Down Expand Up @@ -88,7 +88,7 @@ func (k Keeper) BridgeCallHandler(ctx sdk.Context, msg *types.MsgBridgeCallClaim
sdk.NewAttribute(types.AttributeKeyBridgeCallFailedRefundAddr, msg.GetRefundAddr().Hex()),
))

// onRevert bridgecall
// onRevert bridgeCall
_, err = k.AddOutgoingBridgeCall(ctx, msg.GetToAddr(), common.Address{}, sdk.NewCoins(),
msg.GetSenderAddr(), []byte(revertMsg), []byte{}, 0, msg.EventNonce)
return err
Expand Down Expand Up @@ -137,16 +137,10 @@ func (k Keeper) BridgeCallEvm(ctx sdk.Context, sender, refundAddr, to, receiverA
return nil
}

func (k Keeper) handlerBridgeCallInFee(ctx sdk.Context, from common.Address, quoteId, gasLimit *big.Int) error {
if quoteId == nil || quoteId.Sign() <= 0 {
// Allow free bridgeCall
return nil
}

quote, err := k.ValidateQuote(ctx, quoteId, gasLimit)
if err != nil {
return err
func (k Keeper) CreateBridgeAccount(ctx sdk.Context, address string) {
accAddress := fxtypes.ExternalAddrToAccAddr(k.moduleName, address)
if account := k.ak.GetAccount(ctx, accAddress); account != nil {
return
}

return k.TransferBridgeFee(ctx, from, quote.Oracle, quote.Fee, quote.TokenName)
k.ak.NewAccountWithAddress(ctx, accAddress)
}
2 changes: 1 addition & 1 deletion x/crosschain/keeper/bridge_call_in_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func (suite *KeeperTestSuite) TestBridgeCallHandler() {
erc20Tokens = append(erc20Tokens, erc20Token)
}

err := suite.Keeper().BridgeCallHandler(suite.Ctx, &tc.Msg)
err := suite.Keeper().BridgeCallExecuted(suite.Ctx, &tc.Msg)
if tc.Success {
suite.Require().NoError(err)
if !tc.CallContract {
Expand Down
177 changes: 5 additions & 172 deletions x/crosschain/keeper/bridge_call_out.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,16 @@ package keeper
import (
"encoding/hex"
"fmt"
"math"
"math/big"
"strconv"
"time"

"cosmossdk.io/collections"
"cosmossdk.io/errors"
sdkmath "cosmossdk.io/math"
storetypes "cosmossdk.io/store/types"
"github.com/cosmos/cosmos-sdk/telemetry"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
gogotypes "github.com/cosmos/gogoproto/types"
transfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types"
ibcclienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types"
"github.com/ethereum/go-ethereum/common"
Expand Down Expand Up @@ -101,7 +98,7 @@ func (k Keeper) BuildOutgoingBridgeCall(ctx sdk.Context, sender, refundAddr comm
return outCall, nil
}

func (k Keeper) BridgeCallResultHandler(ctx sdk.Context, claim *types.MsgBridgeCallResultClaim) error {
func (k Keeper) BridgeCallResultExecuted(ctx sdk.Context, claim *types.MsgBridgeCallResultClaim) error {
k.CreateBridgeAccount(ctx, claim.TxOrigin)

outgoingBridgeCall, found := k.GetOutgoingBridgeCallByNonce(ctx, claim.Nonce)
Expand Down Expand Up @@ -195,101 +192,6 @@ func (k Keeper) RefundOutgoingBridgeCall(ctx sdk.Context, data *types.OutgoingBr
return nil
}

func (k Keeper) DeleteOutgoingBridgeCallRecord(ctx sdk.Context, bridgeCallNonce uint64) error {
// 1. delete bridge call
k.DeleteOutgoingBridgeCall(ctx, bridgeCallNonce)

// 2. delete bridge call confirm
k.DeleteBridgeCallConfirm(ctx, bridgeCallNonce)

// 3. delete cache origin amount
return k.erc20Keeper.DeleteCache(ctx, types.NewOriginTokenKey(k.moduleName, bridgeCallNonce))
}

func (k Keeper) SetOutgoingBridgeCall(ctx sdk.Context, outCall *types.OutgoingBridgeCall) {
store := ctx.KVStore(k.storeKey)
store.Set(types.GetOutgoingBridgeCallNonceKey(outCall.Nonce), k.cdc.MustMarshal(outCall))
// value is just a placeholder
store.Set(
types.GetOutgoingBridgeCallAddressAndNonceKey(outCall.Sender, outCall.Nonce),
k.cdc.MustMarshal(&gogotypes.BoolValue{Value: true}),
)
}

func (k Keeper) HasOutgoingBridgeCall(ctx sdk.Context, nonce uint64) bool {
return ctx.KVStore(k.storeKey).Has(types.GetOutgoingBridgeCallNonceKey(nonce))
}

func (k Keeper) HasOutgoingBridgeCallAddressAndNonce(ctx sdk.Context, sender string, nonce uint64) bool {
return ctx.KVStore(k.storeKey).Has(types.GetOutgoingBridgeCallAddressAndNonceKey(sender, nonce))
}

func (k Keeper) GetOutgoingBridgeCallByNonce(ctx sdk.Context, nonce uint64) (*types.OutgoingBridgeCall, bool) {
store := ctx.KVStore(k.storeKey)
bz := store.Get(types.GetOutgoingBridgeCallNonceKey(nonce))
if bz == nil {
return nil, false
}
var outCall types.OutgoingBridgeCall
k.cdc.MustUnmarshal(bz, &outCall)
return &outCall, true
}

func (k Keeper) DeleteOutgoingBridgeCall(ctx sdk.Context, nonce uint64) {
store := ctx.KVStore(k.storeKey)
outCall, found := k.GetOutgoingBridgeCallByNonce(ctx, nonce)
if !found {
return
}
store.Delete(types.GetOutgoingBridgeCallNonceKey(nonce))
store.Delete(types.GetOutgoingBridgeCallAddressAndNonceKey(outCall.Sender, outCall.Nonce))
}

func (k Keeper) IterateOutgoingBridgeCalls(ctx sdk.Context, cb func(outCall *types.OutgoingBridgeCall) bool) {
store := ctx.KVStore(k.storeKey)
iterator := storetypes.KVStorePrefixIterator(store, types.OutgoingBridgeCallNonceKey)
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
var outCall types.OutgoingBridgeCall
k.cdc.MustUnmarshal(iterator.Value(), &outCall)
if cb(&outCall) {
break
}
}
}

func (k Keeper) IterateOutgoingBridgeCallsByAddress(ctx sdk.Context, senderAddr string, cb func(outCall *types.OutgoingBridgeCall) bool) {
store := ctx.KVStore(k.storeKey)
iterator := storetypes.KVStorePrefixIterator(store, types.GetOutgoingBridgeCallAddressKey(senderAddr))
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
nonce := types.ParseOutgoingBridgeCallNonce(iterator.Key(), senderAddr)
outCall, found := k.GetOutgoingBridgeCallByNonce(ctx, nonce)
if !found {
continue
}
if cb(outCall) {
break
}
}
}

func (k Keeper) IterateOutgoingBridgeCallByNonce(ctx sdk.Context, startNonce uint64, cb func(outCall *types.OutgoingBridgeCall) bool) {
store := ctx.KVStore(k.storeKey)
startKey := append(types.OutgoingBridgeCallNonceKey, sdk.Uint64ToBigEndian(startNonce)...)
endKey := append(types.OutgoingBridgeCallNonceKey, sdk.Uint64ToBigEndian(math.MaxUint64)...)
iter := store.Iterator(startKey, endKey)
defer iter.Close()

for ; iter.Valid(); iter.Next() {
outCall := new(types.OutgoingBridgeCall)
k.cdc.MustUnmarshal(iter.Value(), outCall)
if cb(outCall) {
break
}
}
}

func (k Keeper) BridgeCallBaseCoin(ctx sdk.Context, from, refund, to common.Address, coins sdk.Coins, data, memo []byte, quoteId, gasLimit *big.Int, fxTarget *types.FxTarget, originTokenAmount sdkmath.Int) (uint64, error) {
var cacheKey string
var nonce uint64
Expand Down Expand Up @@ -318,7 +220,7 @@ func (k Keeper) BridgeCallBaseCoin(ctx sdk.Context, from, refund, to common.Addr
}
cacheKey = types.NewOriginTokenKey(k.moduleName, nonce)

if err = k.handlerBridgeCallOutFee(ctx, from, nonce, quoteId, gasLimit); err != nil {
if err = k.HandlerBridgeCallOutFee(ctx, from, nonce, quoteId, gasLimit); err != nil {
return 0, err
}
}
Expand All @@ -331,15 +233,8 @@ func (k Keeper) BridgeCallBaseCoin(ctx sdk.Context, from, refund, to common.Addr
return nonce, nil
}

func (k Keeper) CrosschainBaseCoin(
ctx sdk.Context,
from sdk.AccAddress,
receipt string,
amount, fee sdk.Coin,
fxTarget *types.FxTarget,
memo string,
originToken bool,
) error {
// Deprecated: precompile crosschain api has been deprecated
func (k Keeper) CrosschainBaseCoin(ctx sdk.Context, from sdk.AccAddress, receipt string, amount, fee sdk.Coin, fxTarget *types.FxTarget, memo string, originToken bool) error {
if fxTarget.IsIBC() {
sequence, err := k.IBCTransfer(ctx, from.Bytes(), receipt, amount, fxTarget.IBCChannel, memo)
if err != nil {
Expand All @@ -356,14 +251,7 @@ func (k Keeper) CrosschainBaseCoin(
return nil
}

func (k Keeper) IBCTransfer(
ctx sdk.Context,
from sdk.AccAddress,
to string,
amount sdk.Coin,
channel string,
memo string,
) (uint64, error) {
func (k Keeper) IBCTransfer(ctx sdk.Context, from sdk.AccAddress, to string, amount sdk.Coin, channel, memo string) (uint64, error) {
timeout := 12 * time.Hour
transferResponse, err := k.ibcTransferKeeper.Transfer(ctx,
transfertypes.NewMsgTransfer(
Expand All @@ -383,61 +271,6 @@ func (k Keeper) IBCTransfer(
return transferResponse.Sequence, nil
}

func (k Keeper) handlerBridgeCallOutFee(ctx sdk.Context, from common.Address, bridgeCallNonce uint64, quoteId, gasLimit *big.Int) error {
if quoteId == nil || quoteId.Sign() <= 0 {
// Users can send submitBridgeCall by themselves without paying
return nil
}

quote, err := k.ValidateQuote(ctx, quoteId, gasLimit)
if err != nil {
return err
}

bridgeFeeAddr := common.BytesToAddress(k.bridgeFeeCollector)
if err = k.TransferBridgeFee(ctx, from, bridgeFeeAddr, quote.Fee, quote.TokenName); err != nil {
return err
}

k.SetOutgoingBridgeCallQuoteInfo(ctx, bridgeCallNonce, types.NewQuoteInfo(quote))
return nil
}

func (k Keeper) TransferBridgeFeeToRelayer(ctx sdk.Context, bridgeCallNonce uint64) error {
quote, found := k.GetOutgoingBridgeCallQuoteInfo(ctx, bridgeCallNonce)
if !found {
return nil
}

k.DeleteOutgoingBridgeCallQuoteInfo(ctx, bridgeCallNonce)

bridgeFeeAddr := common.BytesToAddress(k.bridgeFeeCollector)
return k.TransferBridgeFee(ctx, bridgeFeeAddr, quote.OracleAddress(), quote.Fee.BigInt(), quote.Token)
}

func (k Keeper) SetOutgoingBridgeCallQuoteInfo(ctx sdk.Context, nonce uint64, quoteInfo types.QuoteInfo) {
store := ctx.KVStore(k.storeKey)
store.Set(types.GetBridgeCallQuoteKey(nonce), k.cdc.MustMarshal(&quoteInfo))
}

func (k Keeper) GetOutgoingBridgeCallQuoteInfo(ctx sdk.Context, nonce uint64) (types.QuoteInfo, bool) {
store := ctx.KVStore(k.storeKey)

bz := store.Get(types.GetBridgeCallQuoteKey(nonce))
if bz == nil {
return types.QuoteInfo{}, false
}

quoteInfo := types.QuoteInfo{}
k.cdc.MustUnmarshal(bz, &quoteInfo)
return quoteInfo, true
}

func (k Keeper) DeleteOutgoingBridgeCallQuoteInfo(ctx sdk.Context, nonce uint64) {
store := ctx.KVStore(k.storeKey)
store.Delete(types.GetBridgeCallQuoteKey(nonce))
}

func (k Keeper) ResendBridgeCall(ctx sdk.Context, bridgeCall types.OutgoingBridgeCall, quoteInfo types.QuoteInfo) error {
bridgeCallTimeout := k.CalExternalTimeoutHeight(ctx, GetBridgeCallTimeout)
if bridgeCallTimeout <= 0 {
Expand Down
2 changes: 1 addition & 1 deletion x/crosschain/keeper/bridge_call_out_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func (s *KeeperMockSuite) TestKeeper_BridgeCallResultHandler() {
Timeout: 0,
BlockHeight: 0,
})
err := s.crosschainKeeper.BridgeCallResultHandler(s.ctx, msg)
err := s.crosschainKeeper.BridgeCallResultExecuted(s.ctx, msg)
s.Require().NoError(err)
outgoingBridgeCall, found := s.crosschainKeeper.GetOutgoingBridgeCallByNonce(s.ctx, msg.Nonce)
s.False(found)
Expand Down
Loading

0 comments on commit 0a3ae7e

Please sign in to comment.