mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-09 14:48:08 -05:00
swapd: Add project skeleton
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -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
19
Cargo.lock
generated
@@ -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"
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
9
Makefile
9
Makefile
@@ -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
34
bin/swapd/Cargo.toml
Normal 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
41
bin/swapd/Makefile
Normal 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
BIN
bin/swapd/darkfi-swapd
Executable file
Binary file not shown.
127
bin/swapd/src/main.rs
Normal file
127
bin/swapd/src/main.rs
Normal 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
67
bin/swapd/src/rpc.rs
Normal 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
14
bin/swapd/swapd.toml
Normal 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"
|
||||||
Reference in New Issue
Block a user