Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
70 changes: 70 additions & 0 deletions crates/dig-node-service/tests/live_funds_tip_e2e.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Loading