Skip to content

Commit f1a5597

Browse files
committed
[rpc] Filter out unrelated transactions
For some reason while doing the "remove blockchain from wallet PR" I changed the tests around in what I thought was a benign way. But it meant (apparently) that both parties "test_sync_double_receive" were using the same "blockchain". This meant that when the blockchain was RPC they both imported their addresses to it and got each other's results when syncing. This bugged out the sync and this commit fixes that.
1 parent 0b8f23e commit f1a5597

File tree

2 files changed

+27
-25
lines changed

2 files changed

+27
-25
lines changed

src/blockchain/rpc.rs

+17-15
Original file line numberDiff line numberDiff line change
@@ -318,22 +318,24 @@ impl WalletSync for RpcBlockchain {
318318
}
319319
}
320320

321-
let current_utxos: HashSet<_> = current_utxo
321+
// Filter out trasactions that are for script pubkeys that aren't in this wallet.
322+
let current_utxos = current_utxo
322323
.into_iter()
323-
.map(|u| {
324-
Ok(LocalUtxo {
325-
outpoint: OutPoint::new(u.txid, u.vout),
326-
keychain: db
327-
.get_path_from_script_pubkey(&u.script_pub_key)?
328-
.ok_or(Error::TransactionNotFound)?
329-
.0,
330-
txout: TxOut {
331-
value: u.amount.as_sat(),
332-
script_pubkey: u.script_pub_key,
333-
},
334-
})
335-
})
336-
.collect::<Result<_, Error>>()?;
324+
.filter_map(
325+
|u| match db.get_path_from_script_pubkey(&u.script_pub_key) {
326+
Err(e) => Some(Err(e)),
327+
Ok(None) => None,
328+
Ok(Some(path)) => Some(Ok(LocalUtxo {
329+
outpoint: OutPoint::new(u.txid, u.vout),
330+
keychain: path.0,
331+
txout: TxOut {
332+
value: u.amount.as_sat(),
333+
script_pubkey: u.script_pub_key,
334+
},
335+
})),
336+
},
337+
)
338+
.collect::<Result<HashSet<_>, Error>>()?;
337339

338340
let spent: HashSet<_> = known_utxos.difference(&current_utxos).collect();
339341
for s in spent {

src/testutils/blockchain_tests.rs

+10-10
Original file line numberDiff line numberDiff line change
@@ -621,41 +621,41 @@ macro_rules! bdk_blockchain_tests {
621621
#[test]
622622
fn test_sync_double_receive() {
623623
let (wallet, blockchain, descriptors, mut test_client) = init_single_sig();
624-
let receiver_wallet = get_wallet_from_descriptors(&("wpkh(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW)".to_string(), None));
624+
let receiver_wallet = get_wallet_from_descriptors(&("wpkh(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW)".to_string(), None));
625625
// need to sync so rpc can start watching
626626
receiver_wallet.sync(&blockchain, SyncOptions::default()).unwrap();
627627

628628
test_client.receive(testutils! {
629629
@tx ( (@external descriptors, 0) => 50_000, (@external descriptors, 1) => 25_000 ) (@confirmations 1)
630630
});
631631

632-
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
632+
wallet.sync(&blockchain, SyncOptions::default()).expect("sync");
633633
assert_eq!(wallet.get_balance().unwrap(), 75_000, "incorrect balance");
634634
let target_addr = receiver_wallet.get_address($crate::wallet::AddressIndex::New).unwrap().address;
635635

636636
let tx1 = {
637637
let mut builder = wallet.build_tx();
638638
builder.add_recipient(target_addr.script_pubkey(), 49_000).enable_rbf();
639-
let (mut psbt, _details) = builder.finish().unwrap();
640-
let finalized = wallet.sign(&mut psbt, Default::default()).unwrap();
639+
let (mut psbt, _details) = builder.finish().expect("building first tx");
640+
let finalized = wallet.sign(&mut psbt, Default::default()).expect("signing first tx");
641641
assert!(finalized, "Cannot finalize transaction");
642642
psbt.extract_tx()
643643
};
644644

645645
let tx2 = {
646646
let mut builder = wallet.build_tx();
647647
builder.add_recipient(target_addr.script_pubkey(), 49_000).enable_rbf().fee_rate(FeeRate::from_sat_per_vb(5.0));
648-
let (mut psbt, _details) = builder.finish().unwrap();
649-
let finalized = wallet.sign(&mut psbt, Default::default()).unwrap();
648+
let (mut psbt, _details) = builder.finish().expect("building replacement tx");
649+
let finalized = wallet.sign(&mut psbt, Default::default()).expect("signing replacement tx");
650650
assert!(finalized, "Cannot finalize transaction");
651651
psbt.extract_tx()
652652
};
653653

654-
blockchain.broadcast(&tx1).unwrap();
655-
blockchain.broadcast(&tx2).unwrap();
654+
blockchain.broadcast(&tx1).expect("broadcasting first");
655+
blockchain.broadcast(&tx2).expect("broadcasting replacement");
656656

657-
receiver_wallet.sync(&blockchain, SyncOptions::default()).unwrap();
658-
assert_eq!(receiver_wallet.get_balance().unwrap(), 49_000, "should have received coins once and only once");
657+
receiver_wallet.sync(&blockchain, SyncOptions::default()).expect("syncing receiver");
658+
assert_eq!(receiver_wallet.get_balance().expect("balance"), 49_000, "should have received coins once and only once");
659659
}
660660

661661
#[test]

0 commit comments

Comments
 (0)