Skip to content

Commit

Permalink
feat: use a generated intermediate address as the forwarder
Browse files Browse the repository at this point in the history
  • Loading branch information
javiersuweijie committed Jul 26, 2023
1 parent ff99bd9 commit 5a9bc08
Show file tree
Hide file tree
Showing 7 changed files with 207 additions and 65 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,5 @@ message InFlightPacket {
int32 retries_remaining = 10;
uint64 timeout = 11;
bool nonrefundable = 12;
string fee_payer = 13;
}
28 changes: 26 additions & 2 deletions middleware/packet-forward-middleware/router/ibc_middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package router
import (
"encoding/json"
"fmt"
"github.com/cosmos/cosmos-sdk/types/address"

Check failure on line 6 in middleware/packet-forward-middleware/router/ibc_middleware.go

View workflow job for this annotation

GitHub Actions / Linter (./middleware/packet-forward-middleware)

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

Check failure on line 8 in middleware/packet-forward-middleware/router/ibc_middleware.go

View workflow job for this annotation

GitHub Actions / Linter (./middleware/packet-forward-middleware)

File is not `gofumpt`-ed (gofumpt)

Expand Down Expand Up @@ -143,6 +144,8 @@ func (im IBCMiddleware) OnRecvPacket(
packet channeltypes.Packet,
relayer sdk.AccAddress,
) ibcexported.Acknowledgement {
var err error

var data transfertypes.FungibleTokenPacketData
if err := transfertypes.ModuleCdc.UnmarshalJSON(packet.GetData(), &data); err != nil {
return channeltypes.NewErrorAcknowledgement(err)
Expand All @@ -156,12 +159,20 @@ func (im IBCMiddleware) OnRecvPacket(
)

d := make(map[string]interface{})
err := json.Unmarshal([]byte(data.Memo), &d)
err = json.Unmarshal([]byte(data.Memo), &d)
if err != nil || d["forward"] == nil {
// not a packet that should be forwarded
im.keeper.Logger(ctx).Debug("packetForwardMiddleware OnRecvPacket forward metadata does not exist")
return im.app.OnRecvPacket(ctx, packet, relayer)
}

// originalReceiver will pay fees for the forwarded packet
originalReceiver := data.Receiver
// Ignore the receiver on the packet and use a generated address instead
data.Receiver, err = DeriveIntermediateAddress(packet.SourcePort, packet.SourceChannel, data.Sender)
if err != nil {
return channeltypes.NewErrorAcknowledgement(err)
}
m := &types.PacketMetadata{}
err = json.Unmarshal([]byte(data.Memo), m)
if err != nil {
Expand All @@ -183,6 +194,11 @@ func (im IBCMiddleware) OnRecvPacket(
// underlying app, otherwise the transfer module's OnRecvPacket callback could be invoked more than once
// which would mint/burn vouchers more than once
if !processed {
// Replace the packet receiver with the address of the generated intermediate account
packet.Data, err = transfertypes.ModuleCdc.MarshalJSON(&data)
if err != nil {
return channeltypes.NewErrorAcknowledgement(err)
}
ack := im.app.OnRecvPacket(ctx, packet, relayer)
if ack == nil || !ack.Success() {
return ack
Expand Down Expand Up @@ -220,7 +236,7 @@ func (im IBCMiddleware) OnRecvPacket(
retries = im.retriesOnTimeout
}

err = im.keeper.ForwardTransferPacket(ctx, nil, packet, data.Sender, data.Receiver, metadata, token, retries, timeout, []metrics.Label{}, nonrefundable)
err = im.keeper.ForwardTransferPacket(ctx, nil, packet, data.Sender, originalReceiver, data.Receiver, metadata, token, retries, timeout, []metrics.Label{}, nonrefundable)
if err != nil {
return channeltypes.NewErrorAcknowledgement(err)
}
Expand Down Expand Up @@ -336,3 +352,11 @@ func (im IBCMiddleware) GetAppVersion(
) (string, bool) {
return im.keeper.GetAppVersion(ctx, portID, channelID)
}

func DeriveIntermediateAddress(port, channel, originalSender string) (string, error) {
senderStr := fmt.Sprintf("%s/%s/%s", port, channel, originalSender)
senderHash32 := address.Hash(types.IntermediateAddrPrefix, []byte(senderStr))
addr := sdk.AccAddress(senderHash32[:])

Check failure on line 359 in middleware/packet-forward-middleware/router/ibc_middleware.go

View workflow job for this annotation

GitHub Actions / Linter (./middleware/packet-forward-middleware)

unslice: could simplify senderHash32[:] to senderHash32 (gocritic)
bech32Prefix := sdk.GetConfig().GetBech32AccountAddrPrefix()
return sdk.Bech32ifyAddressBytes(bech32Prefix, addr)
}
21 changes: 16 additions & 5 deletions middleware/packet-forward-middleware/router/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,8 @@ func (k *Keeper) ForwardTransferPacket(
inFlightPacket *types.InFlightPacket,
srcPacket channeltypes.Packet,
srcPacketSender string,
receiver string,
feePayer string,
intermediateSender string,
metadata *types.ForwardMetadata,
token sdk.Coin,
maxRetries uint8,
Expand All @@ -218,7 +219,7 @@ func (k *Keeper) ForwardTransferPacket(

// pay fees
if feeAmount.IsPositive() {
hostAccAddr, err := sdk.AccAddressFromBech32(receiver)
hostAccAddr, err := sdk.AccAddressFromBech32(feePayer)
if err != nil {
return err
}
Expand Down Expand Up @@ -249,7 +250,7 @@ func (k *Keeper) ForwardTransferPacket(
metadata.Port,
metadata.Channel,
packetCoin,
receiver,
intermediateSender,
metadata.Receiver,
DefaultTransferPacketTimeoutHeight,
uint64(ctx.BlockTime().UnixNano())+uint64(timeout.Nanoseconds()),
Expand All @@ -258,7 +259,7 @@ func (k *Keeper) ForwardTransferPacket(

k.Logger(ctx).Debug("packetForwardMiddleware ForwardTransferPacket",
"port", metadata.Port, "channel", metadata.Channel,
"sender", receiver, "receiver", metadata.Receiver,
"sender", intermediateSender, "receiver", metadata.Receiver,
"amount", packetCoin.Amount.String(), "denom", packetCoin.Denom,
)

Expand All @@ -270,7 +271,7 @@ func (k *Keeper) ForwardTransferPacket(
if err != nil {
k.Logger(ctx).Error("packetForwardMiddleware ForwardTransferPacket error",
"port", metadata.Port, "channel", metadata.Channel,
"sender", receiver, "receiver", metadata.Receiver,
"sender", intermediateSender, "receiver", metadata.Receiver,
"amount", packetCoin.Amount.String(), "denom", packetCoin.Denom,
"error", err,
)
Expand All @@ -285,6 +286,7 @@ func (k *Keeper) ForwardTransferPacket(
inFlightPacket = &types.InFlightPacket{
PacketData: srcPacket.Data,
OriginalSenderAddress: srcPacketSender,
FeePayer: feePayer,
RefundChannelId: srcPacket.DestinationChannel,
RefundPortId: srcPacket.DestinationPort,
RefundSequence: srcPacket.Sequence,
Expand Down Expand Up @@ -391,12 +393,21 @@ func (k *Keeper) RetryTimeout(

token := sdk.NewCoin(denom, amount)

// Handle backward compatibility for inflight packets right after the middleware upgrade
var feePayer string
if inFlightPacket.FeePayer == "" {
feePayer = data.Sender
} else {
feePayer = inFlightPacket.FeePayer
}

// srcPacket and srcPacketSender are empty because inFlightPacket is non-nil.
return k.ForwardTransferPacket(
ctx,
inFlightPacket,
channeltypes.Packet{},
"",
feePayer,
data.Sender,
metadata,
token,
Expand Down
1 change: 0 additions & 1 deletion middleware/packet-forward-middleware/router/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"context"
"encoding/json"
"fmt"

Check failure on line 6 in middleware/packet-forward-middleware/router/module.go

View workflow job for this annotation

GitHub Actions / Linter (./middleware/packet-forward-middleware)

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

"github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v7/router/client/cli"
"github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v7/router/keeper"
"github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v7/router/types"
Expand Down
Loading

0 comments on commit 5a9bc08

Please sign in to comment.