Skip to content

feat(wallet): Retry logic for Monero wallet#417

Merged
binarybaron merged 3 commits intomasterfrom
fix/monero-sys-retries
Jun 17, 2025
Merged

feat(wallet): Retry logic for Monero wallet#417
binarybaron merged 3 commits intomasterfrom
fix/monero-sys-retries

Conversation

@Einliterflasche
Copy link
Copy Markdown

@Einliterflasche Einliterflasche commented Jun 17, 2025

Summary by CodeRabbit

  • New Features

    • Added ability to retrieve the wallet filename from the Monero wallet interface.
    • Introduced support for passing a Tauri handle to the Monero wallet, enabling UI status updates.
  • Improvements

    • Implemented retry logic with exponential backoff for critical wallet operations, improving reliability.
    • Enhanced logging throughout wallet operations, including transaction confirmation progress and wallet lifecycle events.
    • Updated wallet initialization and refresh methods with clearer naming and added tracing logs.
  • Bug Fixes

    • Improved confirmation waiting logic by providing real-time confirmation updates in logs.
  • Chores

    • Updated dependencies to include the backoff crate.
    • Removed unused editor configuration files.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Jun 17, 2025

Walkthrough

This update introduces retry logic with exponential backoff for key wallet operations, enhances logging for wallet actions and transaction confirmations, and adds a method to retrieve the wallet filename via FFI. It also updates the wallet initialization to accept an optional Tauri handle and improves confirmation progress reporting.

Changes

File(s) Change Summary
.vscode/settings.json Deleted file containing C++ language associations for various file types.
monero-sys/Cargo.toml Added backoff = "0.4.0" to dependencies.
monero-sys/src/bridge.h, monero-sys/src/bridge.rs Added walletFilename FFI function to retrieve wallet filename.
monero-sys/src/lib.rs Added retry logic with exponential backoff for wallet operations, enhanced logging, and new helper functions.
swap/src/bin/asb.rs, swap/tests/harness/mod.rs Updated calls to Wallets::new to include an additional argument (None). Minor formatting improvements.
swap/src/cli/api.rs, swap/src/monero/wallet.rs Extended Wallets struct and constructor to accept/store an optional TauriHandle.
swap/src/protocol/alice/state.rs, swap/src/protocol/alice/swap.rs Replaced no-op confirmation listeners with closures that log confirmation progress.

Sequence Diagram(s)

sequenceDiagram
    participant UI/Tauri
    participant Wallets
    participant FfiWallet
    participant MoneroNetwork

    UI/Tauri->>Wallets: new(data_dir, daemon_address, env_config, tauri_handle)
    Wallets->>FfiWallet: initialize()
    loop Retry with backoff
        FfiWallet->>MoneroNetwork: init()
        alt Success
            FfiWallet-->>Wallets: Ok
        else Failure
            FfiWallet-->>Wallets: Error (retry)
        end
    end
    Wallets-->>UI/Tauri: Wallets instance
Loading
sequenceDiagram
    participant User
    participant WalletHandle
    participant FfiWallet
    participant MoneroNetwork

    User->>WalletHandle: transfer/sweep()
    loop Retry with backoff
        WalletHandle->>FfiWallet: transfer/sweep()
        FfiWallet->>MoneroNetwork: send transaction
        alt Success
            FfiWallet-->>WalletHandle: TxReceipt/Success
        else Failure
            FfiWallet-->>WalletHandle: Error (retry)
        end
    end
    WalletHandle-->>User: Result
Loading
sequenceDiagram
    participant Protocol
    participant WalletHandle

    Protocol->>WalletHandle: wait_until_confirmed(txid, tx_key, address, amount, confirmations, listener)
    loop Until confirmations reached
        WalletHandle->>WalletHandle: poll confirmation status
        WalletHandle-->>Protocol: listener(confirmations)
    end
    WalletHandle-->>Protocol: Ok
Loading

Possibly related PRs

Suggested labels

P1

Poem

In fields of code where Monero hops,
The rabbit adds backoff, so nothing stops.
With logs that sparkle, and handles anew,
Wallets now whisper their filenames to you.
Confirmations are counted, each hop and each leap—
This bunny ensures your swaps run deep! 🐇✨


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e6b9ba0 and 114af89.

📒 Files selected for processing (5)
  • monero-sys/src/lib.rs (21 hunks)
  • swap/src/monero/wallet.rs (3 hunks)
  • swap/src/protocol/alice/state.rs (2 hunks)
  • swap/src/protocol/alice/swap.rs (1 hunks)
  • swap/tests/harness/mod.rs (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
  • swap/src/protocol/alice/swap.rs
  • swap/src/protocol/alice/state.rs
  • swap/src/monero/wallet.rs
  • swap/tests/harness/mod.rs
  • monero-sys/src/lib.rs
✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 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.

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
Copy Markdown

@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)
monero-sys/src/lib.rs (1)

585-636: wait_until_confirmed leaks sensitive data & may spam listener

  1. Logging the full txid and recipient address at info! level exposes PII on production logs.
    Mask at least the middle of the hash or downgrade to debug!.

  2. listener(tx_status.confirmations) is invoked every polling tick, even when the confirmations count has not changed.
    An idempotent listener may still perform heavy UI updates or I/O.

-        if let Some(listener) = &listener {
-            listener(tx_status.confirmations);
+        if tx_status.confirmations > last_seen && let Some(listener) = &listener {
+            listener(tx_status.confirmations);
+            last_seen = tx_status.confirmations;
         }

Add let mut last_seen = 0; before the loop.

🧹 Nitpick comments (9)
swap/src/bin/asb.rs (1)

465-472: Pass the actual UI handle where available

Wallets::new(.., false, None) hard-codes None, meaning the UI can never receive progress updates from CLI mode even when compiled with the Tauri feature.

If the CLI can receive a TauriHandle (e.g. through env_config or an optional CLI flag) forward it here; otherwise document why the handle is always unavailable.

monero-sys/src/bridge.h (1)

168-171: Correct wrapper but missing doc-comment parity

walletFilename follows the existing wrapper pattern. Consider adding a one-liner comment (like the neighbouring wrappers) for consistency/readability.

swap/src/monero/wallet.rs (1)

15-16: Unused imports will trigger unused_imports warnings

TauriBackgroundProgress, TauriEmitter and TauriHandle are imported but only TauriHandle is stored.
Either remove/#[allow(unused_imports)] the extras or use them; many CI pipelines treat warnings as errors.

swap/src/protocol/alice/swap.rs (1)

11-12: Remove now-unused no_listener import

With the new listener closure passed to wait_until_confirmed, no_listener is no longer referenced in this module. Keeping an unused import will trigger unused_imports warnings (and breaks the build if #![deny(warnings)] is enabled).

-use crate::monero::wallet::no_listener;
swap/src/protocol/alice/state.rs (1)

578-583: Per-confirmation debug log may be too chatty

Same remark as in swap.rs: the closure passed here fires once per new confirmation while waiting for 10 blocks.
If log volume becomes a concern you may want to:

Some(|c| {
    if c % 5 == 0 {      // every 5 confirmations
        tracing::info!(%c, "Monero lock tx confirmations");
    }
})

or downgrade to trace!.
Purely cosmetic; functionality is correct.

swap/tests/harness/mod.rs (1)

310-317: Hard-coded true flag – use a named builder for clarity

Passing magic booleans (true, None) into Wallets::new makes the call hard to read later.
Consider exposing a small builder/helper:

Wallets::builder()
    .regtest(true)
    .tauri_handle(None)
    .open(monero_wallet_dir, "main", monero_daemon, monero::Network::Mainnet)
    .await?

Not critical for test code, but aids readability.

monero-sys/src/lib.rs (3)

20-22: Remove unused retry import

retry is imported but never referenced after the latest changes. This will trigger a dead_code / unused_imports lint in cargo check.

-use backoff::{future, retry, retry_notify};
+use backoff::{future, retry_notify};

1002-1013: retry_notify captures wallet by mutable borrow – safe but brittle

The closure mutably borrows wallet across retry attempts.
While this compiles (because the closure is FnMut), a non-obvious lifetime arises: if a future inside init holds a borrow across an .await, subsequent retries will dead-lock borrow checking at compile time.

Recommend keeping the mutable borrow inside the closure:

-            || {
-                wallet
-                    .init(&daemon.address, daemon.ssl)
+            || {
+                let result = wallet.init(&daemon.address, daemon.ssl);
+                // never holds the &mut borrow across .await boundaries
+                result

No functional change, but easier to reason about.


1667-1683: Local backoff() helper shadows the backoff crate – rename for clarity

Having both use backoff::… and a free function called backoff in the same module is confusing for readers and IDE tooling.

-fn backoff(
+fn build_backoff(

Update the three call-sites accordingly.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2e6d324 and e6b9ba0.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (11)
  • .vscode/settings.json (0 hunks)
  • monero-sys/Cargo.toml (1 hunks)
  • monero-sys/src/bridge.h (1 hunks)
  • monero-sys/src/bridge.rs (1 hunks)
  • monero-sys/src/lib.rs (21 hunks)
  • swap/src/bin/asb.rs (1 hunks)
  • swap/src/cli/api.rs (2 hunks)
  • swap/src/monero/wallet.rs (3 hunks)
  • swap/src/protocol/alice/state.rs (1 hunks)
  • swap/src/protocol/alice/swap.rs (1 hunks)
  • swap/tests/harness/mod.rs (3 hunks)
💤 Files with no reviewable changes (1)
  • .vscode/settings.json
🧰 Additional context used
🧬 Code Graph Analysis (2)
monero-sys/src/bridge.rs (1)
monero-sys/src/bridge.h (2)
  • walletFilename (168-171)
  • walletFilename (168-168)
swap/tests/harness/mod.rs (2)
swap/src/monero/wallet.rs (1)
  • new (64-97)
monero-harness/src/lib.rs (4)
  • new (57-134)
  • new (355-377)
  • new (414-439)
  • wallet (140-148)
🔇 Additional comments (6)
monero-sys/Cargo.toml (1)

8-8: Pinning to 0.4.0 may break builds on crates-io mirrors

backoff = "0.4.0" is valid today, but several mirrors only host the latest patch (0.4.x).
Suggest relaxing to the compatible spec to avoid build failures and automatically receive patch-level fixes:

-backoff = "0.4.0"
+backoff = "0.4"

Please run cargo update -p backoff afterwards to lock the latest patch in Cargo.lock.

monero-sys/src/bridge.rs (1)

129-131: Looks good – FFI surface stays consistent

walletFilename mirrors walletPath and returns an owned CxxString, matching CXX expectations.
No issues spotted.

swap/src/monero/wallet.rs (1)

70-71: ```shell
#!/bin/bash

Escape parentheses in the rg pattern to avoid the “unclosed group” error

rg --context 2 'Wallets::new(' swap | grep -v ', None'


</details>
<details>
<summary>swap/src/protocol/alice/swap.rs (1)</summary>

`304-311`: **Logging callback looks good, but consider throttling**

The added info/debug logs are helpful, however `wait_until_confirmed` polls frequently and the closure will emit a `tracing::debug!` on *every* confirmation height update (every block).  
If many swaps run concurrently this can flood logs.

Two lightweight options:

1. Emit only on meaningful milestones, e.g. every `n` confirmations.
2. Swap `debug!` for `trace!` to reduce default verbosity.

No functional issue—purely a log-noise consideration.  
[ suggest_nitpick ]

</details>
<details>
<summary>swap/src/cli/api.rs (2)</summary>

`583-590`: **Propagating `tauri_handle` into `Wallets::new` looks correct**

Good to see the handle forwarded; this keeps UI progress consistent with Bitcoin wallet initialisation.

---

`538-540`: **Parameter rename is fine – check callers for outdated `_tauri_handle`**

You renamed the argument to `tauri_handle`.  
All in-repo callers seem updated, but please verify with:

```shell
rg -n "_tauri_handle" swap | head

to ensure no stale call sites remain.

@binarybaron binarybaron changed the title improve(swap): add retry logic to transfer/sweep and init in monero-sys feat(wallet): Retry logic for Monero wallet Jun 17, 2025
@binarybaron binarybaron merged commit cf669a8 into master Jun 17, 2025
1 check passed
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