commands: update our state immediately after broadcasting a tx

This commit is contained in:
Antoine Poinsot 2024-03-15 11:29:56 +01:00
parent 1cf42d9aee
commit b7fde6a9e4
No known key found for this signature in database
GPG Key ID: E13FC145CD3F4304
3 changed files with 32 additions and 3 deletions

View File

@ -12,6 +12,9 @@ use miniscript::bitcoin::secp256k1;
#[derive(Debug, Clone)]
pub enum PollerMessage {
Shutdown,
/// Ask the Bitcoin poller to poll immediately, get notified through the passed channel once
/// it's done.
PollNow(mpsc::SyncSender<()>),
}
/// The Bitcoin poller handler.
@ -84,6 +87,16 @@ impl Poller {
log::info!("Bitcoin poller was told to shut down.");
return;
}
Ok(PollerMessage::PollNow(sender)) => {
// We've been asked to poll, don't wait any further and signal completion to
// the caller.
last_poll = Some(time::Instant::now());
looper::poll(&self.bit, &self.db, &self.secp, &self.descs);
if let Err(e) = sender.send(()) {
log::error!("Error sending immediate poll completion signal: {}.", e);
}
continue;
}
Err(mpsc::RecvTimeoutError::Timeout) => {
// It's been long enough since the last poll.
}

View File

@ -8,6 +8,7 @@ use crate::{
bitcoin::BitcoinInterface,
database::{Coin, DatabaseConnection, DatabaseInterface},
descriptors,
poller::PollerMessage,
spend::{
create_spend, AddrInfo, AncestorInfo, CandidateCoin, CreateSpendRes, SpendCreationError,
SpendOutputAddress, SpendTxFees, TxGetter,
@ -24,7 +25,8 @@ use utils::{
use std::{
collections::{hash_map, HashMap, HashSet},
fmt, sync,
fmt,
sync::{self, mpsc},
};
use miniscript::{
@ -688,7 +690,18 @@ impl DaemonControl {
let final_tx = spend_psbt.extract_tx_unchecked_fee_rate();
self.bitcoin
.broadcast_tx(&final_tx)
.map_err(CommandError::TxBroadcast)
.map_err(CommandError::TxBroadcast)?;
// Finally, update our state with the changes from this transaction.
let (tx, rx) = mpsc::sync_channel(0);
if let Err(e) = self.poller_sender.send(PollerMessage::PollNow(tx)) {
log::error!("Error requesting update from poller: {}", e);
}
if let Err(e) = rx.recv() {
log::error!("Error receiving completion signal from poller: {}", e);
}
Ok(())
}
/// Create PSBT to replace the given transaction using RBF.

View File

@ -257,6 +257,7 @@ fn setup_bitcoind(
pub struct DaemonControl {
config: Config,
bitcoin: sync::Arc<sync::Mutex<dyn BitcoinInterface>>,
poller_sender: mpsc::SyncSender<poller::PollerMessage>,
// FIXME: Should we require Sync on DatabaseInterface rather than using a Mutex?
db: sync::Arc<sync::Mutex<dyn DatabaseInterface>>,
secp: secp256k1::Secp256k1<secp256k1::VerifyOnly>,
@ -266,12 +267,14 @@ impl DaemonControl {
pub(crate) fn new(
config: Config,
bitcoin: sync::Arc<sync::Mutex<dyn BitcoinInterface>>,
poller_sender: mpsc::SyncSender<poller::PollerMessage>,
db: sync::Arc<sync::Mutex<dyn DatabaseInterface>>,
secp: secp256k1::Secp256k1<secp256k1::VerifyOnly>,
) -> DaemonControl {
DaemonControl {
config,
bitcoin,
poller_sender,
db,
secp,
}
@ -387,7 +390,7 @@ impl DaemonHandle {
// Create the API the external world will use to talk to us, either directly through the Rust
// structure or through the JSONRPC server we may setup below.
let control = DaemonControl::new(config, bit, db, secp);
let control = DaemonControl::new(config, bit, poller_sender.clone(), db, secp);
Ok(if with_rpc_server {
let rpcserver_shutdown = sync::Arc::from(sync::atomic::AtomicBool::from(false));