use core::fmt;
use core::net::Ipv4Addr;
use core::net::SocketAddr;
use std::net::TcpListener;
use std::path::PathBuf;
use tempfile::TempDir;
pub use bitcoind::BitcoinD;
pub use utreexod::UtreexoD;
pub mod bitcoind;
pub mod utreexod;
const LOCALHOST: Ipv4Addr = Ipv4Addr::new(127, 0, 0, 1);
pub const MAX_RETRIES_NODE_BUILDING: u8 = 5;
pub fn get_available_port() -> u16 {
TcpListener::bind((LOCALHOST, 0))
.unwrap()
.local_addr()
.unwrap()
.port()
}
#[derive(Debug)]
pub enum DataDir {
Persistent(PathBuf),
Temporary(TempDir),
}
impl DataDir {
pub fn path(&self) -> PathBuf {
match self {
Self::Persistent(path) => path.to_owned(),
Self::Temporary(tmp_dir) => tmp_dir.path().to_path_buf(),
}
}
}
#[derive(Debug)]
pub enum Error {
BinaryNotFound(PathBuf),
FailedToSpawn(std::io::Error),
WalletTimeout,
ExhaustedNodeBuildingRetries,
FailedToStop(corepc_client::client_sync::Error),
Io(std::io::Error),
JsonRpc(corepc_client::client_sync::Error),
PeerConnectionTimeout((SocketAddr, SocketAddr)),
BothDirsSpecified,
UnresponsiveBitcoinD(corepc_client::client_sync::Error),
UnresponsiveUtreexoD(corepc_client::client_sync::Error),
CookieFileTimeout(PathBuf),
RpcClientSetupTimeout,
UnexpectedResponse,
}
#[rustfmt::skip]
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use Error::*;
match self {
BinaryNotFound(path) => write!(f, "The `utreexod` binary was not found at the expected location: {}", path.display()),
FailedToSpawn(err) => write!(f, "Failed to spawn a process for the node: {err:?}"),
WalletTimeout => write!(f, "Timed out whilst creating or loading a wallet"),
ExhaustedNodeBuildingRetries => write!(f, "Failed to instantiate the node after {} attempts", MAX_RETRIES_NODE_BUILDING),
FailedToStop(err) => write!(f, "Failed to stop the node over JSON-RPC: {err:?}"),
Io(err) => write!(f, "I/O Error: {err:?}"),
JsonRpc(err) => write!(f, "JSON-RPC Error: {err:?}"),
PeerConnectionTimeout((local_socket, remote_socket)) => write!(f, "Timed out whilst waiting for connection between local={local_socket} and remote={remote_socket}"),
BothDirsSpecified => write!(f, "Both `tempdir` and `workdir` were specified. You must choose one and only one"),
UnresponsiveBitcoinD(err) => write!(f, "`BitcoinD` is unresponsive to JSON-RPC calls: {err:?}"),
UnresponsiveUtreexoD(err) => write!(f, "`UtreexoD` is unresponsive to JSON-RPC calls: {err:?}"),
CookieFileTimeout(cookie_path) => write!(f, "Timed out whilst waiting for the cookie={} to be generated", cookie_path.display()),
RpcClientSetupTimeout => write!(f, "Timed out whilst waiting for the JSON-RPC client to be ready"),
UnexpectedResponse => write!(f, "Received an unexpected response from the JSON-RPC server"),
}
}
}