mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-09 06:38:12 -05:00
darkfid: introduce a second rpc handler for mm http requests
This commit is contained in:
@@ -23,6 +23,9 @@ threshold = 3
|
||||
# minerd JSON-RPC endpoint
|
||||
minerd_endpoint = "tcp://127.0.0.1:28467"
|
||||
|
||||
# Optional HTTP JSON-RPC listen URL to serve handlers for p2pool merge mining requests
|
||||
#mm_rpc_listen = "http+tcp://127.0.0.1:8241"
|
||||
|
||||
# PoW block production target, in seconds
|
||||
pow_target = 10
|
||||
|
||||
@@ -129,6 +132,9 @@ threshold = 6
|
||||
# minerd JSON-RPC endpoint
|
||||
#minerd_endpoint = "tcp://127.0.0.1:28467"
|
||||
|
||||
# Optional HTTP JSON-RPC listen URL to serve handlers for p2pool merge mining requests
|
||||
#mm_rpc_listen = "http+tcp://127.0.0.1:8241"
|
||||
|
||||
# PoW block production target, in seconds
|
||||
pow_target = 90
|
||||
|
||||
@@ -234,6 +240,9 @@ threshold = 11
|
||||
# minerd JSON-RPC endpoint
|
||||
#minerd_endpoint = "tcp://127.0.0.1:28467"
|
||||
|
||||
# Optional HTTP JSON-RPC listen URL to serve handlers for p2pool merge mining requests
|
||||
#mm_rpc_listen = "http+tcp://127.0.0.1:8241"
|
||||
|
||||
# PoW block production target, in seconds
|
||||
pow_target = 90
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@ use url::Url;
|
||||
use darkfi::{
|
||||
net::settings::Settings,
|
||||
rpc::{
|
||||
client::RpcChadClient,
|
||||
jsonrpc::JsonSubscriber,
|
||||
server::{listen_and_serve, RequestHandler},
|
||||
},
|
||||
@@ -45,6 +44,7 @@ use error::{server_error, RpcError};
|
||||
|
||||
/// JSON-RPC requests handler and methods
|
||||
mod rpc;
|
||||
use rpc::{DefaultRpcHandler, MinerRpcClient, MmRpcHandler};
|
||||
mod rpc_blockchain;
|
||||
mod rpc_tx;
|
||||
|
||||
@@ -56,21 +56,6 @@ use task::{consensus::ConsensusInitTaskConfig, consensus_init_task};
|
||||
mod proto;
|
||||
use proto::{DarkfidP2pHandler, DarkfidP2pHandlerPtr};
|
||||
|
||||
/// Structure to hold a JSON-RPC client and its config,
|
||||
/// so we can recreate it in case of an error.
|
||||
pub struct MinerRpcClient {
|
||||
endpoint: Url,
|
||||
ex: ExecutorPtr,
|
||||
client: RpcChadClient,
|
||||
}
|
||||
|
||||
impl MinerRpcClient {
|
||||
pub async fn new(endpoint: Url, ex: ExecutorPtr) -> Result<Self> {
|
||||
let client = RpcChadClient::new(endpoint.clone(), ex.clone()).await?;
|
||||
Ok(Self { endpoint, ex, client })
|
||||
}
|
||||
}
|
||||
|
||||
/// Atomic pointer to the DarkFi node
|
||||
pub type DarkfiNodePtr = Arc<DarkfiNode>;
|
||||
|
||||
@@ -88,6 +73,8 @@ pub struct DarkfiNode {
|
||||
rpc_connections: Mutex<HashSet<StoppableTaskPtr>>,
|
||||
/// JSON-RPC client to execute requests to the miner daemon
|
||||
rpc_client: Option<Mutex<MinerRpcClient>>,
|
||||
/// HTTP JSON-RPC connection tracker
|
||||
mm_rpc_connections: Mutex<HashSet<StoppableTaskPtr>>,
|
||||
}
|
||||
|
||||
impl DarkfiNode {
|
||||
@@ -105,6 +92,7 @@ impl DarkfiNode {
|
||||
subscribers,
|
||||
rpc_connections: Mutex::new(HashSet::new()),
|
||||
rpc_client,
|
||||
mm_rpc_connections: Mutex::new(HashSet::new()),
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -120,6 +108,8 @@ pub struct Darkfid {
|
||||
dnet_task: StoppableTaskPtr,
|
||||
/// JSON-RPC background task
|
||||
rpc_task: StoppableTaskPtr,
|
||||
/// HTTP JSON-RPC background task
|
||||
mm_rpc_task: StoppableTaskPtr,
|
||||
/// Consensus protocol background task
|
||||
consensus_task: StoppableTaskPtr,
|
||||
}
|
||||
@@ -182,11 +172,12 @@ impl Darkfid {
|
||||
// Generate the background tasks
|
||||
let dnet_task = StoppableTask::new();
|
||||
let rpc_task = StoppableTask::new();
|
||||
let mm_rpc_task = StoppableTask::new();
|
||||
let consensus_task = StoppableTask::new();
|
||||
|
||||
info!(target: "darkfid::Darkfid::init", "Darkfi daemon initialized successfully!");
|
||||
|
||||
Ok(Arc::new(Self { node, dnet_task, rpc_task, consensus_task }))
|
||||
Ok(Arc::new(Self { node, dnet_task, rpc_task, mm_rpc_task, consensus_task }))
|
||||
}
|
||||
|
||||
/// Start the DarkFi daemon in the given executor, using the provided JSON-RPC listen url
|
||||
@@ -195,6 +186,7 @@ impl Darkfid {
|
||||
&self,
|
||||
executor: &ExecutorPtr,
|
||||
rpc_listen: &Url,
|
||||
mm_rpc_listen: &Option<Url>,
|
||||
config: &ConsensusInitTaskConfig,
|
||||
) -> Result<()> {
|
||||
info!(target: "darkfid::Darkfid::start", "Starting Darkfi daemon...");
|
||||
@@ -234,10 +226,10 @@ impl Darkfid {
|
||||
info!(target: "darkfid::Darkfid::start", "Starting JSON-RPC server");
|
||||
let node_ = self.node.clone();
|
||||
self.rpc_task.clone().start(
|
||||
listen_and_serve(rpc_listen.clone(), self.node.clone(), None, executor.clone()),
|
||||
listen_and_serve::<DefaultRpcHandler>(rpc_listen.clone(), self.node.clone(), None, executor.clone()),
|
||||
|res| async move {
|
||||
match res {
|
||||
Ok(()) | Err(Error::RpcServerStopped) => node_.stop_connections().await,
|
||||
Ok(()) | Err(Error::RpcServerStopped) => <DarkfiNode as RequestHandler<DefaultRpcHandler>>::stop_connections(&node_).await,
|
||||
Err(e) => error!(target: "darkfid::Darkfid::start", "Failed starting JSON-RPC server: {}", e),
|
||||
}
|
||||
},
|
||||
@@ -245,6 +237,31 @@ impl Darkfid {
|
||||
executor.clone(),
|
||||
);
|
||||
|
||||
// Start the HTTP JSON-RPC task
|
||||
if let Some(url) = mm_rpc_listen {
|
||||
info!(target: "darkfid::Darkfid::start", "Starting HTTP JSON-RPC server");
|
||||
let node_ = self.node.clone();
|
||||
self.mm_rpc_task.clone().start(
|
||||
listen_and_serve::<MmRpcHandler>(url.clone(), self.node.clone(), None, executor.clone()),
|
||||
|res| async move {
|
||||
match res {
|
||||
Ok(()) | Err(Error::RpcServerStopped) => <DarkfiNode as RequestHandler<MmRpcHandler>>::stop_connections(&node_).await,
|
||||
Err(e) => error!(target: "darkfid::Darkfid::start", "Failed starting HTTP JSON-RPC server: {}", e),
|
||||
}
|
||||
},
|
||||
Error::RpcServerStopped,
|
||||
executor.clone(),
|
||||
);
|
||||
} else {
|
||||
// Create a dummy task
|
||||
self.mm_rpc_task.clone().start(
|
||||
async { Ok(()) },
|
||||
|_| async { /* Do nothing */ },
|
||||
Error::RpcServerStopped,
|
||||
executor.clone(),
|
||||
);
|
||||
}
|
||||
|
||||
// Start the P2P network
|
||||
info!(target: "darkfid::Darkfid::start", "Starting P2P network");
|
||||
self.node
|
||||
@@ -287,6 +304,10 @@ impl Darkfid {
|
||||
info!(target: "darkfid::Darkfid::stop", "Stopping JSON-RPC server...");
|
||||
self.rpc_task.stop().await;
|
||||
|
||||
// Stop the HTTP JSON-RPC task
|
||||
info!(target: "darkfid::Darkfid::stop", "Stopping HTTP JSON-RPC server...");
|
||||
self.rpc_task.stop().await;
|
||||
|
||||
// Stop the P2P network
|
||||
info!(target: "darkfid::Darkfid::stop", "Stopping P2P network protocols handler...");
|
||||
self.node.p2p_handler.stop().await;
|
||||
@@ -303,7 +324,7 @@ impl Darkfid {
|
||||
// Close the JSON-RPC client, if it was initialized
|
||||
if let Some(ref rpc_client) = self.node.rpc_client {
|
||||
info!(target: "darkfid::Darkfid::stop", "Stopping JSON-RPC client...");
|
||||
rpc_client.lock().await.client.stop().await;
|
||||
rpc_client.lock().await.stop().await;
|
||||
};
|
||||
|
||||
info!(target: "darkfid::Darkfid::stop", "Darkfi daemon terminated successfully!");
|
||||
|
||||
@@ -94,6 +94,10 @@ pub struct BlockchainNetwork {
|
||||
/// minerd JSON-RPC endpoint
|
||||
minerd_endpoint: Option<Url>,
|
||||
|
||||
#[structopt(long)]
|
||||
/// Optional HTTP JSON-RPC listen URL to serve handlers for p2pool merge mining requests
|
||||
mm_rpc_listen: Option<Url>,
|
||||
|
||||
#[structopt(long, default_value = "10")]
|
||||
/// PoW block production target, in seconds
|
||||
pow_target: u32,
|
||||
@@ -225,7 +229,9 @@ async fn realmain(args: Args, ex: Arc<smol::Executor<'static>>) -> Result<()> {
|
||||
user_data: blockchain_config.user_data,
|
||||
bootstrap,
|
||||
};
|
||||
daemon.start(&ex, &blockchain_config.rpc_listen, &config).await?;
|
||||
daemon
|
||||
.start(&ex, &blockchain_config.rpc_listen, &blockchain_config.mm_rpc_listen, &config)
|
||||
.await?;
|
||||
|
||||
// Signal handling for graceful termination.
|
||||
let (signals_handler, signals_task) = SignalHandler::new(ex)?;
|
||||
|
||||
@@ -22,6 +22,7 @@ use async_trait::async_trait;
|
||||
use log::{debug, error, info};
|
||||
use smol::lock::MutexGuard;
|
||||
use tinyjson::JsonValue;
|
||||
use url::Url;
|
||||
|
||||
use darkfi::{
|
||||
net::P2pPtr,
|
||||
@@ -31,7 +32,7 @@ use darkfi::{
|
||||
p2p_method::HandlerP2p,
|
||||
server::RequestHandler,
|
||||
},
|
||||
system::{sleep, StoppableTaskPtr},
|
||||
system::{sleep, ExecutorPtr, StoppableTaskPtr},
|
||||
util::time::Timestamp,
|
||||
Error, Result,
|
||||
};
|
||||
@@ -41,9 +42,34 @@ use crate::{
|
||||
DarkfiNode,
|
||||
};
|
||||
|
||||
/// Default JSON-RPC `RequestHandler` type
|
||||
pub struct DefaultRpcHandler;
|
||||
/// HTTP JSON-RPC `RequestHandler` type for p2pool
|
||||
pub struct MmRpcHandler;
|
||||
|
||||
/// Structure to hold a JSON-RPC client and its config,
|
||||
/// so we can recreate it in case of an error.
|
||||
pub struct MinerRpcClient {
|
||||
endpoint: Url,
|
||||
ex: ExecutorPtr,
|
||||
client: RpcChadClient,
|
||||
}
|
||||
|
||||
impl MinerRpcClient {
|
||||
pub async fn new(endpoint: Url, ex: ExecutorPtr) -> Result<Self> {
|
||||
let client = RpcChadClient::new(endpoint.clone(), ex.clone()).await?;
|
||||
Ok(Self { endpoint, ex, client })
|
||||
}
|
||||
|
||||
/// Stop the client.
|
||||
pub async fn stop(&self) {
|
||||
self.client.stop().await
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
#[rustfmt::skip]
|
||||
impl RequestHandler<()> for DarkfiNode {
|
||||
impl RequestHandler<DefaultRpcHandler> for DarkfiNode {
|
||||
async fn handle_request(&self, req: JsonRequest) -> JsonResult {
|
||||
debug!(target: "darkfid::rpc", "--> {}", req.stringify().unwrap());
|
||||
|
||||
@@ -51,7 +77,7 @@ impl RequestHandler<()> for DarkfiNode {
|
||||
// =====================
|
||||
// Miscellaneous methods
|
||||
// =====================
|
||||
"ping" => self.pong(req.id, req.params).await,
|
||||
"ping" => <DarkfiNode as RequestHandler<DefaultRpcHandler>>::pong(self, req.id, req.params).await,
|
||||
"clock" => self.clock(req.id, req.params).await,
|
||||
"ping_miner" => self.ping_miner(req.id, req.params).await,
|
||||
"dnet.switch" => self.dnet_switch(req.id, req.params).await,
|
||||
@@ -94,6 +120,31 @@ impl RequestHandler<()> for DarkfiNode {
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
#[rustfmt::skip]
|
||||
impl RequestHandler<MmRpcHandler> for DarkfiNode {
|
||||
async fn handle_request(&self, req: JsonRequest) -> JsonResult {
|
||||
debug!(target: "darkfid::mm_rpc", "--> {}", req.stringify().unwrap());
|
||||
|
||||
match req.method.as_str() {
|
||||
// =====================
|
||||
// Miscellaneous methods
|
||||
// =====================
|
||||
"ping" => <DarkfiNode as RequestHandler<MmRpcHandler>>::pong(self, req.id, req.params).await,
|
||||
"clock" => self.clock(req.id, req.params).await,
|
||||
|
||||
// ==============
|
||||
// Invalid method
|
||||
// ==============
|
||||
_ => JsonError::new(ErrorCode::MethodNotFound, None, req.id).into(),
|
||||
}
|
||||
}
|
||||
|
||||
async fn connections_mut(&self) -> MutexGuard<'life0, HashSet<StoppableTaskPtr>> {
|
||||
self.mm_rpc_connections.lock().await
|
||||
}
|
||||
}
|
||||
|
||||
impl DarkfiNode {
|
||||
// RPCAPI:
|
||||
// Returns current system clock as `u64` (String) timestamp.
|
||||
|
||||
@@ -271,13 +271,13 @@ fn darkfid_programmatic_control() -> Result<()> {
|
||||
.unwrap();
|
||||
|
||||
// Start it
|
||||
daemon.start(&ex, &rpc_listen, &consensus_config).await.unwrap();
|
||||
daemon.start(&ex, &rpc_listen, &None, &consensus_config).await.unwrap();
|
||||
|
||||
// Stop it
|
||||
daemon.stop().await.unwrap();
|
||||
|
||||
// Start it again
|
||||
daemon.start(&ex, &rpc_listen, &consensus_config).await.unwrap();
|
||||
daemon.start(&ex, &rpc_listen, &None, &consensus_config).await.unwrap();
|
||||
|
||||
// Stop it
|
||||
daemon.stop().await.unwrap();
|
||||
|
||||
@@ -23,6 +23,9 @@ threshold = 1
|
||||
# minerd JSON-RPC endpoint
|
||||
minerd_endpoint = "tcp://127.0.0.1:48467"
|
||||
|
||||
# Optional HTTP JSON-RPC listen URL to serve handlers for p2pool merge mining requests
|
||||
#mm_rpc_listen = "http+tcp://127.0.0.1:8241"
|
||||
|
||||
# PoW block production target, in seconds
|
||||
pow_target = 10
|
||||
|
||||
|
||||
Reference in New Issue
Block a user