Skip to content

Commit 5eb74af

Browse files
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>
1 parent ac19c19 commit 5eb74af

File tree

2 files changed

+25
-26
lines changed

2 files changed

+25
-26
lines changed

src/blockchain/rpc.rs

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -424,24 +424,29 @@ impl DbState {
424424
// check if tx has an immature coinbase output (add to updated UTXOs)
425425
// this is required because `listunspent` does not include immature coinbase outputs
426426
if tx_res.detail.category == GetTransactionResultDetailCategory::Immature {
427-
// let vout = tx_res.detail.vout;
428-
// let txout = raw_tx.output.get(vout as usize).cloned().ok_or_else(|| {
429-
// Error::Generic(format!(
430-
// "Core RPC returned detail with invalid vout '{}' for tx '{}'",
431-
// vout, tx_res.info.txid,
432-
// ))
433-
// })?;
434-
// println!("got immature detail!");
435-
436-
// if let Some((keychain, _)) = db.get_path_from_script_pubkey(&txout.script_pubkey)? {
437-
// let utxo = LocalUtxo {
438-
// outpoint: OutPoint::new(tx_res.info.txid, d.vout),
439-
// txout,
440-
// keychain,
441-
// is_spent: false,
442-
// };
443-
// self.updated_utxos.insert(utxo);
444-
// }
427+
let txout = raw_tx
428+
.output
429+
.get(tx_res.detail.vout as usize)
430+
.cloned()
431+
.ok_or_else(|| {
432+
Error::Generic(format!(
433+
"Core RPC returned detail with invalid vout '{}' for tx '{}'",
434+
tx_res.detail.vout, tx_res.info.txid,
435+
))
436+
})?;
437+
438+
if let Some((keychain, index)) =
439+
db.get_path_from_script_pubkey(&txout.script_pubkey)?
440+
{
441+
let utxo = LocalUtxo {
442+
outpoint: OutPoint::new(tx_res.info.txid, tx_res.detail.vout),
443+
txout,
444+
keychain,
445+
is_spent: false,
446+
};
447+
self.updated_utxos.insert(utxo);
448+
self._update_last_index(keychain, index);
449+
}
445450
}
446451

447452
// update tx deltas
@@ -511,7 +516,7 @@ impl DbState {
511516
let new_utxos = core_utxos.difference(&self.utxos).cloned();
512517

513518
// add to updated utxos
514-
self.updated_utxos = spent_utxos.chain(new_utxos).collect();
519+
self.updated_utxos.extend(spent_utxos.chain(new_utxos));
515520

516521
Ok(self)
517522
}
@@ -604,6 +609,7 @@ impl DbState {
604609
// update utxos
605610
self.updated_utxos
606611
.iter()
612+
.inspect(|&utxo| println!("updating: {:?}", utxo.txout))
607613
.try_for_each(|utxo| batch.set_utxo(utxo))?;
608614

609615
// update last indexes

src/testutils/blockchain_tests.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,13 +1064,6 @@ macro_rules! bdk_blockchain_tests {
10641064

10651065
test_client.generate(1, Some(wallet_addr));
10661066

1067-
#[cfg(feature = "rpc")]
1068-
{
1069-
// rpc consider coinbase only when mature (100 blocks)
1070-
let node_addr = test_client.get_node_address(None);
1071-
test_client.generate(100, Some(node_addr));
1072-
}
1073-
10741067
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
10751068
assert!(wallet.get_balance().unwrap() > 0, "incorrect balance after receiving coinbase");
10761069
}

0 commit comments

Comments
 (0)