Abstract Daemon methods in RpcCall trait

This commit is contained in:
Sosthene 2024-11-18 15:21:52 +01:00 committed by Nicolas Cantu
parent abae89c6cb
commit 98e373bd89
2 changed files with 101 additions and 56 deletions

View File

@ -122,18 +122,14 @@ fn rpc_connect(rpcwallet: Option<String>, network: Network, mut rpc_url: String)
#[derive(Debug)]
pub struct Daemon {
// p2p: Mutex<Connection>,
rpc: Client,
}
impl Daemon {
pub(crate) fn connect(
impl RpcCall for Daemon {
fn connect(
rpcwallet: Option<String>,
rpc_url: String,
network: Network,
// config: &Config,
// exit_flag: &ExitFlag,
// metrics: &Metrics,
) -> Result<Self> {
let mut rpc = rpc_connect(rpcwallet, network, rpc_url)?;
@ -150,9 +146,6 @@ impl Daemon {
}
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 {
anyhow::bail!("electrs requires active bitcoind p2p network");
}
@ -161,16 +154,10 @@ impl Daemon {
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 })
}
pub(crate) fn estimate_fee(&self, nblocks: u16) -> Result<Amount> {
fn estimate_fee(&self, nblocks: u16) -> Result<Amount> {
let res = self
.rpc
.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
.rpc
.get_network_info()
@ -190,21 +177,21 @@ impl Daemon {
.relay_fee)
}
pub(crate) fn get_current_height(&self) -> Result<u64> {
fn get_current_height(&self) -> Result<u64> {
Ok(self
.rpc
.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
.rpc
.get_block(&block_hash)
.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 filter = self
.rpc
@ -214,7 +201,7 @@ impl Daemon {
Ok((block_height, block_hash, filter))
}
pub(crate) fn list_unspent_from_to(
fn list_unspent_from_to(
&self,
minamt: Option<Amount>,
) -> Result<Vec<json::ListUnspentResultEntry>> {
@ -235,7 +222,7 @@ impl Daemon {
)?)
}
pub(crate) fn create_psbt(
fn create_psbt(
&self,
unspents: &[ListUnspentResultEntry],
spk: ScriptBuf,
@ -273,7 +260,7 @@ impl Daemon {
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)?;
match processed_psbt.complete {
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))?;
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()?;
Ok(blockchain_info.chain)
}
pub(crate) fn test_mempool_accept(
fn test_mempool_accept(
&self,
tx: &Transaction,
) -> Result<crate::bitcoin_json::TestMempoolAcceptResult> {
@ -307,13 +294,13 @@ impl Daemon {
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)?;
Ok(txid)
}
pub(crate) fn get_transaction_info(
fn get_transaction_info(
&self,
txid: &Txid,
blockhash: Option<BlockHash>,
@ -327,7 +314,7 @@ impl Daemon {
.context("failed to get transaction info")
}
pub(crate) fn get_transaction_hex(
fn get_transaction_hex(
&self,
txid: &Txid,
blockhash: Option<BlockHash>,
@ -341,7 +328,7 @@ impl Daemon {
serde_json::to_value(TxAsHex(tx)).map_err(Into::into)
}
pub(crate) fn get_transaction(
fn get_transaction(
&self,
txid: &Txid,
blockhash: Option<BlockHash>,
@ -351,7 +338,7 @@ impl Daemon {
.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
.rpc
.get_block_info(&blockhash)
@ -359,13 +346,13 @@ impl Daemon {
.tx)
}
pub(crate) fn get_mempool_txids(&self) -> Result<Vec<Txid>> {
fn get_mempool_txids(&self) -> Result<Vec<Txid>> {
self.rpc
.get_raw_mempool()
.context("failed to get mempool txids")
}
pub(crate) fn get_mempool_entries(
fn get_mempool_entries(
&self,
txids: &[Txid],
) -> Result<Vec<Result<json::GetMempoolEntryResult>>> {
@ -391,7 +378,7 @@ impl Daemon {
.collect())
}
pub(crate) fn get_mempool_transactions(
fn get_mempool_transactions(
&self,
txids: &[Txid],
) -> Result<Vec<Result<Transaction>>> {
@ -420,21 +407,81 @@ impl Daemon {
.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<()>
// where
// B: IntoIterator<Item = BlockHash>,
// F: FnMut(BlockHash, SerBlock),
// {
// self.p2p.lock().for_blocks(blockhashes, func)
// }
pub(crate) trait RpcCall: Send + Sync + std::fmt::Debug {
fn connect(
rpcwallet: Option<String>,
rpc_url: String,
network: Network,
) -> Result<Self> where Self: Sized;
// pub(crate) fn new_block_notification(&self) -> Receiver<()> {
// self.p2p.lock().new_block_notification()
// }
fn estimate_fee(&self, nblocks: u16) -> Result<Amount>;
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;

View File

@ -15,13 +15,13 @@ use futures_util::{future, pin_mut, stream::TryStreamExt, FutureExt, StreamExt};
use log::{debug, error, warn};
use message::{broadcast_message, process_message, BroadcastType, MessageCache, MESSAGECACHE};
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,
hex::{DisplayHex, FromHex},
Amount, Network, Transaction,
}, MutexExt};
use sdk_common::sp_client::{
bitcoin::{Txid, OutPoint},
bitcoin::OutPoint,
bitcoin::secp256k1::rand::{thread_rng, Rng},
spclient::SpWallet,
};
@ -48,7 +48,7 @@ mod scan;
mod commit;
use crate::config::Config;
use crate::{daemon::Daemon, scan::scan_blocks};
use crate::{daemon::{Daemon, RpcCall}, scan::scan_blocks};
type Tx = UnboundedSender<Message>;
@ -56,9 +56,7 @@ type PeerMap = Mutex<HashMap<SocketAddr, Tx>>;
pub(crate) static PEERMAP: OnceLock<PeerMap> = OnceLock::new();
type SharedDaemon = Mutex<Daemon>;
pub(crate) static DAEMON: OnceLock<SharedDaemon> = OnceLock::new();
pub(crate) static DAEMON: OnceLock<Mutex<Box<dyn RpcCall>>> = 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| {
if let Ok(raw_msg) = msg.to_text() {
debug!("Received msg: {}", raw_msg);
// debug!("Received msg: {}", raw_msg);
process_message(raw_msg, addr);
} else {
debug!("Received non-text message {} from peer {}", msg, addr);
@ -309,11 +307,11 @@ async fn main() -> Result<()> {
// Connect the rpc daemon
DAEMON
.set(Mutex::new(Daemon::connect(
.set(Mutex::new(Box::new(Daemon::connect(
config.core_wallet,
config.core_url,
config.network,
)?))
)?)))
.expect("DAEMON initialization failed");
let current_tip: u32 = DAEMON