Skip to content

feat: attach failure reason to solana increment nonce#3918

Merged
skosito merged 9 commits intodevelopfrom
attach-failure-reason-to-increment-nonce
May 30, 2025
Merged

feat: attach failure reason to solana increment nonce#3918
skosito merged 9 commits intodevelopfrom
attach-failure-reason-to-increment-nonce

Conversation

@skosito
Copy link
Member

@skosito skosito commented May 27, 2025

Description

solana PR: zeta-chain/protocol-contracts-solana#115

increment logs example with failure reason attached:

 "logMessages": [
                "Program 94U5AHQMKkV5txNJ17QPXWoh474PheGou6cNP2FEuL1d invoke [1]",
                "Program log: Instruction: IncrementNonce",
                "Program log: Computed message hash: [191, 38, 41, 106, 71, 21, 237, 63, 54, 77, 91, 199, 175, 24, 33, 90, 230, 93, 147, 214, 27, 100, 241, 186, 38, 234, 220, 189, 121, 99, 62, 232]",
                "Program log: Recovered address [62, 34, 14, 146, 183, 30, 47, 163, 110, 144, 185, 67, 154, 111, 241, 193, 59, 163, 0, 53]",
                "Program log: Failure reason: Program 94U5AHQMKkV5txNJ17QPXWoh474PheGou6cNP2FEuL1d failed: instruction changed the balance of an executable account",
                "Program 94U5AHQMKkV5txNJ17QPXWoh474PheGou6cNP2FEuL1d consumed 47220 of 200000 compute units",
                "Program 94U5AHQMKkV5txNJ17QPXWoh474PheGou6cNP2FEuL1d success"
            ],
 "logMessages": [
                "Program 94U5AHQMKkV5txNJ17QPXWoh474PheGou6cNP2FEuL1d invoke [1]",
                "Program log: Instruction: IncrementNonce",
                "Program log: Computed message hash: [186, 161, 242, 52, 212, 132, 86, 187, 66, 121, 38, 34, 243, 30, 136, 208, 100, 76, 148, 251, 151, 164, 30, 163, 20, 132, 133, 59, 138, 141, 37, 190]",
                "Program log: Recovered address [62, 34, 14, 146, 183, 30, 47, 163, 110, 144, 185, 67, 154, 111, 241, 193, 59, 163, 0, 53]",
                "Program log: Failure reason: Program 4xEw862A2SEwMjofPkUyd4NEekmVJKJsdHkK3UkAtDrc failed: custom program error: 0x1771",
                "Program 94U5AHQMKkV5txNJ17QPXWoh474PheGou6cNP2FEuL1d consumed 47557 of 200000 compute units",
                "Program 94U5AHQMKkV5txNJ17QPXWoh474PheGou6cNP2FEuL1d success"
            ],

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 attach and display failure reasons for Solana increment nonce operations, enhancing transparency when outbound transactions fail.
  • Bug Fixes

    • Updated test cases and test data to reflect new behaviors and values related to failure reasons and fallback logic.
  • Documentation

    • Updated changelog and contract documentation to include details about the new failure reason feature.

@skosito skosito added the SOLANA_TESTS Run make start-solana-test label May 27, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented May 27, 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 the ability to attach failure reasons to Solana increment nonce operations. The changes extend instruction parameters, message structures, and fallback logic to capture and propagate failure reasons. Test cases and test data are updated to reflect the new behavior, and the changelog documents the feature addition.

Changes

File(s) Change Summary
changelog.md Updated to document the new feature for attaching failure reasons to increment nonce operations.
pkg/contracts/solana/gateway.json Added failure_reason argument to the increment_nonce instruction and updated its documentation.
pkg/contracts/solana/gateway_message.go Extended MsgIncrementNonce with a private failureReason field and methods to set/get it.
pkg/contracts/solana/instruction.go Added FailureReason field to IncrementNonceInstructionParams struct.
zetaclient/chains/solana/signer/fallback_tx.go Renamed and refactored fallback logic to return both a boolean and a failure reason string.
zetaclient/chains/solana/signer/fallback_tx_test.go Updated and expanded tests to verify both fallback decision and failure reason extraction.
zetaclient/chains/solana/signer/increment_nonce.go Included FailureReason in the serialized increment nonce instruction parameters.
zetaclient/chains/solana/signer/signer.go Changed fallback handling to dynamically generate and sign fallback transactions with failure reasons.
zetaclient/chains/solana/observer/outbound_test.go Updated test expectations to match new transaction data and logic.
zetaclient/testdata/solana/chain_901_outbound_tx_result_5dpFTsscUKCGVQzL9bAUSuEE6yLXaf7d1w... Updated test data to reflect a new transaction instance with updated logs, keys, balances, and failure reason.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Signer
    participant Solana
    participant Contracts

    Client->>Signer: Initiate outbound transaction
    Signer->>Solana: Broadcast transaction
    Solana-->>Signer: Return error (if any)
    Signer->>Signer: parseRPCErrorForFallback(error, program)
    alt Fallback required
        Signer->>Contracts: Add failure reason to MsgIncrementNonce
        Signer->>Solana: Create & sign fallback increment nonce transaction
        Solana-->>Signer: Return fallback transaction result
    else No fallback
        Signer->>Client: Return transaction result or error
    end
Loading
sequenceDiagram
    participant Signer
    participant Contracts

    Signer->>Contracts: MsgIncrementNonce.AddFailureReason(reason)
    Signer->>Contracts: Serialize IncrementNonceInstructionParams (includes FailureReason)
Loading

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.
    • Explain this complex logic.
    • 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 explain this code block.
    • @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 explain its main purpose.
    • @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.

@codecov
Copy link

codecov bot commented May 27, 2025

Codecov Report

Attention: Patch coverage is 40.54054% with 22 lines in your changes missing coverage. Please review.

Project coverage is 64.84%. Comparing base (4bc1423) to head (cb595df).
Report is 1 commits behind head on develop.

Files with missing lines Patch % Lines
zetaclient/chains/solana/signer/signer.go 0.00% 15 Missing ⚠️
zetaclient/chains/solana/signer/fallback_tx.go 71.42% 5 Missing and 1 partial ⚠️
zetaclient/chains/solana/signer/increment_nonce.go 0.00% 1 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##           develop    #3918      +/-   ##
===========================================
- Coverage    64.84%   64.84%   -0.01%     
===========================================
  Files          471      471              
  Lines        34417    34434      +17     
===========================================
+ Hits         22319    22330      +11     
- Misses       11069    11074       +5     
- Partials      1029     1030       +1     
Files with missing lines Coverage Δ
zetaclient/chains/solana/signer/increment_nonce.go 0.00% <0.00%> (ø)
zetaclient/chains/solana/signer/fallback_tx.go 81.25% <71.42%> (-0.75%) ⬇️
zetaclient/chains/solana/signer/signer.go 19.20% <0.00%> (-0.15%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@skosito skosito marked this pull request as ready for review May 28, 2025 14:17
@skosito skosito requested a review from a team as a code owner May 28, 2025 14:17
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: 3

🧹 Nitpick comments (1)
zetaclient/chains/solana/signer/fallback_tx.go (1)

9-42: Consider adding test coverage for edge case error handling.

The implementation correctly handles various error scenarios with appropriate early returns. However, static analysis indicates that error handling paths at lines 18, 23, and 28 lack test coverage. These edge cases should be tested to ensure robust error handling.

Consider adding test cases for:

  • Non-RPC errors that don't contain "Error processing Instruction"
  • RPC errors with invalid data structure
  • RPC errors with missing logs field
🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 18-18: zetaclient/chains/solana/signer/fallback_tx.go#L18
Added line #L18 was not covered by tests


[warning] 23-23: zetaclient/chains/solana/signer/fallback_tx.go#L23
Added line #L23 was not covered by tests


[warning] 28-28: zetaclient/chains/solana/signer/fallback_tx.go#L28
Added line #L28 was not covered by tests

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 4641c74 and 2981afd.

⛔ Files ignored due to path filters (1)
  • contrib/localnet/solana/gateway.so is excluded by !**/*.so
📒 Files selected for processing (10)
  • changelog.md (1 hunks)
  • pkg/contracts/solana/gateway.json (2 hunks)
  • pkg/contracts/solana/gateway_message.go (2 hunks)
  • pkg/contracts/solana/instruction.go (1 hunks)
  • zetaclient/chains/solana/observer/outbound_test.go (2 hunks)
  • zetaclient/chains/solana/signer/fallback_tx.go (1 hunks)
  • zetaclient/chains/solana/signer/fallback_tx_test.go (1 hunks)
  • zetaclient/chains/solana/signer/increment_nonce.go (1 hunks)
  • zetaclient/chains/solana/signer/signer.go (3 hunks)
  • zetaclient/testdata/solana/chain_901_outbound_tx_result_5dpFTsscUKCGVQzL9bAUSuEE6yLXaf7d1wMjZa7RLqvtSUtAdfcdxQHNsbfcS2Sfzu4zBVxMJC2KWzuaUUbg1ZGk.json (4 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/solana/signer/increment_nonce.go
  • zetaclient/chains/solana/observer/outbound_test.go
  • pkg/contracts/solana/gateway_message.go
  • pkg/contracts/solana/instruction.go
  • zetaclient/chains/solana/signer/fallback_tx_test.go
  • zetaclient/chains/solana/signer/signer.go
  • zetaclient/chains/solana/signer/fallback_tx.go
🧠 Learnings (1)
zetaclient/chains/solana/signer/signer.go (1)
Learnt from: gartnera
PR: zeta-chain/node#3632
File: zetaclient/chains/solana/signer/signer.go:304-304
Timestamp: 2025-03-04T22:39:58.395Z
Learning: The Solana signer implementation in zetaclient/chains/solana/signer/signer.go has limited test coverage, particularly for the transaction broadcasting logic with fallback scenarios. Adding this coverage has been acknowledged as a potential future improvement outside the scope of immediate fixes.
🪛 GitHub Check: codecov/patch
zetaclient/chains/solana/signer/increment_nonce.go

[warning] 105-105: zetaclient/chains/solana/signer/increment_nonce.go#L105
Added line #L105 was not covered by tests

zetaclient/chains/solana/signer/signer.go

[warning] 331-338: zetaclient/chains/solana/signer/signer.go#L331-L338
Added lines #L331 - L338 were not covered by tests


[warning] 341-344: zetaclient/chains/solana/signer/signer.go#L341-L344
Added lines #L341 - L344 were not covered by tests


[warning] 346-346: zetaclient/chains/solana/signer/signer.go#L346
Added line #L346 was not covered by tests


[warning] 375-376: zetaclient/chains/solana/signer/signer.go#L375-L376
Added lines #L375 - L376 were not covered by tests

zetaclient/chains/solana/signer/fallback_tx.go

[warning] 18-18: zetaclient/chains/solana/signer/fallback_tx.go#L18
Added line #L18 was not covered by tests


[warning] 23-23: zetaclient/chains/solana/signer/fallback_tx.go#L23
Added line #L23 was not covered by tests


[warning] 28-28: zetaclient/chains/solana/signer/fallback_tx.go#L28
Added line #L28 was not covered by tests


[warning] 54-55: zetaclient/chains/solana/signer/fallback_tx.go#L54-L55
Added lines #L54 - L55 were not covered by tests

🔇 Additional comments (11)
changelog.md (1)

32-32: LGTM: Feature properly documented in changelog.

The changelog entry accurately describes the new failure reason attachment capability for Solana increment nonce operations and follows the established format.

pkg/contracts/solana/instruction.go (1)

171-172: LGTM: Clean addition of failure reason field.

The FailureReason field is properly typed, documented, and follows Go naming conventions. The field placement within the struct is logical and maintains consistency with other fields.

pkg/contracts/solana/gateway.json (1)

1311-1312: LGTM: Clean schema extension for failure reason tracking.

The addition of the failure_reason string parameter to the increment_nonce instruction follows the established schema pattern and includes appropriate documentation. This aligns well with the broader feature to capture detailed failure context for outbound transaction failures.

Also applies to: 1385-1388

pkg/contracts/solana/gateway_message.go (3)

150-152: Well-structured field addition with proper encapsulation.

The private failureReason field follows Go conventions and maintains good encapsulation of the failure context data.


164-172: Clean accessor pattern implementation.

The getter and setter methods follow standard Go conventions and provide appropriate access control to the failure reason field. The method naming is clear and consistent with the existing codebase.


189-206:

Details

❓ Verification inconclusive

Verify exclusion of failure reason from hash calculation.

The Hash() method intentionally excludes the failureReason field from the cryptographic hash computation. This appears to be a deliberate design choice, treating the failure reason as metadata that shouldn't affect message integrity verification.

Please confirm this design decision is intentional. If the failure reason should be part of the message integrity verification, it should be included in the hash calculation:


🏁 Script executed:

#!/bin/bash
# Search for how other message fields are handled in hash calculations
rg -A 10 -B 5 "func.*Hash.*\[32\]byte" --type go

Length of output: 10429


🏁 Script executed:

#!/bin/bash
# Display the definition and fields of MsgIncrementNonce
rg -n "type MsgIncrementNonce" -A 10 pkg/contracts/solana/gateway_message.go
# Check for any occurrence of failureReason in this file
rg -n "failureReason" -n pkg/contracts/solana/gateway_message.go

Length of output: 697


Confirm Intentional Omission of failureReason in Hash Computation

The MsgIncrementNonce.Hash() method serializes only chainID, nonce, and amount, omitting the failureReason field (metadata) from the digest:

• File: pkg/contracts/solana/gateway_message.go
• Method: func (msg *MsgIncrementNonce) Hash() [32]byte (lines ~189–206)

Please verify this is a deliberate design choice. If failureReason must be covered by the integrity check, append it before hashing, for example:

message = append(message, []byte(msg.failureReason)...)
return crypto.Keccak256Hash(message)

Otherwise, no further action is needed.

zetaclient/testdata/solana/chain_901_outbound_tx_result_5dpFTsscUKCGVQzL9bAUSuEE6yLXaf7d1wMjZa7RLqvtSUtAdfcdxQHNsbfcS2Sfzu4zBVxMJC2KWzuaUUbg1ZGk.json (1)

1-68: Test data properly demonstrates the failure reason feature.

The updated test data correctly includes the failure reason in the log messages, aligning with the PR objective to attach failure reasons to Solana increment nonce operations.

zetaclient/chains/solana/signer/fallback_tx.go (1)

44-59: Well-implemented failure reason extraction logic.

The function correctly extracts failure reasons from logs by identifying lines that start with "Program " and contain " failed". The approach of returning the first failure is appropriate as noted in the comment.

Note: Lines 54-55 (empty failures array case) lack test coverage but the implementation correctly handles this edge case.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 54-55: zetaclient/chains/solana/signer/fallback_tx.go#L54-L55
Added lines #L54 - L55 were not covered by tests

zetaclient/chains/solana/signer/fallback_tx_test.go (1)

27-114: Comprehensive test coverage for the refactored fallback logic.

The tests effectively validate both the fallback decision and failure reason extraction. Test scenarios appropriately cover various error conditions including NonceMismatch, program invocations, and invalid error types.

zetaclient/chains/solana/signer/signer.go (2)

40-43: Appropriate refactoring to support dynamic fallback transaction creation.

The change from storing a pre-signed FallbackTx to storing a FallbackMsg enables dynamic attachment of failure reasons at broadcast time, aligning well with the PR objectives.


361-378: Clean simplification of the outbound creation logic.

The method has been appropriately simplified to only sign the main transaction and store the fallback message, deferring fallback transaction creation to broadcast time when the actual failure reason is available.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 375-376: zetaclient/chains/solana/signer/signer.go#L375-L376
Added lines #L375 - L376 were not covered by tests

Copy link
Contributor

@lumtis lumtis left a comment

Choose a reason for hiding this comment

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

Any way to add an assertion in the Solana withdraw and call fail E2E test?

@skosito skosito requested a review from lumtis May 30, 2025 00:46
@skosito skosito enabled auto-merge May 30, 2025 15:04
@skosito skosito added this pull request to the merge queue May 30, 2025
Merged via the queue into develop with commit 9e32ccb May 30, 2025
46 of 47 checks passed
@skosito skosito deleted the attach-failure-reason-to-increment-nonce branch May 30, 2025 15:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

SOLANA_TESTS Run make start-solana-test

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CCTX reported as failed even though tx on connected chain (Solana) succeeded

3 participants