Bladeren bron

Merge branch 'master' of github.com:darkrenaissance/darkfi

lunar-mining 4 jaren geleden
bovenliggende
commit
bd71f34894

+ 213 - 10
Cargo.lock

@@ -23,6 +23,16 @@ version = "1.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"
 
+[[package]]
+name = "aead"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877"
+dependencies = [
+ "generic-array",
+ "rand_core 0.6.3",
+]
+
 [[package]]
 name = "ahash"
 version = "0.7.6"
@@ -426,7 +436,7 @@ dependencies = [
  "cc",
  "cfg-if 1.0.0",
  "constant_time_eq",
- "digest",
+ "digest 0.10.3",
 ]
 
 [[package]]
@@ -627,6 +637,31 @@ version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 
+[[package]]
+name = "chacha20"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "01b72a433d0cf2aef113ba70f62634c56fddb0f244e6377185c56a7cadbd8f91"
+dependencies = [
+ "cfg-if 1.0.0",
+ "cipher",
+ "cpufeatures",
+ "zeroize",
+]
+
+[[package]]
+name = "chacha20poly1305"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b84ed6d1d5f7aa9bdde921a5090e0ca4d934d250ea3b402a5fab3a994e28a2a"
+dependencies = [
+ "aead",
+ "chacha20",
+ "cipher",
+ "poly1305",
+ "zeroize",
+]
+
 [[package]]
 name = "chrono"
 version = "0.4.19"
@@ -640,6 +675,15 @@ dependencies = [
  "winapi",
 ]
 
+[[package]]
+name = "cipher"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7"
+dependencies = [
+ "generic-array",
+]
+
 [[package]]
 name = "clap"
 version = "2.34.0"
@@ -996,6 +1040,21 @@ dependencies = [
  "crypto_api",
 ]
 
+[[package]]
+name = "crypto_box"
+version = "0.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "41d2bcbd5e4fc3ad3de2d0e75509f870a6fa9f488e0e2c9a8ce49721a52efc4e"
+dependencies = [
+ "chacha20",
+ "chacha20poly1305",
+ "rand_core 0.6.3",
+ "salsa20",
+ "x25519-dalek",
+ "xsalsa20poly1305",
+ "zeroize",
+]
+
 [[package]]
 name = "csv"
 version = "1.1.6"
@@ -1055,6 +1114,19 @@ dependencies = [
  "winapi",
 ]
 
+[[package]]
+name = "curve25519-dalek"
+version = "3.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "90f9d052967f590a76e62eb387bd0bbb1b000182c3cefe5364db6b7211651bc0"
+dependencies = [
+ "byteorder",
+ "digest 0.9.0",
+ "rand_core 0.5.1",
+ "subtle",
+ "zeroize",
+]
+
 [[package]]
 name = "dao-cli"
 version = "0.3.0"
@@ -1313,6 +1385,15 @@ dependencies = [
  "syn",
 ]
 
+[[package]]
+name = "digest"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
+dependencies = [
+ "generic-array",
+]
+
 [[package]]
 name = "digest"
 version = "0.10.3"
@@ -1494,6 +1575,24 @@ version = "0.3.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
 
+[[package]]
+name = "encoding_rs"
+version = "0.8.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b"
+dependencies = [
+ "cfg-if 1.0.0",
+]
+
+[[package]]
+name = "encoding_rs_io"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1cc3c5651fb62ab8aa3103998dade57efdd028544bd300516baa31840c252a83"
+dependencies = [
+ "encoding_rs",
+]
+
 [[package]]
 name = "enum-iterator"
 version = "0.7.0"
@@ -1623,7 +1722,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b2958d04124b9f27f175eaeb9a9f383d026098aa837eadd8ba22c11f13a05b9e"
 dependencies = [
  "bitvec 0.22.3",
- "rand_core",
+ "rand_core 0.6.3",
  "subtle",
 ]
 
@@ -1964,7 +2063,7 @@ checksum = "bc5ac374b108929de78460075f3dc439fa66df9d8fc77e8f12caa5165fcf0c89"
 dependencies = [
  "byteorder",
  "ff",
- "rand_core",
+ "rand_core 0.6.3",
  "subtle",
 ]
 
@@ -1999,7 +2098,7 @@ dependencies = [
  "group",
  "pasta_curves",
  "plotters",
- "rand_core",
+ "rand_core 0.6.3",
  "rayon",
  "tabbycat",
 ]
@@ -2155,7 +2254,7 @@ dependencies = [
 ]
 
 [[package]]
-name = "ircd2"
+name = "ircd"
 version = "0.3.0"
 dependencies = [
  "async-channel",
@@ -2558,6 +2657,12 @@ version = "1.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9"
 
+[[package]]
+name = "opaque-debug"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
+
 [[package]]
 name = "openssl"
 version = "0.10.38"
@@ -2801,6 +2906,17 @@ dependencies = [
  "winapi",
 ]
 
+[[package]]
+name = "poly1305"
+version = "0.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "048aeb476be11a4b6ca432ca569e375810de9294ae78f4774e78ea98a9246ede"
+dependencies = [
+ "cpufeatures",
+ "opaque-debug",
+ "universal-hash",
+]
+
 [[package]]
 name = "ppv-lite86"
 version = "0.2.16"
@@ -2965,7 +3081,7 @@ checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
 dependencies = [
  "libc",
  "rand_chacha",
- "rand_core",
+ "rand_core 0.6.3",
 ]
 
 [[package]]
@@ -2975,9 +3091,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
 dependencies = [
  "ppv-lite86",
- "rand_core",
+ "rand_core 0.6.3",
 ]
 
+[[package]]
+name = "rand_core"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
+
 [[package]]
 name = "rand_core"
 version = "0.6.3"
@@ -2993,7 +3115,7 @@ version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f"
 dependencies = [
- "rand_core",
+ "rand_core 0.6.3",
 ]
 
 [[package]]
@@ -3260,6 +3382,16 @@ version = "1.0.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f"
 
+[[package]]
+name = "salsa20"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0c0fbb5f676da676c260ba276a8f43a8dc67cf02d1438423aeb1c677a7212686"
+dependencies = [
+ "cipher",
+ "zeroize",
+]
+
 [[package]]
 name = "same-file"
 version = "1.0.6"
@@ -3420,7 +3552,7 @@ checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f"
 dependencies = [
  "cfg-if 1.0.0",
  "cpufeatures",
- "digest",
+ "digest 0.10.3",
 ]
 
 [[package]]
@@ -3431,7 +3563,7 @@ checksum = "55deaec60f81eefe3cce0dc50bda92d6d8e88f2a27df7c5033b42afeb1ed2676"
 dependencies = [
  "cfg-if 1.0.0",
  "cpufeatures",
- "digest",
+ "digest 0.10.3",
 ]
 
 [[package]]
@@ -3761,6 +3893,18 @@ dependencies = [
  "unicode-xid",
 ]
 
+[[package]]
+name = "synstructure"
+version = "0.12.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "unicode-xid",
+]
+
 [[package]]
 name = "tabbycat"
 version = "0.1.2"
@@ -3816,9 +3960,12 @@ dependencies = [
  "async-trait",
  "chrono",
  "clap 3.1.12",
+ "crypto_box",
  "ctrlc-async",
  "darkfi",
  "easy-parallel",
+ "encoding_rs",
+ "encoding_rs_io",
  "futures",
  "log",
  "num_cpus",
@@ -4120,6 +4267,16 @@ version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e"
 
+[[package]]
+name = "universal-hash"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05"
+dependencies = [
+ "generic-array",
+ "subtle",
+]
+
 [[package]]
 name = "untrusted"
 version = "0.7.1"
@@ -4657,6 +4814,31 @@ dependencies = [
  "tap",
 ]
 
+[[package]]
+name = "x25519-dalek"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2392b6b94a576b4e2bf3c5b2757d63f10ada8020a2e4d08ac849ebcf6ea8e077"
+dependencies = [
+ "curve25519-dalek",
+ "rand_core 0.5.1",
+ "zeroize",
+]
+
+[[package]]
+name = "xsalsa20poly1305"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e68bcb965d6c650091450b95cea12f07dcd299a01c15e2f9433b0813ea3c0886"
+dependencies = [
+ "aead",
+ "poly1305",
+ "rand_core 0.6.3",
+ "salsa20",
+ "subtle",
+ "zeroize",
+]
+
 [[package]]
 name = "yasna"
 version = "0.5.0"
@@ -4666,6 +4848,27 @@ dependencies = [
  "time 0.3.9",
 ]
 
+[[package]]
+name = "zeroize"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd"
+dependencies = [
+ "zeroize_derive",
+]
+
+[[package]]
+name = "zeroize_derive"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f8f187641dad4f680d25c4bfc4225b418165984179f26ca76ec4fb6441d3a17"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "synstructure",
+]
+
 [[package]]
 name = "zkas"
 version = "0.3.0"

+ 1 - 1
bin/darkfid2/src/main.rs

@@ -410,7 +410,7 @@ async fn realmain(args: Args, ex: Arc<Executor<'_>>) -> Result<()> {
         .detach();
 
         info!("Starting consensus protocol task");
-        ex.spawn(proposal_task(consensus_p2p.unwrap(), state)).detach();
+        ex.spawn(proposal_task(consensus_p2p.unwrap(), sync_p2p.unwrap(), state)).detach();
     } else {
         info!("Not starting consensus P2P network");
     }

+ 1 - 1
bin/ircd/Cargo.toml

@@ -1,5 +1,5 @@
 [package]
-name = "ircd2"
+name = "ircd"
 version = "0.3.0"
 homepage = "https://dark.fi"
 description = "P2P IRC daemon"

+ 80 - 0
bin/ircd/script/meeting_bot.py

@@ -0,0 +1,80 @@
+import asyncio
+
+
+async def start():
+    host = "127.0.0.1"
+    port = 11066
+    channel = "#dev"
+    nickname = "meeting"
+
+    print(f"Start a connection {host}:{port}")
+    reader, writer = await asyncio.open_connection(host, port)
+
+    print("Send NICK msg")
+    nick_msg = f"NICK {nickname} \r\n"
+    writer.write(nick_msg.encode('utf8'))
+
+    print(f"Send JOIN msg: {channel}")
+    join_msg = f"JOIN {channel} \r\n"
+    writer.write(join_msg.encode('utf8'))
+
+    topics = []
+
+    while True:
+        msg = await reader.read(350)
+        msg = msg.decode('utf8').strip()
+
+        if not msg:
+            print("Error: Receive empty msg")
+            break
+
+        command = msg.split(" ")[1]
+
+        if command == "PRIVMSG":
+
+            msg_title = msg.split(" ")[3][1:]
+
+            if not msg_title:
+                continue
+
+            reply = None
+
+            if msg_title == "#m_start":
+                reply = f"PRIVMSG {channel} :meeting started \r\n"
+                msg_title = "#m_list"
+
+            if msg_title == "#m_end":
+                reply = f"PRIVMSG {channel} :meeting end \r\n"
+                topics = []
+
+            if msg_title == "#m_topic":
+                topic = msg.split(" ", 4)
+                if len(topic) != 5:
+                    continue
+                topic = topic[4]
+                topics.append(topic)
+                reply = f"PRIVMSG {channel} :add topic: {topic} \r\n"
+
+            if msg_title == "#m_list":
+                tp = " ".join(
+                    [f"{i}-{topic}" for i, topic in enumerate(topics, 1)])
+
+                reply = f"PRIVMSG {channel} :topics: {tp} \r\n"
+
+            if msg_title == "#m_next":
+                if len(topics) == 0:
+                    reply = f"PRIVMSG {channel} :no topics \r\n"
+                else:
+                    tp = topics.pop(0) 
+                    reply = f"PRIVMSG {channel} :current topic: {tp} \r\n"
+
+            if reply != None:
+                writer.write(reply.encode('utf8'))
+                await writer.drain()
+
+        if command == "QUIT":
+            break
+
+    writer.close()
+
+asyncio.run(start())

+ 0 - 6
bin/ircd/script/tmux_session.sh

@@ -1,6 +0,0 @@
-#!/bin/sh
-
-tmux new-session -d 'LOG_TARGETS=net ../../../target/release/ircd -vv --accept 127.0.0.1:9999 --irc 127.0.0.1:6688'
-tmux split-window -v 'LOG_TARGETS=net ../../../target/release/ircd -vv --accept 127.0.0.1:11004 --external 127.0.0.1:11004 --seeds 127.0.0.1:9999 --irc 127.0.0.1:6667'
-tmux split-window -h 'LOG_TARGETS=net ../../../target/release/ircd -vv --slots 5 --seeds 127.0.0.1:9999 --irc 127.0.0.1:6668'
-tmux attach 

+ 52 - 47
bin/ircd/src/main.rs

@@ -4,15 +4,8 @@ use async_std::{
 };
 use std::net::SocketAddr;
 
-use async_channel::Receiver;
+use async_channel::{Receiver, Sender};
 use async_executor::Executor;
-use easy_parallel::Parallel;
-use futures::{io::BufReader, AsyncBufReadExt, AsyncReadExt, FutureExt};
-use log::{debug, error, info, warn};
-use simplelog::{ColorChoice, TermLogger, TerminalMode};
-use smol::future;
-use structopt_toml::StructOptToml;
-
 use darkfi::{
     async_daemonize,
     raft::Raft,
@@ -23,6 +16,12 @@ use darkfi::{
     },
     Error, Result,
 };
+use easy_parallel::Parallel;
+use futures::{io::BufReader, AsyncBufReadExt, AsyncReadExt, FutureExt};
+use log::{debug, error, info, warn};
+use simplelog::{ColorChoice, TermLogger, TerminalMode};
+use smol::future;
+use structopt_toml::StructOptToml;
 
 pub mod privmsg;
 pub mod rpc;
@@ -36,28 +35,41 @@ use crate::{
     settings::{Args, CONFIG_FILE, CONFIG_FILE_CONTENTS},
 };
 
-pub type SeenMsgId = Arc<Mutex<Vec<u32>>>;
+pub type SeenMsgIds = Arc<Mutex<Vec<u32>>>;
 
-async fn process_user_input(
-    mut line: String,
-    peer_addr: SocketAddr,
-    conn: &mut IrcServerConnection,
-    sender: async_channel::Sender<Privmsg>,
-    seen_msg_id: SeenMsgId,
-) -> Result<()> {
+fn build_irc_msg(msg: &Privmsg) -> String {
+    debug!("ABOUT TO SEND: {:?}", msg);
+    let irc_msg =
+        format!(":{}!anon@dark.fi PRIVMSG {} :{}\r\n", msg.nickname, msg.channel, msg.message,);
+    irc_msg
+}
+
+fn clean_input(mut line: String, peer_addr: &SocketAddr) -> Result<String> {
     if line.is_empty() {
-        warn!("Received empty line from {}. Closing connection.", peer_addr);
+        warn!("Received empty line from {}. ", peer_addr);
+        warn!("Closing connection.");
         return Err(Error::ChannelStopped)
     }
 
-    assert!(&line[(line.len() - 2)..] == "\r\n");
+    if &line[(line.len() - 2)..] != "\r\n" {
+        warn!("Closing connection.");
+        return Err(Error::ChannelStopped)
+    }
     // Remove CRLF
     line.pop();
     line.pop();
 
-    debug!("Received '{}' from {}", line, peer_addr);
+    Ok(line)
+}
 
-    if let Err(e) = conn.update(line, sender, seen_msg_id).await {
+async fn broadcast_msg(
+    irc_msg: String,
+    peer_addr: SocketAddr,
+    conn: &mut IrcServerConnection,
+) -> Result<()> {
+    info!("Send msg to IRC server '{}' from {}", irc_msg, peer_addr);
+
+    if let Err(e) = conn.update(irc_msg).await {
         warn!("Connection error: {} for {}", e, peer_addr);
         return Err(Error::ChannelStopped)
     }
@@ -66,48 +78,45 @@ async fn process_user_input(
 }
 
 async fn process(
-    receiver: Receiver<Privmsg>,
+    raft_receiver: Receiver<Privmsg>,
     stream: TcpStream,
     peer_addr: SocketAddr,
-    sender: async_channel::Sender<Privmsg>,
-    seen_msg_id: SeenMsgId,
+    raft_sender: Sender<Privmsg>,
+    seen_msg_id: SeenMsgIds,
 ) -> Result<()> {
     let (reader, writer) = stream.split();
 
     let mut reader = BufReader::new(reader);
-    let mut conn = IrcServerConnection::new(writer);
+    let mut conn = IrcServerConnection::new(writer, seen_msg_id.clone(), raft_sender);
 
     loop {
         let mut line = String::new();
         futures::select! {
-            privmsg = receiver.recv().fuse() => {
+            privmsg = raft_receiver.recv().fuse() => {
+                info!("Receive msg from raft");
                 let msg = privmsg?;
 
                 let mut smi = seen_msg_id.lock().await;
                 if smi.contains(&msg.id) {
                    continue
                 }
-
                 smi.push(msg.id);
                 drop(smi);
 
-                debug!("ABOUT TO SEND: {:?}", msg);
-                let irc_msg = format!(":{}!anon@dark.fi PRIVMSG {} :{}\r\n",
-                                      msg.nickname,
-                                      msg.channel,
-                                      msg.message,
-                                      );
-
+                let irc_msg = build_irc_msg(&msg);
                 conn.reply(&irc_msg).await?;
             }
-
             err = reader.read_line(&mut line).fuse() => {
                 if let Err(e) = err {
                     warn!("Read line error. Closing stream for {}: {}", peer_addr, e);
                     return Ok(())
                 }
-
-                process_user_input(line, peer_addr, &mut conn, sender.clone(), seen_msg_id.clone()).await?;
+                info!("Receive msg from IRC server");
+                let irc_msg = match clean_input(line, &peer_addr) {
+                    Ok(m) => m,
+                    Err(e) => return Err(e)
+                };
+                broadcast_msg(irc_msg, peer_addr,&mut conn).await?;
             }
         };
     }
@@ -117,29 +126,25 @@ async_daemonize!(realmain);
 async fn realmain(settings: Args, executor: Arc<Executor<'_>>) -> Result<()> {
     let listener = TcpListener::bind(settings.irc_listen).await?;
     let local_addr = listener.local_addr()?;
-    info!("Listening on {}", local_addr);
+    info!("IRC listening on {}", local_addr);
 
-    let datastore_path = expand_path(&settings.datastore)?;
+    let seen_msg_id: SeenMsgIds = Arc::new(Mutex::new(vec![]));
 
-    let seen_msg_id: SeenMsgId = Arc::new(Mutex::new(vec![]));
-
-    let net_settings = settings.net;
     //
     //Raft
     //
+    let datastore_path = expand_path(&settings.datastore)?;
+    let net_settings = settings.net;
     let datastore_raft = datastore_path.join("ircd.db");
-
     let mut raft = Raft::<Privmsg>::new(net_settings.inbound, datastore_raft)?;
-
     let raft_sender = raft.get_broadcast();
-    let commits = raft.get_commits();
+    let raft_receiver = raft.get_commits();
 
     //
     // RPC interface
     //
     let rpc_config = RpcServerConfig {
         socket_addr: settings.rpc_listen,
-        // TODO: Use net/transport:
         use_tls: false,
         identity_path: Default::default(),
         identity_pass: Default::default(),
@@ -164,11 +169,11 @@ async fn realmain(settings: Args, executor: Arc<Executor<'_>>) -> Result<()> {
                 }
             };
 
-            info!("Accepted client: {}", peer_addr);
+            info!("IRC Accepted client: {}", peer_addr);
 
             executor_cloned
                 .spawn(process(
-                    commits.clone(),
+                    raft_receiver.clone(),
                     stream,
                     peer_addr,
                     raft_sender.clone(),

+ 0 - 10
bin/ircd/src/rpc.rs

@@ -40,14 +40,4 @@ impl JsonRpcInterface {
     async fn pong(&self, id: Value, _params: Value) -> JsonResult {
         jsonrpc::response(json!("pong"), id).into()
     }
-
-    // TODO
-    // 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;
-    //    jsonrpc::response(resp, id).into()
-    //}
 }

+ 14 - 11
bin/ircd/src/server.rs

@@ -5,7 +5,7 @@ use rand::{rngs::OsRng, RngCore};
 
 use darkfi::{Error, Result};
 
-use crate::privmsg::Privmsg;
+use crate::{privmsg::Privmsg, SeenMsgIds};
 
 pub struct IrcServerConnection {
     write_stream: WriteHalf<TcpStream>,
@@ -14,10 +14,16 @@ pub struct IrcServerConnection {
     is_registered: bool,
     nickname: String,
     _channels: Vec<String>,
+    seen_msg_id: SeenMsgIds,
+    p2p_sender: async_channel::Sender<Privmsg>,
 }
 
 impl IrcServerConnection {
-    pub fn new(write_stream: WriteHalf<TcpStream>) -> Self {
+    pub fn new(
+        write_stream: WriteHalf<TcpStream>,
+        seen_msg_id: SeenMsgIds,
+        p2p_sender: async_channel::Sender<Privmsg>,
+    ) -> Self {
         Self {
             write_stream,
             is_nick_init: false,
@@ -25,21 +31,18 @@ impl IrcServerConnection {
             is_registered: false,
             nickname: "".to_string(),
             _channels: vec![],
+            seen_msg_id,
+            p2p_sender,
         }
     }
 
-    pub async fn update(
-        &mut self,
-        line: String,
-        sender: async_channel::Sender<Privmsg>,
-        seen_msg_id: crate::SeenMsgId,
-    ) -> Result<()> {
+    pub async fn update(&mut self, line: String) -> Result<()> {
         let mut tokens = line.split_ascii_whitespace();
         // Commands can begin with :garbage but we will reject clients doing
         // that for now to keep the protocol simple and focused.
         let command = tokens.next().ok_or(Error::MalformedPacket)?;
 
-        debug!("Received command: {}", command);
+        info!("Received command: {}", command);
 
         match command {
             "USER" => {
@@ -93,11 +96,11 @@ impl IrcServerConnection {
                     message: message.to_string(),
                 };
 
-                let mut smi = seen_msg_id.lock().await;
+                let mut smi = self.seen_msg_id.lock().await;
                 smi.push(random_id);
                 drop(smi);
 
-                sender.send(protocol_msg).await?;
+                self.p2p_sender.send(protocol_msg).await?;
             }
             "QUIT" => {
                 // Close the connection

+ 4 - 1
bin/tau/tau-cli/src/main.rs

@@ -168,7 +168,10 @@ async fn main() -> Result<()> {
 
     spawn_config(&config_path, CONFIG_FILE_CONTENTS)?;
 
-    let config: TauConfig = Config::<TauConfig>::load(config_path)?;
+    let config: TauConfig = match Config::<TauConfig>::load(config_path) {
+        Ok(c) => c,
+        Err(_) => TauConfig::default(),
+    };
 
     start(args, config).await
 }

+ 7 - 1
bin/tau/tau-cli/src/util.rs

@@ -2,7 +2,7 @@ use std::{
     env::{temp_dir, var},
     fs::{self, File},
     io::{self, Read, Write},
-    net::SocketAddr,
+    net::{IpAddr, Ipv4Addr, SocketAddr},
     ops::Index,
     process::Command,
 };
@@ -24,6 +24,12 @@ pub struct TauConfig {
     pub rpc_listen: SocketAddr,
 }
 
+impl Default for TauConfig {
+    fn default() -> Self {
+        Self { rpc_listen: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 11055) }
+    }
+}
+
 #[derive(Subcommand)]
 pub enum CliTauSubCommands {
     /// Add a new task

+ 3 - 0
bin/tau/taud/Cargo.toml

@@ -26,9 +26,12 @@ rand = "0.8.5"
 chrono = "0.4.19"
 thiserror = "1.0.30"
 ctrlc-async = {version= "3.2.2", default-features = false, features = ["async-std", "termination"]}
+encoding_rs = "0.8.31"
+encoding_rs_io = "0.1.7"
 
 # Encoding and parsing
 serde = {version = "1.0.136", features = ["derive"]}
 serde_json = "1.0.79"
 structopt = "0.3.26"
 structopt-toml = "0.5.0"
+crypto_box = {version = "0.7.2", features = ["std"]}

+ 63 - 4
bin/tau/taud/src/main.rs

@@ -1,10 +1,12 @@
 use async_std::sync::Arc;
+use serde::{Deserialize, Serialize};
 use std::fs::create_dir_all;
 
 use async_executor::Executor;
+use crypto_box::{aead::Aead, Box, SecretKey, KEY_SIZE};
 use easy_parallel::Parallel;
 use futures::{select, FutureExt};
-use log::{info, warn};
+use log::{error, info, warn};
 use simplelog::{ColorChoice, TermLogger, TerminalMode};
 use smol::future;
 use structopt_toml::StructOptToml;
@@ -17,6 +19,7 @@ use darkfi::{
         cli::{log_config, spawn_config},
         expand_path,
         path::get_config_path,
+        serial::{deserialize, serialize, SerialDecodable, SerialEncodable},
     },
     Error, Result,
 };
@@ -34,8 +37,15 @@ use crate::{
     month_tasks::MonthTasks,
     settings::{Args, CONFIG_FILE, CONFIG_FILE_CONTENTS},
     task_info::TaskInfo,
+    util::{load, save},
 };
 
+#[derive(Debug, Clone, SerialEncodable, SerialDecodable, Serialize, Deserialize)]
+pub struct MsgPayload {
+    nonce: Vec<u8>,
+    payload: Vec<u8>,
+}
+
 async_daemonize!(realmain);
 async fn realmain(settings: Args, executor: Arc<Executor<'_>>) -> Result<()> {
     let datastore_path = expand_path(&settings.datastore)?;
@@ -44,6 +54,23 @@ async fn realmain(settings: Args, executor: Arc<Executor<'_>>) -> Result<()> {
     create_dir_all(datastore_path.join("month"))?;
     create_dir_all(datastore_path.join("task"))?;
 
+    let mut rng = crypto_box::rand_core::OsRng;
+
+    let secret_key = match load::<[u8; KEY_SIZE]>(&datastore_path.join("secret_key")) {
+        Ok(t) => SecretKey::try_from(t)?,
+        Err(_) => {
+            info!(target: "tau", "generating a new secret key");
+            let secret = SecretKey::generate(&mut rng);
+            let sk_string = secret.as_bytes();
+            save::<[u8; KEY_SIZE]>(&datastore_path.join("secret_key"), sk_string)
+                .map_err(Error::from)?;
+            secret
+        }
+    };
+
+    let public_key = secret_key.public_key();
+    let msg_box = Box::new(&public_key, &secret_key);
+
     //
     // RPC
     //
@@ -69,7 +96,7 @@ async fn realmain(settings: Args, executor: Arc<Executor<'_>>) -> Result<()> {
     //Raft
     //
     let datastore_raft = datastore_path.join("tau.db");
-    let mut raft = Raft::<TaskInfo>::new(net_settings.inbound, datastore_raft)?;
+    let mut raft = Raft::<Vec<u8>>::new(net_settings.inbound, datastore_raft)?;
 
     let raft_sender = raft.get_broadcast();
     let commits = raft.get_commits();
@@ -83,7 +110,15 @@ async fn realmain(settings: Args, executor: Arc<Executor<'_>>) -> Result<()> {
 
         for task in tasks {
             info!(target: "tau", "send local task {:?}", task);
-            initial_sync_raft_sender.send(task).await.map_err(Error::from)?;
+
+            let nonce = crypto_box::generate_nonce(&mut rng);
+            let payload = &serialize(&task)[..];
+            let encrypted_payload = msg_box.encrypt(&nonce, payload).unwrap();
+
+            let msg = MsgPayload { nonce: nonce.to_vec(), payload: encrypted_payload };
+            let ser_msg = serialize(&msg);
+
+            initial_sync_raft_sender.send(ser_msg).await.map_err(Error::from)?;
         }
 
         loop {
@@ -93,12 +128,36 @@ async fn realmain(settings: Args, executor: Arc<Executor<'_>>) -> Result<()> {
                     if let Some(tk) = task {
                         info!(target: "tau", "save the received task {:?}", tk);
                         tk.save(&datastore_path_cloned)?;
-                        raft_sender.send(tk).await.map_err(Error::from)?;
+
+                        let nonce = crypto_box::generate_nonce(&mut rng);
+                        let payload = &serialize(&tk)[..];
+                        let encrypted_payload = msg_box.encrypt(&nonce, payload).unwrap();
+
+                        let msg = MsgPayload {
+                            nonce: nonce.to_vec(),
+                            payload: encrypted_payload,
+                        };
+                        let ser_msg = serialize(&msg);
+
+                        raft_sender.send(ser_msg).await.map_err(Error::from)?;
                     }
                 }
                 task = commits.recv().fuse() => {
                     let task = task.map_err(Error::from)?;
+
+                    let recv: MsgPayload = deserialize(&task)?;
+                    let nonce = recv.nonce.as_slice();
+                    let message = match msg_box.decrypt(nonce.try_into().unwrap(), &recv.payload[..]){
+                        Ok(m) => m,
+                        Err(_) => {
+                            error!("Invalid secret or public key");
+                            vec![]
+                        },
+                    };
+
+                    let task: TaskInfo = deserialize(&message)?;
                     info!(target: "tau", "receive update from the commits {:?}", task);
+                    
                     task.save(&datastore_path_cloned)?;
                 }
 

+ 42 - 0
contrib/update_pkg_versions.py

@@ -0,0 +1,42 @@
+#!/usr/bin/env python3
+import subprocess
+
+from os import chdir
+from subprocess import PIPE
+
+import tomlkit
+
+
+def update_package_version(filename, version):
+    with open(filename) as f:
+        content = f.read()
+
+    p = tomlkit.parse(content)
+    p["package"]["version"] = version
+
+    with open(filename, "w") as f:
+        f.write(tomlkit.dumps(p))
+
+
+def main():
+    toplevel = subprocess.run(["git", "rev-parse", "--show-toplevel"],
+                              capture_output=True)
+    toplevel = toplevel.stdout.decode().strip()
+    chdir(toplevel)
+
+    with open("Cargo.toml") as f:
+        content = f.read()
+
+    p = tomlkit.parse(content)
+    version = p["package"]["version"]
+
+    find_output = subprocess.run(
+        ["find", ".", "-type", "f", "-name", "Cargo.toml"], stdout=PIPE)
+    files = [i.strip() for i in find_output.stdout.decode().split("\n")][:-1]
+
+    for filename in files:
+        update_package_version(filename, version)
+
+
+if __name__ == "__main__":
+    main()

+ 1 - 1
example/smart-contract/Cargo.toml

@@ -1,6 +1,6 @@
 [package]
 name = "smart-contract"
-version = "0.1.0"
+version = "0.3.0"
 edition = "2021"
 
 [workspace]

+ 1 - 1
script/research/consensusd/Cargo.toml

@@ -1,6 +1,6 @@
 [package]
 name = "consensusd"
-version = "0.1.0"
+version = "0.3.0"
 edition = "2021"
 
 [dependencies.darkfi]

+ 1 - 1
script/research/crypsinous/zk/plonk-by-hand/Cargo.toml

@@ -1,6 +1,6 @@
 [package]
 name = "plonkbyhand"
-version = "0.1.0"
+version = "0.3.0"
 
 edition = "2021"
 

+ 1 - 1
script/research/nodes-tool/Cargo.toml

@@ -1,6 +1,6 @@
 [package]
 name = "nodes-tool"
-version = "0.1.0"
+version = "0.3.0"
 edition = "2021"
 
 [dependencies.darkfi]

+ 1 - 1
script/research/pasta/Cargo.toml

@@ -1,6 +1,6 @@
 [package]
 name = "pasta"
-version = "0.1.0"
+version = "0.3.0"
 authors = ["narodnik <x@x.org>"]
 edition = "2018"
 

+ 1 - 1
script/research/streamlet_rust/Cargo.toml

@@ -1,6 +1,6 @@
 [package]
 name = "streamlet_rust"
-version = "0.1.0"
+version = "0.3.0"
 edition = "2021"
 
 [dependencies.darkfi]

+ 1 - 1
script/research/validatord/Cargo.toml

@@ -1,6 +1,6 @@
 [package]
 name = "validatord"
-version = "0.1.0"
+version = "0.3.0"
 edition = "2021"
 
 [dependencies.darkfi]

+ 2 - 2
src/blockchain/blockstore.rs

@@ -1,4 +1,4 @@
-use log::warn;
+use log::debug;
 use sled::Batch;
 
 use crate::{
@@ -130,7 +130,7 @@ impl BlockOrderStore {
                 ret.push(Some(hash));
             } else {
                 if strict {
-                    warn!("BlockOrderStore::get() Slot {} not found", i);
+                    debug!("BlockOrderStore::get() Slot {} not found", i);
                     return Err(Error::SlotNotFound(*i))
                 }
                 ret.push(None);

+ 1 - 1
src/consensus/proto/protocol_sync.rs

@@ -78,7 +78,7 @@ impl ProtocolSync {
 
             debug!("ProtocolSync::handle_receive_block() received block");
 
-            // Node stores finalized flock, if it doesn't exist (checking by slot),
+            // Node stores finalized block, if it doesn't exist (checking by slot),
             // and removes its transactions from the unconfirmed_txs vector.
             // Consensus-mode enabled nodes have already performed these steps,
             // during proposal finalization.

+ 24 - 2
src/consensus/task/proposal.rs

@@ -10,7 +10,7 @@ use crate::{
 };
 
 /// async task used for participating in the consensus protocol
-pub async fn proposal_task(p2p: net::P2pPtr, state: ValidatorStatePtr) {
+pub async fn proposal_task(p2p: net::P2pPtr, sync_p2p: net::P2pPtr, state: ValidatorStatePtr) {
     // Node waits just before the current or next epoch end,
     // so it can start syncing latest state.
     let mut seconds_until_next_epoch = state.read().await.next_epoch_start();
@@ -89,7 +89,29 @@ pub async fn proposal_task(p2p: net::P2pPtr, state: ValidatorStatePtr) {
                             let vote = v.unwrap();
                             let result = state.write().await.receive_vote(&vote);
                             match result {
-                                Ok(_) => info!(target: "consensus", "Vote saved successfully."),
+                                Ok((_, to_broadcast)) => {
+                                    info!(target: "consensus", "Vote saved successfully.");
+                                    // Broadcast finalized blocks info, if any
+                                    match to_broadcast {
+                                        Some(blocks) => {
+                                            debug!("handle_receive_vote(): Broadcasting finalized blocks");
+                                            for info in blocks {
+                                                let result = sync_p2p.broadcast(info).await;
+                                                match result {
+                                                    Ok(()) => {
+                                                        info!(target: "consensus", "Finalized block broadcasted successfully.")
+                                                    }
+                                                    Err(e) => {
+                                                        error!(target: "consensus", "Failed broadcasting finalized block: {}", e)
+                                                    }
+                                                }
+                                            }
+                                        }
+                                        None => {
+                                            debug!("handle_receive_vote(): No finalized blocks to broadcast");
+                                        }
+                                    }
+                                }
                                 Err(e) => {
                                     error!(target: "consensus", "Vote save failed: {}", e)
                                 }