From 5eb74af41494b7ec4894d7da3015da2981639228 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BF=97=E5=AE=87?= Date: Sat, 30 Jul 2022 19:47:33 +0800 Subject: [PATCH] Rpc: Manually add immature coinbase utxos 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 --- src/blockchain/rpc.rs | 44 ++++++++++++++++++------------- src/testutils/blockchain_tests.rs | 7 ----- 2 files changed, 25 insertions(+), 26 deletions(-) diff --git a/src/blockchain/rpc.rs b/src/blockchain/rpc.rs index 410e92f92..f711452bf 100644 --- a/src/blockchain/rpc.rs +++ b/src/blockchain/rpc.rs @@ -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 diff --git a/src/testutils/blockchain_tests.rs b/src/testutils/blockchain_tests.rs index ed73a2994..975c377dc 100644 --- a/src/testutils/blockchain_tests.rs +++ b/src/testutils/blockchain_tests.rs @@ -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"); }