]> Untitled Git - bdk/commitdiff
[rpc] Filter out unrelated transactions
authorLLFourn <lloyd.fourn@gmail.com>
Thu, 24 Feb 2022 09:32:47 +0000 (20:32 +1100)
committerLLFourn <lloyd.fourn@gmail.com>
Thu, 24 Feb 2022 09:39:00 +0000 (20:39 +1100)
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.

src/blockchain/rpc.rs
src/testutils/blockchain_tests.rs

index a474a0e2855113b9f5ae11fc01aeade05d3b8261..e4a798460ccd524902b8231c210b3d729521cd51 100644 (file)
@@ -318,22 +318,24 @@ impl WalletSync for RpcBlockchain {
             }
         }
 
-        let current_utxos: HashSet<_> = current_utxo
+        // Filter out trasactions that are for script pubkeys that aren't in this wallet.
+        let current_utxos = current_utxo
             .into_iter()
-            .map(|u| {
-                Ok(LocalUtxo {
-                    outpoint: OutPoint::new(u.txid, u.vout),
-                    keychain: db
-                        .get_path_from_script_pubkey(&u.script_pub_key)?
-                        .ok_or(Error::TransactionNotFound)?
-                        .0,
-                    txout: TxOut {
-                        value: u.amount.as_sat(),
-                        script_pubkey: u.script_pub_key,
-                    },
-                })
-            })
-            .collect::<Result<_, Error>>()?;
+            .filter_map(
+                |u| match db.get_path_from_script_pubkey(&u.script_pub_key) {
+                    Err(e) => Some(Err(e)),
+                    Ok(None) => None,
+                    Ok(Some(path)) => Some(Ok(LocalUtxo {
+                        outpoint: OutPoint::new(u.txid, u.vout),
+                        keychain: path.0,
+                        txout: TxOut {
+                            value: u.amount.as_sat(),
+                            script_pubkey: u.script_pub_key,
+                        },
+                    })),
+                },
+            )
+            .collect::<Result<HashSet<_>, Error>>()?;
 
         let spent: HashSet<_> = known_utxos.difference(&current_utxos).collect();
         for s in spent {
index eefdd75bd60d7984623088468133b1583b6a9dd0..b54da105ceba45bf1af9dcda944b4a4e6835d5ae 100644 (file)
@@ -621,7 +621,7 @@ macro_rules! bdk_blockchain_tests {
             #[test]
             fn test_sync_double_receive() {
                 let (wallet, blockchain, descriptors, mut test_client) = init_single_sig();
-                                let receiver_wallet = get_wallet_from_descriptors(&("wpkh(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW)".to_string(), None));
+                let receiver_wallet = get_wallet_from_descriptors(&("wpkh(cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW)".to_string(), None));
                 // need to sync so rpc can start watching
                 receiver_wallet.sync(&blockchain, SyncOptions::default()).unwrap();
 
@@ -629,15 +629,15 @@ macro_rules! bdk_blockchain_tests {
                     @tx ( (@external descriptors, 0) => 50_000, (@external descriptors, 1) => 25_000 ) (@confirmations 1)
                 });
 
-                wallet.sync(&blockchain, SyncOptions::default()).unwrap();
+                wallet.sync(&blockchain, SyncOptions::default()).expect("sync");
                 assert_eq!(wallet.get_balance().unwrap(), 75_000, "incorrect balance");
                 let target_addr = receiver_wallet.get_address($crate::wallet::AddressIndex::New).unwrap().address;
 
                 let tx1 = {
                     let mut builder = wallet.build_tx();
                     builder.add_recipient(target_addr.script_pubkey(), 49_000).enable_rbf();
-                    let (mut psbt, _details) = builder.finish().unwrap();
-                    let finalized = wallet.sign(&mut psbt, Default::default()).unwrap();
+                    let (mut psbt, _details) = builder.finish().expect("building first tx");
+                    let finalized = wallet.sign(&mut psbt, Default::default()).expect("signing first tx");
                     assert!(finalized, "Cannot finalize transaction");
                     psbt.extract_tx()
                 };
@@ -645,17 +645,17 @@ macro_rules! bdk_blockchain_tests {
                 let tx2 = {
                     let mut builder = wallet.build_tx();
                     builder.add_recipient(target_addr.script_pubkey(), 49_000).enable_rbf().fee_rate(FeeRate::from_sat_per_vb(5.0));
-                    let (mut psbt, _details) = builder.finish().unwrap();
-                    let finalized = wallet.sign(&mut psbt, Default::default()).unwrap();
+                    let (mut psbt, _details) = builder.finish().expect("building replacement tx");
+                    let finalized = wallet.sign(&mut psbt, Default::default()).expect("signing replacement tx");
                     assert!(finalized, "Cannot finalize transaction");
                     psbt.extract_tx()
                 };
 
-                blockchain.broadcast(&tx1).unwrap();
-                blockchain.broadcast(&tx2).unwrap();
+                blockchain.broadcast(&tx1).expect("broadcasting first");
+                blockchain.broadcast(&tx2).expect("broadcasting replacement");
 
-                receiver_wallet.sync(&blockchain, SyncOptions::default()).unwrap();
-                assert_eq!(receiver_wallet.get_balance().unwrap(), 49_000, "should have received coins once and only once");
+                receiver_wallet.sync(&blockchain, SyncOptions::default()).expect("syncing receiver");
+                assert_eq!(receiver_wallet.get_balance().expect("balance"), 49_000, "should have received coins once and only once");
             }
 
             #[test]