Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[POC] sendTransfer callback #5767

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions modules/apps/transfer/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,32 @@ func (k Keeper) Transfer(goCtx context.Context, msg *types.MsgTransfer) (*types.
return nil, err
}

if !k.bankKeeper.IsSendEnabledCoin(ctx, msg.Token) {
return nil, errorsmod.Wrapf(types.ErrSendDisabled, "%s transfers are currently disabled", msg.Token.Denom)
var tokens []sdk.Coin

if msg.Token.IsZero() {
tokens = msg.Tokens
} else {
tokens = append(tokens, msg.Token)
}

for _, token := range tokens {
if !k.bankKeeper.IsSendEnabledCoin(ctx, token) {
return nil, errorsmod.Wrapf(types.ErrSendDisabled, "transfers are currently disabled for %s", token.Denom)
}
}

if k.bankKeeper.BlockedAddr(sender) {
return nil, errorsmod.Wrapf(ibcerrors.ErrUnauthorized, "%s is not allowed to send funds", sender)
}

sequence, err := k.sendTransfer(
ctx, msg.SourcePort, msg.SourceChannel, msg.Token, sender, msg.Receiver, msg.TimeoutHeight, msg.TimeoutTimestamp,
ctx, msg.SourcePort, msg.SourceChannel, tokens, sender, msg.Receiver, msg.TimeoutHeight, msg.TimeoutTimestamp,
msg.Memo)
if err != nil {
return nil, err
}

// TODO
k.Logger(ctx).Info("IBC fungible token transfer", "token", msg.Token.Denom, "amount", msg.Token.Amount.String(), "sender", msg.Sender, "receiver", msg.Receiver)

ctx.EventManager().EmitEvents(sdk.Events{
Expand Down
130 changes: 72 additions & 58 deletions modules/apps/transfer/keeper/relay.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/cosmos/ibc-go/v8/modules/apps/transfer/types"
transferv2 "github.com/cosmos/ibc-go/v8/modules/apps/transfer/v2"
clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types"
channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types"
host "github.com/cosmos/ibc-go/v8/modules/core/24-host"
Expand Down Expand Up @@ -56,7 +57,7 @@
ctx sdk.Context,
sourcePort,
sourceChannel string,
token sdk.Coin,
coins []sdk.Coin,
sender sdk.AccAddress,
receiver string,
timeoutHeight clienttypes.Height,
Expand All @@ -78,82 +79,95 @@
return 0, errorsmod.Wrap(channeltypes.ErrChannelCapabilityNotFound, "module does not own channel capability")
}

// NOTE: denomination and hex hash correctness checked during msg.ValidateBasic
fullDenomPath := token.Denom
var v2Tokens []*types.Token

var err error
for _, coin := range coins {
// NOTE: denomination and hex hash correctness checked during msg.ValidateBasic
fullDenomPath := coin.Denom

// deconstruct the token denomination into the denomination trace info
// to determine if the sender is the source chain
if strings.HasPrefix(token.Denom, "ibc/") {
fullDenomPath, err = k.DenomPathFromHash(ctx, token.Denom)
if err != nil {
return 0, err
var err error

// deconstruct the token denomination into the denomination trace info
// to determine if the sender is the source chain
if strings.HasPrefix(coin.Denom, "ibc/") {
fullDenomPath, err = k.DenomPathFromHash(ctx, coin.Denom)
if err != nil {
return 0, err
}
}
}

labels := []metrics.Label{
telemetry.NewLabel(coretypes.LabelDestinationPort, destinationPort),
telemetry.NewLabel(coretypes.LabelDestinationChannel, destinationChannel),
}
labels := []metrics.Label{
telemetry.NewLabel(coretypes.LabelDestinationPort, destinationPort),
telemetry.NewLabel(coretypes.LabelDestinationChannel, destinationChannel),
}

// NOTE: SendTransfer simply sends the denomination as it exists on its own
// chain inside the packet data. The receiving chain will perform denom
// prefixing as necessary.
// NOTE: SendTransfer simply sends the denomination as it exists on its own
// chain inside the packet data. The receiving chain will perform denom
// prefixing as necessary.

if types.SenderChainIsSource(sourcePort, sourceChannel, fullDenomPath) {
labels = append(labels, telemetry.NewLabel(coretypes.LabelSource, "true"))
if types.SenderChainIsSource(sourcePort, sourceChannel, fullDenomPath) {
labels = append(labels, telemetry.NewLabel(coretypes.LabelSource, "true"))

Check failure on line 109 in modules/apps/transfer/keeper/relay.go

View workflow job for this annotation

GitHub Actions / lint

ineffectual assignment to labels (ineffassign)

Check failure on line 109 in modules/apps/transfer/keeper/relay.go

View workflow job for this annotation

GitHub Actions / lint

ineffectual assignment to labels (ineffassign)

Check failure on line 109 in modules/apps/transfer/keeper/relay.go

View workflow job for this annotation

GitHub Actions / lint

ineffectual assignment to labels (ineffassign)

Check warning

Code scanning / CodeQL

Useless assignment to local variable Warning

This definition of labels is never used.

// obtain the escrow address for the source channel end
escrowAddress := types.GetEscrowAddress(sourcePort, sourceChannel)
if err := k.escrowToken(ctx, sender, escrowAddress, token); err != nil {
return 0, err
}
// obtain the escrow address for the source channel end
escrowAddress := types.GetEscrowAddress(sourcePort, sourceChannel)
if err := k.escrowToken(ctx, sender, escrowAddress, coin); err != nil {
return 0, err
}

} else {
labels = append(labels, telemetry.NewLabel(coretypes.LabelSource, "false"))

Check failure on line 118 in modules/apps/transfer/keeper/relay.go

View workflow job for this annotation

GitHub Actions / lint

ineffectual assignment to labels (ineffassign)

Check failure on line 118 in modules/apps/transfer/keeper/relay.go

View workflow job for this annotation

GitHub Actions / lint

ineffectual assignment to labels (ineffassign)

Check failure on line 118 in modules/apps/transfer/keeper/relay.go

View workflow job for this annotation

GitHub Actions / lint

ineffectual assignment to labels (ineffassign)

Check warning

Code scanning / CodeQL

Useless assignment to local variable Warning

This definition of labels is never used.

} else {
labels = append(labels, telemetry.NewLabel(coretypes.LabelSource, "false"))
// transfer the coins to the module account and burn them
if err := k.bankKeeper.SendCoinsFromAccountToModule(
ctx, sender, types.ModuleName, sdk.NewCoins(coin),
); err != nil {
return 0, err
}

// transfer the coins to the module account and burn them
if err := k.bankKeeper.SendCoinsFromAccountToModule(
ctx, sender, types.ModuleName, sdk.NewCoins(token),
); err != nil {
return 0, err
if err := k.bankKeeper.BurnCoins(
ctx, types.ModuleName, sdk.NewCoins(coin),
); err != nil {
// NOTE: should not happen as the module account was
// retrieved on the step above and it has enough balance
// to burn.
panic(fmt.Errorf("cannot burn coins after a successful send to a module account: %v", err))
}
}

if err := k.bankKeeper.BurnCoins(
ctx, types.ModuleName, sdk.NewCoins(token),
); err != nil {
// NOTE: should not happen as the module account was
// retrieved on the step above and it has enough balance
// to burn.
panic(fmt.Errorf("cannot burn coins after a successful send to a module account: %v", err))
denom, trace := transferv2.ExtractDenomAndTraceFromV1Denom(fullDenomPath)

token := &types.Token{
Denom: denom,
Amount: coin.Amount.Uint64(),
Trace: trace,
Metadata: &types.Metadata{},
}

v2Tokens = append(v2Tokens, token)
}

packetData := types.NewFungibleTokenPacketData(
fullDenomPath, token.Amount.String(), sender.String(), receiver, memo,
)
packetDataV2 := types.NewFungibleTokenPacketDataV2(v2Tokens, sender.String(), receiver, memo)

sequence, err := k.ics4Wrapper.SendPacket(ctx, channelCap, sourcePort, sourceChannel, timeoutHeight, timeoutTimestamp, packetData.GetBytes())
sequence, err := k.ics4Wrapper.SendPacket(ctx, channelCap, sourcePort, sourceChannel, timeoutHeight, timeoutTimestamp, packetDataV2.GetBytes())
if err != nil {
return 0, err
}

defer func() {
if token.Amount.IsInt64() {
telemetry.SetGaugeWithLabels(
[]string{"tx", "msg", "ibc", "transfer"},
float32(token.Amount.Int64()),
[]metrics.Label{telemetry.NewLabel(coretypes.LabelDenom, fullDenomPath)},
)
}

telemetry.IncrCounterWithLabels(
[]string{"ibc", types.ModuleName, "send"},
1,
labels,
)
}()
// defer func() {
// if token.Amount.IsInt64() {
// telemetry.SetGaugeWithLabels(
// []string{"tx", "msg", "ibc", "transfer"},
// float32(token.Amount.Int64()),
// []metrics.Label{telemetry.NewLabel(coretypes.LabelDenom, fullDenomPath)},
// )
// }

// telemetry.IncrCounterWithLabels(
// []string{"ibc", types.ModuleName, "send"},
// 1,
// labels,
// )
// }()

return sequence, nil
}
Expand Down
5 changes: 5 additions & 0 deletions modules/apps/transfer/types/packet.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,8 @@
Memo: memo,
}
}

// GetBytes is a helper for serialising
func (ftpdv2 FungibleTokenPacketDataV2) GetBytes() []byte {
return sdk.MustSortJSON(mustProtoMarshalJSON(&ftpdv2))
}

Check failure on line 125 in modules/apps/transfer/types/packet.go

View workflow job for this annotation

GitHub Actions / lint

File is not `gci`-ed with --skip-generated -s standard -s default -s blank -s dot -s prefix(cosmossdk.io) -s prefix(github.com/cosmos/cosmos-sdk) -s prefix(github.com/cometbft/cometbft) -s prefix(github.com/cosmos/ibc-go) --custom-order (gci)

Check failure on line 125 in modules/apps/transfer/types/packet.go

View workflow job for this annotation

GitHub Actions / lint

File is not `gci`-ed with --skip-generated -s standard -s default -s blank -s dot -s prefix(cosmossdk.io) -s prefix(github.com/cosmos/cosmos-sdk) -s prefix(github.com/cometbft/cometbft) -s prefix(github.com/cosmos/ibc-go) --custom-order (gci)

Check failure on line 125 in modules/apps/transfer/types/packet.go

View workflow job for this annotation

GitHub Actions / lint

File is not `gci`-ed with --skip-generated -s standard -s default -s blank -s dot -s prefix(cosmossdk.io) -s prefix(github.com/cosmos/cosmos-sdk) -s prefix(github.com/cometbft/cometbft) -s prefix(github.com/cosmos/ibc-go) --custom-order (gci)
137 changes: 97 additions & 40 deletions modules/apps/transfer/types/tx.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading