bitcoin: interface for broadcasting a transaction
This commit is contained in:
parent
9bb20303e7
commit
b14bc602d4
@ -679,6 +679,14 @@ impl BitcoinD {
|
||||
blockhash,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn broadcast_tx(&self, tx: &bitcoin::Transaction) -> Result<(), BitcoindError> {
|
||||
self.make_fallible_node_request(
|
||||
"sendrawtransaction",
|
||||
¶ms!(bitcoin::consensus::encode::serialize_hex(tx)),
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
// Bitcoind uses a guess for the value of verificationprogress. It will eventually get to
|
||||
// be 1, and we want to be less conservative.
|
||||
|
||||
@ -4,12 +4,30 @@
|
||||
pub mod d;
|
||||
pub mod poller;
|
||||
|
||||
use d::LSBlockEntry;
|
||||
use d::{BitcoindError, LSBlockEntry};
|
||||
|
||||
use std::{collections::HashMap, fmt, sync};
|
||||
use std::{collections::HashMap, error, fmt, sync};
|
||||
|
||||
use miniscript::bitcoin;
|
||||
|
||||
/// Error occuring when querying our Bitcoin backend.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum BitcoinError {
|
||||
Broadcast(String),
|
||||
}
|
||||
|
||||
impl fmt::Display for BitcoinError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
BitcoinError::Broadcast(reason) => {
|
||||
write!(f, "Failed to broadcast transaction: '{}'", reason)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl error::Error for BitcoinError {}
|
||||
|
||||
/// Information about the best block in the chain
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Copy)]
|
||||
pub struct BlockChainTip {
|
||||
@ -60,6 +78,9 @@ pub trait BitcoinInterface: Send {
|
||||
|
||||
/// Get the common ancestor between the Bitcoin backend's tip and the given tip.
|
||||
fn common_ancestor(&self, tip: &BlockChainTip) -> BlockChainTip;
|
||||
|
||||
/// Broadcast this transaction to the Bitcoin P2P network
|
||||
fn broadcast_tx(&self, tx: &bitcoin::Transaction) -> Result<(), BitcoinError>;
|
||||
}
|
||||
|
||||
impl BitcoinInterface for d::BitcoinD {
|
||||
@ -234,6 +255,18 @@ impl BitcoinInterface for d::BitcoinD {
|
||||
|
||||
ancestor
|
||||
}
|
||||
|
||||
fn broadcast_tx(&self, tx: &bitcoin::Transaction) -> Result<(), BitcoinError> {
|
||||
match self.broadcast_tx(tx) {
|
||||
Ok(()) => Ok(()),
|
||||
Err(BitcoindError::Server(e)) => Err(BitcoinError::Broadcast(e.to_string())),
|
||||
// We assume the Bitcoin backend doesn't fail, so it must be a JSONRPC error.
|
||||
Err(e) => panic!(
|
||||
"Unexpected Bitcoin error when broadcast transaction: '{}'.",
|
||||
e
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: do we need to repeat the entire trait implemenation? Isn't there a nicer way?
|
||||
@ -282,6 +315,10 @@ impl BitcoinInterface for sync::Arc<sync::Mutex<dyn BitcoinInterface + 'static>>
|
||||
fn common_ancestor(&self, tip: &BlockChainTip) -> BlockChainTip {
|
||||
self.lock().unwrap().common_ancestor(tip)
|
||||
}
|
||||
|
||||
fn broadcast_tx(&self, tx: &bitcoin::Transaction) -> Result<(), BitcoinError> {
|
||||
self.lock().unwrap().broadcast_tx(tx)
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: We could avoid this type (and all the conversions entailing allocations) if bitcoind
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
use crate::{
|
||||
bitcoin::{BitcoinInterface, BlockChainTip, UTxO},
|
||||
bitcoin::{BitcoinError, BitcoinInterface, BlockChainTip, UTxO},
|
||||
config::{BitcoinConfig, Config},
|
||||
database::{Coin, DatabaseConnection, DatabaseInterface, SpendBlock},
|
||||
DaemonHandle,
|
||||
@ -66,6 +66,10 @@ impl BitcoinInterface for DummyBitcoind {
|
||||
fn common_ancestor(&self, _: &BlockChainTip) -> BlockChainTip {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn broadcast_tx(&self, _: &bitcoin::Transaction) -> Result<(), BitcoinError> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DummyDb {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user