Skip to content

Commit d6fca63

Browse files
oleonardolimaclaude
andcommitted
test(wallet): make truc tx test bdk_testenv-agnostic
Rewrite `test_create_and_spend_from_truc_tx` to exercise the BIP-431 rule #2 filter in-memory, dropping `bdk_testenv`/`bdk_electrum`: funding via `insert_checkpoint`+`receive_output`, broadcasts via `insert_tx`. Also fix txD to be genuinely non-TRUC. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 2347280 commit d6fca63

2 files changed

Lines changed: 27 additions & 87 deletions

File tree

Cargo.toml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ test-utils = ["std", "anyhow", "tempfile"]
4646
[dev-dependencies]
4747
anyhow = "1"
4848
assert_matches = "1.5.0"
49-
bdk_testenv = { version = "0.13.1" }
5049
bdk_bitcoind_rpc = { version = "0.22.0" }
5150
bdk_electrum = { version = "0.23.2" }
5251
bdk_esplora = { version = "0.22.1", features = ["async-https", "blocking-https", "tokio"] }
@@ -78,7 +77,3 @@ name = "esplora_blocking"
7877

7978
[[example]]
8079
name = "bitcoind_rpc"
81-
82-
# override `bdk_testenv` to the latest one, as it's the one that have `bitcoind v0.28`
83-
[patch.crates-io]
84-
bdk_testenv = { git = "https://github.com/bitcoindevkit/bdk.git", branch = "master", package = "bdk_testenv" }

tests/wallet.rs

Lines changed: 27 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
use std::str::FromStr;
22
use std::sync::Arc;
3-
use std::time::Duration;
43

54
use assert_matches::assert_matches;
65
use bdk_chain::{BlockId, CanonicalizationParams, ConfirmationBlockTime};
7-
use bdk_testenv::TestEnv;
86
use bdk_wallet::coin_selection;
97
use bdk_wallet::coin_selection::InsufficientFunds;
108
use bdk_wallet::descriptor::{calc_checksum, DescriptorError, IntoWalletDescriptor};
@@ -3065,57 +3063,35 @@ fn test_tx_ordering_untouched_preserves_insertion_ordering_bnb_success() {
30653063

30663064
#[test]
30673065
fn test_create_and_spend_from_truc_tx() -> anyhow::Result<()> {
3068-
let env = TestEnv::new().expect("should create `TestEnv` successfully!");
3069-
3070-
let _ = env
3071-
.mine_blocks(101, None)
3072-
.expect("should mine blocks successfully!");
3073-
30743066
let (descriptor, change_descriptor) = get_test_wpkh_and_change_desc();
30753067
let mut wallet = Wallet::create(descriptor, change_descriptor)
30763068
.network(Network::Regtest)
30773069
.create_wallet_no_persist()
30783070
.expect("should create wallet successfully!");
30793071

3080-
let recv_addr = wallet.next_unused_address(KeychainKind::External);
3081-
3082-
// add funds to the wallet (two 250k sats UTXOs)
3083-
let _ = env
3084-
.send(&recv_addr, Amount::from_sat(250_000))
3085-
.expect("should fund wallet successfully!");
3086-
let _ = env
3087-
.send(&recv_addr, Amount::from_sat(250_000))
3088-
.expect("should fund wallet successfully!");
3089-
3090-
// mine block that confirms tx
3091-
let _ = env.mine_blocks(6, None)?;
3092-
env.wait_until_electrum_sees_block(Duration::from_secs(6))?;
3093-
3094-
let balance = wallet.balance();
3095-
assert_eq!(
3096-
balance.total(),
3097-
Amount::ZERO,
3098-
"wallet balance SHOULD be zero before any scan/sync"
3099-
);
3100-
3101-
// wallet full scan
3102-
let electrum_client = bdk_electrum::BdkElectrumClient::new(env.electrum_client());
3103-
3104-
let request = wallet.start_full_scan();
3105-
let response = electrum_client
3106-
.full_scan(request, 50, 5, true)
3107-
.expect("should execute full scan successfully!");
3072+
// establish a chain tip so confirmed funds can be anchored to a block in the active chain.
3073+
let block = BlockId {
3074+
height: 1_000,
3075+
hash: BlockHash::all_zeros(),
3076+
};
3077+
insert_checkpoint(&mut wallet, block);
3078+
let anchor = ConfirmationBlockTime {
3079+
block_id: block,
3080+
confirmation_time: 0,
3081+
};
31083082

3109-
wallet.apply_update(response)?;
3083+
// add funds to the wallet (two 250k sats confirmed UTXOs)
3084+
receive_output(&mut wallet, Amount::from_sat(250_000), anchor);
3085+
receive_output(&mut wallet, Amount::from_sat(250_000), anchor);
31103086

31113087
let balance = wallet.balance();
31123088
assert_eq!(
31133089
balance.total(),
31143090
Amount::from_sat(500_000),
3115-
"wallet balance SHOULD be 500K after initial full scan"
3091+
"wallet balance SHOULD be 500K after funding"
31163092
);
31173093

3118-
// Should be able to create/broadcast TRUC (v3) transactions.
3094+
// Should be able to create TRUC (v3) transactions.
31193095
// NOTE: "A TRUC transaction can spend outputs from confirmed non-TRUC transactions. A non-TRUC
31203096
// transaction can spend outputs from confirmed TRUC transactions" See, rule #2: https://github.com/bitcoin/bips/blob/master/bip-0431.mediawiki#specification
31213097

@@ -3130,26 +3106,16 @@ fn test_create_and_spend_from_truc_tx() -> anyhow::Result<()> {
31303106

31313107
let _ = wallet.sign(&mut psbt, SignOptions::default())?;
31323108
let tx_a = psbt.extract_tx()?;
3109+
let txid_a = tx_a.compute_txid();
31333110

3134-
// broadcast txA (TRUC)
3135-
let txid_a = electrum_client
3136-
.transaction_broadcast(&tx_a)
3137-
.expect("should broadcast txA (TRUC) successfully!");
3138-
let _ = env.wait_until_electrum_sees_txid(txid_a, Duration::from_secs(6));
3139-
3140-
// wallet sync
3141-
let request = wallet.start_sync_with_revealed_spks();
3142-
let response = electrum_client
3143-
.sync(request, 5, true)
3144-
.expect("should execute sync successfully!");
3145-
3146-
wallet.apply_update(response)?;
3111+
// "broadcast" txA (TRUC): insert it into the wallet's local view as an unconfirmed tx.
3112+
insert_tx(&mut wallet, tx_a);
31473113

31483114
let balance = wallet.balance();
31493115
assert_eq!(
31503116
balance.untrusted_pending,
31513117
Amount::from_sat(125_000),
3152-
"wallet balance SHOULD have 125K unconfirmed (TRUC) UTXO after txA sync!"
3118+
"wallet balance SHOULD have 125K unconfirmed (TRUC) UTXO after txA!"
31533119
);
31543120

31553121
// create txB (non-TRUC)
@@ -3173,24 +3139,15 @@ fn test_create_and_spend_from_truc_tx() -> anyhow::Result<()> {
31733139
"SHOULD NOT try to spend an unconfirmed TRUC output in a non-TRUC tx!"
31743140
);
31753141

3176-
// broadcast txB (non-TRUC)
3177-
let txid_b = electrum_client
3178-
.transaction_broadcast(&tx_b)
3179-
.expect("should broadcast txB (non-TRUC) successfully!");
3180-
3181-
// wallet sync
3182-
let request = wallet.start_sync_with_revealed_spks();
3183-
let response = electrum_client
3184-
.sync(request, 5, true)
3185-
.expect("should execute sync successfully!");
3186-
3187-
wallet.apply_update(response)?;
3142+
// "broadcast" txB (non-TRUC)
3143+
let txid_b = tx_b.compute_txid();
3144+
insert_tx(&mut wallet, tx_b);
31883145

31893146
let balance = wallet.balance();
31903147
assert_eq!(
31913148
balance.untrusted_pending,
31923149
Amount::from_sat(250_000),
3193-
"wallet balance SHOULD have 250K unconfirmed, both non-TRUC (txB) and TRUC (txA) UTXOs after txB sync!"
3150+
"wallet balance SHOULD have 250K unconfirmed, both non-TRUC (txB) and TRUC (txA) UTXOs after txB!"
31943151
);
31953152

31963153
// create txC (TRUC)
@@ -3200,7 +3157,7 @@ fn test_create_and_spend_from_truc_tx() -> anyhow::Result<()> {
32003157
builder.add_recipient(recv_addr.script_pubkey(), Amount::from_sat(200_000));
32013158
builder.version(3);
32023159

3203-
let mut psbt = builder.finish().expect("should create txB (TRUC) successfully! as per BIP-431 it can spend unconfirmed outputs from TRUC txs.");
3160+
let mut psbt = builder.finish().expect("should create txC (TRUC) successfully! as per BIP-431 it can spend unconfirmed outputs from TRUC txs.");
32043161

32053162
let _ = wallet.sign(&mut psbt, SignOptions::default())?;
32063163
let tx_c = psbt.extract_tx()?;
@@ -3213,33 +3170,21 @@ fn test_create_and_spend_from_truc_tx() -> anyhow::Result<()> {
32133170
"SHOULD NOT try to spend an unconfirmed non-TRUC output in a TRUC tx!"
32143171
);
32153172

3216-
// broadcast txC (TRUC)
3217-
let txid_c = electrum_client
3218-
.transaction_broadcast(&tx_c)
3219-
.expect("should broadcast txC (TRUC) successfully!");
3220-
let _ = env.wait_until_electrum_sees_txid(txid_c, Duration::from_secs(6));
3221-
3222-
// wallet sync
3223-
let request = wallet.start_sync_with_revealed_spks();
3224-
let response = electrum_client
3225-
.sync(request, 5, true)
3226-
.expect("should execute sync successfully!");
3227-
3228-
wallet.apply_update(response)?;
3173+
// "broadcast" txC (TRUC)
3174+
insert_tx(&mut wallet, tx_c);
32293175

32303176
let balance = wallet.balance();
32313177
assert_eq!(
32323178
balance.untrusted_pending,
32333179
Amount::from_sat(325_000),
3234-
"wallet balance SHOULD have 325K unconfirmed UTXOs after sync!"
3180+
"wallet balance SHOULD have 325K unconfirmed UTXOs after txC!"
32353181
);
32363182

32373183
// create txD (non-TRUC)
32383184
let recv_addr = wallet.next_unused_address(KeychainKind::External);
32393185

32403186
let mut builder = wallet.build_tx();
32413187
builder.add_recipient(recv_addr.script_pubkey(), Amount::from_sat(400_000));
3242-
builder.version(3);
32433188

32443189
let psbt = builder.finish();
32453190

0 commit comments

Comments
 (0)