Skip to content

feat: cancel invalid withdrawAndCall if execution fails with unknown error#3837

Merged
ws4charlie merged 5 commits intodevelopfrom
sui-cancel-invalid-withdrawAndCall-tx
May 7, 2025
Merged

feat: cancel invalid withdrawAndCall if execution fails with unknown error#3837
ws4charlie merged 5 commits intodevelopfrom
sui-cancel-invalid-withdrawAndCall-tx

Conversation

@ws4charlie
Copy link
Contributor

@ws4charlie ws4charlie commented Apr 30, 2025

Description

If withdrawAndCall can't go through due to unknown errors, ZetaClient should check execution error in detail and cancel the outbound properly. This is a safety check that prevents Sui outbound blockage

Closes: #3799
Closes: #3778

How Has This Been Tested?

  • Tested CCTX in localnet
  • Tested in development environment
  • Go unit tests
  • Go integration tests
  • Tested via GitHub Actions

Summary by CodeRabbit

  • New Features

    • Added the ability to cancel Sui withdrawAndCall transactions if the on_call operation fails due to invalid data.
  • Bug Fixes

    • Improved error handling for Sui transaction execution errors, providing more granular detection of retryable and non-retryable errors.
  • Tests

    • Expanded test coverage for Sui execution error scenarios, including new cases for command index handling and revert conditions.
  • Chores

    • Updated changelog to document new feature.
    • Minor update to error message wording for improved clarity.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Apr 30, 2025

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

📝 Walkthrough

Walkthrough

This update introduces a mechanism to deliberately trigger and handle transaction reverts in Sui's withdrawAndCall flow when invalid data is detected. A special revert payload is now used in the Move contract and end-to-end tests to simulate and verify this behavior. The error-handling logic in the Go codebase is enhanced to parse command indices from Sui execution errors, allowing for more granular and accurate determination of whether an error is retryable. Associated tests are expanded for comprehensive coverage, and minor improvements are made to error message wording for clarity.

Changes

Files / Paths Change Summary
e2e/contracts/sui/example/sources/example.move Added a new constant for nonce mismatch error; updated on_call to abort with this error if payload is "revert".
e2e/e2etests/test_sui_token_withdraw_and_call_revert_with_call.go
e2e/e2etests/test_sui_withdraw_and_call_revert_with_call.go
Updated tests to use a new revert payload instead of an invalid address; removed unused imports.
e2e/runner/sui.go Introduced a constant and method to generate a revert-triggering payload for Sui on_call.
pkg/contracts/sui/errors.go Refactored error handling to extract command indices; improved retryability logic for execution errors; added helper and regex.
pkg/contracts/sui/errors_test.go Renamed a test function; expanded test cases to cover new error handling scenarios and edge cases.
zetaclient/chains/sui/signer/signer_tx.go Refined error message wording in transaction broadcasting logic.
changelog.md Documented the new feature regarding cancellation of Sui withdrawAndCall transactions on invalid data.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant ZetaClient
    participant SuiContract
    participant MoveOnCall

    User->>ZetaClient: Initiate withdrawAndCall with data
    ZetaClient->>SuiContract: Broadcast transaction
    SuiContract->>MoveOnCall: Execute on_call(data)
    alt data == "revert"
        MoveOnCall-->>SuiContract: Abort with ENonceMismatch
        SuiContract-->>ZetaClient: Execution error with command index
        ZetaClient->>ZetaClient: Parse error, determine non-retryable
        ZetaClient-->>User: Transaction cancelled, funds safe
    else data valid
        MoveOnCall-->>SuiContract: Success
        SuiContract-->>ZetaClient: Success response
        ZetaClient-->>User: Transaction completed
    end
Loading

Assessment against linked issues

Objective Addressed Explanation
Cancel transaction if it contains invalid data (#3799)

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ 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 gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @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.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

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 generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this 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.

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.

@github-actions
Copy link

!!!WARNING!!!
nosec detected in the following files: pkg/contracts/sui/errors.go

Be very careful about using #nosec in code. It can be a quick way to suppress security warnings and move forward with development, it should be employed with caution. Suppressing warnings with #nosec can hide potentially serious vulnerabilities. Only use #nosec when you're absolutely certain that the security issue is either a false positive or has been mitigated in another way.

Only suppress a single rule (or a specific set of rules) within a section of code, while continuing to scan for other problems. To do this, you can list the rule(s) to be suppressed within the #nosec annotation, e.g: /* #nosec G401 */ or //#nosec G201 G202 G203
Broad #nosec annotations should be avoided, as they can hide other vulnerabilities. The CI will block you from merging this PR until you remove #nosec annotations that do not target specific rules.

Pay extra attention to the way #nosec is being used in the files listed above.

@github-actions github-actions bot added the nosec label Apr 30, 2025
@codecov
Copy link

codecov bot commented Apr 30, 2025

Codecov Report

Attention: Patch coverage is 0% with 1 line in your changes missing coverage. Please review.

Project coverage is 64.40%. Comparing base (62d4c9a) to head (9f4bb94).
Report is 3 commits behind head on develop.

Files with missing lines Patch % Lines
zetaclient/chains/sui/signer/signer_tx.go 0.00% 1 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff            @@
##           develop    #3837   +/-   ##
========================================
  Coverage    64.40%   64.40%           
========================================
  Files          466      466           
  Lines        33761    33761           
========================================
  Hits         21743    21743           
  Misses       11011    11011           
  Partials      1007     1007           
Files with missing lines Coverage Δ
zetaclient/chains/sui/signer/signer_tx.go 50.22% <0.00%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@ws4charlie ws4charlie added zetaclient Issues related to ZetaClient chain:sui SUI_TESTS Run make start-sui-tests labels Apr 30, 2025
@ws4charlie ws4charlie marked this pull request as ready for review April 30, 2025 16:07
@ws4charlie ws4charlie requested a review from a team as a code owner April 30, 2025 16:07
Copy link
Contributor

@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

🧹 Nitpick comments (1)
pkg/contracts/sui/errors.go (1)

116-132: Add explicit range check for command index

The current implementation assumes the command index is always within uint16 range, but this might not always be the case.

Consider adding an explicit range check before the conversion:

func extractCommandIndex(errorMsg string) (uint16, error) {
    matches := commandIndexRegex.FindStringSubmatch(errorMsg)
    if len(matches) != 2 {
        return 0, errors.New("no command index found")
    }

    cmdIndex, err := strconv.ParseUint(matches[1], 10, 16)
    if err != nil {
        return 0, errors.Wrap(err, "unable to convert command index to uint16")
    }

+   // Validate the command index range explicitly
+   if cmdIndex > 65535 {
+       return 0, errors.Errorf("command index %d exceeds uint16 range", cmdIndex)
+   }

    // #nosec G103 always in range
    return uint16(cmdIndex), nil
}
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4c51775 and 01d6768.

📒 Files selected for processing (8)
  • changelog.md (1 hunks)
  • e2e/contracts/sui/example/sources/example.move (2 hunks)
  • e2e/e2etests/test_sui_token_withdraw_and_call_revert_with_call.go (2 hunks)
  • e2e/e2etests/test_sui_withdraw_and_call_revert_with_call.go (2 hunks)
  • e2e/runner/sui.go (2 hunks)
  • pkg/contracts/sui/errors.go (2 hunks)
  • pkg/contracts/sui/errors_test.go (2 hunks)
  • zetaclient/chains/sui/signer/signer_tx.go (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
`**/*.go`: Review the Go code, point out issues relative to principles of clean code, expressiveness, and performance.

**/*.go: Review the Go code, point out issues relative to principles of clean code, expressiveness, and performance.

  • zetaclient/chains/sui/signer/signer_tx.go
  • e2e/e2etests/test_sui_withdraw_and_call_revert_with_call.go
  • e2e/e2etests/test_sui_token_withdraw_and_call_revert_with_call.go
  • pkg/contracts/sui/errors_test.go
  • e2e/runner/sui.go
  • pkg/contracts/sui/errors.go
🧬 Code Graph Analysis (1)
e2e/runner/sui.go (3)
e2e/runner/runner.go (1)
  • E2ERunner (80-207)
pkg/contracts/sui/payload.go (2)
  • CallPayload (26-35)
  • NewCallPayload (37-43)
e2e/config/config.go (1)
  • SuiExample (148-154)
🪛 GitHub Check: codecov/patch
zetaclient/chains/sui/signer/signer_tx.go

[warning] 291-291: zetaclient/chains/sui/signer/signer_tx.go#L291
Added line #L291 was not covered by tests

🔇 Additional comments (16)
e2e/contracts/sui/example/sources/example.move (2)

6-8: Good addition of explanatory comments for the error code.

The comments clearly explain the purpose of ENonceMismatch constant and its relationship to the zetaclient's error handling, which enhances code readability and maintainability.


62-65: Well-implemented error condition for testing withdrawAndCall reverts.

This addition implements a specific error path to test the cancellation of invalid withdrawAndCall transactions. The use of a special "revert" message ensures it's easy to trigger this condition in tests.

e2e/runner/sui.go (2)

20-23: Good practice defining the revert trigger message as a constant.

Centralizing the message value as a constant improves maintainability by ensuring consistency between the contract and test code.


266-281: Well-structured implementation for the revert payload creator.

The SuiCreateExampleWACPayloadForRevert method mirrors the existing payload creation approach while providing a specialized version for testing revert scenarios. The comment clearly explains its purpose and relationship to the on_call function.

changelog.md (1)

26-26: Clear and concise changelog entry.

The entry effectively communicates the feature's purpose and benefits - cancelling Sui withdrawAndCall transactions when they cannot proceed due to invalid data in the on_call operation.

zetaclient/chains/sui/signer/signer_tx.go (1)

291-291:

Details

❓ Verification inconclusive

Improved error message for execution status checking failures.

The error message now more accurately refers to the execution status "error" rather than "error code", which better aligns with the enhanced error parsing implemented in the Sui contracts error handling.

I noticed the static analysis indicates this line lacks test coverage. Consider adding a test case that triggers this error path to ensure complete coverage:


🏁 Script executed:

#!/bin/bash
# Search for existing tests of the broadcastWithdrawalWithFallback function
grep -r "Test.*broadcastWithdrawalWithFallback" --include="*.go" ./

Length of output: 69


🏁 Script executed:

#!/bin/bash
# Broader search for any references to broadcastWithdrawalWithFallback in test files
grep -R "broadcastWithdrawalWithFallback" --include="*_test.go" -n .

Length of output: 68


Verify test coverage for broadcastWithdrawalWithFallback error path

I wasn’t able to find any existing unit tests that exercise the error return on line 291 of
zetaclient/chains/sui/signer/signer_tx.go. Please manually confirm whether your test suite covers this failure path—or, if not, add a dedicated test case that triggers the error in broadcastWithdrawalWithFallback.

• Location to cover:

  • zetaclient/chains/sui/signer/signer_tx.go at line 291 (errors.Wrapf(err, "unable to check tx execution status error: %s", ...))
🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 291-291: zetaclient/chains/sui/signer/signer_tx.go#L291
Added line #L291 was not covered by tests

e2e/e2etests/test_sui_token_withdraw_and_call_revert_with_call.go (2)

26-28: Improved test robustness with dedicated revert payload generator

The change from a manually constructed invalid payload to a specialized revert payload generator improves test reliability and maintainability by creating a standardized way to trigger the revert scenario.


48-48: Consistent application of revert payload

The updated parameter correctly utilizes the newly generated revert payload, ensuring that the test properly exercises the transaction cancellation path.

e2e/e2etests/test_sui_withdraw_and_call_revert_with_call.go (2)

26-28: Improved test robustness with dedicated revert payload generator

The change from a manually constructed invalid payload to a specialized revert payload generator improves test reliability and maintainability by creating a standardized way to trigger the revert scenario.


47-47: Consistent application of revert payload

The updated parameter correctly utilizes the newly generated revert payload, ensuring that the test properly exercises the transaction cancellation path.

pkg/contracts/sui/errors_test.go (4)

9-9: Function name aligned with implementation

Renaming the test function to match the function under test enhances code clarity and maintainability.


61-65: Enhanced test structure for error messages

The test struct has been improved with a dedicated errMsg field for validating error messages and a more descriptive errorMsgExec field name, making the tests more maintainable and explicit.


67-96: Comprehensive test coverage for non-retryable scenarios

The expanded test cases provide thorough coverage of various non-retryable error scenarios, including different MoveAbort codes, function contexts, and command index values. This ensures the error handling logic correctly identifies errors that should trigger transaction cancellation.


101-106: Improved error assertion logic

The updated test logic now properly checks for expected error messages, enhancing the verification of error handling behavior.

pkg/contracts/sui/errors.go (2)

44-46: Well-defined regex for command index extraction

The new regex pattern correctly extracts command indices from Sui execution error messages, enabling more precise error handling.


80-114: Enhanced retryability determination based on command index

The refactored function correctly implements a more granular approach to determining error retryability based on the command index, allowing for precise handling of different error scenarios in the Sui command sequence:

  • Command index 0: withdraw_impl errors (potentially retryable)
  • Command index 1: gas budget transfer errors (non-retryable)
  • Command index 2: on_call errors (non-retryable)

This implementation aligns with the PR objective to cancel outbound transactions when on_call operations fail due to invalid data.

Copy link
Contributor

@swift1337 swift1337 left a comment

Choose a reason for hiding this comment

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

LGTM

@ws4charlie ws4charlie requested a review from lumtis May 5, 2025 18:18
@ws4charlie ws4charlie enabled auto-merge May 7, 2025 17:31
@ws4charlie ws4charlie added this pull request to the merge queue May 7, 2025
Merged via the queue into develop with commit cd10da4 May 7, 2025
46 of 47 checks passed
@ws4charlie ws4charlie deleted the sui-cancel-invalid-withdrawAndCall-tx branch May 7, 2025 18:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

chain:sui nosec SUI_TESTS Run make start-sui-tests zetaclient Issues related to ZetaClient

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cancel tx if it contains invalid data improve Sui cancel tx error handling

4 participants