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 <danielabrozzoni@protonmail.com>
This commit is contained in:
志宇 2022-07-30 19:47:33 +08:00
parent ac19c19f21
commit 5eb74af414
No known key found for this signature in database
GPG Key ID: F6345C9837C2BDE8
2 changed files with 24 additions and 25 deletions

View File

@ -424,24 +424,29 @@ impl DbState {
// check if tx has an immature coinbase output (add to updated UTXOs) // check if tx has an immature coinbase output (add to updated UTXOs)
// this is required because `listunspent` does not include immature coinbase outputs // this is required because `listunspent` does not include immature coinbase outputs
if tx_res.detail.category == GetTransactionResultDetailCategory::Immature { if tx_res.detail.category == GetTransactionResultDetailCategory::Immature {
// let vout = tx_res.detail.vout; let txout = raw_tx
// let txout = raw_tx.output.get(vout as usize).cloned().ok_or_else(|| { .output
// Error::Generic(format!( .get(tx_res.detail.vout as usize)
// "Core RPC returned detail with invalid vout '{}' for tx '{}'", .cloned()
// vout, tx_res.info.txid, .ok_or_else(|| {
// )) Error::Generic(format!(
// })?; "Core RPC returned detail with invalid vout '{}' for tx '{}'",
// println!("got immature detail!"); tx_res.detail.vout, tx_res.info.txid,
))
})?;
// if let Some((keychain, _)) = db.get_path_from_script_pubkey(&txout.script_pubkey)? { if let Some((keychain, index)) =
// let utxo = LocalUtxo { db.get_path_from_script_pubkey(&txout.script_pubkey)?
// outpoint: OutPoint::new(tx_res.info.txid, d.vout), {
// txout, let utxo = LocalUtxo {
// keychain, outpoint: OutPoint::new(tx_res.info.txid, tx_res.detail.vout),
// is_spent: false, txout,
// }; keychain,
// self.updated_utxos.insert(utxo); is_spent: false,
// } };
self.updated_utxos.insert(utxo);
self._update_last_index(keychain, index);
}
} }
// update tx deltas // update tx deltas
@ -511,7 +516,7 @@ impl DbState {
let new_utxos = core_utxos.difference(&self.utxos).cloned(); let new_utxos = core_utxos.difference(&self.utxos).cloned();
// add to updated utxos // add to updated utxos
self.updated_utxos = spent_utxos.chain(new_utxos).collect(); self.updated_utxos.extend(spent_utxos.chain(new_utxos));
Ok(self) Ok(self)
} }
@ -604,6 +609,7 @@ impl DbState {
// update utxos // update utxos
self.updated_utxos self.updated_utxos
.iter() .iter()
.inspect(|&utxo| println!("updating: {:?}", utxo.txout))
.try_for_each(|utxo| batch.set_utxo(utxo))?; .try_for_each(|utxo| batch.set_utxo(utxo))?;
// update last indexes // update last indexes

View File

@ -1064,13 +1064,6 @@ macro_rules! bdk_blockchain_tests {
test_client.generate(1, Some(wallet_addr)); 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(); wallet.sync(&blockchain, SyncOptions::default()).unwrap();
assert!(wallet.get_balance().unwrap() > 0, "incorrect balance after receiving coinbase"); assert!(wallet.get_balance().unwrap() > 0, "incorrect balance after receiving coinbase");
} }