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

DRAFT: Convert error to Acknowledgements #115

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 2 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
39 changes: 27 additions & 12 deletions src/ICS26Router.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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
);
Copy link
Member

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?

Copy link
Member Author

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)

Copy link
Member Author

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

Copy link
Contributor

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).

}

writeAcknowledgement(msg_.packet, acks);
writeAcknowledgement(msg_.packet, recvSuccess, acks);

emit RecvPacket(msg_.packet);
}
Expand All @@ -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({
Expand All @@ -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,
Expand All @@ -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
Copy link
Member

Choose a reason for hiding this comment

The 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

Copy link
Member Author

Choose a reason for hiding this comment

The 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);
}
Expand Down Expand Up @@ -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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, we need the timeout callback to succeed to unescrow funds

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto: What if the timeout callback can never succeed?

Copy link
Member

Choose a reason for hiding this comment

The 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
Expand Down
3 changes: 2 additions & 1 deletion src/interfaces/IIBCStore.sol
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,9 @@ interface IIBCStore {

/// @notice Commits a packet acknowledgement
/// @param packet The packet to commit the acknowledgement for
/// @param recvSuccess The success of the receivePacket app callback
/// @param acks The list of acknowledgements (one for each payload) to commit
function commitPacketAcknowledgement(IICS26RouterMsgs.Packet memory packet, bytes[] memory acks) external;
function commitPacketAcknowledgement(IICS26RouterMsgs.Packet memory packet, bool recvSuccess, bytes[] memory acks) external;

// --------------------- Events --------------------- //

Expand Down
3 changes: 2 additions & 1 deletion src/interfaces/IICS26Router.sol
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,9 @@ interface IICS26Router is IICS26RouterMsgs {
event RecvPacket(Packet packet);
/// @notice Emitted when a packet acknowledgement is written
/// @param packet The packet that was acknowledged
/// @param recvSuccess The success of the receivePacket app callback
/// @param acknowledgements The list of acknowledgements data
event WriteAcknowledgement(Packet packet, bytes[] acknowledgements);
event WriteAcknowledgement(Packet packet, bool recvSuccess, bytes[] acknowledgements);
/// @notice Emitted when a packet is timed out
/// @param packet The packet that was timed out
event TimeoutPacket(Packet packet);
Expand Down
2 changes: 2 additions & 0 deletions src/msgs/IICS26RouterMsgs.sol
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,13 @@ interface IICS26RouterMsgs {

/// @notice Message for acknowledging packets, submitted by relayer
/// @param packet The packet to be acknowledged
/// @param recvSuccess The success of receivePacket app callback
/// @param acknowledgement The acknowledgement
/// @param proofAcked The proof of the acknowledgement commitment
/// @param proofHeight The proof height
struct MsgAckPacket {
Packet packet;
bool recvSuccess;
bytes acknowledgement;
bytes proofAcked;
IICS02ClientMsgs.Height proofHeight;
Expand Down
4 changes: 2 additions & 2 deletions src/utils/IBCStore.sol
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ contract IBCStore is IIBCStore, IICS24HostErrors, Ownable {
}

/// @inheritdoc IIBCStore
function commitPacketAcknowledgement(IICS26RouterMsgs.Packet memory packet, bytes[] memory acks) public onlyOwner {
function commitPacketAcknowledgement(IICS26RouterMsgs.Packet memory packet, bool recvSuccess, bytes[] memory acks) public onlyOwner {
bytes32 path = ICS24Host.packetAcknowledgementCommitmentKeyCalldata(packet.destChannel, packet.sequence);
require(
commitments[path] == 0,
Expand All @@ -83,7 +83,7 @@ contract IBCStore is IIBCStore, IICS24HostErrors, Ownable {
)
);

bytes32 commitment = ICS24Host.packetAcknowledgementCommitmentBytes32(acks);
bytes32 commitment = ICS24Host.packetAcknowledgementCommitmentBytes32(recvSuccess, acks);
emit AckCommitted(path, commitment);
commitments[path] = commitment;
}
Expand Down
4 changes: 2 additions & 2 deletions src/utils/ICS24Host.sol
Original file line number Diff line number Diff line change
Expand Up @@ -152,13 +152,13 @@ library ICS24Host {
/// @dev each payload get one ack each from their application, so this function accepts a list of acks
/// @param acks The list of acknowledgements to get the commitment for
/// @return The commitment bytes
function packetAcknowledgementCommitmentBytes32(bytes[] memory acks) internal pure returns (bytes32) {
function packetAcknowledgementCommitmentBytes32(bool recvSuccess, bytes[] memory acks) internal pure returns (bytes32) {
bytes memory ackBytes = "";
for (uint256 i = 0; i < acks.length; i++) {
ackBytes = abi.encodePacked(ackBytes, sha256(acks[i]));
}

return sha256(abi.encodePacked(uint8(2), ackBytes));
return sha256(abi.encodePacked(uint8(2), recvSuccess, ackBytes));
}

/// @notice Create a prefixed path
Expand Down
4 changes: 2 additions & 2 deletions test/BenchmarkTest.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ contract BenchmarkTest is FixtureTest {
recvFixture.packet.destChannel, recvFixture.packet.sequence
)
);
assertEq(storedAck, ICS24Host.packetAcknowledgementCommitmentBytes32(singleSuccessAck));
assertEq(storedAck, ICS24Host.packetAcknowledgementCommitmentBytes32(true, singleSuccessAck));
}

function test_ICS20TransferNativeSdkCoinWithSP1Fixtures_Plonk() public {
Expand All @@ -84,7 +84,7 @@ contract BenchmarkTest is FixtureTest {
recvNativeFixture.packet.destChannel, recvNativeFixture.packet.sequence
)
);
assertEq(storedAck, ICS24Host.packetAcknowledgementCommitmentBytes32(singleSuccessAck));
assertEq(storedAck, ICS24Host.packetAcknowledgementCommitmentBytes32(true, singleSuccessAck));
}

function test_ICS20TimeoutWithSP1Fixtures_Plonk() public {
Expand Down
4 changes: 2 additions & 2 deletions test/ICS24HostTest.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@ contract ICS24HostTest is Test {
bytes memory ack = abi.encodePacked("some bytes");
bytes[] memory acks = new bytes[](1);
acks[0] = ack;
bytes32 ackHash = ICS24Host.packetAcknowledgementCommitmentBytes32(acks);
bytes32 ackHash = ICS24Host.packetAcknowledgementCommitmentBytes32(true, acks);
string memory actualAckHash = Strings.toHexString(uint256(ackHash));
string memory expectedAckHash = "0xf03b4667413e56aaf086663267913e525c442b56fa1af4fa3f3dab9f37044c5b";
string memory expectedAckHash = "0xfc02a4453c297c9b65189ec354f4fc7f0c1327b72f6044a20d4dd1fac8fda9f7";
assertEq(actualAckHash, expectedAckHash);
}

Expand Down
32 changes: 20 additions & 12 deletions test/IntegrationTest.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ contract IntegrationTest is Test {

IICS26RouterMsgs.MsgAckPacket memory ackMsg = IICS26RouterMsgs.MsgAckPacket({
packet: packet,
recvSuccess: true,
acknowledgement: ICS20Lib.SUCCESSFUL_ACKNOWLEDGEMENT_JSON,
proofAcked: bytes("doesntmatter"), // dummy client will accept
proofHeight: IICS02ClientMsgs.Height({ revisionNumber: 1, revisionHeight: 42 }) // dummy client will accept
Expand Down Expand Up @@ -135,6 +136,7 @@ contract IntegrationTest is Test {

IICS26RouterMsgs.MsgAckPacket memory ackMsg = IICS26RouterMsgs.MsgAckPacket({
packet: packet,
recvSuccess: false,
acknowledgement: ICS20Lib.FAILED_ACKNOWLEDGEMENT_JSON,
proofAcked: bytes("doesntmatter"), // dummy client will accept
proofHeight: IICS02ClientMsgs.Height({ revisionNumber: 1, revisionHeight: 42 }) // dummy client will accept
Expand All @@ -159,6 +161,7 @@ contract IntegrationTest is Test {

IICS26RouterMsgs.MsgAckPacket memory ackMsg = IICS26RouterMsgs.MsgAckPacket({
packet: packet,
recvSuccess: false,
acknowledgement: ICS20Lib.FAILED_ACKNOWLEDGEMENT_JSON,
proofAcked: bytes("doesntmatter"), // dummy client will accept
proofHeight: IICS02ClientMsgs.Height({ revisionNumber: 1, revisionHeight: 42 }) // dummy client will accept
Expand All @@ -181,6 +184,7 @@ contract IntegrationTest is Test {

IICS26RouterMsgs.MsgAckPacket memory ackMsg = IICS26RouterMsgs.MsgAckPacket({
packet: packet,
recvSuccess: false,
acknowledgement: ICS20Lib.FAILED_ACKNOWLEDGEMENT_JSON,
proofAcked: bytes("doesntmatter"), // dummy client will accept
proofHeight: IICS02ClientMsgs.Height({ revisionNumber: 1, revisionHeight: 42 }) // dummy client will accept
Expand Down Expand Up @@ -285,6 +289,7 @@ contract IntegrationTest is Test {

IICS26RouterMsgs.MsgAckPacket memory ackMsg = IICS26RouterMsgs.MsgAckPacket({
packet: packet,
recvSuccess: true,
acknowledgement: ICS20Lib.SUCCESSFUL_ACKNOWLEDGEMENT_JSON,
proofAcked: bytes("doesntmatter"), // dummy client will accept
proofHeight: IICS02ClientMsgs.Height({ revisionNumber: 1, revisionHeight: 42 }) // dummy client will accept
Expand Down Expand Up @@ -339,7 +344,7 @@ contract IntegrationTest is Test {
address(erc20)
);
vm.expectEmit();
emit IICS26Router.WriteAcknowledgement(packet, singleSuccessAck);
emit IICS26Router.WriteAcknowledgement(packet, true, singleSuccessAck);
vm.expectEmit();
emit IICS26Router.RecvPacket(packet);

Expand All @@ -359,14 +364,15 @@ contract IntegrationTest is Test {
bytes32 storedAck = ics26Router.IBC_STORE().getCommitment(
ICS24Host.packetAcknowledgementCommitmentKeyCalldata(packet.destChannel, packet.sequence)
);
assertEq(storedAck, ICS24Host.packetAcknowledgementCommitmentBytes32(singleSuccessAck));
assertEq(storedAck, ICS24Host.packetAcknowledgementCommitmentBytes32(true, singleSuccessAck));
}

function test_success_recvNoop() public {
IICS26RouterMsgs.Packet memory packet = _sendICS20Transfer();

IICS26RouterMsgs.MsgAckPacket memory ackMsg = IICS26RouterMsgs.MsgAckPacket({
packet: packet,
recvSuccess: true,
acknowledgement: ICS20Lib.SUCCESSFUL_ACKNOWLEDGEMENT_JSON,
proofAcked: bytes("doesntmatter"), // dummy client will accept
proofHeight: IICS02ClientMsgs.Height({ revisionNumber: 1, revisionHeight: 42 }) // dummy client will accept
Expand Down Expand Up @@ -421,7 +427,7 @@ contract IntegrationTest is Test {
bytes32 storedAck = ics26Router.IBC_STORE().getCommitment(
ICS24Host.packetAcknowledgementCommitmentKeyCalldata(packet.destChannel, packet.sequence)
);
assertEq(storedAck, ICS24Host.packetAcknowledgementCommitmentBytes32(singleSuccessAck));
assertEq(storedAck, ICS24Host.packetAcknowledgementCommitmentBytes32(true, singleSuccessAck));

// call recv again, should be noop
vm.expectEmit();
Expand All @@ -435,6 +441,7 @@ contract IntegrationTest is Test {

IICS26RouterMsgs.MsgAckPacket memory ackMsg = IICS26RouterMsgs.MsgAckPacket({
packet: packet,
recvSuccess: true,
acknowledgement: ICS20Lib.SUCCESSFUL_ACKNOWLEDGEMENT_JSON,
proofAcked: bytes("doesntmatter"), // dummy client will accept
proofHeight: IICS02ClientMsgs.Height({ revisionNumber: 1, revisionHeight: 42 }) // dummy client will accept
Expand Down Expand Up @@ -489,7 +496,7 @@ contract IntegrationTest is Test {
bytes32 storedAck = ics26Router.IBC_STORE().getCommitment(
ICS24Host.packetAcknowledgementCommitmentKeyCalldata(packet.destChannel, packet.sequence)
);
assertEq(storedAck, ICS24Host.packetAcknowledgementCommitmentBytes32(singleSuccessAck));
assertEq(storedAck, ICS24Host.packetAcknowledgementCommitmentBytes32(true, singleSuccessAck));

// override IBCStore to ErroneousIBCStore
vm.mockFunction(
Expand Down Expand Up @@ -535,7 +542,7 @@ contract IntegrationTest is Test {
vm.expectEmit(true, true, true, false); // Not checking data because we don't know the address yet
emit IICS20Transfer.ICS20ReceiveTransfer(packetData, erc20Address); // we check these values later
vm.expectEmit();
emit IICS26Router.WriteAcknowledgement(receivePacket, singleSuccessAck);
emit IICS26Router.WriteAcknowledgement(receivePacket, true, singleSuccessAck);
vm.expectEmit();
emit IICS26Router.RecvPacket(receivePacket);

Expand All @@ -552,7 +559,7 @@ contract IntegrationTest is Test {
bytes32 storedAck = ics26Router.IBC_STORE().getCommitment(
ICS24Host.packetAcknowledgementCommitmentKeyCalldata(receivePacket.destChannel, receivePacket.sequence)
);
assertEq(storedAck, ICS24Host.packetAcknowledgementCommitmentBytes32(singleSuccessAck));
assertEq(storedAck, ICS24Host.packetAcknowledgementCommitmentBytes32(true, singleSuccessAck));

// find and extract data from the ICS20ReceiveTransfer event
Vm.Log memory receiveTransferLog = vm.getRecordedLogs()[3];
Expand Down Expand Up @@ -701,11 +708,11 @@ contract IntegrationTest is Test {
bytes32 storedAck = ics26Router.IBC_STORE().getCommitment(
ICS24Host.packetAcknowledgementCommitmentKeyCalldata(receivePacket.destChannel, receivePacket.sequence)
);
assertEq(storedAck, ICS24Host.packetAcknowledgementCommitmentBytes32(singleSuccessAck));
assertEq(storedAck, ICS24Host.packetAcknowledgementCommitmentBytes32(true, singleSuccessAck));
bytes32 storedAck2 = ics26Router.IBC_STORE().getCommitment(
ICS24Host.packetAcknowledgementCommitmentKeyCalldata(receivePacket2.destChannel, receivePacket2.sequence)
);
assertEq(storedAck2, ICS24Host.packetAcknowledgementCommitmentBytes32(singleSuccessAck));
assertEq(storedAck2, ICS24Host.packetAcknowledgementCommitmentBytes32(true, singleSuccessAck));
}

function test_failure_receiveMultiPacketWithForeignBaseDenom() public {
Expand Down Expand Up @@ -806,7 +813,7 @@ contract IntegrationTest is Test {
address erc20Address;
emit IICS20Transfer.ICS20ReceiveTransfer(packetData, erc20Address); // we check these values later
vm.expectEmit();
emit IICS26Router.WriteAcknowledgement(receivePacket, singleSuccessAck);
emit IICS26Router.WriteAcknowledgement(receivePacket, true, singleSuccessAck);
vm.expectEmit();
emit IICS26Router.RecvPacket(receivePacket);

Expand All @@ -823,7 +830,7 @@ contract IntegrationTest is Test {
bytes32 storedAck = ics26Router.IBC_STORE().getCommitment(
ICS24Host.packetAcknowledgementCommitmentKeyCalldata(receivePacket.destChannel, receivePacket.sequence)
);
assertEq(storedAck, ICS24Host.packetAcknowledgementCommitmentBytes32(singleSuccessAck));
assertEq(storedAck, ICS24Host.packetAcknowledgementCommitmentBytes32(true, singleSuccessAck));

// find and extract data from the ICS20ReceiveTransfer event
Vm.Log memory receiveTransferLog = vm.getRecordedLogs()[3];
Expand Down Expand Up @@ -945,7 +952,7 @@ contract IntegrationTest is Test {
address erc20Address;
emit IICS20Transfer.ICS20ReceiveTransfer(packetData, erc20Address); // we check these values later
vm.expectEmit();
emit IICS26Router.WriteAcknowledgement(receivePacket, singleSuccessAck);
emit IICS26Router.WriteAcknowledgement(receivePacket, true, singleSuccessAck);
vm.expectEmit();
emit IICS26Router.RecvPacket(receivePacket);

Expand All @@ -962,7 +969,7 @@ contract IntegrationTest is Test {
bytes32 storedAck = ics26Router.IBC_STORE().getCommitment(
ICS24Host.packetAcknowledgementCommitmentKeyCalldata(receivePacket.destChannel, receivePacket.sequence)
);
assertEq(storedAck, ICS24Host.packetAcknowledgementCommitmentBytes32(singleSuccessAck));
assertEq(storedAck, ICS24Host.packetAcknowledgementCommitmentBytes32(true, singleSuccessAck));

// find and extract data from the ICS20ReceiveTransfer event
Vm.Log memory receiveTransferLog = vm.getRecordedLogs()[3];
Expand Down Expand Up @@ -1054,6 +1061,7 @@ contract IntegrationTest is Test {

IICS26RouterMsgs.MsgAckPacket memory ackMsg = IICS26RouterMsgs.MsgAckPacket({
packet: packet,
recvSuccess: true,
acknowledgement: ICS20Lib.SUCCESSFUL_ACKNOWLEDGEMENT_JSON,
proofAcked: bytes("doesntmatter"), // dummy client will accept
proofHeight: IICS02ClientMsgs.Height({ revisionNumber: 1, revisionHeight: 42 }) // dummy client will accept
Expand Down
2 changes: 1 addition & 1 deletion test/mocks/ErroneousIBCStore.sol
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ contract ErroneousIBCStore is IIBCStore {
revert CallFailure("setPacketReceipt");
}

function commitPacketAcknowledgement(IICS26RouterMsgs.Packet memory, bytes[] memory) external pure {
function commitPacketAcknowledgement(IICS26RouterMsgs.Packet memory, bool, bytes[] memory) external pure {
revert CallFailure("commitPacketAcknowledgement");
}
}
Loading