diff --git a/src/bitcoind/interface.rs b/src/bitcoind/interface.rs index 9d0290e5..97ff6dcc 100644 --- a/src/bitcoind/interface.rs +++ b/src/bitcoind/interface.rs @@ -5,7 +5,12 @@ use revault_tx::bitcoin::{ Address, Amount, BlockHash, OutPoint, Script, Transaction, TxOut, Txid, }; -use std::{collections::HashMap, fs, str::FromStr, time::Duration}; +use std::{ + collections::{HashMap, HashSet}, + fs, + str::FromStr, + time::Duration, +}; use jsonrpc::{ arg, @@ -401,13 +406,21 @@ impl BitcoinD { "importdescriptors", ¶ms!(Json::Array(all_descriptors)), )?; - if res.get(0).map(|x| x.get("success")) == Some(Some(&Json::Bool(true))) { + let all_succeeded = res + .as_array() + .map(|results| { + results + .iter() + .all(|res| res.get("success") == Some(&Json::Bool(true))) + }) + .unwrap_or(false); + if all_succeeded { return Ok(()); } Err(BitcoindError::Custom(format!( "Error returned from 'importdescriptor': {:?}", - res.get(0).map(|r| r.get("error")) + res ))) } @@ -827,6 +840,11 @@ impl BitcoinD { block_hash )); + // Get the spent txid to ignore the entries about this transaction + let spent_txid = spent_outpoint.txid.to_string(); + // We use a cache to avoid needless iterations, since listsinceblock returns an entry + // per transaction output, not per transaction. + let mut visited_txs = HashSet::new(); for transaction in transactions { if transaction.get("category").map(|c| c.as_str()).flatten() != Some("send") { continue; @@ -844,6 +862,12 @@ impl BitcoinD { block_hash )); + if visited_txs.contains(&spending_txid) || &spent_txid == spending_txid { + continue; + } else { + visited_txs.insert(spending_txid); + } + let gettx_res = self.make_watchonly_request( "gettransaction", ¶ms!(