Abstract Daemon methods in RpcCall trait
This commit is contained in:
parent
8eae4408f2
commit
39a8ff87a9
141
src/daemon.rs
141
src/daemon.rs
@ -122,18 +122,14 @@ fn rpc_connect(rpcwallet: Option<String>, network: Network, mut rpc_url: String)
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Daemon {
|
pub struct Daemon {
|
||||||
// p2p: Mutex<Connection>,
|
|
||||||
rpc: Client,
|
rpc: Client,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Daemon {
|
impl RpcCall for Daemon {
|
||||||
pub(crate) fn connect(
|
fn connect(
|
||||||
rpcwallet: Option<String>,
|
rpcwallet: Option<String>,
|
||||||
rpc_url: String,
|
rpc_url: String,
|
||||||
network: Network,
|
network: Network,
|
||||||
// config: &Config,
|
|
||||||
// exit_flag: &ExitFlag,
|
|
||||||
// metrics: &Metrics,
|
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
let mut rpc = rpc_connect(rpcwallet, network, rpc_url)?;
|
let mut rpc = rpc_connect(rpcwallet, network, rpc_url)?;
|
||||||
|
|
||||||
@ -150,9 +146,6 @@ impl Daemon {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let network_info = rpc.get_network_info()?;
|
let network_info = rpc.get_network_info()?;
|
||||||
// if network_info.version < 21_00_00 {
|
|
||||||
// bail!("electrs requires bitcoind 0.21+");
|
|
||||||
// }
|
|
||||||
if !network_info.network_active {
|
if !network_info.network_active {
|
||||||
anyhow::bail!("electrs requires active bitcoind p2p network");
|
anyhow::bail!("electrs requires active bitcoind p2p network");
|
||||||
}
|
}
|
||||||
@ -161,16 +154,10 @@ impl Daemon {
|
|||||||
anyhow::bail!("electrs requires non-pruned bitcoind node");
|
anyhow::bail!("electrs requires non-pruned bitcoind node");
|
||||||
}
|
}
|
||||||
|
|
||||||
// let p2p = tokio::sync::Mutex::new(Connection::connect(
|
|
||||||
// config.network,
|
|
||||||
// config.daemon_p2p_addr,
|
|
||||||
// metrics,
|
|
||||||
// config.signet_magic,
|
|
||||||
// )?);
|
|
||||||
Ok(Self { rpc })
|
Ok(Self { rpc })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn estimate_fee(&self, nblocks: u16) -> Result<Amount> {
|
fn estimate_fee(&self, nblocks: u16) -> Result<Amount> {
|
||||||
let res = self
|
let res = self
|
||||||
.rpc
|
.rpc
|
||||||
.estimate_smart_fee(nblocks, None)
|
.estimate_smart_fee(nblocks, None)
|
||||||
@ -182,7 +169,7 @@ impl Daemon {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_relay_fee(&self) -> Result<Amount> {
|
fn get_relay_fee(&self) -> Result<Amount> {
|
||||||
Ok(self
|
Ok(self
|
||||||
.rpc
|
.rpc
|
||||||
.get_network_info()
|
.get_network_info()
|
||||||
@ -190,21 +177,21 @@ impl Daemon {
|
|||||||
.relay_fee)
|
.relay_fee)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_current_height(&self) -> Result<u64> {
|
fn get_current_height(&self) -> Result<u64> {
|
||||||
Ok(self
|
Ok(self
|
||||||
.rpc
|
.rpc
|
||||||
.get_block_count()
|
.get_block_count()
|
||||||
.context("failed to get block count")?)
|
.context("failed to get block count")?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_block(&self, block_hash: BlockHash) -> Result<Block> {
|
fn get_block(&self, block_hash: BlockHash) -> Result<Block> {
|
||||||
Ok(self
|
Ok(self
|
||||||
.rpc
|
.rpc
|
||||||
.get_block(&block_hash)
|
.get_block(&block_hash)
|
||||||
.context("failed to get block")?)
|
.context("failed to get block")?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_filters(&self, block_height: u32) -> Result<(u32, BlockHash, BlockFilter)> {
|
fn get_filters(&self, block_height: u32) -> Result<(u32, BlockHash, BlockFilter)> {
|
||||||
let block_hash = self.rpc.get_block_hash(block_height.try_into()?)?;
|
let block_hash = self.rpc.get_block_hash(block_height.try_into()?)?;
|
||||||
let filter = self
|
let filter = self
|
||||||
.rpc
|
.rpc
|
||||||
@ -214,7 +201,7 @@ impl Daemon {
|
|||||||
Ok((block_height, block_hash, filter))
|
Ok((block_height, block_hash, filter))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn list_unspent_from_to(
|
fn list_unspent_from_to(
|
||||||
&self,
|
&self,
|
||||||
minamt: Option<Amount>,
|
minamt: Option<Amount>,
|
||||||
) -> Result<Vec<json::ListUnspentResultEntry>> {
|
) -> Result<Vec<json::ListUnspentResultEntry>> {
|
||||||
@ -235,7 +222,7 @@ impl Daemon {
|
|||||||
)?)
|
)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn create_psbt(
|
fn create_psbt(
|
||||||
&self,
|
&self,
|
||||||
unspents: &[ListUnspentResultEntry],
|
unspents: &[ListUnspentResultEntry],
|
||||||
spk: ScriptBuf,
|
spk: ScriptBuf,
|
||||||
@ -273,7 +260,7 @@ impl Daemon {
|
|||||||
Ok(wallet_create_funded_result.psbt.to_string())
|
Ok(wallet_create_funded_result.psbt.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn process_psbt(&self, psbt: String) -> Result<String> {
|
fn process_psbt(&self, psbt: String) -> Result<String> {
|
||||||
let processed_psbt = self.rpc.wallet_process_psbt(&psbt, None, None, None)?;
|
let processed_psbt = self.rpc.wallet_process_psbt(&psbt, None, None, None)?;
|
||||||
match processed_psbt.complete {
|
match processed_psbt.complete {
|
||||||
true => Ok(processed_psbt.psbt),
|
true => Ok(processed_psbt.psbt),
|
||||||
@ -281,7 +268,7 @@ impl Daemon {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn finalize_psbt(&self, psbt: String) -> Result<String> {
|
fn finalize_psbt(&self, psbt: String) -> Result<String> {
|
||||||
let final_tx = self.rpc.finalize_psbt(&psbt, Some(false))?;
|
let final_tx = self.rpc.finalize_psbt(&psbt, Some(false))?;
|
||||||
|
|
||||||
match final_tx.complete {
|
match final_tx.complete {
|
||||||
@ -292,13 +279,13 @@ impl Daemon {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_network(&self) -> Result<Network> {
|
fn get_network(&self) -> Result<Network> {
|
||||||
let blockchain_info = self.rpc.get_blockchain_info()?;
|
let blockchain_info = self.rpc.get_blockchain_info()?;
|
||||||
|
|
||||||
Ok(blockchain_info.chain)
|
Ok(blockchain_info.chain)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn test_mempool_accept(
|
fn test_mempool_accept(
|
||||||
&self,
|
&self,
|
||||||
tx: &Transaction,
|
tx: &Transaction,
|
||||||
) -> Result<crate::bitcoin_json::TestMempoolAcceptResult> {
|
) -> Result<crate::bitcoin_json::TestMempoolAcceptResult> {
|
||||||
@ -307,13 +294,13 @@ impl Daemon {
|
|||||||
Ok(res.get(0).unwrap().clone())
|
Ok(res.get(0).unwrap().clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn broadcast(&self, tx: &Transaction) -> Result<Txid> {
|
fn broadcast(&self, tx: &Transaction) -> Result<Txid> {
|
||||||
let txid = self.rpc.send_raw_transaction(tx)?;
|
let txid = self.rpc.send_raw_transaction(tx)?;
|
||||||
|
|
||||||
Ok(txid)
|
Ok(txid)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_transaction_info(
|
fn get_transaction_info(
|
||||||
&self,
|
&self,
|
||||||
txid: &Txid,
|
txid: &Txid,
|
||||||
blockhash: Option<BlockHash>,
|
blockhash: Option<BlockHash>,
|
||||||
@ -327,7 +314,7 @@ impl Daemon {
|
|||||||
.context("failed to get transaction info")
|
.context("failed to get transaction info")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_transaction_hex(
|
fn get_transaction_hex(
|
||||||
&self,
|
&self,
|
||||||
txid: &Txid,
|
txid: &Txid,
|
||||||
blockhash: Option<BlockHash>,
|
blockhash: Option<BlockHash>,
|
||||||
@ -341,7 +328,7 @@ impl Daemon {
|
|||||||
serde_json::to_value(TxAsHex(tx)).map_err(Into::into)
|
serde_json::to_value(TxAsHex(tx)).map_err(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_transaction(
|
fn get_transaction(
|
||||||
&self,
|
&self,
|
||||||
txid: &Txid,
|
txid: &Txid,
|
||||||
blockhash: Option<BlockHash>,
|
blockhash: Option<BlockHash>,
|
||||||
@ -351,7 +338,7 @@ impl Daemon {
|
|||||||
.context("failed to get transaction")
|
.context("failed to get transaction")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_block_txids(&self, blockhash: BlockHash) -> Result<Vec<Txid>> {
|
fn get_block_txids(&self, blockhash: BlockHash) -> Result<Vec<Txid>> {
|
||||||
Ok(self
|
Ok(self
|
||||||
.rpc
|
.rpc
|
||||||
.get_block_info(&blockhash)
|
.get_block_info(&blockhash)
|
||||||
@ -359,13 +346,13 @@ impl Daemon {
|
|||||||
.tx)
|
.tx)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_mempool_txids(&self) -> Result<Vec<Txid>> {
|
fn get_mempool_txids(&self) -> Result<Vec<Txid>> {
|
||||||
self.rpc
|
self.rpc
|
||||||
.get_raw_mempool()
|
.get_raw_mempool()
|
||||||
.context("failed to get mempool txids")
|
.context("failed to get mempool txids")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_mempool_entries(
|
fn get_mempool_entries(
|
||||||
&self,
|
&self,
|
||||||
txids: &[Txid],
|
txids: &[Txid],
|
||||||
) -> Result<Vec<Result<json::GetMempoolEntryResult>>> {
|
) -> Result<Vec<Result<json::GetMempoolEntryResult>>> {
|
||||||
@ -391,7 +378,7 @@ impl Daemon {
|
|||||||
.collect())
|
.collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_mempool_transactions(
|
fn get_mempool_transactions(
|
||||||
&self,
|
&self,
|
||||||
txids: &[Txid],
|
txids: &[Txid],
|
||||||
) -> Result<Vec<Result<Transaction>>> {
|
) -> Result<Vec<Result<Transaction>>> {
|
||||||
@ -420,21 +407,81 @@ impl Daemon {
|
|||||||
.collect())
|
.collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub(crate) fn get_new_headers(&self, chain: &Chain) -> Result<Vec<NewHeader>> {
|
}
|
||||||
// self.p2p.lock().get_new_headers(chain)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// pub(crate) fn for_blocks<B, F>(&self, blockhashes: B, func: F) -> Result<()>
|
pub(crate) trait RpcCall: Send + Sync + std::fmt::Debug {
|
||||||
// where
|
fn connect(
|
||||||
// B: IntoIterator<Item = BlockHash>,
|
rpcwallet: Option<String>,
|
||||||
// F: FnMut(BlockHash, SerBlock),
|
rpc_url: String,
|
||||||
// {
|
network: Network,
|
||||||
// self.p2p.lock().for_blocks(blockhashes, func)
|
) -> Result<Self> where Self: Sized;
|
||||||
// }
|
|
||||||
|
|
||||||
// pub(crate) fn new_block_notification(&self) -> Receiver<()> {
|
fn estimate_fee(&self, nblocks: u16) -> Result<Amount>;
|
||||||
// self.p2p.lock().new_block_notification()
|
|
||||||
// }
|
fn get_relay_fee(&self) -> Result<Amount>;
|
||||||
|
|
||||||
|
fn get_current_height(&self) -> Result<u64>;
|
||||||
|
|
||||||
|
fn get_block(&self, block_hash: BlockHash) -> Result<Block>;
|
||||||
|
|
||||||
|
fn get_filters(&self, block_height: u32) -> Result<(u32, BlockHash, BlockFilter)>;
|
||||||
|
|
||||||
|
fn list_unspent_from_to(
|
||||||
|
&self,
|
||||||
|
minamt: Option<Amount>,
|
||||||
|
) -> Result<Vec<json::ListUnspentResultEntry>>;
|
||||||
|
|
||||||
|
fn create_psbt(
|
||||||
|
&self,
|
||||||
|
unspents: &[ListUnspentResultEntry],
|
||||||
|
spk: ScriptBuf,
|
||||||
|
network: Network,
|
||||||
|
) -> Result<String>;
|
||||||
|
|
||||||
|
fn process_psbt(&self, psbt: String) -> Result<String>;
|
||||||
|
|
||||||
|
fn finalize_psbt(&self, psbt: String) -> Result<String>;
|
||||||
|
|
||||||
|
fn get_network(&self) -> Result<Network>;
|
||||||
|
|
||||||
|
fn test_mempool_accept(
|
||||||
|
&self,
|
||||||
|
tx: &Transaction,
|
||||||
|
) -> Result<crate::bitcoin_json::TestMempoolAcceptResult>;
|
||||||
|
|
||||||
|
fn broadcast(&self, tx: &Transaction) -> Result<Txid>;
|
||||||
|
|
||||||
|
fn get_transaction_info(
|
||||||
|
&self,
|
||||||
|
txid: &Txid,
|
||||||
|
blockhash: Option<BlockHash>,
|
||||||
|
) -> Result<Value>;
|
||||||
|
|
||||||
|
fn get_transaction_hex(
|
||||||
|
&self,
|
||||||
|
txid: &Txid,
|
||||||
|
blockhash: Option<BlockHash>,
|
||||||
|
) -> Result<Value>;
|
||||||
|
|
||||||
|
fn get_transaction(
|
||||||
|
&self,
|
||||||
|
txid: &Txid,
|
||||||
|
blockhash: Option<BlockHash>,
|
||||||
|
) -> Result<Transaction>;
|
||||||
|
|
||||||
|
fn get_block_txids(&self, blockhash: BlockHash) -> Result<Vec<Txid>>;
|
||||||
|
|
||||||
|
fn get_mempool_txids(&self) -> Result<Vec<Txid>>;
|
||||||
|
|
||||||
|
fn get_mempool_entries(
|
||||||
|
&self,
|
||||||
|
txids: &[Txid],
|
||||||
|
) -> Result<Vec<Result<json::GetMempoolEntryResult>>>;
|
||||||
|
|
||||||
|
fn get_mempool_transactions(
|
||||||
|
&self,
|
||||||
|
txids: &[Txid],
|
||||||
|
) -> Result<Vec<Result<Transaction>>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) type RpcError = bitcoincore_rpc::jsonrpc::error::RpcError;
|
pub(crate) type RpcError = bitcoincore_rpc::jsonrpc::error::RpcError;
|
||||||
|
16
src/main.rs
16
src/main.rs
@ -15,13 +15,13 @@ use futures_util::{future, pin_mut, stream::TryStreamExt, FutureExt, StreamExt};
|
|||||||
use log::{debug, error, warn};
|
use log::{debug, error, warn};
|
||||||
use message::{broadcast_message, process_message, BroadcastType, MessageCache, MESSAGECACHE};
|
use message::{broadcast_message, process_message, BroadcastType, MessageCache, MESSAGECACHE};
|
||||||
use scan::compute_partial_tweak_to_transaction;
|
use scan::compute_partial_tweak_to_transaction;
|
||||||
use sdk_common::{pcd::{AnkPcdHash, RoleDefinition}, process::CACHEDPROCESSES, signature::{AnkHash, Proof}, sp_client::bitcoin::{
|
use sdk_common::{process::CACHEDPROCESSES, sp_client::bitcoin::{
|
||||||
consensus::deserialize,
|
consensus::deserialize,
|
||||||
hex::{DisplayHex, FromHex},
|
hex::{DisplayHex, FromHex},
|
||||||
Amount, Network, Transaction,
|
Amount, Network, Transaction,
|
||||||
}, MutexExt};
|
}, MutexExt};
|
||||||
use sdk_common::sp_client::{
|
use sdk_common::sp_client::{
|
||||||
bitcoin::{Txid, OutPoint},
|
bitcoin::OutPoint,
|
||||||
bitcoin::secp256k1::rand::{thread_rng, Rng},
|
bitcoin::secp256k1::rand::{thread_rng, Rng},
|
||||||
spclient::SpWallet,
|
spclient::SpWallet,
|
||||||
};
|
};
|
||||||
@ -48,7 +48,7 @@ mod scan;
|
|||||||
mod commit;
|
mod commit;
|
||||||
|
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::{daemon::Daemon, scan::scan_blocks};
|
use crate::{daemon::{Daemon, RpcCall}, scan::scan_blocks};
|
||||||
|
|
||||||
type Tx = UnboundedSender<Message>;
|
type Tx = UnboundedSender<Message>;
|
||||||
|
|
||||||
@ -56,9 +56,7 @@ type PeerMap = Mutex<HashMap<SocketAddr, Tx>>;
|
|||||||
|
|
||||||
pub(crate) static PEERMAP: OnceLock<PeerMap> = OnceLock::new();
|
pub(crate) static PEERMAP: OnceLock<PeerMap> = OnceLock::new();
|
||||||
|
|
||||||
type SharedDaemon = Mutex<Daemon>;
|
pub(crate) static DAEMON: OnceLock<Mutex<Box<dyn RpcCall>>> = OnceLock::new();
|
||||||
|
|
||||||
pub(crate) static DAEMON: OnceLock<SharedDaemon> = OnceLock::new();
|
|
||||||
|
|
||||||
pub static FREEZED_UTXOS: OnceLock<Mutex<HashSet<OutPoint>>> = OnceLock::new();
|
pub static FREEZED_UTXOS: OnceLock<Mutex<HashSet<OutPoint>>> = OnceLock::new();
|
||||||
|
|
||||||
@ -190,7 +188,7 @@ async fn handle_connection(raw_stream: TcpStream, addr: SocketAddr) {
|
|||||||
|
|
||||||
let broadcast_incoming = incoming.try_for_each(|msg| {
|
let broadcast_incoming = incoming.try_for_each(|msg| {
|
||||||
if let Ok(raw_msg) = msg.to_text() {
|
if let Ok(raw_msg) = msg.to_text() {
|
||||||
debug!("Received msg: {}", raw_msg);
|
// debug!("Received msg: {}", raw_msg);
|
||||||
process_message(raw_msg, addr);
|
process_message(raw_msg, addr);
|
||||||
} else {
|
} else {
|
||||||
debug!("Received non-text message {} from peer {}", msg, addr);
|
debug!("Received non-text message {} from peer {}", msg, addr);
|
||||||
@ -309,11 +307,11 @@ async fn main() -> Result<()> {
|
|||||||
|
|
||||||
// Connect the rpc daemon
|
// Connect the rpc daemon
|
||||||
DAEMON
|
DAEMON
|
||||||
.set(Mutex::new(Daemon::connect(
|
.set(Mutex::new(Box::new(Daemon::connect(
|
||||||
config.core_wallet,
|
config.core_wallet,
|
||||||
config.core_url,
|
config.core_url,
|
||||||
config.network,
|
config.network,
|
||||||
)?))
|
)?)))
|
||||||
.expect("DAEMON initialization failed");
|
.expect("DAEMON initialization failed");
|
||||||
|
|
||||||
let current_tip: u32 = DAEMON
|
let current_tip: u32 = DAEMON
|
||||||
|
Loading…
x
Reference in New Issue
Block a user