Skip to content

test: E2E test for the Bitcoin RBF transaction#3417

Merged
ws4charlie merged 96 commits intodevelopfrom
E2E-test-bitcoin-RBF
May 14, 2025
Merged

test: E2E test for the Bitcoin RBF transaction#3417
ws4charlie merged 96 commits intodevelopfrom
E2E-test-bitcoin-RBF

Conversation

@ws4charlie
Copy link
Contributor

@ws4charlie ws4charlie commented Jan 25, 2025

Description

Added new E2E test TestBitcoinWithdrawRBF to ensure the RBF transaction feature is working.

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 a new end-to-end test to verify Bitcoin withdrawal using Replace-By-Fee (RBF).
    • Introduced helper functions for Bitcoin transaction state assertions in tests.
    • Added utilities for querying cross-chain transactions and monitoring outbound trackers.
  • Tests

    • Implemented a dedicated test for Bitcoin RBF withdrawals, ensuring correct fee bump behavior.
    • Improved synchronization between Bitcoin deposit and withdrawal test routines.
  • Documentation

    • Updated the changelog to better categorize the Bitcoin RBF feature and its associated tests.
  • Refactor

    • Simplified internal test logic by extracting approval and withdrawal processes into a helper function.
  • Style

    • Minor formatting improvement in a Bitcoin deposit and withdraw test.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 25, 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

The changes introduce a new end-to-end test for the Bitcoin Replace-By-Fee (RBF) withdrawal feature, refactor related helper functions for clarity, and add synchronization between deposit and withdrawal test routines. Additional utility functions are provided for Bitcoin transaction state assertions and Zetacore cross-chain transaction queries. The changelog is reorganized to better categorize feature and test entries.

Changes

File(s) Change Summary
changelog.md Moved the Bitcoin RBF feature entry from "Features" to a new "Tests" section and documented the addition of an end-to-end test for Bitcoin RBF.
cmd/zetae2e/local/bitcoin.go Updated test routine creation to accept a dependency wait group, ensuring the RBF withdraw test runs only after deposit tests complete. Modified function signature and return values, and added explicit synchronization logic.
e2e/e2etests/e2etests.go Added a new Bitcoin end-to-end test (bitcoin_withdraw_rbf) to the test suite, with relevant metadata and version gating. Introduced a constant for the test name and included the test in the list of all E2E tests.
e2e/e2etests/helpers.go Refactored the Bitcoin withdrawal helper by moving approval and withdrawal logic into a new helper function (approveAndWithdrawBTCZRC20). Updated the original function to delegate to this helper, simplifying its structure.
e2e/e2etests/test_bitcoin_deposit_and_withdraw_with_dust.go Removed an extraneous blank line after an ARRANGE comment; no functional changes.
e2e/e2etests/test_bitcoin_withdraw_rbf.go Introduced a new test function (TestBitcoinWithdrawRBF) to validate the RBF withdrawal flow, including transaction mining, confirmation checks, and fee rate assertions.
e2e/utils/bitcoin.go Added new utility functions for asserting that a Bitcoin transaction has been dropped (MustHaveDroppedTx) or mined (MustHaveMinedTx), enhancing test state verification capabilities.
e2e/utils/zetacore.go Added functions to fetch cross-chain transaction data by inbound hash (GetCCTXByInboundHash) and to wait for outbound tracker hashes (WaitOutboundTracker), improving test orchestration and state monitoring.

Sequence Diagram(s)

sequenceDiagram
    participant TestRunner as E2E Test Runner
    participant ZEVM as ZEVM
    participant Zetacore as Zetacore
    participant BitcoinNode as Bitcoin Node

    TestRunner->>ZEVM: Initiate BTC withdrawal (RBF test)
    ZEVM->>Zetacore: Submit cross-chain withdrawal
    Zetacore->>BitcoinNode: Create initial BTC tx (low fee)
    Note right of BitcoinNode: Mining paused (tx unconfirmed)
    Zetacore->>BitcoinNode: Create RBF tx (higher fee)
    Note right of BitcoinNode: Mining resumed
    BitcoinNode->>Zetacore: RBF tx mined, original dropped
    Zetacore->>TestRunner: Return withdrawal status and tx details
    TestRunner->>BitcoinNode: Assert RBF tx mined, original dropped
Loading
sequenceDiagram
    participant TestSuite as Test Suite
    participant DepositRoutine as Deposit Routine
    participant WithdrawRoutine as Withdraw Routine (RBF)

    TestSuite->>DepositRoutine: Start deposit tests
    DepositRoutine-->>TestSuite: Signal completion (WaitGroup)
    TestSuite->>WithdrawRoutine: Start withdraw RBF test (after deposit)
    WithdrawRoutine->>DepositRoutine: Wait for deposit completion
    WithdrawRoutine-->>TestSuite: Complete RBF withdraw test
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.

@ws4charlie ws4charlie changed the title test: E2e test for the Bitcoin RBF transaction test: DON'T review before previous PRs, E2E test for the Bitcoin RBF transaction Jan 25, 2025
@ws4charlie ws4charlie added test Tests related chain:bitcoin Bitcoin chain related E2E E2E tests related labels Jan 25, 2025
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: 4

🔭 Outside diff range comments (1)
cmd/zetae2e/local/bitcoin.go (1)

185-222: ⚠️ Potential issue

WaitGroup not released on early exit – can deadlock withdraw runner

thisRoutine.Done() is invoked only at the happy-path end of the function.
If an error occurs before reaching that line (e.g. failing GetE2ETestsToRunByName or a test failure), the deposit wait-group is never decremented.
Since the RBF withdraw test blocks on wgDependency.Wait(), the withdraw routine may hang indefinitely.

A simple fix is to defer the Done() call immediately after incrementing the counter:

@@
-	var thisRoutine sync.WaitGroup
-	thisRoutine.Add(1)
+	var thisRoutine sync.WaitGroup
+	thisRoutine.Add(1)
+
 	return func() (err error) {
-		r.Logger.Print("🏃 starting bitcoin tests")
+		defer thisRoutine.Done()
+		r.Logger.Print("🏃 starting bitcoin tests")
@@
-		thisRoutine.Done()
 		r.Logger.Print("🍾 bitcoin tests completed in %s", time.Since(startTime).String())
🧹 Nitpick comments (7)
changelog.md (1)

28-33: Duplicate “Tests” subsection causes section confusion

The file now contains two separate ### Tests subsections under the same UNRELEASED header (lines 28 and 51). Having duplicate section headers makes changelog automation brittle and can confuse readers or tooling that parses the file.
Move the new test entry under the existing Tests section (line 51) or merge the two sections.

cmd/zetae2e/local/bitcoin.go (2)

62-65: Hard-coded instruction to edit source breaks reproducibility

The commented guidance to “change the constant minTxConfirmations to 1” requires contributors to modify core observer code manually to enable the RBF test.
Embedding such ad-hoc steps:

  • increases the chance of them being forgotten,
  • makes the test non-deterministic across environments,
  • and couples E2E tests to internal implementation details.

Provide a programmatic switch instead (e.g. env-var, test flag or config field) so the observer behaviour can be changed without editing production code.


130-132: Wait-group instance leaked for withdraw routine

createBitcoinTestRoutine returns a *sync.WaitGroup, but the withdraw caller ignores the second value (_).
If a future caller needs to wait for withdraw completion, the handle is lost.

Either capture the pointer or return only the routine when the wait-group is not required.

e2e/e2etests/test_bitcoin_withdraw_rbf.go (2)

36-37: Fix incorrect log formatting.

The log statement uses a format string with %s for an argument that is already a stringer type (txHash). This is redundant and could cause confusion.

-	r.Logger.Info("got 1st tracker hash: %s", txHash)
+	r.Logger.Info("got 1st tracker hash: %s", txHash.String())

48-49: Fix incorrect log formatting.

Similar to the previous issue, the log statement uses a format string with %s for an argument that is already a stringer type (txHashRBF).

-	r.Logger.Info("got 2nd tracker hash: %s", txHashRBF)
+	r.Logger.Info("got 2nd tracker hash: %s", txHashRBF.String())
e2e/utils/zetacore.go (1)

233-238: Remove redundant fmt.Sprintf in require.False statement.

The use of fmt.Sprintf inside require.False is redundant and less efficient.

	require.False(
		t,
		time.Since(startTime) > timeout,
-		fmt.Sprintf("waiting outbound tracker timeout, chainID: %d, nonce: %d", chainID, nonce),
+		"waiting outbound tracker timeout, chainID: %d, nonce: %d", chainID, nonce,
	)
e2e/e2etests/helpers.go (1)

84-88: Dynamically calculate approval amount based on fees.

The approval amount is hardcoded to double the withdrawal amount, which might be insufficient if gas fees exceed the withdrawal amount. Calculate the approval amount dynamically based on the actual withdrawal amount and gas fees.

	// approve more to cover withdraw fee
	tx, err := r.BTCZRC20.Approve(
		r.ZEVMAuth,
		r.BTCZRC20Addr,
-		big.NewInt(amount.Int64()*2),
+		new(big.Int).Add(amount, new(big.Int).Mul(gasFee, big.NewInt(2))), // amount + 2x gas fee for safety
	)
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 5c73a45 and fc88b12.

📒 Files selected for processing (8)
  • changelog.md (1 hunks)
  • cmd/zetae2e/local/bitcoin.go (5 hunks)
  • e2e/e2etests/e2etests.go (2 hunks)
  • e2e/e2etests/helpers.go (3 hunks)
  • e2e/e2etests/test_bitcoin_deposit_and_withdraw_with_dust.go (0 hunks)
  • e2e/e2etests/test_bitcoin_withdraw_rbf.go (1 hunks)
  • e2e/utils/bitcoin.go (1 hunks)
  • e2e/utils/zetacore.go (3 hunks)
💤 Files with no reviewable changes (1)
  • e2e/e2etests/test_bitcoin_deposit_and_withdraw_with_dust.go
🧰 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.

  • cmd/zetae2e/local/bitcoin.go
  • e2e/e2etests/test_bitcoin_withdraw_rbf.go
  • e2e/utils/bitcoin.go
  • e2e/utils/zetacore.go
  • e2e/e2etests/e2etests.go
  • e2e/e2etests/helpers.go
🧬 Code Graph Analysis (1)
cmd/zetae2e/local/bitcoin.go (2)
e2e/runner/runner.go (1)
  • E2ERunner (80-207)
e2e/e2etests/e2etests.go (1)
  • TestBitcoinWithdrawRBFName (142-142)
⏰ Context from checks skipped due to timeout of 90000ms (6)
  • GitHub Check: build-zetanode
  • GitHub Check: build-and-test
  • GitHub Check: gosec
  • GitHub Check: lint
  • GitHub Check: analyze (go)
  • GitHub Check: build
🔇 Additional comments (5)
e2e/e2etests/e2etests.go (1)

1142-1151: RBF test defined but never scheduled – risk of dead code

TestBitcoinWithdrawRBF is added to AllE2ETests, yet the withdraw-runner’s test lists (see cmd/zetae2e/local/bitcoin.go) keep the name commented-out.
As a result this new test is never executed in CI, even when the Zetacore version satisfies the minimum requirement, which may leave the feature un-tested.

Consider one of:

  1. Uncomment the name in bitcoinWithdrawTestsAdvanced so it runs automatically; or
  2. Add an explanatory comment here stating that the test is intentionally disabled and how to enable it (e.g. via a flag).
e2e/e2etests/test_bitcoin_withdraw_rbf.go (1)

21-72: Test covers key RBF functionality effectively.

This test comprehensively validates the Replace-By-Fee functionality by:

  1. Simulating a stuck transaction by stopping block mining
  2. Verifying the original transaction is dropped
  3. Confirming the RBF transaction with a higher fee is successfully mined

The structure and flow of the test provide excellent coverage of the critical path for Bitcoin RBF processing.

e2e/utils/zetacore.go (1)

34-50: Well-structured utility for CCTX retrieval.

This function provides a clean abstraction for retrieving cross-chain transactions by inbound hash, with appropriate error handling and assertion logic.

e2e/utils/bitcoin.go (1)

13-49: Well-structured transaction state verification utilities.

The MustHaveDroppedTx and MustHaveMinedTx functions provide clear, thorough verification of Bitcoin transaction states through multiple conditions, making the tests more robust and reliable.

e2e/e2etests/helpers.go (1)

68-102: Good extraction of approval and withdrawal logic.

The refactoring to extract the approveAndWithdrawBTCZRC20 helper function improves code organization and reusability, making it easier to use this functionality in multiple test scenarios including the new RBF test.

@ws4charlie ws4charlie requested a review from swift1337 May 8, 2025 19:06
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.

Looks goo

@ws4charlie ws4charlie enabled auto-merge May 13, 2025 15:35
@ws4charlie ws4charlie added this pull request to the merge queue May 13, 2025
@github-actions github-actions bot added the MERGE_FAILED Merge Queue CI failed label May 13, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks May 13, 2025
@ws4charlie ws4charlie added this pull request to the merge queue May 13, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks May 13, 2025
@ws4charlie ws4charlie enabled auto-merge May 14, 2025 19:04
@ws4charlie ws4charlie added this pull request to the merge queue May 14, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks May 14, 2025
@ws4charlie ws4charlie added this pull request to the merge queue May 14, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks May 14, 2025
@ws4charlie ws4charlie enabled auto-merge May 14, 2025 20:29
@ws4charlie ws4charlie added this pull request to the merge queue May 14, 2025
Merged via the queue into develop with commit 33a70df May 14, 2025
47 checks passed
@ws4charlie ws4charlie deleted the E2E-test-bitcoin-RBF branch May 14, 2025 21:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking:cli chain:bitcoin Bitcoin chain related E2E E2E tests related MERGE_FAILED Merge Queue CI failed nosec test Tests related

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants