From 8ede114b1a6b0ef8fee113598c726372f6d35c56 Mon Sep 17 00:00:00 2001 From: Michael Taylor Date: Sun, 2 Aug 2026 15:30:32 +0000 Subject: [PATCH] test: add live-mainnet integration test for control.wallet.balance (#1959) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add #[ignore]d live-mainnet wallet balance read test to verify the control.wallet.balance RPC reads confirmed balance from a funded address on mainnet. Test gates on DIG_LIVE_FUNDS_TEST=1 + DIG_TEST_WALLET_MNEMONIC env vars (sourced from /.test-credentials, never printed or committed). Imports the funded test wallet and asserts the balance read returns Known with confirmed > 0 mojos, distinguishing from StillSyncing/Unknown states. Bump version 0.75.4 → 0.75.5 (test: patch). Co-Authored-By: Claude --- Cargo.lock | 2 +- Cargo.toml | 2 +- .../tests/live_funds_tip_e2e.rs | 70 +++++++++++++++++++ 3 files changed, 72 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index db93e13..f999106 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2281,7 +2281,7 @@ dependencies = [ [[package]] name = "dig-node-service" -version = "0.75.4" +version = "0.75.5" dependencies = [ "async-trait", "axum", diff --git a/Cargo.toml b/Cargo.toml index c5e62f7..b6988bb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,7 +32,7 @@ edition = "2021" # the ROOT manifest (`[workspace.package].version`), so it MUST be set here for a # release to fire (§3.6). The library crates (dig-node-core/dig-runtime/dig-wallet) # keep their own independent versions — only the released binary tracks the workspace version. -version = "0.75.4" +version = "0.75.5" # Release hardening, matching digstore: keep integer-overflow checks ON in release. # The node parses untrusted serialized input and does offset/length arithmetic over diff --git a/crates/dig-node-service/tests/live_funds_tip_e2e.rs b/crates/dig-node-service/tests/live_funds_tip_e2e.rs index 2162065..67cc710 100644 --- a/crates/dig-node-service/tests/live_funds_tip_e2e.rs +++ b/crates/dig-node-service/tests/live_funds_tip_e2e.rs @@ -152,3 +152,73 @@ async fn live_funds_dev_tip_broadcasts_and_confirms() { let _ = std::fs::remove_dir_all(&dir); } + +/// End-to-end: a live mainnet wallet balance read on a funded address (#1959). Gated + `#[ignore]` +/// so it never runs in CI or an ordinary `cargo test`; the operator opts in per the live-funds gate. +#[tokio::test] +#[ignore = "reads real mainnet balance — run only with DIG_LIVE_FUNDS_TEST=1 + the funded test wallet (see live_funds_dev_tip_broadcasts_and_confirms)"] +async fn live_wallet_balance_reads_a_funded_address() { + // ── Gate 1: the explicit opt-in env. Without it, this is a no-op skip (belt-and-suspenders + // beside `#[ignore]`, so even a `--ignored` sweep on a normal machine can't trigger the read). ── + if std::env::var("DIG_LIVE_FUNDS_TEST").as_deref() != Ok("1") { + eprintln!( + "SKIP live_wallet_balance_reads_a_funded_address: set DIG_LIVE_FUNDS_TEST=1 (and \ + DIG_TEST_WALLET_MNEMONIC) to run the live mainnet balance read — same gate as \ + live_funds_dev_tip_broadcasts_and_confirms" + ); + return; + } + + // ── Gate 2: the funded test wallet mnemonic, by env (exported from /.test-credentials — NEVER + // inlined or logged). Absent-while-gated is a hard, explicit failure. ── + let mnemonic = std::env::var("DIG_TEST_WALLET_MNEMONIC").expect( + "DIG_LIVE_FUNDS_TEST=1 requires DIG_TEST_WALLET_MNEMONIC (export it from /.test-credentials; \ + never commit or print it)", + ); + let password = "live-funds-e2e-password"; + + // ── Assemble a LIVE wallet (real chia_query broadcaster + confirmer + lineage + fallback). ── + let dir = scratch_dir(); + let svc = WalletService::build_with( + &dir, + WalletServiceConfig { + enable_live_broadcast: true, + }, + ) + .await; + + // Import + unlock the funded test wallet (persist_and_unlock loads the signer). NEVER logs the + // mnemonic. + let custody = svc + .backend + .custody() + .expect("live wallet must carry node custody"); + let wallet = custody + .import(&mnemonic, password, None) + .expect("import + unlock the funded test wallet"); + eprintln!( + "live e2e balance read: funded test wallet unlocked at {}", + wallet.address + ); + + // ── Read the live mainnet balance for the funded address. ── + let result = svc + .backend + .balance_for_address(&wallet.address, dig_wallet::sage::rpc::BalanceAsset::Xch) + .await + .expect("balance read must succeed for a funded address on live mainnet"); + + // Assert the balance is non-zero and confirmed. + eprintln!( + "live e2e balance read: confirmed = {} mojos, pending = {} mojos, synced = {}", + result.balance, result.pending, result.synced + ); + + // The funded test address must have a non-zero confirmed balance on mainnet. + assert!( + result.balance > 0, + "the funded test wallet must have confirmed balance on live mainnet" + ); + + let _ = std::fs::remove_dir_all(&dir); +}