fix(electrum): Don't ignore multiple coinbase txs
We would previously insert just one coinbase transaction in the database if we caught multiple in the same sync. When we sync with electrum, before committing to the database, we remove from the update conflicting transactions, using the `make_txs_consistent` function. This function considers two txs to be conflicting if they spend from the same outpoint - but every coinbase transaction spends from the same outpoint! Here we make sure to avoid filtering out coinbase transactions, by adding a check on the txid just before we do the filtering. Fixes #1051
This commit is contained in:
parent
d1af252ac4
commit
7a359d5eef
@ -9,7 +9,7 @@ use crate::{
|
||||
wallet::time::Instant,
|
||||
BlockTime, Error, KeychainKind, LocalUtxo, TransactionDetails,
|
||||
};
|
||||
use bitcoin::{OutPoint, Script, ScriptBuf, Transaction, TxOut, Txid};
|
||||
use bitcoin::{hashes::Hash, OutPoint, Script, ScriptBuf, Transaction, TxOut, Txid};
|
||||
use log::*;
|
||||
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet, VecDeque};
|
||||
|
||||
@ -444,8 +444,14 @@ impl<'a, D: BatchDatabase> State<'a, D> {
|
||||
/// Remove conflicting transactions -- tie breaking them by fee.
|
||||
fn make_txs_consistent(txs: &[TransactionDetails]) -> Vec<&TransactionDetails> {
|
||||
let mut utxo_index: HashMap<OutPoint, &TransactionDetails> = HashMap::default();
|
||||
let mut coinbase_txs = vec![];
|
||||
for tx in txs {
|
||||
for input in &tx.transaction.as_ref().unwrap().input {
|
||||
if input.previous_output.txid == Txid::all_zeros() {
|
||||
coinbase_txs.push(tx);
|
||||
break;
|
||||
}
|
||||
|
||||
utxo_index
|
||||
.entry(input.previous_output)
|
||||
.and_modify(|existing| match (tx.fee, existing.fee) {
|
||||
@ -463,5 +469,6 @@ fn make_txs_consistent(txs: &[TransactionDetails]) -> Vec<&TransactionDetails> {
|
||||
.collect::<HashMap<_, _>>()
|
||||
.into_iter()
|
||||
.map(|(_, tx)| tx)
|
||||
.chain(coinbase_txs)
|
||||
.collect()
|
||||
}
|
||||
|
@ -1098,18 +1098,18 @@ macro_rules! bdk_blockchain_tests {
|
||||
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
|
||||
assert_eq!(wallet.get_balance().unwrap().immature, 0, "incorrect balance");
|
||||
|
||||
test_client.generate(1, Some(wallet_addr));
|
||||
test_client.generate(2, Some(wallet_addr));
|
||||
|
||||
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
|
||||
|
||||
assert!(wallet.get_balance().unwrap().immature > 0, "incorrect balance after receiving coinbase");
|
||||
assert_eq!(wallet.get_balance().unwrap().immature, 5000000000*2, "incorrect balance after receiving coinbase");
|
||||
|
||||
// make coinbase 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().confirmed > 0, "incorrect balance after maturing coinbase");
|
||||
assert_eq!(wallet.get_balance().unwrap().confirmed, 5000000000 * 2, "incorrect balance after maturing coinbase");
|
||||
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user