-
Notifications
You must be signed in to change notification settings - Fork 751
Fix and simplify reverts of forwarding state #6574
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
Merged
DimitrisJim
merged 16 commits into
feat/ics20-v2-path-forwarding
from
serdar/6558-refactor-revert-forward
Jun 13, 2024
Merged
Changes from all commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
6305f3f
refactor: initial simplification attempt
srdtrk b13dae4
refactor: further organize
srdtrk f25c918
fix: all tests fixed
srdtrk 492ecac
docs: improved godocs
srdtrk 7770197
fix: logic and testing error
srdtrk bcf359d
style: self suggestion
srdtrk d867a5e
docs: suggestion
srdtrk a092154
docs: spellcheck
srdtrk 0f4c22c
style: suggestions
srdtrk 13270d8
style: renamed to revertForwardedPacket
srdtrk e5b9d78
style: suggestion
srdtrk e75c29e
docs: remove docs
srdtrk 3123d67
docs: godoc suggestion
srdtrk cbad515
style: suggestion
srdtrk d3a60fc
Merge branch 'feat/ics20-v2-path-forwarding' into serdar/6558-refacto…
srdtrk 45c7efa
docs: colin suggestions
srdtrk File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,99 @@ | ||
| package keeper | ||
|
|
||
| import ( | ||
| "errors" | ||
|
|
||
| errorsmod "cosmossdk.io/errors" | ||
| sdkmath "cosmossdk.io/math" | ||
|
|
||
| sdk "github.com/cosmos/cosmos-sdk/types" | ||
|
|
||
| "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" | ||
| channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" | ||
| host "github.com/cosmos/ibc-go/v8/modules/core/24-host" | ||
| ) | ||
|
|
||
| // ackForwardPacketError reverts the receive packet logic that occurs in the middle chain and writes the async ack for the prevPacket | ||
| func (k Keeper) ackForwardPacketError(ctx sdk.Context, prevPacket channeltypes.Packet, failedPacketData types.FungibleTokenPacketDataV2) error { | ||
| // the forwarded packet has failed, thus the funds have been refunded to the intermediate address. | ||
| // we must revert the changes that came from successfully receiving the tokens on our chain | ||
| // before propagating the error acknowledgement back to original sender chain | ||
| if err := k.revertForwardedPacket(ctx, prevPacket, failedPacketData); err != nil { | ||
| return err | ||
| } | ||
|
|
||
| forwardAck := channeltypes.NewErrorAcknowledgement(errors.New("forwarded packet failed")) | ||
damiannolan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| return k.acknowledgeForwardedPacket(ctx, prevPacket, forwardAck) | ||
| } | ||
|
|
||
| // ackForwardPacketSuccess writes a successful async acknowledgement for the prevPacket | ||
| func (k Keeper) ackForwardPacketSuccess(ctx sdk.Context, prevPacket channeltypes.Packet) error { | ||
| forwardAck := channeltypes.NewResultAcknowledgement([]byte("forwarded packet succeeded")) | ||
damiannolan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| return k.acknowledgeForwardedPacket(ctx, prevPacket, forwardAck) | ||
| } | ||
|
|
||
| // ackForwardPacketTimeout reverts the receive packet logic that occurs in the middle chain and writes a failed async ack for the prevPacket | ||
| func (k Keeper) ackForwardPacketTimeout(ctx sdk.Context, prevPacket channeltypes.Packet, timeoutPacketData types.FungibleTokenPacketDataV2) error { | ||
| if err := k.revertForwardedPacket(ctx, prevPacket, timeoutPacketData); err != nil { | ||
| return err | ||
| } | ||
|
|
||
| // the timeout is converted into an error acknowledgement in order to propagate the failed packet forwarding | ||
| // back to the original sender | ||
| forwardAck := channeltypes.NewErrorAcknowledgement(errors.New("forwarded packet timed out")) | ||
| return k.acknowledgeForwardedPacket(ctx, prevPacket, forwardAck) | ||
| } | ||
|
|
||
| // acknowledgeForwardedPacket writes the async acknowledgement for packet | ||
| func (k Keeper) acknowledgeForwardedPacket(ctx sdk.Context, packet channeltypes.Packet, ack channeltypes.Acknowledgement) error { | ||
colin-axner marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| capability, ok := k.scopedKeeper.GetCapability(ctx, host.ChannelCapabilityPath(packet.DestinationPort, packet.DestinationChannel)) | ||
| if !ok { | ||
| return errorsmod.Wrap(channeltypes.ErrChannelCapabilityNotFound, "module does not own channel capability") | ||
| } | ||
|
|
||
| return k.ics4Wrapper.WriteAcknowledgement(ctx, capability, packet, ack) | ||
| } | ||
|
|
||
| // revertForwardedPacket reverts the logic of receive packet that occurs in the middle chains during a packet forwarding. | ||
damiannolan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| // If the packet fails to be forwarded all the way to the final destination, the state changes on this chain must be reverted | ||
| // before sending back the error acknowledgement to ensure atomic packet forwarding. | ||
| func (k Keeper) revertForwardedPacket(ctx sdk.Context, prevPacket channeltypes.Packet, failedPacketData types.FungibleTokenPacketDataV2) error { | ||
| /* | ||
| Recall that RecvPacket handles an incoming packet depending on the denom of the received funds: | ||
| 1. If the funds are native, then the amount is sent to the receiver from the escrow. | ||
| 2. If the funds are foreign, then a voucher token is minted. | ||
| We revert it in this function by: | ||
| 1. Sending funds back to escrow if the funds are native. | ||
| 2. Burning voucher tokens if the funds are foreign | ||
| */ | ||
|
|
||
| forwardingAddr := types.GetForwardAddress(prevPacket.DestinationPort, prevPacket.DestinationChannel) | ||
| escrow := types.GetEscrowAddress(prevPacket.DestinationPort, prevPacket.DestinationChannel) | ||
|
|
||
| // we can iterate over the received tokens of prevPacket by iterating over the sent tokens of failedPacketData | ||
| for _, token := range failedPacketData.Tokens { | ||
| // parse the transfer amount | ||
| transferAmount, ok := sdkmath.NewIntFromString(token.Amount) | ||
| if !ok { | ||
| return errorsmod.Wrapf(types.ErrInvalidAmount, "unable to parse transfer amount (%s) into math.Int", transferAmount) | ||
| } | ||
| coin := sdk.NewCoin(token.Denom.IBCDenom(), transferAmount) | ||
|
|
||
| // check if the token we received originated on the sender | ||
| // given that the packet is being reversed, we check the DestinationChannel and DestinationPort | ||
| // of the prevPacket to see if a hop was added to the trace during the receive step | ||
| if token.Denom.SenderChainIsSource(prevPacket.DestinationPort, prevPacket.DestinationChannel) { | ||
| // then send it back to the escrow address | ||
| if err := k.escrowCoin(ctx, forwardingAddr, escrow, coin); err != nil { | ||
| return err | ||
| } | ||
|
|
||
| continue | ||
| } | ||
|
|
||
| if err := k.burnCoin(ctx, forwardingAddr, coin); err != nil { | ||
| return err | ||
| } | ||
| } | ||
| return nil | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.