Kaynağa Gözat

mmproxy: Skeleton impl

parazyd 2 yıl önce
ebeveyn
işleme
fbe42f3f66

+ 1 - 0
.gitignore

@@ -20,6 +20,7 @@
 /dhtd
 /darkfid
 /darkfid2
+/darkfi-mmproxy
 /darkotc
 /dnetview
 /drk

+ 18 - 0
Cargo.lock

@@ -1596,6 +1596,24 @@ dependencies = [
  "syn 2.0.29",
 ]
 
+[[package]]
+name = "darkfi-mmproxy"
+version = "0.4.1"
+dependencies = [
+ "darkfi",
+ "darkfi-serial",
+ "easy-parallel",
+ "log",
+ "serde",
+ "signal-hook",
+ "signal-hook-async-std",
+ "simplelog",
+ "smol",
+ "structopt",
+ "structopt-toml",
+ "url",
+]
+
 [[package]]
 name = "darkfi-money-contract"
 version = "0.4.1"

+ 1 - 0
Cargo.toml

@@ -22,6 +22,7 @@ members = [
     "bin/zkas",
     "bin/darkfid",
     "bin/darkfid2",
+    "bin/darkfi-mmproxy",
     #"bin/drk",
     "bin/faucetd",
     #"bin/fud/fu",

+ 31 - 0
bin/darkfi-mmproxy/Cargo.toml

@@ -0,0 +1,31 @@
+[package]
+name = "darkfi-mmproxy"
+version = "0.4.1"
+homepage = "https://dark.fi"
+description = "Proxy server for DarkFi/Monero merge mining"
+authors = ["Dyne.org foundation <foundation@dyne.org>"]
+repository = "https://github.com/darkrenaissance/darkfi"
+license = "AGPL-3.0-only"
+edition = "2021"
+
+[dependencies]
+darkfi = {path = "../../", features = ["async-daemonize", "async-serial", "system", "util", "rpc"]}
+darkfi-serial = {path = "../../src/serial", features = ["async"]}
+
+# Misc
+log = "0.4.20"
+
+# Encoding
+url = "2.4.1"
+
+# Daemon
+easy-parallel = "3.3.0"
+signal-hook-async-std = "0.2.2"
+signal-hook = "0.3.17"
+simplelog = "0.12.1"
+smol = "1.3.0"
+
+# Argument parsing
+serde = {version = "1.0.188", features = ["derive"]}
+structopt = "0.3.26"
+structopt-toml = "0.5.1"

+ 34 - 0
bin/darkfi-mmproxy/Makefile

@@ -0,0 +1,34 @@
+.POSIX:
+
+# Install prefix
+PREFIX = $(HOME)/.cargo
+
+# Cargo binary
+CARGO = cargo +nightly
+
+SRC = \
+	Cargo.toml \
+	../../Cargo.toml \
+	$(shell find src -type f) \
+	$(shell find ../../src -type f) \
+
+BIN = ../../darkfi-mmproxy
+
+all: $(BIN)
+
+$(BIN): $(SRC)
+	$(CARGO) build $(TARGET_PRFX)$(RUST_TARGET) --release --package darkfi-mmproxy
+	cp -f ../../target/$(RUST_TARGET)/release/darkfi-mmproxy $@
+
+clean:
+	rm -f $(BIN)
+
+install: all
+	mkdir -p $(DESTDIR)$(PREFIX)/bin
+	cp -f $(BIN) $(DESTDIR)$(PREFIX)/bin
+	chmod 755 $(DESTDIR)$(PREFIX)/bin/darkfi-mmproxy
+
+uninstall:
+	rm -f $(DESTDIR)$(PREFIX)/bin/darkfi-mmproxy
+
+.PHONY: all clean install uninstall

+ 0 - 0
bin/darkfi-mmproxy/darkfi_mmproxy.toml


+ 101 - 0
bin/darkfi-mmproxy/src/main.rs

@@ -0,0 +1,101 @@
+use std::{collections::HashSet, sync::Arc};
+
+use darkfi::{
+    async_daemonize, cli_desc,
+    rpc::{
+        jsonrpc::{ErrorCode, JsonError, JsonRequest, JsonResult},
+        server::{listen_and_serve, RequestHandler},
+    },
+    system::{StoppableTask, StoppableTaskPtr},
+    Error, Result,
+};
+use darkfi_serial::async_trait;
+use log::{debug, error, info};
+use serde::Deserialize;
+use smol::{
+    lock::{Mutex, MutexGuard},
+    stream::StreamExt,
+    Executor,
+};
+use structopt::StructOpt;
+use structopt_toml::StructOptToml;
+use url::Url;
+
+mod stratum;
+
+const CONFIG_FILE: &str = "darkfi_mmproxy.toml";
+const CONFIG_FILE_CONTENTS: &str = include_str!("../darkfi_mmproxy.toml");
+
+#[derive(Clone, Debug, Deserialize, StructOpt, StructOptToml)]
+#[serde(default)]
+#[structopt(name = "darkfi-mmproxy", about = cli_desc!())]
+struct Args {
+    #[structopt(short, parse(from_occurrences))]
+    /// Increase verbosity (-vvv supported)
+    verbose: u8,
+
+    #[structopt(short, long)]
+    /// Configuration file to use
+    config: Option<String>,
+
+    #[structopt(long, default_value = "tcp://127.0.0.1:3333")]
+    /// JSON-RPC server listen URL
+    rpc_listen: Url,
+
+    #[structopt(long)]
+    /// Set log file output
+    log: Option<String>,
+}
+
+struct MiningProxy {
+    /// JSON-RPC connection tracker
+    rpc_connections: Mutex<HashSet<StoppableTaskPtr>>,
+}
+
+impl MiningProxy {
+    fn new() -> Self {
+        Self { rpc_connections: Mutex::new(HashSet::new()) }
+    }
+}
+
+#[async_trait]
+impl RequestHandler for MiningProxy {
+    async fn handle_request(&self, req: JsonRequest) -> JsonResult {
+        error!(target: "mmproxy::rpc", "--> {}", req.stringify().unwrap());
+
+        match req.method.as_str() {
+            "ping" => self.pong(req.id, req.params).await,
+            _ => JsonError::new(ErrorCode::MethodNotFound, None, req.id).into(),
+        }
+    }
+
+    async fn connections_mut(&self) -> MutexGuard<'_, HashSet<StoppableTaskPtr>> {
+        self.rpc_connections.lock().await
+    }
+}
+
+async_daemonize!(realmain);
+async fn realmain(args: Args, ex: Arc<Executor<'static>>) -> Result<()> {
+    info!("Starting JSON-RPC server");
+    let mmproxy = Arc::new(MiningProxy::new());
+    let mmproxy_ = Arc::clone(&mmproxy);
+    let rpc_task = StoppableTask::new();
+    rpc_task.clone().start(
+        listen_and_serve(args.rpc_listen, mmproxy.clone(), None, ex.clone()),
+        |res| async move {
+            match res {
+                Ok(()) | Err(Error::RpcServerStopped) => mmproxy_.stop_connections().await,
+                Err(e) => error!("Failed stopping JSON-RPC server: {}", e),
+            }
+        },
+        Error::RpcServerStopped,
+        ex.clone(),
+    );
+
+    // Signal handling for graceful termination.
+    let (signals_handler, signals_task) = SignalHandler::new(ex)?;
+    signals_handler.wait_termination(signals_task).await?;
+    info!("Caught termination signal, cleaning up and exiting...");
+
+    Ok(())
+}

+ 3 - 0
bin/darkfi-mmproxy/src/stratum.rs

@@ -0,0 +1,3 @@
+use super::MiningProxy;
+
+impl MiningProxy {}