swapd: Add project skeleton

This commit is contained in:
parazyd
2023-12-07 23:40:34 +01:00
parent b2c4000477
commit 5a526fe10e
10 changed files with 315 additions and 0 deletions

3
.gitignore vendored
View File

@@ -28,6 +28,9 @@
/bin/lilith/lilith /bin/lilith/lilith
/lilith /lilith
/bin/swapd/swapd
/swapd
/bin/tau/taud/taud /bin/tau/taud/taud
/taud /taud

19
Cargo.lock generated
View File

@@ -6335,6 +6335,25 @@ dependencies = [
"sval_fmt", "sval_fmt",
] ]
[[package]]
name = "swapd"
version = "0.4.1"
dependencies = [
"darkfi",
"darkfi-serial",
"easy-parallel",
"log",
"serde",
"signal-hook",
"signal-hook-async-std",
"simplelog",
"sled",
"smol",
"structopt",
"structopt-toml",
"url",
]
[[package]] [[package]]
name = "syn" name = "syn"
version = "1.0.109" version = "1.0.109"

View File

@@ -30,6 +30,7 @@ members = [
"bin/genev/genevd", "bin/genev/genevd",
"bin/genev/genev-cli", "bin/genev/genev-cli",
"bin/darkirc", "bin/darkirc",
"bin/swapd",
"bin/tau/taud", "bin/tau/taud",
#"bin/tau/tau-cli", #"bin/tau/tau-cli",
"bin/vanityaddr", "bin/vanityaddr",

View File

@@ -24,6 +24,7 @@ BINS = \
genev \ genev \
genevd \ genevd \
lilith \ lilith \
swapd \
taud \ taud \
vanityaddr vanityaddr
@@ -87,6 +88,13 @@ lilith:
RUST_TARGET="$(RUST_TARGET)" \ RUST_TARGET="$(RUST_TARGET)" \
RUSTFLAGS="$(RUSTFLAGS)" RUSTFLAGS="$(RUSTFLAGS)"
swapd:
$(MAKE) -C bin/$@ \
PREFIX="$(PREFIX)" \
CARGO="$(CARGO)" \
RUST_TARGET="$(RUST_TARGET)" \
RUSTFLAGS="$(RUSTFLAGS)"
taud: taud:
$(MAKE) -C bin/tau/$@ \ $(MAKE) -C bin/tau/$@ \
PREFIX="$(PREFIX)" \ PREFIX="$(PREFIX)" \
@@ -142,6 +150,7 @@ clean:
$(MAKE) -C bin/genev/genev-cli clean $(MAKE) -C bin/genev/genev-cli clean
$(MAKE) -C bin/genev/genevd clean $(MAKE) -C bin/genev/genevd clean
$(MAKE) -C bin/lilith clean $(MAKE) -C bin/lilith clean
$(MAKE) -C bin/swapd clean
$(MAKE) -C bin/tau/taud clean $(MAKE) -C bin/tau/taud clean
$(MAKE) -C bin/vanityaddr clean $(MAKE) -C bin/vanityaddr clean
RUSTFLAGS="$(RUSTFLAGS)" $(CARGO) clean --target=$(RUST_TARGET) --release RUSTFLAGS="$(RUSTFLAGS)" $(CARGO) clean --target=$(RUST_TARGET) --release

34
bin/swapd/Cargo.toml Normal file
View File

@@ -0,0 +1,34 @@
[package]
name = "swapd"
version = "0.4.1"
homepage = "https://dark.fi"
description = "Atomic Swap Daemon"
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", "net", "rpc", "sled"]}
darkfi-serial = {path = "../../src/serial", features = ["async"]}
# Misc
log = "0.4.20"
# Encoding
url = "2.5.0"
# Database
sled = "0.34.7"
# Daemon
easy-parallel = "3.3.1"
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.193", features = ["derive"]}
structopt = "0.3.26"
structopt-toml = "0.5.1"

41
bin/swapd/Makefile Normal file
View File

@@ -0,0 +1,41 @@
.POSIX:
# Install prefix
PREFIX = $(HOME)/.cargo
# Cargo binary
CARGO = cargo +nightly
# Compile target
RUST_TARGET = $(shell rustc -Vv | grep '^host: ' | cut -d' ' -f2)
# Uncomment when doing musl static builds
#RUSTFLAGS = -C target-feature=+crt-static -C link-self-contained=yes
SRC = \
Cargo.toml \
../../Cargo.toml \
$(shell find src -type f -name '*.rs') \
$(shell find ../../src -type f -name '*.rs') \
BIN = $(shell grep '^name = ' Cargo.toml | cut -d' ' -f3 | tr -d '"')
all: $(BIN)
$(BIN): $(SRC)
RUSTFLAGS="$(RUSTFLAGS)" $(CARGO) build --target=$(RUST_TARGET) --release --package $@
cp -f ../../target/$(RUST_TARGET)/release/$@ $@
cp -f ../../target/$(RUST_TARGET)/release/$@ ../../$@
clean:
RUSTFLAGS="$(RUSTFLAGS)" $(CARGO) clean --target=$(RUST_TARGET) --release --package $(BIN)
rm -f $(BIN) ../../$(BIN)
install: all
mkdir -p $(DESTDIR)$(PREFIX)/bin
cp -f $(BIN) $(DESTDIR)$(PREFIX)/bin
chmod 755 $(DESTDIR)$(PREFIX)/bin/$(BIN)
uninstall:
rm -f $(DESTDIR)$(PREFIX)/bin/$(BIN)
.PHONY: all clean install uninstall

BIN
bin/swapd/darkfi-swapd Executable file

Binary file not shown.

127
bin/swapd/src/main.rs Normal file
View File

@@ -0,0 +1,127 @@
/* This file is part of DarkFi (https://dark.fi)
*
* Copyright (C) 2020-2023 Dyne.org foundation
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
use std::{collections::HashSet, sync::Arc};
use darkfi::{
async_daemonize, cli_desc,
rpc::server::{listen_and_serve, RequestHandler},
system::{StoppableTask, StoppableTaskPtr},
util::path::expand_path,
Error, Result,
};
use log::{error, info};
use serde::Deserialize;
use smol::{fs, lock::Mutex, stream::StreamExt, Executor};
use structopt::StructOpt;
use structopt_toml::StructOptToml;
use url::Url;
const CONFIG_FILE: &str = "swapd.toml";
const CONFIG_FILE_CONTENTS: &str = include_str!("../swapd.toml");
/// JSON-RPC server methods
mod rpc;
#[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)]
/// Set log file output
log: Option<String>,
#[structopt(flatten)]
swapd: SwapdArgs,
}
#[derive(Clone, Debug, Deserialize, StructOpt, StructOptToml)]
#[structopt()]
struct SwapdArgs {
#[structopt(long, default_value = "tcp://127.0.0.1:52821")]
/// darkfi-swapd JSON-RPC listen URL
swapd_rpc: Url,
#[structopt(long, default_value = "~/.local/darkfi/swapd")]
/// Path to swapd's filesystem database
swapd_db: String,
}
/// Swapd daemon state
struct Swapd {
/// Main reference to the swapd filesystem databaase
_sled_db: sled::Db,
/// JSON-RPC connection tracker
rpc_connections: Mutex<HashSet<StoppableTaskPtr>>,
}
impl Swapd {
/// Instantiate `Swapd` state
async fn new(_swapd_args: &SwapdArgs, sled_db: sled::Db) -> Result<Self> {
Ok(Self { _sled_db: sled_db, rpc_connections: Mutex::new(HashSet::new()) })
}
}
async_daemonize!(realmain);
async fn realmain(args: Args, ex: Arc<Executor<'static>>) -> Result<()> {
info!("Starting DarkFi Atomic Swap Daemon...");
// Create datastore path if not there already.
let datastore = expand_path(&args.swapd.swapd_db)?;
fs::create_dir_all(&datastore).await?;
let sled_db = sled::open(datastore)?;
info!("Initializing daemon state");
let swapd = Arc::new(Swapd::new(&args.swapd, sled_db.clone()).await?);
info!("Starting JSON-RPC server on {}", args.swapd.swapd_rpc);
let swapd_ = Arc::clone(&swapd);
let rpc_task = StoppableTask::new();
rpc_task.clone().start(
listen_and_serve(args.swapd.swapd_rpc, swapd.clone(), None, ex.clone()),
|res| async move {
match res {
Ok(()) | Err(Error::RpcServerStopped) => swapd_.stop_connections().await,
Err(e) => error!("Failed stopping JSON-RPC server: {}", e),
}
},
Error::RpcServerStopped,
ex.clone(),
);
info!("Ready to operate");
// 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");
info!("Flushing sled database");
sled_db.flush_async().await?;
info!("Shut down successfully");
Ok(())
}

67
bin/swapd/src/rpc.rs Normal file
View File

@@ -0,0 +1,67 @@
/* This file is part of DarkFi (https://dark.fi)
*
* Copyright (C) 2020-2023 Dyne.org foundation
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
use std::collections::HashSet;
use darkfi::{
rpc::{
jsonrpc::{ErrorCode, JsonError, JsonRequest, JsonResponse, JsonResult},
server::RequestHandler,
util::JsonValue,
},
system::StoppableTaskPtr,
};
use darkfi_serial::async_trait;
use smol::lock::MutexGuard;
use super::Swapd;
#[async_trait]
impl RequestHandler for Swapd {
async fn handle_request(&self, req: JsonRequest) -> JsonResult {
match req.method.as_str() {
"ping" => self.pong(req.id, req.params).await,
"hello" => self.hello(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
}
}
impl Swapd {
// RPCAPI:
// Use this kind of comment in order to have the RPC spec automatically
// generated in the mdbook. You should be able to write any kind of
// markdown in here.
//
// At the bottom, you should have the reqrep in JSON:
//
// --> {"jsonrpc": "2.0", "method": "hello", "params": ["hello"], "id": 42}
// --> {"jsonrpc": "2.0", "result": "hello", "id": 42}
async fn hello(&self, id: u16, params: JsonValue) -> JsonResult {
let params = params.get::<Vec<JsonValue>>().unwrap();
if params.len() != 1 || !params[0].is_string() {
return JsonError::new(ErrorCode::InvalidParams, None, id).into()
}
return JsonResponse::new(params[0].clone(), id).into()
}
}

14
bin/swapd/swapd.toml Normal file
View File

@@ -0,0 +1,14 @@
## darkfi-swapd configuration file
##
## Please make sure you go through all the settings so you can configure
## your daemon properly.
##
## The default values are left commented. They can be overridden either by
## uncommenting, or by using the command-line.
#[swapd]
# darkfi-swapd JSON-RPC listen URL.
#swapd_rpc = "tcp://127.0.0.1:52821"
# Path to swapd's filesystem database
#swapd_db = "~/.local/darkfi/swapd"