This resolves a panic like the following, which is caused when a
non-Tokio thread tries to broadcast a transaction, for example
when a transaction is broadcasted indirectly by the background
processor.
```
thread '<unnamed>' panicked at 'there is no reactor running, must be called from the context of a Tokio 1.x runtime', src/bitcoind_client.rs:253:9
```
rpc_user: String,
rpc_password: String,
fees: Arc<HashMap<Target, AtomicU32>>,
rpc_user: String,
rpc_password: String,
fees: Arc<HashMap<Target, AtomicU32>>,
+ handle: tokio::runtime::Handle,
}
#[derive(Clone, Eq, Hash, PartialEq)]
}
#[derive(Clone, Eq, Hash, PartialEq)]
impl BitcoindClient {
pub async fn new(
host: String, port: u16, rpc_user: String, rpc_password: String,
impl BitcoindClient {
pub async fn new(
host: String, port: u16, rpc_user: String, rpc_password: String,
+ handle: tokio::runtime::Handle,
) -> std::io::Result<Self> {
let http_endpoint = HttpEndpoint::for_host(host.clone()).with_port(port);
let rpc_credentials =
) -> std::io::Result<Self> {
let http_endpoint = HttpEndpoint::for_host(host.clone()).with_port(port);
let rpc_credentials =
rpc_user,
rpc_password,
fees: Arc::new(fees),
rpc_user,
rpc_password,
fees: Arc::new(fees),
+ handle: handle.clone(),
};
BitcoindClient::poll_for_fee_estimates(
client.fees.clone(),
client.bitcoind_rpc_client.clone(),
};
BitcoindClient::poll_for_fee_estimates(
client.fees.clone(),
client.bitcoind_rpc_client.clone(),
- async fn poll_for_fee_estimates(
+ fn poll_for_fee_estimates(
fees: Arc<HashMap<Target, AtomicU32>>, rpc_client: Arc<Mutex<RpcClient>>,
fees: Arc<HashMap<Target, AtomicU32>>, rpc_client: Arc<Mutex<RpcClient>>,
+ handle: tokio::runtime::Handle,
- tokio::spawn(async move {
+ handle.spawn(async move {
loop {
let background_estimate = {
let mut rpc = rpc_client.lock().await;
loop {
let background_estimate = {
let mut rpc = rpc_client.lock().await;
fn broadcast_transaction(&self, tx: &Transaction) {
let bitcoind_rpc_client = self.bitcoind_rpc_client.clone();
let tx_serialized = serde_json::json!(encode::serialize_hex(tx));
fn broadcast_transaction(&self, tx: &Transaction) {
let bitcoind_rpc_client = self.bitcoind_rpc_client.clone();
let tx_serialized = serde_json::json!(encode::serialize_hex(tx));
- tokio::spawn(async move {
+ self.handle.spawn(async move {
let mut rpc = bitcoind_rpc_client.lock().await;
// This may error due to RL calling `broadcast_transaction` with the same transaction
// multiple times, but the error is safe to ignore.
let mut rpc = bitcoind_rpc_client.lock().await;
// This may error due to RL calling `broadcast_transaction` with the same transaction
// multiple times, but the error is safe to ignore.
args.bitcoind_rpc_port,
args.bitcoind_rpc_username.clone(),
args.bitcoind_rpc_password.clone(),
args.bitcoind_rpc_port,
args.bitcoind_rpc_username.clone(),
args.bitcoind_rpc_password.clone(),
+ tokio::runtime::Handle::current(),