Prechádzať zdrojové kódy

example/p2pdebug: add rpc listener to work with dnetview

ghassmo 4 rokov pred
rodič
commit
b58058bf31

+ 1 - 1
example/p2pdebug/Cargo.toml

@@ -9,7 +9,7 @@ edition = "2021"
 [workspace]
 
 [dependencies]
-darkfi = {path = "../../", features = ["net3"]}
+darkfi = {path = "../../", features = ["net3", "rpc"]}
 # Async
 smol = "1.2.5"
 futures = "0.3.21"

+ 29 - 3
example/p2pdebug/src/main.rs

@@ -1,4 +1,4 @@
-use std::sync::Arc;
+use std::{net::SocketAddr, sync::Arc};
 
 use async_executor::Executor;
 use clap::Parser;
@@ -9,11 +9,13 @@ use url::Url;
 
 use darkfi::{
     cli_desc, net3 as net,
+    rpc::rpcserver::{listen_and_serve, RpcServerConfig},
     util::{cli::log_config, sleep},
     Result,
 };
 
 pub(crate) mod proto;
+pub(crate) mod rpc;
 
 use crate::proto::debugmsg::{Debugmsg, ProtocolDebugmsg, SeenDebugmsgIds};
 
@@ -35,6 +37,9 @@ struct Args {
     /// communicate using tls protocol by default is tcp
     #[clap(long)]
     tls: bool,
+    /// communicate using tls protocol by default is tcp
+    #[clap(long, default_value = "127.0.0.1:11055")]
+    rpc: SocketAddr,
 }
 
 #[derive(Debug, Clone)]
@@ -114,7 +119,12 @@ impl MockP2p {
         Ok((p2p, Self { node_number, state, broadcast, address }))
     }
 
-    async fn run(&self, p2p: net::P2pPtr, executor: Arc<Executor<'_>>) -> Result<()> {
+    async fn run(
+        &self,
+        p2p: net::P2pPtr,
+        rpc_addr: SocketAddr,
+        executor: Arc<Executor<'_>>,
+    ) -> Result<()> {
         let state = self.state.clone();
         let node_number = self.node_number;
         let address = self.address.clone();
@@ -180,6 +190,22 @@ impl MockP2p {
             })
             .detach();
 
+        // RPC
+        let rpc_config = RpcServerConfig {
+            socket_addr: rpc_addr,
+            use_tls: false,
+            identity_path: Default::default(),
+            identity_pass: Default::default(),
+        };
+
+        let executor_cloned = executor.clone();
+        let rpc_interface = Arc::new(rpc::JsonRpcInterface { addr: rpc_addr, p2p: p2p.clone() });
+        executor
+            .spawn(async move {
+                listen_and_serve(rpc_config, rpc_interface, executor_cloned.clone()).await
+            })
+            .detach();
+
         p2p.clone().start(executor.clone()).await?;
         p2p.run(executor).await
     }
@@ -189,7 +215,7 @@ async fn start(executor: Arc<Executor<'_>>, args: Args) -> Result<()> {
     let scheme = if args.tls { "tls" } else { "tcp" };
 
     let (p2p, mock_p2p) = MockP2p::new(args.node, args.broadcast, scheme).await?;
-    mock_p2p.run(p2p.clone(), executor).await
+    mock_p2p.run(p2p.clone(), args.rpc.clone(), executor).await
 }
 
 fn main() -> Result<()> {

+ 56 - 0
example/p2pdebug/src/rpc.rs

@@ -0,0 +1,56 @@
+use std::{net::SocketAddr, sync::Arc};
+
+use async_executor::Executor;
+use async_trait::async_trait;
+use log::debug;
+use serde_json::{json, Value};
+
+use darkfi::{
+    net3 as net,
+    rpc::{
+        jsonrpc,
+        jsonrpc::{ErrorCode, JsonRequest, JsonResult},
+        rpcserver::RequestHandler,
+    },
+};
+
+pub struct JsonRpcInterface {
+    pub addr: SocketAddr,
+    pub p2p: net::P2pPtr,
+}
+
+#[async_trait]
+impl RequestHandler for JsonRpcInterface {
+    async fn handle_request(&self, req: JsonRequest, _executor: Arc<Executor<'_>>) -> JsonResult {
+        if req.params.as_array().is_none() {
+            return jsonrpc::error(ErrorCode::InvalidRequest, None, req.id).into()
+        }
+
+        debug!(target: "RPC", "--> {}", serde_json::to_string(&req).unwrap());
+
+        match req.method.as_str() {
+            Some("ping") => self.pong(req.id, req.params).await,
+            Some("get_info") => self.get_info(req.id, req.params).await,
+            Some(_) | None => jsonrpc::error(ErrorCode::MethodNotFound, None, req.id).into(),
+        }
+    }
+}
+
+impl JsonRpcInterface {
+    // RPCAPI:
+    // Replies to a ping method.
+    // --> {"jsonrpc": "2.0", "method": "ping", "params": [], "id": 42}
+    // <-- {"jsonrpc": "2.0", "result": "pong", "id": 42}
+    async fn pong(&self, id: Value, _params: Value) -> JsonResult {
+        jsonrpc::response(json!("pong"), id).into()
+    }
+
+    // RPCAPI:
+    // Retrieves P2P network information.
+    // --> {"jsonrpc": "2.0", "method": "get_info", "params": [], "id": 42}
+    // <-- {"jsonrpc": "2.0", result": {"nodeID": [], "nodeinfo": [], "id": 42}
+    async fn get_info(&self, id: Value, _params: Value) -> JsonResult {
+        let resp = self.p2p.get_info().await;
+        jsonrpc::response(resp, id).into()
+    }
+}