From 0caad5f3d9b63c7814055441dc7cf7f48795ff36 Mon Sep 17 00:00:00 2001 From: Alekos Filini Date: Tue, 13 Oct 2020 11:56:59 +0200 Subject: [PATCH] [blockchain] Fix receiving a coinbase using Electrum/Esplora Closes #107 --- src/blockchain/utils.rs | 7 ++++++- testutils-macros/src/lib.rs | 15 +++++++++++++++ testutils/src/lib.rs | 10 +++++----- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/blockchain/utils.rs b/src/blockchain/utils.rs index 0ae3d531..bf8ff6cb 100644 --- a/src/blockchain/utils.rs +++ b/src/blockchain/utils.rs @@ -243,6 +243,11 @@ pub trait ElectrumLikeSync { // look for our own inputs for (i, input) in tx.input.iter().enumerate() { + // skip coinbase inputs + if input.previous_output.is_null() { + continue; + } + // the fact that we visit addresses in a BFS fashion starting from the external addresses // should ensure that this query is always consistent (i.e. when we get to call this all // the transactions at a lower depth have already been indexed, so if an outpoint is ours @@ -312,7 +317,7 @@ pub trait ElectrumLikeSync { sent: outgoing, height, timestamp: 0, - fees: inputs_sum - outputs_sum, + fees: inputs_sum.saturating_sub(outputs_sum), // if the tx is a coinbase, fees would be negative }; info!("Saving tx {}", txid); updates.set_tx(&tx)?; diff --git a/testutils-macros/src/lib.rs b/testutils-macros/src/lib.rs index 7dfcb0ec..baabefac 100644 --- a/testutils-macros/src/lib.rs +++ b/testutils-macros/src/lib.rs @@ -520,6 +520,21 @@ pub fn bdk_blockchain_tests(attr: TokenStream, item: TokenStream) -> TokenStream assert_eq!(wallet.get_balance().unwrap(), 0); assert_eq!(new_details.received, 0); } + + #[test] + #[serial] + fn test_sync_receive_coinbase() { + let (wallet, descriptors, mut test_client) = init_single_sig(); + let wallet_addr = wallet.get_new_address().unwrap(); + + wallet.sync(noop_progress(), None).unwrap(); + assert_eq!(wallet.get_balance().unwrap(), 0); + + test_client.generate(1, Some(wallet_addr)); + + wallet.sync(noop_progress(), None).unwrap(); + assert!(wallet.get_balance().unwrap() > 0); + } } }; diff --git a/testutils/src/lib.rs b/testutils/src/lib.rs index b73a8de3..f7947a54 100644 --- a/testutils/src/lib.rs +++ b/testutils/src/lib.rs @@ -341,7 +341,7 @@ impl TestClient { .unwrap(); if let Some(num) = meta_tx.min_confirmations { - self.generate(num); + self.generate(num, None); } let monitor_script = Address::from_str(&meta_tx.output[0].to_address) @@ -464,9 +464,9 @@ impl TestClient { block.header.block_hash().to_hex() } - pub fn generate(&mut self, num_blocks: u64) { - let our_addr = self.get_new_address(None, None).unwrap(); - let hashes = self.generate_to_address(num_blocks, &our_addr).unwrap(); + pub fn generate(&mut self, num_blocks: u64, address: Option
) { + let address = address.unwrap_or_else(|| self.get_new_address(None, None).unwrap()); + let hashes = self.generate_to_address(num_blocks, &address).unwrap(); let best_hash = hashes.last().unwrap(); let height = self.get_block_info(best_hash).unwrap().height; @@ -505,7 +505,7 @@ impl TestClient { pub fn reorg(&mut self, num_blocks: u64) { self.invalidate(num_blocks); - self.generate(num_blocks); + self.generate(num_blocks, None); } pub fn get_node_address(&self, address_type: Option) -> Address {