]> Untitled Git - bdk/commitdiff
[blockchain] Fix receiving a coinbase using Electrum/Esplora
authorAlekos Filini <alekos.filini@gmail.com>
Tue, 13 Oct 2020 09:56:59 +0000 (11:56 +0200)
committerAlekos Filini <alekos.filini@gmail.com>
Tue, 13 Oct 2020 09:56:59 +0000 (11:56 +0200)
Closes #107

src/blockchain/utils.rs
testutils-macros/src/lib.rs
testutils/src/lib.rs

index 0ae3d53120c798d04a9cc15acf63c4f4037b0a54..bf8ff6cb2cdcb40f1eb9699554ef5c6f3fa093bc 100644 (file)
@@ -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)?;
index 7dfcb0ec31dea504bc2d80b1b4fb2ef1b82c5a8b..baabefacf9b3bbdafff0b6918dd94c2adfd59d56 100644 (file)
@@ -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);
+                }
             }
 
                         };
index b73a8de3443185be78e4b5bf7746ec7395416fd1..f7947a542c1d787f03fa87670661783d2e17525a 100644 (file)
@@ -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<Address>) {
+        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<AddressType>) -> Address {