Skip to content

Commit 21ac65c

Browse files
committed
fix: remove NonrefundableKey feature (by codex)
1 parent 684775c commit 21ac65c

12 files changed

Lines changed: 257 additions & 215 deletions

File tree

modules/apps/packet-forward-middleware/ibc_middleware.go

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -100,18 +100,6 @@ func getDenomForThisChain(port, channel, counterpartyPort, counterpartyChannel s
100100
return denom.IBCDenom()
101101
}
102102

103-
// getBoolFromAny returns the bool value is any is a valid bool, otherwise false.
104-
func getBoolFromAny(value any) bool {
105-
if value == nil {
106-
return false
107-
}
108-
boolVal, ok := value.(bool)
109-
if !ok {
110-
return false
111-
}
112-
return boolVal
113-
}
114-
115103
// GetReceiver returns the receiver address for a given channel and original sender.
116104
// it overrides the receiver address to be a hash of the channel/origSender so that
117105
// the receiver address is deterministic and can be used to identify the sender on the
@@ -176,9 +164,6 @@ func (im *IBCMiddleware) OnRecvPacket(ctx sdk.Context, channelVersion string, pa
176164

177165
metadata := packetMetadata.Forward
178166

179-
goCtx := ctx.Context()
180-
nonrefundable := getBoolFromAny(goCtx.Value(types.NonrefundableKey{}))
181-
182167
if err := metadata.Validate(); err != nil {
183168
logger.Error("packetForwardMiddleware OnRecvPacket forward metadata is invalid", "error", err)
184169
return newErrorAcknowledgement(err)
@@ -221,7 +206,7 @@ func (im *IBCMiddleware) OnRecvPacket(ctx sdk.Context, channelVersion string, pa
221206
retries = im.retriesOnTimeout
222207
}
223208

224-
err = im.keeper.ForwardTransferPacket(ctx, nil, packet, data.Sender, overrideReceiver, metadata, token, retries, timeout, []metrics.Label{}, nonrefundable)
209+
err = im.keeper.ForwardTransferPacket(ctx, nil, packet, data.Sender, overrideReceiver, metadata, token, retries, timeout, []metrics.Label{})
225210
if err != nil {
226211
logger.Error("packetForwardMiddleware OnRecvPacket error forwarding packet", "error", err)
227212
return newErrorAcknowledgement(err)

modules/apps/packet-forward-middleware/ibc_middleware_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
package packetforward_test
22

33
import (
4-
"testing"
5-
64
"github.com/stretchr/testify/suite"
5+
"testing"
76

87
packetforward "github.com/cosmos/ibc-go/v11/modules/apps/packet-forward-middleware"
98
packetforwardkeeper "github.com/cosmos/ibc-go/v11/modules/apps/packet-forward-middleware/keeper"

modules/apps/packet-forward-middleware/keeper/genesis_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ func (s *KeeperTestSuite) TestGenesis() {
1717

1818
RetriesRemaining: 2,
1919
Timeout: 10101010101,
20-
Nonrefundable: false,
2120
}
2221

2322
key := types.RefundPacketKey(sampleInflight.PacketSrcChannelId, sampleInflight.PacketSrcPortId, sampleInflight.RefundSequence)

modules/apps/packet-forward-middleware/keeper/keeper.go

Lines changed: 2 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import (
1616
"github.com/cosmos/cosmos-sdk/codec"
1717
"github.com/cosmos/cosmos-sdk/telemetry"
1818
sdk "github.com/cosmos/cosmos-sdk/types"
19-
"github.com/cosmos/cosmos-sdk/types/bech32"
2019
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
2120

2221
"github.com/cosmos/ibc-go/v11/modules/apps/packet-forward-middleware/types"
@@ -94,69 +93,6 @@ func (*Keeper) Logger(ctx sdk.Context) log.Logger {
9493
return ctx.Logger().With("module", "x/"+ibcexported.ModuleName+"-"+types.ModuleName)
9594
}
9695

97-
// moveFundsToUserRecoverableAccount will move the funds from the escrow account to the user recoverable account
98-
// this is only used when the maximum timeouts have been reached or there is an acknowledgement error and the packet is nonrefundable,
99-
// i.e. an operation has occurred to make the original packet funds inaccessible to the user, e.g. a swap.
100-
// We cannot refund the funds back to the original chain, so we move them to an account on this chain that the user can access.
101-
func (k *Keeper) moveFundsToUserRecoverableAccount(ctx sdk.Context, packet channeltypes.Packet, token transfertypes.Token, inFlightPacket *types.InFlightPacket) error {
102-
amount, ok := sdkmath.NewIntFromString(token.GetAmount())
103-
if !ok {
104-
return fmt.Errorf("failed to parse amount from packet data for forward recovery: %s", token.GetAmount())
105-
}
106-
denom := token.GetDenom()
107-
coin := sdk.NewCoin(denom.IBCDenom(), amount)
108-
109-
userAccount, err := k.userRecoverableAccount(inFlightPacket)
110-
if err != nil {
111-
return fmt.Errorf("failed to get user recoverable account: %w", err)
112-
}
113-
114-
if !denom.HasPrefix(packet.SourcePort, packet.SourceChannel) {
115-
// mint vouchers back to sender
116-
if err := k.bankKeeper.MintCoins(ctx, transfertypes.ModuleName, sdk.NewCoins(coin)); err != nil {
117-
return err
118-
}
119-
120-
if err := k.bankKeeper.SendCoinsFromModuleToAccount(ctx, transfertypes.ModuleName, userAccount, sdk.NewCoins(coin)); err != nil {
121-
panic(fmt.Sprintf("unable to send coins from module to account despite previously minting coins to module account: %v", err))
122-
}
123-
return nil
124-
}
125-
126-
escrowAddress := transfertypes.GetEscrowAddress(packet.SourcePort, packet.SourceChannel)
127-
128-
if err := k.bankKeeper.SendCoins(ctx, escrowAddress, userAccount, sdk.NewCoins(coin)); err != nil {
129-
return fmt.Errorf("failed to send coins from escrow account to user recoverable account: %w", err)
130-
}
131-
132-
// update the total escrow amount for the denom.
133-
k.unescrowToken(ctx, coin)
134-
135-
return nil
136-
}
137-
138-
// userRecoverableAccount finds an account on this chain that the original sender of the packet can recover funds from.
139-
// If the destination receiver of the original packet is a valid bech32 address for this chain, we use that address.
140-
// Otherwise, if the sender of the original packet is a valid bech32 address for another chain, we translate that address to this chain.
141-
// Note that for the fallback, the coin type of the source chain sender account must be compatible with this chain.
142-
func (k *Keeper) userRecoverableAccount(inFlightPacket *types.InFlightPacket) (sdk.AccAddress, error) {
143-
var originalData transfertypes.FungibleTokenPacketData
144-
err := transfertypes.ModuleCdc.UnmarshalJSON(inFlightPacket.PacketData, &originalData)
145-
if err == nil { // if NO error
146-
sender, err := k.addressCodec.StringToBytes(originalData.Receiver)
147-
if err == nil { // if NO error
148-
return sender, nil
149-
}
150-
}
151-
152-
_, sender, fallbackErr := bech32.DecodeAndConvert(inFlightPacket.OriginalSenderAddress)
153-
if fallbackErr == nil { // if NO error
154-
return sender, nil
155-
}
156-
157-
return nil, fmt.Errorf("failed to decode bech32 addresses: %w", errors.Join(err, fallbackErr))
158-
}
159-
16096
func (k *Keeper) WriteAcknowledgementForForwardedPacket(ctx sdk.Context, packet channeltypes.Packet, transferDetail transfertypes.InternalTransferRepresentation, inFlightPacket *types.InFlightPacket, ack channeltypes.Acknowledgement) error {
16197
// Lookup module by channel capability
16298
_, found := k.channelKeeper.GetChannel(ctx, inFlightPacket.RefundPortId, inFlightPacket.RefundChannelId)
@@ -172,21 +108,6 @@ func (k *Keeper) WriteAcknowledgementForForwardedPacket(ctx sdk.Context, packet
172108
// On an ack error or timeout on a forwarded packet, the funds in the escrow account
173109
// should be moved to the other escrow account on the other side or burned.
174110

175-
// If this packet is non-refundable due to some action that took place between the initial ibc transfer and the forward
176-
// we write a successful ack containing details on what happened regardless of ack error or timeout
177-
if inFlightPacket.Nonrefundable {
178-
// We are not allowed to refund back to the source chain.
179-
// attempt to move funds to user recoverable account on this chain.
180-
if err := k.moveFundsToUserRecoverableAccount(ctx, packet, transferDetail.Token, inFlightPacket); err != nil {
181-
return err
182-
}
183-
184-
ackResult := fmt.Sprintf("packet forward failed after point of no return: %s", ack.GetError())
185-
newAck := channeltypes.NewResultAcknowledgement([]byte(ackResult))
186-
187-
return k.ics4Wrapper.WriteAcknowledgement(ctx, inFlightPacket.ChannelPacket(), newAck)
188-
}
189-
190111
amount, ok := sdkmath.NewIntFromString(transferDetail.Token.GetAmount())
191112
if !ok {
192113
return fmt.Errorf("failed to parse amount from packet data for forward refund: %s", transferDetail.Token.GetAmount())
@@ -252,7 +173,7 @@ func (k *Keeper) unescrowToken(ctx sdk.Context, token sdk.Coin) {
252173
k.transferKeeper.SetTotalEscrowForDenom(ctx, newTotalEscrow)
253174
}
254175

255-
func (k *Keeper) ForwardTransferPacket(ctx sdk.Context, inFlightPacket *types.InFlightPacket, srcPacket channeltypes.Packet, srcPacketSender, receiver string, metadata types.ForwardMetadata, token sdk.Coin, maxRetries uint8, timeoutDelta time.Duration, labels []metrics.Label, nonrefundable bool) error {
176+
func (k *Keeper) ForwardTransferPacket(ctx sdk.Context, inFlightPacket *types.InFlightPacket, srcPacket channeltypes.Packet, srcPacketSender, receiver string, metadata types.ForwardMetadata, token sdk.Coin, maxRetries uint8, timeoutDelta time.Duration, labels []metrics.Label) error {
256177
memo := ""
257178

258179
// set memo for next transfer with next from this transfer.
@@ -308,7 +229,6 @@ func (k *Keeper) ForwardTransferPacket(ctx sdk.Context, inFlightPacket *types.In
308229

309230
RetriesRemaining: int32(maxRetries),
310231
Timeout: uint64(timeoutDelta.Nanoseconds()),
311-
Nonrefundable: nonrefundable,
312232
}
313233
} else {
314234
inFlightPacket.RetriesRemaining--
@@ -390,7 +310,7 @@ func (k *Keeper) RetryTimeout(ctx sdk.Context, channel, port string, transferDet
390310
token := sdk.NewCoin(ibcDenom, amount)
391311

392312
// srcPacket and srcPacketSender are empty because inFlightPacket is non-nil.
393-
return k.ForwardTransferPacket(ctx, inFlightPacket, channeltypes.Packet{}, "", transferDetail.Sender, metadata, token, uint8(inFlightPacket.RetriesRemaining), time.Duration(inFlightPacket.Timeout)*time.Nanosecond, nil, inFlightPacket.Nonrefundable)
313+
return k.ForwardTransferPacket(ctx, inFlightPacket, channeltypes.Packet{}, "", transferDetail.Sender, metadata, token, uint8(inFlightPacket.RetriesRemaining), time.Duration(inFlightPacket.Timeout)*time.Nanosecond, nil)
394314
}
395315

396316
func (k *Keeper) SetInflightPacket(ctx sdk.Context, channel, port string, sequence uint64, packet *types.InFlightPacket) error {

modules/apps/packet-forward-middleware/keeper/keeper_test.go

Lines changed: 10 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"bytes"
55
"context"
66
"encoding/hex"
7-
"fmt"
87
"testing"
98
"time"
109

@@ -59,31 +58,17 @@ func (s *KeeperTestSuite) TestWriteAcknowledgementForForwardedPacket() {
5958
var expectedAckBz []byte
6059

6160
tests := []struct {
62-
name string
63-
ack channeltypes.Acknowledgement
64-
malleate func()
65-
nonRefundable bool
61+
name string
62+
ack channeltypes.Acknowledgement
63+
malleate func()
6664
}{
6765
{
68-
name: "Ack success -> propagated to ics4 wrapper",
69-
ack: channeltypes.NewResultAcknowledgement([]byte{1}),
70-
nonRefundable: false,
66+
name: "Ack success -> propagated to ics4 wrapper",
67+
ack: channeltypes.NewResultAcknowledgement([]byte{1}),
7168
},
7269
{
73-
name: "Ack error + Non refundable -> Asset moved to recoverable account then propagate ack to ics4 wrapper",
70+
name: "Ack error + Refundable -> Escrow coin then propagate ack to ics4 wrapper",
7471
ack: channeltypes.NewErrorAcknowledgement(nil),
75-
malleate: func() {
76-
ack := channeltypes.NewErrorAcknowledgement(nil)
77-
ackResult := fmt.Sprintf("packet forward failed after point of no return: %s", ack.GetError())
78-
newAck := channeltypes.NewResultAcknowledgement([]byte(ackResult))
79-
expectedAckBz = channeltypes.CommitAcknowledgement(newAck.Acknowledgement())
80-
},
81-
nonRefundable: true,
82-
},
83-
{
84-
name: "Ack error + Refundable -> Escrow coin then propagate ack to ics4 wrapper",
85-
ack: channeltypes.NewErrorAcknowledgement(nil),
86-
nonRefundable: false,
8772
},
8873
}
8974

@@ -133,7 +118,7 @@ func (s *KeeperTestSuite) TestWriteAcknowledgementForForwardedPacket() {
133118

134119
fundAcc(ctxB, s.chainB.GetSimApp().BankKeeper, intermediateAcc)
135120

136-
err := pfmKeeperB.ForwardTransferPacket(ctxB, nil, srcPacket, initialSender.String(), intermediateAcc.String(), metadata, ibctesting.TestCoin, 2, timeout, nil, tc.nonRefundable)
121+
err := pfmKeeperB.ForwardTransferPacket(ctxB, nil, srcPacket, initialSender.String(), intermediateAcc.String(), metadata, ibctesting.TestCoin, 2, timeout, nil)
137122
s.Require().NoError(err)
138123

139124
inflightPacket, err := pfmKeeperB.GetInflightPacket(ctxB, srcPacket)
@@ -212,8 +197,6 @@ func (s *KeeperTestSuite) TestForwardTransferPacket() {
212197

213198
retries := uint8(2)
214199
timeout := time.Duration(1010101010)
215-
nonRefundable := false
216-
217200
metadata := pfmtypes.ForwardMetadata{
218201
Receiver: "first-receiver",
219202
Port: path.EndpointA.ChannelConfig.PortID,
@@ -228,7 +211,7 @@ func (s *KeeperTestSuite) TestForwardTransferPacket() {
228211

229212
tc.malleate()
230213

231-
err := pfmKeeper.ForwardTransferPacket(ctx, nil, srcPacket, initialSender, finalReceiver, metadata, sdk.NewInt64Coin("denom", 1000), 2, timeout, nil, nonRefundable)
214+
err := pfmKeeper.ForwardTransferPacket(ctx, nil, srcPacket, initialSender, finalReceiver, metadata, sdk.NewInt64Coin("denom", 1000), 2, timeout, nil)
232215
s.Require().NoError(err)
233216

234217
// Get the inflight packer
@@ -238,7 +221,7 @@ func (s *KeeperTestSuite) TestForwardTransferPacket() {
238221
s.Require().Equal(inflightPacket.RetriesRemaining, int32(retries))
239222

240223
// Call the same function again with inflight packet. Num retries should decrease.
241-
err = pfmKeeper.ForwardTransferPacket(ctx, inflightPacket, srcPacket, initialSender, finalReceiver, metadata, sdk.NewInt64Coin("denom", 1000), 2, timeout, nil, nonRefundable)
224+
err = pfmKeeper.ForwardTransferPacket(ctx, inflightPacket, srcPacket, initialSender, finalReceiver, metadata, sdk.NewInt64Coin("denom", 1000), 2, timeout, nil)
242225
s.Require().NoError(err)
243226

244227
// Get the inflight packer
@@ -274,8 +257,6 @@ func (s *KeeperTestSuite) TestForwardTransferPacketWithNext() {
274257

275258
retries := uint8(2)
276259
timeout := time.Duration(1010101010)
277-
nonRefundable := false
278-
279260
// Test with valid metadata.Next - it should be a *PacketMetadata
280261
nextPacketMetadata := &pfmtypes.PacketMetadata{
281262
Forward: pfmtypes.ForwardMetadata{
@@ -300,7 +281,7 @@ func (s *KeeperTestSuite) TestForwardTransferPacketWithNext() {
300281
initialSender := s.chainA.SenderAccount.GetAddress()
301282
finalReceiver := s.chainB.SenderAccount.GetAddress()
302283

303-
err := pfmKeeper.ForwardTransferPacket(ctx, nil, srcPacket, initialSender.String(), finalReceiver.String(), metadata, sdk.NewInt64Coin("denom", 1000), 2, timeout, nil, nonRefundable)
284+
err := pfmKeeper.ForwardTransferPacket(ctx, nil, srcPacket, initialSender.String(), finalReceiver.String(), metadata, sdk.NewInt64Coin("denom", 1000), 2, timeout, nil)
304285
s.Require().NoError(err)
305286

306287
// Verify the inflight packet was created
@@ -332,7 +313,6 @@ func (s *KeeperTestSuite) TestRetryTimeoutErrorGettingNext() {
332313
inFlightPacket := &pfmtypes.InFlightPacket{
333314
RetriesRemaining: 1,
334315
Timeout: 1000,
335-
Nonrefundable: false,
336316
}
337317

338318
err := pfmKeeper.RetryTimeout(ctx, path.EndpointA.ChannelID, path.EndpointA.ChannelConfig.PortID, transferDetail, inFlightPacket)

modules/apps/packet-forward-middleware/keeper/migrator.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
sdk "github.com/cosmos/cosmos-sdk/types"
55

66
"github.com/cosmos/ibc-go/v11/modules/apps/packet-forward-middleware/migrations/v3"
7+
"github.com/cosmos/ibc-go/v11/modules/apps/packet-forward-middleware/migrations/v4"
78
)
89

910
// Migrator is a struct for handling in-place state migrations.
@@ -22,3 +23,9 @@ func NewMigrator(k *Keeper) Migrator {
2223
func (m Migrator) Migrate2to3(ctx sdk.Context) error {
2324
return v3.Migrate(ctx, m.keeper.bankKeeper, m.keeper.channelKeeper, m.keeper.transferKeeper)
2425
}
26+
27+
// Migrate3to4 migrates the module state from the consensus version 3 to
28+
// version 4.
29+
func (m Migrator) Migrate3to4(ctx sdk.Context) error {
30+
return v4.Migrate(ctx, m.keeper.storeService, m.keeper.cdc)
31+
}

0 commit comments

Comments
 (0)