]> Untitled Git - bdk/commitdiff
Rpc: Manually add immature coinbase utxos
author志宇 <hello@evanlinjin.me>
Sat, 30 Jul 2022 11:47:33 +0000 (19:47 +0800)
committer志宇 <hello@evanlinjin.me>
Thu, 4 Aug 2022 03:27:50 +0000 (11:27 +0800)
Before this commit, the rpc backend would not notice immature utxos
(`listunspent` does not return them), making the rpc balance different
to other blockchain implementations.

Co-authored-by: Daniela Brozzoni <danielabrozzoni@protonmail.com>
src/blockchain/rpc.rs
src/testutils/blockchain_tests.rs

index 410e92f929df6ffcbd112b5a01523bff76b3da5a..f711452bf1ed873ae52390022170a072094f35c6 100644 (file)
@@ -424,24 +424,29 @@ impl DbState {
             // check if tx has an immature coinbase output (add to updated UTXOs)
             // this is required because `listunspent` does not include immature coinbase outputs
             if tx_res.detail.category == GetTransactionResultDetailCategory::Immature {
-                // let vout = tx_res.detail.vout;
-                // let txout = raw_tx.output.get(vout as usize).cloned().ok_or_else(|| {
-                //     Error::Generic(format!(
-                //         "Core RPC returned detail with invalid vout '{}' for tx '{}'",
-                //         vout, tx_res.info.txid,
-                //     ))
-                // })?;
-                // println!("got immature detail!");
-
-                // if let Some((keychain, _)) = db.get_path_from_script_pubkey(&txout.script_pubkey)? {
-                //     let utxo = LocalUtxo {
-                //         outpoint: OutPoint::new(tx_res.info.txid, d.vout),
-                //         txout,
-                //         keychain,
-                //         is_spent: false,
-                //     };
-                //     self.updated_utxos.insert(utxo);
-                // }
+                let txout = raw_tx
+                    .output
+                    .get(tx_res.detail.vout as usize)
+                    .cloned()
+                    .ok_or_else(|| {
+                        Error::Generic(format!(
+                            "Core RPC returned detail with invalid vout '{}' for tx '{}'",
+                            tx_res.detail.vout, tx_res.info.txid,
+                        ))
+                    })?;
+
+                if let Some((keychain, index)) =
+                    db.get_path_from_script_pubkey(&txout.script_pubkey)?
+                {
+                    let utxo = LocalUtxo {
+                        outpoint: OutPoint::new(tx_res.info.txid, tx_res.detail.vout),
+                        txout,
+                        keychain,
+                        is_spent: false,
+                    };
+                    self.updated_utxos.insert(utxo);
+                    self._update_last_index(keychain, index);
+                }
             }
 
             // update tx deltas
@@ -511,7 +516,7 @@ impl DbState {
         let new_utxos = core_utxos.difference(&self.utxos).cloned();
 
         // add to updated utxos
-        self.updated_utxos = spent_utxos.chain(new_utxos).collect();
+        self.updated_utxos.extend(spent_utxos.chain(new_utxos));
 
         Ok(self)
     }
@@ -604,6 +609,7 @@ impl DbState {
         // update utxos
         self.updated_utxos
             .iter()
+            .inspect(|&utxo| println!("updating: {:?}", utxo.txout))
             .try_for_each(|utxo| batch.set_utxo(utxo))?;
 
         // update last indexes
index ed73a2994a3d651d05e759eea811ac35b0d6dc87..975c377dc0fcc272978de5e548d6c268fbfd61f3 100644 (file)
@@ -1064,13 +1064,6 @@ macro_rules! bdk_blockchain_tests {
 
                 test_client.generate(1, Some(wallet_addr));
 
-                #[cfg(feature = "rpc")]
-                {
-                    // rpc consider coinbase only when mature (100 blocks)
-                    let node_addr = test_client.get_node_address(None);
-                    test_client.generate(100, Some(node_addr));
-                }
-
                 wallet.sync(&blockchain, SyncOptions::default()).unwrap();
                 assert!(wallet.get_balance().unwrap() > 0, "incorrect balance after receiving coinbase");
             }