Skip to content

fix: cherry pick mainnet bitcoin fix to be able to revert missed inbound w…#3754

Merged
ws4charlie merged 2 commits intodevelopfrom
port-fix-revert-btc-inbound-if-no-memo-provided
Mar 25, 2025
Merged

fix: cherry pick mainnet bitcoin fix to be able to revert missed inbound w…#3754
ws4charlie merged 2 commits intodevelopfrom
port-fix-revert-btc-inbound-if-no-memo-provided

Conversation

@ws4charlie
Copy link
Contributor

@ws4charlie ws4charlie commented Mar 24, 2025

Description

This PR is to cherry pick the mainnet v29 fix: #3752

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

  • Bug Fixes
    • Bitcoin deposits that lack a memo now automatically revert, ensuring only complete transactions are processed. This update improves deposit transaction consistency and provides clearer feedback when essential deposit details are missing.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 24, 2025

📝 Walkthrough

Walkthrough

This pull request updates Bitcoin deposit handling by ensuring that deposits revert when the memo output is missing. The changes include a new changelog entry referencing PR [3754] and adjustments in transaction construction to conditionally include an OP_RETURN output only when a memo is provided. Error handling has been enhanced in the event decoding and witness processing functions, and accompanying tests have been expanded to cover scenarios with nil, empty, or invalid memos.

Changes

File(s) Change Summary
changelog.md Added a new changelog entry for PR [3754] indicating Bitcoin deposits revert when the memo is missing.
e2e/.../test_bitcoin_deposit_invalid_memo_revert.go, e2e/.../runner/bitcoin.go Modified tests to include cases with nil and empty memos; updated transaction output ordering and conditional memo handling in the runner function.
zetaclient/.../observer/event.go, .../event_test.go, .../inbound_test.go Updated memo decoding to check for missing memos, returning an error ("no memo found in inbound"), and adjusted test cases to reflect the new logic.
zetaclient/.../observer/witness.go, .../witness_test.go Introduced a new constant noMemoFound and modified the witness event flow to assign this placeholder when no memo is found, ensuring proper transaction reversion.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Processor
    participant Runner
    participant Observer
    participant Witness
    User->>Processor: Submit Bitcoin deposit transaction
    Processor->>Runner: Call sendToAddrFromDeployerWithMemo(memo?)
    alt Memo Provided
      Runner->>Processor: Create transaction with OP_RETURN output
      Processor->>Observer: Process transaction normally
    else No Memo Provided
      Runner->>Observer: Check for memo (nil)
      Observer-->>Runner: Return error ("no memo found in inbound")
      Runner->>Witness: Pass error status and trigger revert
      Witness->>Processor: Mark transaction as reverted (using "noMemoFound")
    end
Loading

Possibly related PRs

Suggested labels

no-changelog, UPGRADE_TESTS

Suggested reviewers

  • fbac
  • kingpinXD
  • lumtis
  • skosito
  • swift1337
✨ Finishing Touches
  • 📝 Generate Docstrings

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.

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 resolve resolve all the CodeRabbit review comments.
  • @coderabbitai plan to trigger planning for file edits and PR creation.
  • @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.

@ws4charlie ws4charlie marked this pull request as ready for review March 24, 2025 22:13
@ws4charlie ws4charlie requested a review from a team as a code owner March 24, 2025 22:13
@ws4charlie ws4charlie added mainnet bug zetaclient Issues related to ZetaClient chain:bitcoin Bitcoin chain related labels Mar 24, 2025
@codecov
Copy link

codecov bot commented Mar 24, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 64.34%. Comparing base (4881c8f) to head (7199af1).
Report is 2 commits behind head on develop.

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff            @@
##           develop    #3754   +/-   ##
========================================
  Coverage    64.33%   64.34%           
========================================
  Files          462      462           
  Lines        32910    32914    +4     
========================================
+ Hits         21173    21177    +4     
  Misses       10767    10767           
  Partials       970      970           
Files with missing lines Coverage Δ
zetaclient/chains/bitcoin/observer/event.go 93.61% <100.00%> (+0.28%) ⬆️
zetaclient/chains/bitcoin/observer/witness.go 83.73% <100.00%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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)
zetaclient/chains/bitcoin/observer/inbound_test.go (1)

13-16: Verify new imports are needed.

The added imports appear to be unused in the changed code sections. Please verify these are necessary or remove them if not needed.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 4881c8f and 7199af1.

📒 Files selected for processing (8)
  • changelog.md (1 hunks)
  • e2e/e2etests/test_bitcoin_deposit_invalid_memo_revert.go (1 hunks)
  • e2e/runner/bitcoin.go (1 hunks)
  • zetaclient/chains/bitcoin/observer/event.go (1 hunks)
  • zetaclient/chains/bitcoin/observer/event_test.go (1 hunks)
  • zetaclient/chains/bitcoin/observer/inbound_test.go (6 hunks)
  • zetaclient/chains/bitcoin/observer/witness.go (3 hunks)
  • zetaclient/chains/bitcoin/observer/witness_test.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/bitcoin/observer/event_test.go
  • zetaclient/chains/bitcoin/observer/witness_test.go
  • e2e/runner/bitcoin.go
  • e2e/e2etests/test_bitcoin_deposit_invalid_memo_revert.go
  • zetaclient/chains/bitcoin/observer/event.go
  • zetaclient/chains/bitcoin/observer/witness.go
  • zetaclient/chains/bitcoin/observer/inbound_test.go
🧠 Learnings (2)
zetaclient/chains/bitcoin/observer/event_test.go (1)
Learnt from: ws4charlie
PR: zeta-chain/node#3025
File: zetaclient/chains/bitcoin/observer/event.go:110-115
Timestamp: 2025-03-24T14:49:37.949Z
Learning: In the `DecodeEventMemoBytes` function, a non-nil `memoStd` with a non-nil `err` indicates that the memo bytes are well-formatted as a memo but contain improper data.
zetaclient/chains/bitcoin/observer/event.go (1)
Learnt from: ws4charlie
PR: zeta-chain/node#3025
File: zetaclient/chains/bitcoin/observer/event.go:110-115
Timestamp: 2025-03-24T14:49:37.949Z
Learning: In the `DecodeEventMemoBytes` function, a non-nil `memoStd` with a non-nil `err` indicates that the memo bytes are well-formatted as a memo but contain improper data.
🧬 Code Definitions (3)
zetaclient/chains/bitcoin/observer/event_test.go (2)
zetaclient/chains/bitcoin/observer/event.go (3)
  • event (53-76)
  • event (80-139)
  • BTCInboundEvent (23-50)
zetaclient/types/event.go (2)
  • event (76-95)
  • event (98-117)
zetaclient/chains/bitcoin/observer/witness_test.go (2)
zetaclient/chains/bitcoin/observer/event.go (4)
  • BTCInboundEvent (23-50)
  • event (53-76)
  • event (80-139)
  • err (82-82)
zetaclient/chains/bitcoin/observer/witness.go (1)
  • GetBtcEventWithWitness (27-109)
zetaclient/chains/bitcoin/observer/inbound_test.go (2)
zetaclient/testutils/testrpc/rpc_btc.go (1)
  • CreateBTCRPCAndLoadTx (61-80)
zetaclient/testutils/testdata.go (1)
  • LoadBTCInboundRawResult (137-148)
🔇 Additional comments (14)
changelog.md (1)

73-73: LGTM: Clear changelog entry for the fix.

The changelog entry accurately describes the fix, making it clear that Bitcoin deposits will now revert when the memo output is missing.

zetaclient/chains/bitcoin/observer/event_test.go (1)

171-178: Good test coverage for memo not found case.

This test case properly verifies the error handling when no memo is found in an inbound Bitcoin transaction, ensuring that the system will respond with the expected error message.

zetaclient/chains/bitcoin/observer/event.go (1)

88-92: LGTM: Proper error handling for missing memo.

The implementation correctly checks for the absence of a memo and returns an appropriate error message, ensuring that inbound transactions without a memo will be reverted. This is consistent with the updated behavior described in the changelog.

zetaclient/chains/bitcoin/observer/witness_test.go (1)

108-148: Comprehensive test for handling transactions without memo.

The test effectively simulates a Bitcoin transaction without an OP_RETURN output, validating that the GetBtcEventWithWitness function correctly handles this case by setting the appropriate memo bytes value. This ensures that downstream processing can properly identify and revert these transactions.

zetaclient/chains/bitcoin/observer/witness.go (3)

19-22: Good addition with clear purpose.

The new constant noMemoFound is well-defined with a descriptive comment explaining its role as a placeholder for missing memos in Bitcoin inbound transactions.


74-75: Clear comment update reflecting the new behavior.

The updated comment accurately describes the new logic where a placeholder is set when no memo is found, rather than exiting the function early.


84-85: Critical change in error handling flow.

This implementation change is the core of the fix - instead of returning early with nil, nil when no memo is found, the function now sets a special placeholder value. This ensures that the transaction will be processed and properly reverted later.

e2e/runner/bitcoin.go (2)

247-259: Good implementation of conditional memo handling.

The code now properly handles the case when no memo is provided, making it suitable for testing no-memo edge cases. The OP_RETURN output is only added when a memo is present, which aligns with the PR's purpose of enhancing error handling for missing memo outputs.


267-270: Improved transaction output management.

The code now dynamically determines the index of the change output based on the actual number of outputs, making the solution more robust when handling transactions with or without memo outputs.

e2e/e2etests/test_bitcoin_deposit_invalid_memo_revert.go (2)

18-29: Well-structured test case for missing memo.

This test case properly verifies that a Bitcoin deposit without a memo output is correctly reverted with the appropriate error status. The test is clear, focused, and directly targets the behavior introduced by this PR.


30-40: Complete coverage with empty memo test case.

This additional test case checks for proper handling of empty memo byte slices, providing comprehensive test coverage for the different memo scenarios. The assertions correctly verify that the transaction is reverted with the INVALID_MEMO status.

zetaclient/chains/bitcoin/observer/inbound_test.go (3)

476-507: Test correctly updated to validate new behavior.

This test has been properly updated to verify the new behavior with missing memos. Instead of expecting the transaction to be skipped, it now correctly asserts that the transaction is processed with the noMemoFound placeholder.


586-612: Aligned test expectations with new behavior.

The test correctly expects that transactions with invalid OP_RETURN outputs should be processed (not skipped) according to the new behavior. The updates to the setup and assertions are appropriate.


614-640: Consistent test update for memo decoding failures.

This test has been properly updated to expect that transactions with memo decoding failures should be processed rather than skipped, aligning with the other changes in behavior for handling invalid memos.

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)
e2e/runner/bitcoin.go (1)

267-269: Good improvement to output swapping logic.

Using the dynamic index calculation for the change output makes the code more resilient when dealing with variable numbers of transaction outputs. However, consider adding a comment explaining the expected ordering of transaction outputs after swapping for better maintainability.

// swap the TxOut[0] and the last output (change)
idxChange := len(tx.TxOut) - 1
tx.TxOut[0], tx.TxOut[idxChange] = tx.TxOut[idxChange], tx.TxOut[0]
+// After swapping: TxOut[0] is the payment to recipient, the optional memo is TxOut[1] (if present), and the last output is change to deployer address
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 4881c8f and 7199af1.

📒 Files selected for processing (8)
  • changelog.md (1 hunks)
  • e2e/e2etests/test_bitcoin_deposit_invalid_memo_revert.go (1 hunks)
  • e2e/runner/bitcoin.go (1 hunks)
  • zetaclient/chains/bitcoin/observer/event.go (1 hunks)
  • zetaclient/chains/bitcoin/observer/event_test.go (1 hunks)
  • zetaclient/chains/bitcoin/observer/inbound_test.go (6 hunks)
  • zetaclient/chains/bitcoin/observer/witness.go (3 hunks)
  • zetaclient/chains/bitcoin/observer/witness_test.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.

  • e2e/e2etests/test_bitcoin_deposit_invalid_memo_revert.go
  • zetaclient/chains/bitcoin/observer/event_test.go
  • zetaclient/chains/bitcoin/observer/witness_test.go
  • zetaclient/chains/bitcoin/observer/event.go
  • zetaclient/chains/bitcoin/observer/inbound_test.go
  • zetaclient/chains/bitcoin/observer/witness.go
  • e2e/runner/bitcoin.go
🧠 Learnings (3)
zetaclient/chains/bitcoin/observer/event_test.go (1)
Learnt from: ws4charlie
PR: zeta-chain/node#3025
File: zetaclient/chains/bitcoin/observer/event.go:110-115
Timestamp: 2025-03-24T14:49:37.949Z
Learning: In the `DecodeEventMemoBytes` function, a non-nil `memoStd` with a non-nil `err` indicates that the memo bytes are well-formatted as a memo but contain improper data.
zetaclient/chains/bitcoin/observer/event.go (1)
Learnt from: ws4charlie
PR: zeta-chain/node#3025
File: zetaclient/chains/bitcoin/observer/event.go:110-115
Timestamp: 2025-03-24T14:49:37.949Z
Learning: In the `DecodeEventMemoBytes` function, a non-nil `memoStd` with a non-nil `err` indicates that the memo bytes are well-formatted as a memo but contain improper data.
zetaclient/chains/bitcoin/observer/witness.go (1)
Learnt from: ws4charlie
PR: zeta-chain/node#3025
File: zetaclient/chains/bitcoin/observer/event.go:110-115
Timestamp: 2025-03-24T14:49:37.949Z
Learning: In the `DecodeEventMemoBytes` function, a non-nil `memoStd` with a non-nil `err` indicates that the memo bytes are well-formatted as a memo but contain improper data.
🧬 Code Definitions (4)
e2e/e2etests/test_bitcoin_deposit_invalid_memo_revert.go (3)
e2e/runner/bitcoin.go (16)
  • r (37-70)
  • r (74-94)
  • r (98-102)
  • r (105-137)
  • r (140-157)
  • r (161-191)
  • r (193-199)
  • r (201-325)
  • r (328-374)
  • r (377-381)
  • r (384-386)
  • r (390-399)
  • r (402-418)
  • r (423-444)
  • txHash (111-111)
  • err (110-110)
e2e/runner/require.go (2)
  • r (19-27)
  • r (30-49)
testutil/sample/crosschain.go (2)
  • InboundParams (176-191)
  • Status (248-260)
zetaclient/chains/bitcoin/observer/witness_test.go (2)
zetaclient/chains/bitcoin/observer/event.go (4)
  • BTCInboundEvent (23-50)
  • event (53-76)
  • event (80-139)
  • err (82-82)
zetaclient/chains/bitcoin/observer/observer.go (1)
  • Logger (70-76)
zetaclient/chains/bitcoin/observer/inbound_test.go (2)
zetaclient/testutils/testrpc/rpc_btc.go (1)
  • CreateBTCRPCAndLoadTx (61-80)
zetaclient/testutils/testdata.go (1)
  • LoadBTCInboundRawResult (137-148)
e2e/runner/bitcoin.go (3)
e2e/runner/accounting.go (6)
  • r (36-50)
  • r (52-87)
  • r (89-137)
  • r (140-171)
  • r (173-188)
  • r (190-216)
e2e/runner/setup_bitcoin.go (4)
  • r (13-27)
  • r (30-49)
  • r (52-70)
  • r (73-109)
e2e/runner/logger.go (1)
  • Logger (22-27)
🔇 Additional comments (13)
changelog.md (1)

73-73: LGTM: Clear and descriptive changelog entry.

The entry clearly communicates that Bitcoin deposits will now revert when memo output is missing, which aligns with the implementation in the code.

zetaclient/chains/bitcoin/observer/event_test.go (1)

171-178: LGTM: Well-structured test case for missing memo scenario.

This test effectively verifies the new behavior where Bitcoin deposits with missing memos should revert, ensuring the system handles this edge case properly.

zetaclient/chains/bitcoin/observer/event.go (1)

88-92: LGTM: Proper error handling for missing memo condition.

The implementation correctly identifies transactions with missing memos and returns an appropriate error, which will trigger a revert of the Bitcoin deposit as intended by the PR.

zetaclient/chains/bitcoin/observer/witness.go (3)

19-22: LGTM: Well-defined constant for missing memo identification.

The noMemoFound constant clearly communicates its purpose through both its name and comment.


74-76: LGTM: Improved comment clarity.

The updated comment accurately describes the new behavior of setting a placeholder when no memo is found.


84-84: LGTM: Proper handling of missing memo scenario.

Instead of leaving the memo as nil, the code now explicitly sets it to a recognizable placeholder value, enabling proper error handling in downstream components.

zetaclient/chains/bitcoin/observer/witness_test.go (1)

108-148: Well-structured test for the no-memo scenario.

This test case properly validates the handling of Bitcoin transactions without a memo output, ensuring the system returns a standardized "no memo found" message rather than failing. The test's setup effectively simulates this edge case by removing the OP_RETURN output and verifies the expected behavior.

e2e/e2etests/test_bitcoin_deposit_invalid_memo_revert.go (2)

18-29: Good test coverage for nil memo scenario.

This case effectively tests the system's behavior when a deposit is made without any memo output, ensuring that such transactions are properly reverted with an INVALID_MEMO status rather than causing failures elsewhere in the system.


30-40: Appropriate test for empty memo case.

This test properly verifies that empty memos are handled consistently with the system's requirements, resulting in a reverted transaction with the correct status. This complements the nil memo test by covering another important edge case.

e2e/runner/bitcoin.go (1)

247-259: Good implementation of optional memo handling.

The conditional handling of memo data appropriately supports the testing of no-memo scenarios for transaction reversion. This change aligns well with the PR's objective to fix handling of Bitcoin deposits with missing memo outputs.

zetaclient/chains/bitcoin/observer/inbound_test.go (3)

476-507: Properly implemented test for transactions without memo.

This test case correctly verifies that transactions without a memo are now processed (not skipped) and include the standardized "no memo found" message. This change is consistent with the PR's objective to improve handling of Bitcoin deposits with missing memo outputs.


586-612: Updated test to match new transaction handling policy.

This test has been appropriately modified to verify that transactions with non-OP_RETURN outputs are now processed rather than skipped. This reflects the shift from silently dropping problematic transactions to processing them with proper error handling.


614-640: Correctly updated test for memo decoding failures.

This test now properly verifies that transactions with memo decoding failures are processed rather than skipped, which allows for more robust error reporting and tracking in the system. The test setup effectively simulates the error condition by modifying the memo length.

@ws4charlie ws4charlie added this pull request to the merge queue Mar 25, 2025
Merged via the queue into develop with commit d575d3d Mar 25, 2025
63 of 71 checks passed
@ws4charlie ws4charlie deleted the port-fix-revert-btc-inbound-if-no-memo-provided branch March 25, 2025 15:27
lumtis pushed a commit that referenced this pull request Mar 28, 2025
…und w… (#3754)

* cherry pick mainnet bitcoin fix to be able to revert missed inbound without memo

* add changelog entry
github-merge-queue bot pushed a commit that referenced this pull request Mar 28, 2025
* parse withdraw payload

* prepare withdraw and call and add payload parsing

* initialize withdraw and call test

* add format payload function

* changelog

* fix parsing

* improve testing

* change returns

* Update pkg/contracts/sui/payload.go

Co-authored-by: Dmitry S <11892559+swift1337@users.noreply.github.com>

* fix: cherry pick mainnet bitcoin fix to be able to revert missed inbound w… (#3754)

* cherry pick mainnet bitcoin fix to be able to revert missed inbound without memo

* add changelog entry

* chore(e2e): print stack trace on nil dereference (#3751)

* chore(e2e): print stack trace on nil dereference

* fix go vet

* Update e2e/runner/run.go

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix imports

* use const for abi args

* create payloadCall object

* add argument for payload

* refactor rawPayload

---------

Co-authored-by: Dmitry S <11892559+swift1337@users.noreply.github.com>
Co-authored-by: Charlie Chen <34498985+ws4charlie@users.noreply.github.com>
Co-authored-by: Alex Gartner <alexg@zetachain.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

chain:bitcoin Bitcoin chain related mainnet zetaclient Issues related to ZetaClient

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants