-
Notifications
You must be signed in to change notification settings - Fork 8
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
DRAFT: Convert error to Acknowledgements #115
base: main
Are you sure you want to change the base?
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -147,18 +147,29 @@ contract ICS26Router is IICS26Router, IICS26RouterErrors, Ownable, ReentrancyGua | |
} | ||
|
||
bytes[] memory acks = new bytes[](1); | ||
acks[0] = getIBCApp(payload.destPort).onRecvPacket( | ||
bool recvSuccess = true; | ||
try getIBCApp(payload.destPort).onRecvPacket( | ||
IIBCAppCallbacks.OnRecvPacketCallback({ | ||
sourceChannel: msg_.packet.sourceChannel, | ||
destinationChannel: msg_.packet.destChannel, | ||
sequence: msg_.packet.sequence, | ||
payload: payload, | ||
relayer: _msgSender() | ||
}) | ||
); | ||
require(acks[0].length != 0, IBCAsyncAcknowledgementNotSupported()); | ||
) returns (bytes memory ack) { | ||
require(ack.length != 0, IBCAsyncAcknowledgementNotSupported()); | ||
|
||
acks[0] = abi.encodePacked( | ||
ack | ||
); | ||
} catch (bytes memory errorData) { | ||
recvSuccess = false; | ||
acks[0] = abi.encodePacked( | ||
errorData | ||
); | ||
} | ||
|
||
writeAcknowledgement(msg_.packet, acks); | ||
writeAcknowledgement(msg_.packet, recvSuccess, acks); | ||
|
||
emit RecvPacket(msg_.packet); | ||
} | ||
|
@@ -181,7 +192,7 @@ contract ICS26Router is IICS26Router, IICS26RouterErrors, Ownable, ReentrancyGua | |
ICS24Host.packetAcknowledgementCommitmentPathCalldata(msg_.packet.destChannel, msg_.packet.sequence); | ||
bytes[] memory acks = new bytes[](1); | ||
acks[0] = msg_.acknowledgement; | ||
bytes32 commitmentBz = ICS24Host.packetAcknowledgementCommitmentBytes32(acks); | ||
bytes32 commitmentBz = ICS24Host.packetAcknowledgementCommitmentBytes32(msg_.recvSuccess, acks); | ||
|
||
// verify the packet acknowledgement | ||
ILightClientMsgs.MsgMembership memory membershipMsg = ILightClientMsgs.MsgMembership({ | ||
|
@@ -203,7 +214,7 @@ contract ICS26Router is IICS26Router, IICS26RouterErrors, Ownable, ReentrancyGua | |
return noopOnCorrectReason(reason, IICS24HostErrors.IBCPacketCommitmentNotFound.selector); | ||
} | ||
|
||
getIBCApp(payload.sourcePort).onAcknowledgementPacket( | ||
try getIBCApp(payload.sourcePort).onAcknowledgementPacket( | ||
IIBCAppCallbacks.OnAcknowledgementPacketCallback({ | ||
sourceChannel: msg_.packet.sourceChannel, | ||
destinationChannel: msg_.packet.destChannel, | ||
|
@@ -212,7 +223,9 @@ contract ICS26Router is IICS26Router, IICS26RouterErrors, Ownable, ReentrancyGua | |
acknowledgement: msg_.acknowledgement, | ||
relayer: _msgSender() | ||
}) | ||
); | ||
) {} catch { | ||
// no-op | ||
} | ||
Comment on lines
+223
to
+225
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we shouldn't actually be acking a packet if the callback cannot be made right? This feels wrong There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the callback fails permanently then there's no point in resubmitting. This is for the case where ack just errors in an unrecoverable way. Resubmission won't fix anything here, so we may as well do cleanup. |
||
|
||
emit AckPacket(msg_.packet, msg_.acknowledgement); | ||
} | ||
|
@@ -256,25 +269,27 @@ contract ICS26Router is IICS26Router, IICS26RouterErrors, Ownable, ReentrancyGua | |
return noopOnCorrectReason(reason, IICS24HostErrors.IBCPacketCommitmentNotFound.selector); | ||
} | ||
|
||
getIBCApp(payload.sourcePort).onTimeoutPacket( | ||
try getIBCApp(payload.sourcePort).onTimeoutPacket( | ||
IIBCAppCallbacks.OnTimeoutPacketCallback({ | ||
sourceChannel: msg_.packet.sourceChannel, | ||
destinationChannel: msg_.packet.destChannel, | ||
sequence: msg_.packet.sequence, | ||
payload: payload, | ||
relayer: _msgSender() | ||
}) | ||
); | ||
) {} catch { | ||
// no-op | ||
} | ||
Comment on lines
+277
to
+279
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again, we need the timeout callback to succeed to unescrow funds There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ditto: What if the timeout callback can never succeed? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Then I think the packet should just be stuck? |
||
|
||
emit TimeoutPacket(msg_.packet); | ||
} | ||
|
||
/// @notice Writes a packet acknowledgement and emits an event | ||
/// @param packet The packet to acknowledge | ||
/// @param acks The acknowledgement | ||
function writeAcknowledgement(Packet calldata packet, bytes[] memory acks) private { | ||
IBC_STORE.commitPacketAcknowledgement(packet, acks); | ||
emit WriteAcknowledgement(packet, acks); | ||
function writeAcknowledgement(Packet calldata packet, bool recvSuccess, bytes[] memory acks) private { | ||
IBC_STORE.commitPacketAcknowledgement(packet, recvSuccess, acks); | ||
emit WriteAcknowledgement(packet, recvSuccess, acks); | ||
} | ||
|
||
/// @notice No-op if the reason is correct, otherwise reverts with the same reason | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't get this. We are returning an error ack if callback fails, couldn't this happen due to gas reasons?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AHh yes, i forgot about gas being an issue, in this case entire tx should revert. I basically want to return an error ack if the error is unrecoverable (i.e. the callback itself is returning an error)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Though it would be strange if you can try/catch a gas error right? Seems like a loophole that wouldn't exist 😄
Trying to read through the docs to see what the behavior of gas panics in EVM is
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the gas issue is only relevant if we call the external contract with a specific amount of gas. With a normal call we would forward all the gas the tx has, which means that we would be out of gas in the catch (therefore never get to do anything anyway). If we had limited the call to some amount of gas, then we could in theory catch it here and handle it (if we had gas left).