mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-09 14:48:08 -05:00
rpc: WIP network transports, and darkfid skeleton for further integration.
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -9,6 +9,7 @@
|
||||
/dao-cli
|
||||
/daod
|
||||
/darkfid
|
||||
/darkfid2
|
||||
/dnetview
|
||||
/drk
|
||||
/gatewayd
|
||||
|
||||
156
Cargo.lock
generated
156
Cargo.lock
generated
@@ -773,6 +773,12 @@ dependencies = [
|
||||
"syn 1.0.91",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bytecount"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72feb31ffc86498dacdbd0fcebb56138e7177a8cc5cea4516031d15ae85a742e"
|
||||
|
||||
[[package]]
|
||||
name = "bytemuck"
|
||||
version = "1.9.1"
|
||||
@@ -832,6 +838,15 @@ version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1db59621ec70f09c5e9b597b220c7a2b43611f4710dc03ceb8748637775692c"
|
||||
|
||||
[[package]]
|
||||
name = "camino"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f3132262930b0522068049f5870a856ab8affc80c70d08b6ecb785771a6fc23"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "caps"
|
||||
version = "0.5.3"
|
||||
@@ -843,6 +858,28 @@ dependencies = [
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cargo-platform"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cbdb825da8a5df079a43676dbe042702f1707b1109f713a01420fbb4cc71fa27"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cargo_metadata"
|
||||
version = "0.14.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4acbb09d9ee8e23699b9634375c72795d095bf268439da88562cf9b501f181fa"
|
||||
dependencies = [
|
||||
"camino",
|
||||
"cargo-platform",
|
||||
"semver 1.0.7",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cashierd"
|
||||
version = "0.3.0"
|
||||
@@ -1669,6 +1706,27 @@ dependencies = [
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darkfid2"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"async-channel",
|
||||
"async-executor",
|
||||
"async-std",
|
||||
"async-trait",
|
||||
"darkfi",
|
||||
"easy-parallel",
|
||||
"futures-lite",
|
||||
"log",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"simplelog",
|
||||
"structopt",
|
||||
"structopt-toml",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling"
|
||||
version = "0.10.2"
|
||||
@@ -2189,6 +2247,15 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "error-chain"
|
||||
version = "0.12.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2d2f06b9cac1506ece98fe3231e3cc9c4410ec3d5b1f24ae1c8946f0742cdefc"
|
||||
dependencies = [
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "event-listener"
|
||||
version = "2.5.2"
|
||||
@@ -4100,6 +4167,17 @@ dependencies = [
|
||||
"syn 1.0.91",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pulldown-cmark"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34f197a544b0c9ab3ae46c359a7ec9cbbb5c7bf97054266fecb7ead794a181d6"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"memchr",
|
||||
"unicase",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "qstring"
|
||||
version = "0.7.2"
|
||||
@@ -4884,6 +4962,9 @@ name = "semver"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d65bd28f48be7196d222d95b9243287f48d27aca604e08497513019ff0502cc4"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver-parser"
|
||||
@@ -5111,6 +5192,21 @@ dependencies = [
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "skeptic"
|
||||
version = "0.13.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "16d23b015676c90a0f01c197bfdc786c20342c73a0afdda9025adb0bc42940a8"
|
||||
dependencies = [
|
||||
"bytecount",
|
||||
"cargo_metadata",
|
||||
"error-chain",
|
||||
"glob",
|
||||
"pulldown-cmark",
|
||||
"tempfile",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.6"
|
||||
@@ -6045,6 +6141,57 @@ version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||
|
||||
[[package]]
|
||||
name = "structopt"
|
||||
version = "0.3.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10"
|
||||
dependencies = [
|
||||
"clap 2.34.0",
|
||||
"lazy_static",
|
||||
"structopt-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "structopt-derive"
|
||||
version = "0.4.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0"
|
||||
dependencies = [
|
||||
"heck 0.3.3",
|
||||
"proc-macro-error",
|
||||
"proc-macro2 1.0.37",
|
||||
"quote 1.0.17",
|
||||
"syn 1.0.91",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "structopt-toml"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c27d68c57e6cc3fb03041c49534e50a6ccef677c511effc1c5bf12a4bc865a62"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap 2.34.0",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"skeptic",
|
||||
"structopt",
|
||||
"structopt-toml-derive",
|
||||
"toml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "structopt-toml-derive"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "316302a563af68baf93e5e77b8355a8bfe168c67c4424623365ca5bf521d013e"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.37",
|
||||
"quote 1.0.17",
|
||||
"syn 1.0.91",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
version = "2.4.1"
|
||||
@@ -6537,6 +6684,15 @@ dependencies = [
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicase"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
|
||||
dependencies = [
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.7"
|
||||
|
||||
@@ -16,6 +16,7 @@ members = [
|
||||
"bin/zkas",
|
||||
"bin/cashierd",
|
||||
"bin/darkfid",
|
||||
"bin/darkfid2",
|
||||
"bin/drk",
|
||||
"bin/gatewayd",
|
||||
"bin/ircd",
|
||||
|
||||
28
bin/darkfid2/Cargo.toml
Normal file
28
bin/darkfid2/Cargo.toml
Normal file
@@ -0,0 +1,28 @@
|
||||
[package]
|
||||
name = "darkfid2"
|
||||
version = "0.3.0"
|
||||
homepage = "https://dark.fi"
|
||||
description = "DarkFi node daemon"
|
||||
authors = ["darkfi <dev@dark.fi>"]
|
||||
repository = "https://github.com/darkrenaissance/darkfi"
|
||||
license = "AGPL-3.0-only"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
async-channel = "1.6.1"
|
||||
async-executor = "1.4.1"
|
||||
async-std = "1.11.0"
|
||||
async-trait = "0.1.53"
|
||||
darkfi = {path = "../../", features = ["crypto", "rpc", "net"]}
|
||||
easy-parallel = "3.2.0"
|
||||
futures-lite = "1.12.0"
|
||||
log = "0.4.16"
|
||||
serde_json = "1.0.79"
|
||||
simplelog = "0.12.0-alpha1"
|
||||
url = "2.2.2"
|
||||
|
||||
# Argument parsing
|
||||
serde = "1.0.136"
|
||||
serde_derive = "1.0.136"
|
||||
structopt = "0.3.26"
|
||||
structopt-toml = "0.5.0"
|
||||
14
bin/darkfid2/darkfid_config.toml
Normal file
14
bin/darkfid2/darkfid_config.toml
Normal file
@@ -0,0 +1,14 @@
|
||||
## darkfid configuration file
|
||||
##
|
||||
## Please make sure you go through all the settings so you can configure
|
||||
## your daemon properly.
|
||||
|
||||
# Path to the client database
|
||||
#database_path = "~/.config/darkfi/darkfid_client.db"
|
||||
|
||||
# Path to the wallet database
|
||||
#wallet_path = "~/.config/darkfi/darkfid_wallet.db"
|
||||
|
||||
# JSON-RPC listening url
|
||||
#rpc_listen = "tcp://127.0.0.1:5397"
|
||||
#rpc_listen = "tls://127.0.0.1:5397"
|
||||
111
bin/darkfid2/src/main.rs
Normal file
111
bin/darkfid2/src/main.rs
Normal file
@@ -0,0 +1,111 @@
|
||||
use async_executor::Executor;
|
||||
use async_std::sync::Arc;
|
||||
use async_trait::async_trait;
|
||||
use easy_parallel::Parallel;
|
||||
use futures_lite::future;
|
||||
use serde_derive::Deserialize;
|
||||
use serde_json::{json, Value};
|
||||
use simplelog::{ColorChoice, TermLogger, TerminalMode};
|
||||
use structopt::StructOpt;
|
||||
use structopt_toml::StructOptToml;
|
||||
use url::Url;
|
||||
|
||||
use darkfi::{
|
||||
cli_desc,
|
||||
net::transport::{TcpTransport, TlsTransport},
|
||||
rpc::{
|
||||
jsonrpc,
|
||||
jsonrpc::{ErrorCode, JsonRequest, JsonResult},
|
||||
rpcserver2::{listen_and_serve, RequestHandler},
|
||||
},
|
||||
util::{
|
||||
cli::{log_config, spawn_config},
|
||||
path::get_config_path,
|
||||
},
|
||||
Error, Result,
|
||||
};
|
||||
|
||||
const CONFIG_FILE: &str = "darkfid_config.toml";
|
||||
const CONFIG_FILE_CONTENTS: &str = include_str!("../darkfid_config.toml");
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, StructOpt, StructOptToml)]
|
||||
#[serde(default)]
|
||||
#[structopt(name = "darkfid", about = cli_desc!())]
|
||||
struct Args {
|
||||
#[structopt(short, long)]
|
||||
/// Configuration file to use
|
||||
config: Option<String>,
|
||||
|
||||
#[structopt(long, default_value = "~/.config/darkfi/darkfid_client.db")]
|
||||
/// Path to the client database
|
||||
database_path: String,
|
||||
|
||||
#[structopt(long, default_value = "~/.config/darkfi/darkfid_wallet.db")]
|
||||
/// Path to the wallet database
|
||||
wallet_path: String,
|
||||
|
||||
#[structopt(long, default_value = "tcp://127.0.0.1:5397")]
|
||||
/// JSON-RPC listen URL
|
||||
rpc_listen: String,
|
||||
|
||||
#[structopt(short, parse(from_occurrences))]
|
||||
/// Increase verbosity (-vvv supported)
|
||||
verbose: u8,
|
||||
}
|
||||
|
||||
pub struct Darkfid;
|
||||
|
||||
#[async_trait]
|
||||
impl RequestHandler for Darkfid {
|
||||
async fn handle_request(&self, req: JsonRequest) -> JsonResult {
|
||||
if req.params.as_array().is_none() {
|
||||
return jsonrpc::error(ErrorCode::InvalidParams, None, req.id).into()
|
||||
}
|
||||
|
||||
match req.method.as_str() {
|
||||
Some("ping") => return self.pong(req.id, req.params).await,
|
||||
Some(_) | None => return jsonrpc::error(ErrorCode::MethodNotFound, None, req.id).into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Darkfid {
|
||||
// RPCAPI:
|
||||
// Returns a `pong` to the `ping` request.
|
||||
// --> {"jsonrpc":"2.0","method":"ping","params":[],"id":1}
|
||||
// <-- {"jsonrpc":"2.0","result":"pong","id":1}
|
||||
async fn pong(&self, id: Value, _params: Value) -> JsonResult {
|
||||
jsonrpc::response(json!("pong"), id).into()
|
||||
}
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let args = Args::from_args_with_toml("").unwrap();
|
||||
let cfg_path = get_config_path(args.config.clone(), CONFIG_FILE)?;
|
||||
spawn_config(&cfg_path, CONFIG_FILE_CONTENTS.as_bytes())?;
|
||||
let args = Args::from_args_with_toml(&std::fs::read_to_string(cfg_path)?).unwrap();
|
||||
|
||||
let (lvl, conf) = log_config(args.verbose.into())?;
|
||||
TermLogger::init(lvl, conf, TerminalMode::Mixed, ColorChoice::Auto)?;
|
||||
|
||||
// Validate args
|
||||
|
||||
let ex = Executor::new();
|
||||
let (signal, shutdown) = async_channel::unbounded::<()>();
|
||||
|
||||
// // https://docs.rs/smol/latest/smol/struct.Executor.html#examples
|
||||
// let (_, result) = Parallel::new()
|
||||
// // Run four executor threads
|
||||
// .each(0..4, |_| future::block_on(ex.run(shutdown.recv())))
|
||||
// // Run the main future on the current thread.
|
||||
// .finish(|| {
|
||||
// future::block_on(async {
|
||||
// realmain(args).await?;
|
||||
// drop(signal);
|
||||
// Ok::<(), darkfi::Error>(())
|
||||
// })
|
||||
// });
|
||||
|
||||
// result
|
||||
Ok(())
|
||||
}
|
||||
@@ -12,7 +12,7 @@ use serde::{
|
||||
ser::Serializer,
|
||||
Deserialize, Serialize,
|
||||
};
|
||||
use subtle::{ConstantTimeEq, CtOption};
|
||||
use subtle::CtOption;
|
||||
|
||||
use crate::{
|
||||
crypto::{
|
||||
|
||||
@@ -222,6 +222,9 @@ pub enum Error {
|
||||
#[cfg(any(feature = "blockchain2", feature = "raft"))]
|
||||
#[error(transparent)]
|
||||
SledError(#[from] sled::Error),
|
||||
|
||||
#[error("Unsupported network transport")]
|
||||
UnsupportedTransport,
|
||||
}
|
||||
|
||||
#[cfg(feature = "node")]
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
pub mod jsonrpc;
|
||||
pub mod rpcserver;
|
||||
// TODO: Replace rpcserver with this
|
||||
pub mod rpcserver2;
|
||||
pub mod websockets;
|
||||
|
||||
102
src/rpc/rpcserver2.rs
Normal file
102
src/rpc/rpcserver2.rs
Normal file
@@ -0,0 +1,102 @@
|
||||
use async_std::{
|
||||
io::{ReadExt, WriteExt},
|
||||
stream::StreamExt,
|
||||
sync::Arc,
|
||||
};
|
||||
use async_trait::async_trait;
|
||||
use log::{debug, error, info};
|
||||
use url::Url;
|
||||
|
||||
use super::jsonrpc::{JsonRequest, JsonResult};
|
||||
use crate::{
|
||||
net::transport::{TcpTransport, TlsTransport, Transport},
|
||||
Error, Result,
|
||||
};
|
||||
|
||||
#[async_trait]
|
||||
pub trait RequestHandler: Sync + Send {
|
||||
async fn handle_request(&self, req: JsonRequest) -> JsonResult;
|
||||
}
|
||||
|
||||
pub async fn listen_and_serve(url: Url, rh: Arc<impl RequestHandler + 'static>) -> Result<()> {
|
||||
debug!(target: "JSON-RPC SERVER", "Trying to start listener on {}", url);
|
||||
|
||||
macro_rules! handle_stream {
|
||||
($stream:expr) => {
|
||||
let mut buf = vec![0; 8192];
|
||||
|
||||
loop {
|
||||
let n = match $stream.read(&mut buf).await {
|
||||
Ok(n) if n == 0 => {
|
||||
info!(target: "JSON-RPC SERVER", "Closed connection");
|
||||
break;
|
||||
}
|
||||
Ok(n) => n,
|
||||
Err(e) => {
|
||||
error!(target: "JSON-RPC SERVER", "Failed reading from socket: {}", e);
|
||||
info!(target: "JSON-RPC SERVER", "Closed connection");
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
let r: JsonRequest = match serde_json::from_slice(&buf[0..n]) {
|
||||
Ok(r) => {
|
||||
debug!(target: "JSON-RPC SERVER", "--> {}", String::from_utf8_lossy(&buf));
|
||||
r
|
||||
}
|
||||
Err(e) => {
|
||||
error!(target: "JSON-RPC SERVER", "Received invalid JSON: {:?}", e);
|
||||
info!(target: "JSON-RPC SERVER", "Closed connection");
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
let reply = rh.handle_request(r).await;
|
||||
let j = serde_json::to_string(&reply)?;
|
||||
debug!(target: "JSON-RPC SERVER", "<-- {}", j);
|
||||
|
||||
if let Err(e) = $stream.write_all(j.as_bytes()).await {
|
||||
error!(target: "JSON-RPC SERVER", "Failed writing to socket: {}", e);
|
||||
info!(target: "JSON-RPC SERVER", "Closed connection");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
match url.scheme() {
|
||||
"tcp" => {
|
||||
let transport = TcpTransport::new(None, 1024);
|
||||
let listener = transport.listen_on(url).unwrap().await.unwrap();
|
||||
let mut incoming = listener.incoming();
|
||||
while let Some(stream) = incoming.next().await {
|
||||
info!(target: "JSON-RPC SERVER", "Accepted TCP connection");
|
||||
let mut stream = stream.unwrap();
|
||||
handle_stream!(stream);
|
||||
}
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
"tls" => {
|
||||
let transport = TlsTransport::new(None, 1024);
|
||||
let (acceptor, listener) = transport.listen_on(url).unwrap().await.unwrap();
|
||||
let mut incoming = listener.incoming();
|
||||
while let Some(stream) = incoming.next().await {
|
||||
info!(target: "JSON-RPC SERVER", "Accepted TLS connection");
|
||||
let stream = stream.unwrap();
|
||||
let mut stream = acceptor.accept(stream).await.unwrap();
|
||||
handle_stream!(stream);
|
||||
}
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
"tor" => {
|
||||
todo!()
|
||||
}
|
||||
|
||||
x => {
|
||||
error!(target: "JSON-RPC SERVER", "Transport protocol '{}' isn't implemented", x);
|
||||
Err(Error::UnsupportedTransport)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -45,7 +45,7 @@ pub fn spawn_config(path: &Path, contents: &[u8]) -> Result<()> {
|
||||
|
||||
let mut file = fs::File::create(path)?;
|
||||
file.write_all(contents)?;
|
||||
println!("Config file created in `{:?}`. Please review it and try again.", path);
|
||||
println!("Config file created in '{:?}'. Please review it and try again.", path);
|
||||
std::process::exit(2);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user