merge crypsinous into master in crypsinousintomaster branch

This commit is contained in:
mohab metwally
2022-09-15 18:38:11 +02:00
382 changed files with 26304 additions and 7598 deletions

29
example/dchat/Cargo.toml Normal file
View File

@@ -0,0 +1,29 @@
[package]
name = "dchat"
version = "0.1.0"
edition = "2021"
description = "Demo chat to document darkfi net code"
[dependencies]
darkfi = {path = "../../", features = ["net", "rpc"]}
# Async
async-std = "1.12.0"
async-trait = "0.1.57"
async-executor = "1.4.1"
async-channel = "1.7.1"
easy-parallel = "3.2.0"
smol = "1.2.5"
num_cpus = "1.13.1"
# Misc
log = "0.4.17"
simplelog = "0.12.0"
url = "2.2.2"
# Encoding and parsing
serde_json = "1.0.85"
serde = {version = "1.0.144", features = ["derive"]}
toml = "0.5.9"

45
example/dchat/README.md Normal file
View File

@@ -0,0 +1,45 @@
# Dchat
A demo chat program to document DarkFi net
code. Tutorial can be found in the [DarkFi
book](https://darkrenaissance.github.io/darkfi/learn/writing-a-p2p-app.html).
## Usage
Spin up a seed node:
```shell
cd example/dchat-seed
cargo run
```
Run dchat as an inbound node:
```shell
cargo run a
```
Run dchat as an outbound node:
```shell
cargo run b
```
## Logging
Dchat creates a logging file for the inbound node at /tmp/alice.log.
Logging for the outbound node is found at /tmp/bob.log.
Tail them like so:
```shell
tail -f /tmp/alice.log
```
Or use multitail for colored output:
```shell
multitail -c /tmp/alice.log
```

View File

@@ -0,0 +1,28 @@
# chat toml
[net]
## P2P accept addresses
#inbound=["tls://127.0.0.1:11002"]
## Connection slots
outbound_connections=5
## P2P external addresses
#external_addr=["tls://127.0.0.1:11002"]
## Peers to connect to
#peers=["tls://127.0.0.1:11003"]
## Seed nodes to connect to
#seeds=["tls://irc0.dark.fi:11001", "tls://irc1.dark.fi:11001"]
seeds=["tcp://127.0.0.1:55555"]
## Only used for debugging. Compromises privacy when set.
#node_id = "foo"
## these are the default configuration for the p2p network
#manual_attempt_limit=0
#seed_query_timeout_seconds=8
#connect_timeout_seconds=10
#channel_handshake_seconds=4
#channel_heartbeat_seconds=10

View File

@@ -0,0 +1,12 @@
use std::{error, fmt};
#[derive(Debug, Clone)]
pub struct ErrorMissingSpecifier;
impl fmt::Display for ErrorMissingSpecifier {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "missing node specifier. you must specify either a or b")
}
}
impl error::Error for ErrorMissingSpecifier {}

View File

@@ -0,0 +1,19 @@
use async_std::sync::{Arc, Mutex};
use darkfi::{
net,
util::serial::{SerialDecodable, SerialEncodable},
};
pub type DchatMsgsBuffer = Arc<Mutex<Vec<DchatMsg>>>;
impl net::Message for DchatMsg {
fn name() -> &'static str {
"DchatMsg"
}
}
#[derive(Debug, Clone, SerialEncodable, SerialDecodable)]
pub struct DchatMsg {
pub msg: String,
}

224
example/dchat/src/main.rs Normal file
View File

@@ -0,0 +1,224 @@
use async_executor::Executor;
use async_std::sync::{Arc, Mutex};
use easy_parallel::Parallel;
use std::{error, fs::File, io::stdin};
use log::debug;
use simplelog::WriteLogger;
use url::Url;
use darkfi::{net, net::Settings, rpc::server::listen_and_serve};
use crate::{
dchat_error::ErrorMissingSpecifier,
dchatmsg::{DchatMsg, DchatMsgsBuffer},
protocol_dchat::ProtocolDchat,
rpc::JsonRpcInterface,
};
pub mod dchat_error;
pub mod dchatmsg;
pub mod protocol_dchat;
pub mod rpc;
pub type Error = Box<dyn error::Error>;
pub type Result<T> = std::result::Result<T, Error>;
struct Dchat {
p2p: net::P2pPtr,
recv_msgs: DchatMsgsBuffer,
}
impl Dchat {
fn new(p2p: net::P2pPtr, recv_msgs: DchatMsgsBuffer) -> Self {
Self { p2p, recv_msgs }
}
async fn menu(&self) -> Result<()> {
let mut buffer = String::new();
let stdin = stdin();
loop {
println!(
"Welcome to dchat.
s: send message
i: inbox
q: quit "
);
stdin.read_line(&mut buffer)?;
// Remove trailing \n
buffer.pop();
match buffer.as_str() {
"q" => return Ok(()),
"s" => {
// Remove trailing s
buffer.pop();
stdin.read_line(&mut buffer)?;
match self.send(buffer.clone()).await {
Ok(_) => {
println!("you sent: {}", buffer);
}
Err(e) => {
println!("send failed for reason: {}", e);
}
}
buffer.clear();
}
"i" => {
let msgs = self.recv_msgs.lock().await;
if msgs.is_empty() {
println!("inbox is empty")
} else {
println!("received:");
for i in msgs.iter() {
if !i.msg.is_empty() {
println!("{}", i.msg);
}
}
}
buffer.clear();
}
_ => {}
}
}
}
async fn register_protocol(&self, msgs: DchatMsgsBuffer) -> Result<()> {
debug!(target: "dchat", "Dchat::register_protocol() [START]");
let registry = self.p2p.protocol_registry();
registry
.register(!net::SESSION_SEED, move |channel, _p2p| {
let msgs2 = msgs.clone();
async move { ProtocolDchat::init(channel, msgs2).await }
})
.await;
debug!(target: "dchat", "Dchat::register_protocol() [STOP]");
Ok(())
}
async fn start(&mut self, ex: Arc<Executor<'_>>) -> Result<()> {
debug!(target: "dchat", "Dchat::start() [START]");
let ex2 = ex.clone();
self.register_protocol(self.recv_msgs.clone()).await?;
self.p2p.clone().start(ex.clone()).await?;
ex2.spawn(self.p2p.clone().run(ex.clone())).detach();
self.menu().await?;
self.p2p.stop().await;
debug!(target: "dchat", "Dchat::start() [STOP]");
Ok(())
}
async fn send(&self, msg: String) -> Result<()> {
let dchatmsg = DchatMsg { msg };
self.p2p.broadcast(dchatmsg).await?;
Ok(())
}
}
#[derive(Clone, Debug)]
struct AppSettings {
accept_addr: Url,
net: Settings,
}
impl AppSettings {
pub fn new(accept_addr: Url, net: Settings) -> Self {
Self { accept_addr, net }
}
}
fn alice() -> Result<AppSettings> {
let log_level = simplelog::LevelFilter::Debug;
let log_config = simplelog::Config::default();
let log_path = "/tmp/alice.log";
let file = File::create(log_path).unwrap();
WriteLogger::init(log_level, log_config, file)?;
let seed = Url::parse("tcp://127.0.0.1:50515").unwrap();
let inbound = Url::parse("tcp://127.0.0.1:51554").unwrap();
let ext_addr = Url::parse("tcp://127.0.0.1:51554").unwrap();
let net = Settings {
inbound: vec![inbound],
external_addr: vec![ext_addr],
seeds: vec![seed],
..Default::default()
};
let accept_addr = Url::parse("tcp://127.0.0.1:55054").unwrap();
let settings = AppSettings::new(accept_addr, net);
Ok(settings)
}
fn bob() -> Result<AppSettings> {
let log_level = simplelog::LevelFilter::Debug;
let log_config = simplelog::Config::default();
let log_path = "/tmp/bob.log";
let file = File::create(log_path).unwrap();
WriteLogger::init(log_level, log_config, file)?;
let seed = Url::parse("tcp://127.0.0.1:50515").unwrap();
let net = Settings {
inbound: vec![],
outbound_connections: 5,
seeds: vec![seed],
..Default::default()
};
let accept_addr = Url::parse("tcp://127.0.0.1:51054").unwrap();
let settings = AppSettings::new(accept_addr, net);
Ok(settings)
}
#[async_std::main]
async fn main() -> Result<()> {
let settings: Result<AppSettings> = match std::env::args().nth(1) {
Some(id) => match id.as_str() {
"a" => alice(),
"b" => bob(),
_ => Err(ErrorMissingSpecifier.into()),
},
None => Err(ErrorMissingSpecifier.into()),
};
let settings = settings?.clone();
let p2p = net::P2p::new(settings.net).await;
let nthreads = num_cpus::get();
let (signal, shutdown) = async_channel::unbounded::<()>();
let ex = Arc::new(Executor::new());
let ex2 = ex.clone();
let ex3 = ex2.clone();
let msgs: DchatMsgsBuffer = Arc::new(Mutex::new(vec![DchatMsg { msg: String::new() }]));
let mut dchat = Dchat::new(p2p.clone(), msgs);
let accept_addr = settings.accept_addr.clone();
let rpc = Arc::new(JsonRpcInterface { addr: accept_addr.clone(), p2p });
ex.spawn(async move { listen_and_serve(accept_addr.clone(), rpc).await }).detach();
let (_, result) = Parallel::new()
.each(0..nthreads, |_| smol::future::block_on(ex2.run(shutdown.recv())))
.finish(|| {
smol::future::block_on(async move {
dchat.start(ex3).await?;
drop(signal);
Ok(())
})
});
result
}

View File

@@ -0,0 +1,55 @@
use async_executor::Executor;
use async_std::sync::Arc;
use async_trait::async_trait;
use darkfi::{net, Result};
use log::debug;
use crate::dchatmsg::{DchatMsg, DchatMsgsBuffer};
pub struct ProtocolDchat {
jobsman: net::ProtocolJobsManagerPtr,
msg_sub: net::MessageSubscription<DchatMsg>,
msgs: DchatMsgsBuffer,
}
impl ProtocolDchat {
pub async fn init(channel: net::ChannelPtr, msgs: DchatMsgsBuffer) -> net::ProtocolBasePtr {
debug!(target: "dchat", "ProtocolDchat::init() [START]");
let message_subsytem = channel.get_message_subsystem();
message_subsytem.add_dispatch::<DchatMsg>().await;
let msg_sub =
channel.subscribe_msg::<DchatMsg>().await.expect("Missing DchatMsg dispatcher!");
Arc::new(Self {
jobsman: net::ProtocolJobsManager::new("ProtocolDchat", channel.clone()),
msg_sub,
msgs,
})
}
async fn handle_receive_msg(self: Arc<Self>) -> Result<()> {
debug!(target: "dchat", "ProtocolDchat::handle_receive_msg() [START]");
while let Ok(msg) = self.msg_sub.receive().await {
let msg = (*msg).to_owned();
self.msgs.lock().await.push(msg);
}
Ok(())
}
}
#[async_trait]
impl net::ProtocolBase for ProtocolDchat {
async fn start(self: Arc<Self>, executor: Arc<Executor<'_>>) -> Result<()> {
debug!(target: "dchat", "ProtocolDchat::ProtocolBase::start() [START]");
self.jobsman.clone().start(executor.clone());
self.jobsman.clone().spawn(self.clone().handle_receive_msg(), executor.clone()).await;
debug!(target: "dchat", "ProtocolDchat::ProtocolBase::start() [STOP]");
Ok(())
}
fn name(&self) -> &'static str {
"ProtocolDchat"
}
}

53
example/dchat/src/rpc.rs Normal file
View File

@@ -0,0 +1,53 @@
use async_trait::async_trait;
use log::debug;
use serde_json::{json, Value};
use url::Url;
use darkfi::{
net,
rpc::{
jsonrpc::{ErrorCode, JsonError, JsonRequest, JsonResponse, JsonResult},
server::RequestHandler,
},
};
pub struct JsonRpcInterface {
pub addr: Url,
pub p2p: net::P2pPtr,
}
#[async_trait]
impl RequestHandler for JsonRpcInterface {
async fn handle_request(&self, req: JsonRequest) -> JsonResult {
if req.params.as_array().is_none() {
return JsonError::new(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 => JsonError::new(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 {
JsonResponse::new(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;
JsonResponse::new(resp, id).into()
}
}

View File

@@ -32,6 +32,7 @@ use darkfi::{
zk::circuit::lead_contract::LeadContract,
};
fn main() {
let k: u32 = 13;
//

View File

@@ -48,9 +48,9 @@ impl ProgramOptions {
let programcli = DarkCli::parse();
let accept_addr = if let Some(accept_addr) = programcli.accept {
Some(accept_addr.parse()?)
vec![accept_addr.parse()?]
} else {
None
vec![]
};
let mut seed_addrs: Vec<url::Url> = vec![];

View File

@@ -12,10 +12,10 @@ edition = "2021"
darkfi = {path = "../../", features = ["net", "rpc"]}
# Async
smol = "1.2.5"
futures = "0.3.21"
async-std = "1.11.0"
async-trait = "0.1.53"
async-channel = "1.6.1"
futures = "0.3.24"
async-std = "1.12.0"
async-trait = "0.1.57"
async-channel = "1.7.1"
async-executor = "1.4.1"
easy-parallel = "3.2.0"
@@ -23,11 +23,11 @@ easy-parallel = "3.2.0"
rand = "0.8.5"
# Misc
clap = {version = "3.1.18", features = ["derive"]}
clap = {version = "3.2.20", features = ["derive"]}
log = "0.4.17"
simplelog = "0.12.0"
fxhash = "0.2.1"
url = "2.2.2"
# Encoding and parsing
serde_json = "1.0.81"
serde_json = "1.0.85"

2
example/serial_derive/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
target/*
Cargo.lock

View File

@@ -0,0 +1,11 @@
[package]
name = "serial_derive"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
darkfi = {path = "../../", features = ["util"]}
[workspace]

View File

@@ -0,0 +1,14 @@
use darkfi::util::serial::{
serialize, Decodable, Encodable, SerialDecodable, SerialEncodable, VarInt,
};
#[derive(SerialEncodable)]
enum Test {
Type1(u32),
Type2,
Type3,
}
fn main() {
println!("Hello, world!");
}

View File

@@ -5,7 +5,7 @@ use rand::rngs::OsRng;
use darkfi::{
crypto::{
constants::MERKLE_DEPTH_ORCHARD,
constants::MERKLE_DEPTH,
keypair::{Keypair, PublicKey, SecretKey},
merkle_node::MerkleNode,
note::{EncryptedNote, Note},
@@ -22,8 +22,6 @@ use darkfi::{
Result,
};
const MERKLE_DEPTH: u8 = MERKLE_DEPTH_ORCHARD as u8;
/// The state machine, held in memory.
struct MemoryState {
/// The entire Merkle tree state
@@ -172,7 +170,7 @@ fn main() -> Result<()> {
// Now spend
let owncoin = &state.own_coins[0];
let note = owncoin.note;
let note = &owncoin.note;
let leaf_position = owncoin.leaf_position;
let root = state.tree.root(0).unwrap();
let merkle_path = state.tree.authentication_path(leaf_position, &root).unwrap();
@@ -183,7 +181,7 @@ fn main() -> Result<()> {
leaf_position,
merkle_path,
secret: keypair.secret,
note,
note: note.clone(),
}],
outputs: vec![TransactionBuilderOutputInfo {
value: 110,