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

Working version of making acks optional #202

Closed
wants to merge 2 commits into from
Closed

Working version of making acks optional #202

wants to merge 2 commits into from

Conversation

mvpoyatt
Copy link

@mvpoyatt mvpoyatt commented Sep 18, 2024

Summary by CodeRabbit

  • New Features

    • Introduced AckStatus enumeration for improved acknowledgment handling.
    • Added a new Pluto contract to demonstrate IBC functionality.
  • Bug Fixes

    • Enhanced acknowledgment processing to handle different statuses (SKIP, SUCCESS, FAILURE) more robustly.
  • Tests

    • Updated tests to validate acknowledgment statuses using the new AckStatus enumeration instead of boolean values.
    • Added new test cases for the Pluto contract to ensure correct acknowledgment behavior.
    • Expanded test coverage for acknowledgment handling across various contracts.

@mvpoyatt mvpoyatt requested a review from RnkSngh September 18, 2024 17:22
Copy link

coderabbitai bot commented Sep 18, 2024

Walkthrough

The changes introduced in this pull request enhance the acknowledgment handling within the Inter-Blockchain Communication (IBC) framework. The modifications include the introduction of an AckStatus enumeration to replace boolean values, improving clarity and robustness in acknowledgment processing across multiple contracts. Additionally, new contracts and test cases are added to ensure proper functionality and coverage of the updated acknowledgment logic.

Changes

File Change Summary
contracts/core/Dispatcher.sol Enhanced acknowledgment handling by adding AckStatus checks and modifying control flow.
contracts/examples/Earth.sol Updated acknowledge function to return AckStatus.SUCCESS instead of a boolean.
contracts/examples/Mars.sol Modified acknowledgment handling to use AckStatus instead of boolean values across multiple contracts.
contracts/examples/Pluto.sol Added a new contract to serve as an IBC receiver with specific acknowledgment behavior.
contracts/libs/Ibc.sol Introduced AckStatus enumeration and updated AckPacket structure and related functions.
test/Dispatcher/Dispatcher.ack.sol Changed acknowledgment handling to return AckStatus instead of boolean in tests.
test/Dispatcher/Dispatcher.dappHandlerRevert.t.sol Updated acknowledgment status handling to use AckStatus.FAILURE.
test/Dispatcher/Dispatcher.proof.t.sol Modified acknowledgment instantiation to use AckStatus.SUCCESS.
test/Dispatcher/Dispatcher.t.sol Updated acknowledgment emissions to include AckStatus and added new test for Pluto.
test/Ibc.t.sol Adjusted acknowledgment packet validation to compare AckStatus enums instead of booleans.
test/mocks/GasUsingMars.sol Changed acknowledgment return values to use AckStatus.SUCCESS.
test/payload/ack.t.sol Updated AckPacket construction to use AckStatus instead of boolean values.
test/utils/Dispatcher.base.t.sol Modified acknowledgment handling to use AckStatus in ackToBytes and genAckPacket functions.

Possibly related PRs

Suggested labels

enhancement, bug

Poem

🐰 In the world of chains, we hop and play,
With statuses clear, we brighten the day.
From true and false, we now take flight,
Acknowledge with joy, our futures look bright!
Hooray for the changes, let’s cheer and dance,
In the land of IBC, we take our chance! 🌟


Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between e45dea0 and 18a6c0c.

Files selected for processing (1)
  • test/Dispatcher/Dispatcher.dappHandlerRevert.t.sol (3 hunks)
Files skipped from review as they are similar to previous changes (1)
  • test/Dispatcher/Dispatcher.dappHandlerRevert.t.sol

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share
Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    -- I pushed a fix in commit <commit_id>, please review it.
    -- Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    -- @coderabbitai generate unit testing code for this file.
    -- @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    -- @coderabbitai generate interesting stats about this repository and render them as a table.
    -- @coderabbitai read src/utils.ts and generate unit testing code.
    -- @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    -- @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Outside diff range and nitpick comments (1)
contracts/libs/Ibc.sol (1)

254-255: Consider handling the AckStatus.SKIP case.

The changes to the parseAckData function are consistent with the introduction of the AckStatus enum. The function correctly maps the acknowledgment data to the appropriate AckStatus value.

However, the function does not handle the AckStatus.SKIP case. Is this intentional? If skipping is applicable for this specific acknowledgment data, please consider adding a condition to return AckPacket(AckStatus.SKIP, ...) when appropriate.

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between bb93db8 and e45dea0.

Files selected for processing (13)
  • contracts/core/Dispatcher.sol (2 hunks)
  • contracts/examples/Earth.sol (2 hunks)
  • contracts/examples/Mars.sol (6 hunks)
  • contracts/examples/Pluto.sol (1 hunks)
  • contracts/libs/Ibc.sol (2 hunks)
  • test/Dispatcher/Dispatcher.ack.sol (1 hunks)
  • test/Dispatcher/Dispatcher.dappHandlerRevert.t.sol (3 hunks)
  • test/Dispatcher/Dispatcher.proof.t.sol (1 hunks)
  • test/Dispatcher/Dispatcher.t.sol (3 hunks)
  • test/Ibc.t.sol (1 hunks)
  • test/mocks/GasUsingMars.sol (2 hunks)
  • test/payload/ack.t.sol (2 hunks)
  • test/utils/Dispatcher.base.t.sol (1 hunks)
Additional comments not posted (33)
test/mocks/GasUsingMars.sol (2)

6-6: LGTM!

Importing AckStatus is a good practice as it provides a more explicit and semantically meaningful representation of the acknowledgment status.


39-39: LGTM!

Using AckStatus.SUCCESS instead of a boolean value (true) is a good practice as it provides a more explicit and semantically meaningful representation of the acknowledgment status. This change enhances the clarity and intent of the code by using a defined status rather than a generic boolean.

contracts/examples/Pluto.sol (1)

31-51: LGTM!

The Pluto contract is a simple and clear example of how to implement an IBC receiver contract that receives packets without sending acks. The contract is well-documented and follows best practices.

Some key points:

  • The contract inherits from Mars and takes an IbcDispatcher in the constructor, which is a good practice for reusability and modularity.
  • The onRecvPacket function is well-documented with clear instructions on how to validate the incoming packet.
  • The function appends the received packet to a list, which can be useful for testing and debugging.
  • The function returns an acknowledgment packet with a status of SKIP, which is a valid status for IBC packets.
  • The acknowledgment packet includes a JSON-encoded message, which is a good practice for interoperability.
  • The function is marked with the onlyIbcDispatcher modifier, which is a good practice for access control.

Overall, this contract serves as a good example for dapp developers on how to integrate with the vibc protocol.

test/payload/ack.t.sol (2)

25-25: Looks good!

The update to ackPacket1 instantiation aligns perfectly with the changes made in the getAckPacketBytes function. It ensures that the test accurately reflects the intended functionality of AckPacket.


11-11: LGTM! Verify the usage of getAckPacketBytes in the codebase.

The change from using a boolean ack.success to an enumerated AckStatus.SUCCESS enhances clarity and maintainability. It aligns well with the PR objective of making acks optional.

Please ensure that all calls to getAckPacketBytes have been updated to pass the correct AckStatus value. You can use the following script to verify the usage:

Verification successful

Verification successful: getAckPacketBytes change correctly implemented

The modification to getAckPacketBytes using AckStatus.SUCCESS instead of a boolean value has been correctly implemented. The function is only used in test files and not in the main contract code. Furthermore, the AckStatus enum is consistently used throughout the codebase, including in test files, mock contracts, and main contract files.

Key observations:

  • getAckPacketBytes implementation in test/payload/ack.t.sol is correct.
  • No instances of getAckPacketBytes being called with a boolean argument were found.
  • AckStatus is widely and consistently used across the codebase (SUCCESS, FAILURE, and SKIP statuses).

This change aligns well with the PR objective of making acks optional and enhances the overall clarity and maintainability of the code.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify all calls to `getAckPacketBytes` pass the correct `AckStatus` value.

# Test: Search for the function usage. Expect: Only occurrences with `AckStatus` argument.
rg --type solidity -A 5 $'getAckPacketBytes'

Length of output: 76


Script:

#!/bin/bash
# Description: Verify the usage of getAckPacketBytes and related concepts

# Search for getAckPacketBytes usage
echo "=== getAckPacketBytes usage ==="
rg "getAckPacketBytes" -n

# Search for getAckPacketBytes function definition
echo -e "\n=== getAckPacketBytes function definition ==="
rg "function getAckPacketBytes" -n -A 5

# Search for AckStatus usage
echo -e "\n=== AckStatus usage ==="
rg "AckStatus" -n

Length of output: 4914

test/Dispatcher/Dispatcher.ack.sol (3)

23-23: LGTM!

The code segment correctly handles the new return type of the ackPackets function, which now returns an AckStatus enum instead of a boolean. This change enhances the granularity of the acknowledgment handling by allowing for more detailed status checks.


25-27: LGTM!

The code segment correctly compares the integer representation of the AckStatus enum returned by ackPackets with the integer representation of the status from the parsed AckPacket. This ensures that the status returned by ackPackets matches the status in the parsed AckPacket.


Line range hint 1-88: No further comments.

The rest of the file looks good. The test functions provide good coverage of different scenarios related to acknowledgment handling, and there are no apparent issues or improvements needed.

test/Ibc.t.sol (2)

55-57: LGTM!

The code segment correctly compares the expected AckStatus.SUCCESS enum value with the parsed status from the acknowledgment packet by converting both to their corresponding uint8 values.


62-64: LGTM!

Similar to the previous code segment, this code segment correctly compares the expected AckStatus.FAILURE enum value with the parsed status from the error acknowledgment packet by converting both to their corresponding uint8 values.

test/Dispatcher/Dispatcher.dappHandlerRevert.t.sol (4)

68-68: LGTM!

The change from using a boolean value to the AckStatus.FAILURE enum value improves clarity and type safety when emitting the WriteAckPacket event.


79-79: LGTM!

Similar to the previous change, using the AckStatus.FAILURE enum value instead of a boolean improves clarity and type safety when emitting the WriteAckPacket event.


86-86: LGTM!

The change to use the AckStatus.FAILURE enum value in the AckPacket struct when emitting the WriteAckPacket event is consistent with the previous changes and improves clarity and type safety.


96-96: LGTM!

Once again, using the AckStatus.FAILURE enum value in the AckPacket struct when emitting the WriteAckPacket event is a consistent and clear way to indicate a failure scenario.

contracts/examples/Earth.sol (2)

20-20: LGTM!

The import statement is syntactically correct and the AckStatus enum is likely used in the contract to represent the status of an acknowledgment packet.


169-169: Excellent change!

Replacing the boolean value with the AckStatus.SUCCESS enum value enhances the clarity and robustness of the acknowledgment mechanism. It provides a more structured and explicit way to represent the status of an acknowledgment packet.

The change is consistent with the import of the AckStatus enum and improves the overall code quality.

test/Dispatcher/Dispatcher.proof.t.sol (1)

131-131: LGTM!

The change from using a boolean value to AckStatus.SUCCESS for instantiating the AckPacket improves the clarity and maintainability of the code. It provides a more descriptive and type-safe representation of the acknowledgment status.

The change is consistent with the emit statement and aligns the test with the expected behavior of the recvPacket function.

contracts/libs/Ibc.sol (2)

68-72: LGTM!

The new AckStatus enum provides more granular and expressive acknowledgment status compared to the previous boolean field. The enum values are well-named and self-explanatory.


77-77: Verify the impact of the field change.

The change from success to status is consistent with the introduction of the AckStatus enum. However, please ensure that:

  1. The parseAckData function is updated to use the new status field.
  2. Existing code that uses the success field of AckPacket is updated to use the status field.

Run the following script to verify the usage of the success field:

test/utils/Dispatcher.base.t.sol (2)

253-255: Refactor to use AckStatus enumeration improves code clarity and robustness.

The change from using a boolean to an enumeration for determining the success of the acknowledgment is a good refactor. It enhances code clarity and robustness by explicitly defining the acknowledgment states.

Ensure that the AckStatus enumeration is defined and imported correctly.


260-260: Consistent usage of AckStatus.SUCCESS maintains code consistency.

The change to use AckStatus.SUCCESS when creating the AckPacket is consistent with the refactor in the ackToBytes function. It maintains code consistency and aligns with the usage of the AckStatus enumeration.

contracts/examples/Mars.sol (5)

20-20: LGTM!

The import statement for AckStatus is necessary to support the transition from using boolean values to the AckStatus enum for representing acknowledgment statuses in the subsequent code changes.


90-90: Looks good!

Using AckStatus.SUCCESS instead of true for a successful acknowledgment improves code clarity and aligns with the transition to using the AckStatus enum for representing acknowledgment statuses.


249-249: LGTM!

Using AckStatus.FAILURE instead of false for a failed acknowledgment improves code clarity and aligns with the transition to using the AckStatus enum for representing acknowledgment statuses.


284-284: Looks good!

Using AckStatus.FAILURE instead of false for a failed acknowledgment improves code clarity and aligns with the transition to using the AckStatus enum for representing acknowledgment statuses.


300-300: LGTM!

Using AckStatus.FAILURE instead of false for failed acknowledgments in the RevertingEmptyMars and PanickingMars contracts improves code clarity and aligns with the transition to using the AckStatus enum for representing acknowledgment statuses.

Also applies to: 309-309

test/Dispatcher/Dispatcher.t.sol (3)

4-4: LGTM!

The import statement for the AckStatus enum is correct and relevant to the test suite.


354-354: Improved clarity in the WriteAckPacket emission.

Using the AckStatus.SUCCESS enum value instead of a boolean enhances the readability and maintainability of the code.


359-368: Valid addition of the test_pluto_noAck test function.

The new test function correctly verifies that receiving a packet from the Pluto contract does not trigger an acknowledgment. It sets up the necessary components, such as creating an instance of Pluto and constructing an IbcEndpoint, and uses the vm.expectEmit cheatcode to validate the emitted events.

contracts/core/Dispatcher.sol (4)

28-28: LGTM!

The import statement for AckStatus is syntactically correct and consistent with the list of alterations.


626-628: Verify the intended behavior and impact of skipping packet processing for the AckStatus.SKIP status.

The added check for AckStatus.SKIP introduces an early return, effectively ignoring the packet when this status is received. Please ensure that this is the intended behavior and consider the potential impact on the packet processing flow.


630-630: LGTM!

Using the AckStatus.FAILURE enum value for the failure case enhances clarity regarding the acknowledgment's outcome compared to the previous boolean representation.


626-630: LGTM!

The changes introduce explicit handling of different acknowledgment statuses, improving the robustness of the packet handling logic. Skipping packet processing for AckStatus.SKIP and setting the status to AckStatus.FAILURE in the failure case align with the expected behavior based on the status values.

@@ -623,8 +623,11 @@ contract Dispatcher is Ownable2StepUpgradeable, UUPSUpgradeable, ReentrancyGuard
_callIfContract(receiver, abi.encodeWithSelector(IbcPacketReceiver.onRecvPacket.selector, packet));
if (success) {
(ack) = abi.decode(data, (AckPacket));
if (ack.status == AckStatus.SKIP) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

consider adding some in-line comments explaining that this is the case where app choses not to have an ack

IbcEndpoint memory plutoDest = IbcEndpoint(plutoPort, channelId);
vm.expectEmit(true, true, true, true, address(dispatcherProxy));
emit RecvPacket(address(pluto), channelId, packetSeq);
dispatcherProxy.recvPacket(IbcPacket(src, plutoDest, packetSeq, payload, ZERO_HEIGHT, maxTimeout), validProof);
Copy link
Collaborator

Choose a reason for hiding this comment

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

in addition to the asserting that the recvPacket event was emitted, we also need to test that:

  • the WriteAckPacket was NOT emitted
  • _ackPacketCommitment was NOT set to true

for the first case, we have to be a bit clever, use expectEmit and emit a unique event after the call, such that the expect emit will pass iff writeAckPacket event was not emitted (I'd suggest reading expect emit docs first to understand how event testing works, it's a tad unintuitive)

for second case, you can use something like findAckPacketCommitmentSlot in test/upgradeableProxy/UpgradeUtils.t.sol to calculate and read from a storage slot in dispatcher proxy, and ensure that that is indeed not set to true

struct AckPacket {
// success indicates the dApp-level logic. Even when a dApp fails to process a packet per its dApp logic, the
// delivery of packet and ack packet are still considered successful.
bool success;
AckStatus status;
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm just now realizing that, because this AckPacket type is used in the acknowledgement proof, we can't change this existing type and need to add a new type with the enum. Otherwise we might have to make changes to peptide to support this new enum change.

So I think we need to have two seperate AckPackets types now:

  • an AckPacket with the enum status which the dapp returns in the onrecv callback
  • the original AckPacket type with the bool success that is emitted in the dispatcher events (and in turn used in peptide proofs)

? AckPacket(true, Base64.decode(string(ack[11:ack.length - 2]))) // result success
: AckPacket(false, ack[10:ack.length - 2]); // this is an error
? AckPacket(AckStatus.SUCCESS, Base64.decode(string(ack[11:ack.length - 2]))) // result success
: AckPacket(AckStatus.FAILURE, ack[10:ack.length - 2]); // this is an error
Copy link
Collaborator

Choose a reason for hiding this comment

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

See the other comment, but we actually can't change the AckPacket return type here, since parseAckData is used to find the proof key in the acknowledge method in dispatcher. We need to have two seperate ackPacket types now

@mvpoyatt mvpoyatt closed this Sep 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants