Merge branch 'master' of github.com:narodnik/sapvi

This commit is contained in:
narodnik
2021-04-29 13:26:08 +02:00
24 changed files with 303 additions and 199 deletions

View File

@@ -330,6 +330,7 @@ fn sub_scalar(a: MalArgs) -> MalRet {
}
fn mul_scalar(a: MalArgs) -> MalRet {
println!("mul {:?}", a[0]);
match (a[0].clone(), a[1].clone()) {
(Func(_, _), ZKScalar(a1)) => {
if let Vector(ref values, _) = a[0].apply(vec![]).unwrap() {
@@ -627,7 +628,8 @@ fn scalar_is_zero(a: MalArgs) -> MalRet {
}
}
fn add_scalar(a: MalArgs) -> MalRet {
fn add_scalar(a: MalArgs) -> MalRet {
println!("add_scalar {:?}", a);
match (a[0].clone(), a[1].clone()) {
(Func(_, _), ZKScalar(a1)) => {
if let Vector(ref values, _) = a[0].apply(vec![]).unwrap() {
@@ -672,6 +674,20 @@ fn add_scalar(a: MalArgs) -> MalRet {
s0.add_assign(s1);
Ok(ZKScalar(s0))
}
(ZKScalar(a1), Str(a0)) => {
let (mut s0, s1) = (bls12_381::Scalar::from_string(&a0), a1);
s0.add_assign(s1);
Ok(ZKScalar(s0))
}
// (List(a0, _), ZKScalar(mut a1)) => {
// let first_slice = a0.to_vec();
// let result = first_slice[0].apply(first_slice[1..].to_vec());
// println!("result {:?}", result);
// if let ZKScalar(value) = result.unwrap() {
// a1.add_assign(value);
// }
// Ok(ZKScalar(a1))
// }
_ => error(&format!("scalar add expect (zkscalar, zkscalar) found \n {:?}", a).to_string()),
}
}

View File

@@ -181,7 +181,7 @@
(scalar::one ~v3)
((scalar::one ~U) (scalar::one::neg ~A) (scalar::one::neg ~B))
)
`{ "u3" u3, "v3" v3 }
{ "u3" u3, "v3" v3 }
)
)
))
@@ -213,6 +213,7 @@
(def! u-add (get add-result "u3"))
(def! v-add (get add-result "v3"))
(def! val (last (last (zk-double u-add v-add))))
(println acc val)
(def! acc (i+ acc 1))
))
(val)
@@ -287,11 +288,9 @@
(conj value-result
(get (last (last
(rangeproof-alloc bit digit))) "lc")))
(println 'digit digit 'bit bit)
(def! digit (double digit))
(def! idx (i+ idx 1))
))
(println 'value-result value-result)
(def! value-alloc (alloc-input "value-alloc" value))
(enforce
(value-result)
@@ -307,10 +306,7 @@
(def! generator-value-commit-v (scalar "09d2a25018194750e9adacf78531ee3bfddbadd767671d517aa788c352641ff1"))
(def! generator-value-random-u (scalar "002924d15ccf8014ce724a41753d17dce3a9f7382a3db18fba3c8e286bb77382"))
(def! generator-value-random-v (scalar "0cb825b790b0601c4999e52d9added7d10d013b33fd95ca7d2ddd51691a09075"))
(def! mint-contract (fn* [secret value serial rnd-coin rnd-value] (
(def! result-mul (last (last (jj-mul generator-coin-u generator-coin-v secret))) "lc")
(def! public-u (alloc "public-u" (get result-mul "u")))
(def! public-v (alloc "public-v" (get result-mul "v")))
(def! mint-contract (fn* [public-u public-v value serial rnd-coin rnd-value] (
(def! mimc-round-1 (get (last (mimc public-u public-v)) "result"))
(def! mimc-round-2 (get (last (mimc mimc-round-1 value)) "result"))
(def! mimc-round-3 (get (last (mimc mimc-round-2 serial)) "result"))
@@ -320,12 +316,10 @@
(last (last (jj-mul generator-value-commit-u generator-value-commit-v value))))
(def! result-mul-rnd-value
(last (last (jj-mul generator-value-random-u generator-value-random-v rnd-value))))
(def! add-result (last
(jj-add (get result-mul-value "u") (get result-mul-value "u")
(get result-mul-rnd-value "u") (get result-mul-rnd-value "u"))))
(def! value-commit add-result)
(println 'value-commit value-commit)
(alloc-input "value-commit" value-commit)
(def! add-result (jj-add (get result-mul-value "u3") (get result-mul-value "v3")
(get result-mul-rnd-value "u3") (get result-mul-rnd-value "v3")))
(println 'add-result add-result)
;;(alloc-input "value-commit" add-result)
)))
;; (def! spend-contract (fn*
@@ -336,53 +330,12 @@
(prove
(
(def! secret (scalar 1))
(def! value (scalar 2))
(def! serial (scalar 3))
(def! public-u (scalar "0d7b70a0c82cbabf8f59ee61a63b8e0adcff42e9f2da7bda84f9308b3531dd18"))
(def! public-v (scalar "0cb825b790b0601c4999e52d9added7d10d013b33fd95ca7d2ddd51691a09075"))
(def! value (scalar 3))
(def! serial (scalar 4))
(def! rnd-coin (rnd-scalar))
(def! rnd-value (rnd-scalar))
(mint-contract secret value serial rnd-coin rnd-value)
(mint-contract public-u public-v value serial rnd-coin rnd-value)
)
)
;; (defmacro! test (fn* [value value-digit] (
;; (let* [bit (gensym2 'bit)
;; digit (gensym2 'digit)] (
;; `(def! ~bit (alloc ~bit ~value))
;; `(def! ~digit (alloc ~digit ~value-digit))
;; (println (str digit))
;; )))))
;; (def! param-u (scalar "6800f4fa0f001cfc7ff6826ad58004b4d1d8da41af03744e3bce3b7793664337"))
;; (def! param-v (scalar "6d81d3a9cb45dedbe6fb2a6e1e22ab50ad46f1b0473b803b3caefab9380b6a8b"))
;; (println (test param-u param-v))
;; (mint-contract param-u param-v)
;; (def! param3 (rnd-scalar))
;; (def! param-u (scalar "6800f4fa0f001cfc7ff6826ad58004b4d1d8da41af03744e3bce3b7793664337"))
;; (def! param-v (scalar "6d81d3a9cb45dedbe6fb2a6e1e22ab50ad46f1b0473b803b3caefab9380b6a8b"))
;; (jj-mul param-u param-v param3)
;; following some examples
;; (def! left (scalar "15a36d1f0f390d8852a35a8c1908dd87a361ee3fd48fdf77b9819dc82d90607e"))
;; (def! right (scalar "015d8c7f5b43fe33f7891142c001d9251f3abeeb98fad3e87b0dc53c4ebf1891"))
;; (mimc left right)
;; (def! param3 (rnd-scalar))
;; (jj-mul param-u param-v param3)
;; (def! param3 (rnd-scalar))
;; (def! param-u (scalar "6800f4fa0f001cfc7ff6826ad58004b4d1d8da41af03744e3bce3b7793664337"))
;; (def! param-v (scalar "6d81d3a9cb45dedbe6fb2a6e1e22ab50ad46f1b0473b803b3caefab9380b6a8b"))
;; (jj-mul param-u param-v param3)
;; (def! param3 (rnd-scalar))
;; (println 'rnd-scalar param3)
;; (def! param-u (scalar "6800f4fa0f001cfc7ff6826ad58004b4d1d8da41af03744e3bce3b7793664337"))
;; (def! param-v (scalar "6d81d3a9cb45dedbe6fb2a6e1e22ab50ad46f1b0473b803b3caefab9380b6a8b"))
;; (println (zk-mul param1 param2))
;; (jj-mul param-u param-v param3)
;; (println (zk-mul param1 param2))
;; (def! param1 (scalar 3))
;; (def! param2 (scalar 9))
;; (println (zk-square param1))
;; (println (zk-mul param1 param2))
;; (println 'witness (zk-witness param-u param-v))
;; (println 'double (last (last (zk-double param-u param-v))))
;; (println 'nonzero (zk-nonzero? param3))
;; (println 'not-small-order? (zk-not-small-order? param-u param-v))

View File

@@ -14,8 +14,7 @@ use rand::rngs::OsRng;
use std::rc::Rc;
use std::time::Instant;
use std::{
borrow::{Borrow, BorrowMut},
fs,
borrow::{Borrow, BorrowMut},
};
use std::{cell::RefCell, collections::HashMap};
use types::EnforceAllocation;
@@ -150,6 +149,8 @@ fn eval(mut ast: MalVal, mut env: Env) -> MalRet {
let start = Instant::now();
'tco: loop {
// TODO check DEBUG symbol on env
println!("debug eval \t {:?} \t {:?}", ast, start.elapsed());
ret = match ast.clone() {
List(l, _) => {
if l.len() == 0 {
@@ -296,7 +297,7 @@ fn eval(mut ast: MalVal, mut env: Env) -> MalRet {
match eval(l[1].clone(), env.clone())? {
MalVal::Int(v) => {
for _i in 0..v {
eval(l[2].clone(), env.clone())?;
ast = eval_ast(&l[2], &env)?;
}
Ok(Nil)
}
@@ -350,10 +351,16 @@ fn eval(mut ast: MalVal, mut env: Env) -> MalRet {
// TODO add debug param
prove(a1.clone(), env.clone())
}
Sym(ref a0sym) if a0sym == "kill" => {
error(&format!("KILL at: {:?}", ast).to_string())
}
Sym(ref a0sym) if a0sym == "alloc-const" => {
// let start = Instant::now();
let start = Instant::now();
let a1 = l[1].clone();
let value = eval(l[2].clone(), env.clone())?;
let mut value = eval(l[2].clone(), env.clone())?;
if let Func(_, _) = value {
value = value.apply(vec![]).unwrap();
}
let result = eval(value.clone(), env.clone())?;
let allocs = get_allocations(&env, "AllocationsConst");
allocs.borrow_mut().insert(a1.pr_str(false), result.clone());
@@ -362,13 +369,16 @@ fn eval(mut ast: MalVal, mut env: Env) -> MalRet {
} else {
env_set(&env, Sym("AllocationsConst".to_string()), Alloc(allocs))?;
}
// println!("Alloc Const: {:?}", start.elapsed());
println!("Alloc Const: {:?}", start.elapsed());
Ok(result.clone())
}
Sym(ref a0sym) if a0sym == "alloc-input" => {
// let start = Instant::now();
let start = Instant::now();
let a1 = l[1].clone();
let value = eval(l[2].clone(), env.clone())?;
let mut value = eval(l[2].clone(), env.clone())?;
if let Func(_, _) = value {
value = value.apply(vec![]).unwrap();
}
let result = eval(value.clone(), env.clone())?;
let allocs = get_allocations(&env, "AllocationsInput");
allocs.borrow_mut().insert(a1.pr_str(false), result.clone());
@@ -377,11 +387,11 @@ fn eval(mut ast: MalVal, mut env: Env) -> MalRet {
} else {
env_set(&env, Sym("AllocationsInput".to_string()), Alloc(allocs))?;
}
// println!("Alloc Input: {:?}", start.elapsed());
println!("Alloc Input: {:?}", start.elapsed());
Ok(result.clone())
}
Sym(ref a0sym) if a0sym == "alloc" => {
// let start = Instant::now();
let start = Instant::now();
let a1 = l[1].clone();
let mut value = eval(l[2].clone(), env.clone())?;
if let Func(_, _) = value {
@@ -395,7 +405,7 @@ fn eval(mut ast: MalVal, mut env: Env) -> MalRet {
} else {
env_set(&env, Sym("Allocations".to_string()), Alloc(allocs))?;
}
// println!("Alloc: {:?}", start.elapsed());
println!("Alloc:\t{:?}\t{:?}\t{:?}", value, result, start.elapsed());
Ok(result.clone())
}
//Sym(ref a0sym) if a0sym == "verify" => {
@@ -515,10 +525,6 @@ fn eval(mut ast: MalVal, mut env: Env) -> MalRet {
output: out_vec,
};
enforce_vec.push(enforce);
// let mut new_vec: Vec<EnforceAllocation> = vec![enforce];
// for value in enforce_vec.iter() {
// new_vec.push(value.clone());
// }
if let Some(e) = &env.outer {
env_set(
&e,
@@ -533,12 +539,6 @@ fn eval(mut ast: MalVal, mut env: Env) -> MalRet {
)?;
}
// println!(
// "allocs here {:?}",
// get_allocations_nested(&env, "Allocations")
// );
// println!("enforce here {:?}", get_enforce_allocs_nested(&env));
Ok(MalVal::Str("enforce-eof".to_string()))
}
_ => match eval_ast(&ast, &env)? {
@@ -576,8 +576,7 @@ fn eval(mut ast: MalVal, mut env: Env) -> MalRet {
break;
} // end 'tco loop
// println!("eval end \t {:?} \t {:?}", ast, start.elapsed());
// println!("debug eval \t {:?} \t {:?}", ast, start.elapsed());
ret
}

View File

@@ -71,11 +71,13 @@ impl Circuit<bls12_381::Scalar> for LispCircuit {
cs: &mut CS,
) -> Result<(), SynthesisError> {
let mut variables: HashMap<String, Variable> = HashMap::default();
// TODO change the name from alloc-const to constant
let params_const = self.params;
let circuitTime = Instant::now();
let start = Instant::now();
// println!("Allocations\n");
// TODO is the private and params
for (k, v) in &self.allocs {
match v {
MalVal::ZKScalar(val) => {
@@ -101,6 +103,7 @@ impl Circuit<bls12_381::Scalar> for LispCircuit {
println!("circuit alloc \t {:?}", start.elapsed());
let start = Instant::now();
// println!("Allocations Input\n");
// TODO alloc-input is the public value
for (k, v) in &self.alloc_inputs {
match v {
MalVal::ZKScalar(val) => {

View File

@@ -1,66 +1,68 @@
max_width = 100
hard_tabs = false
tab_spaces = 4
newline_style = "Auto"
use_small_heuristics = "Default"
indent_style = "Block"
# Config file for cargo fmt. Uncomment line to edit the default settings.
# max_width = 100
# hard_tabs = false
# tab_spaces = 4
# newline_style = "Auto"
# use_small_heuristics = "Default"
# indent_style = "Block"
wrap_comments = true
format_code_in_doc_comments = false
format_code_in_doc_comments = true
comment_width = 80
normalize_comments = true
normalize_doc_attributes = true
license_template_path = ""
# normalize_comments = true
# normalize_doc_attributes = true
# license_template_path = ""
format_strings = true
format_macro_matchers = true
format_macro_bodies = true
empty_item_single_line = true
struct_lit_single_line = true
fn_single_line = false
where_single_line = false
imports_indent = "Block"
imports_layout = "Mixed"
merge_imports = false
reorder_imports = true
reorder_modules = true
reorder_impl_items = false
type_punctuation_density = "Wide"
space_before_colon = false
space_after_colon = true
spaces_around_ranges = false
binop_separator = "Front"
remove_nested_parens = true
combine_control_expr = true
overflow_delimited_expr = false
struct_field_align_threshold = 0
enum_discrim_align_threshold = 0
match_arm_blocks = true
force_multiline_blocks = false
fn_args_layout = "Tall"
brace_style = "SameLineWhere"
control_brace_style = "AlwaysSameLine"
trailing_semicolon = true
trailing_comma = "Vertical"
match_block_trailing_comma = false
blank_lines_upper_bound = 1
blank_lines_lower_bound = 0
edition = "2015"
version = "One"
inline_attribute_width = 0
merge_derives = true
use_try_shorthand = false
use_field_init_shorthand = false
force_explicit_abi = true
condense_wildcard_suffixes = false
color = "Auto"
required_version = "1.4.21"
unstable_features = false
disable_all_formatting = false
skip_children = false
hide_parse_errors = false
error_on_line_overflow = false
error_on_unformatted = false
report_todo = "Never"
report_fixme = "Never"
ignore = []
emit_mode = "Files"
make_backup = false
# format_macro_matchers = true
# format_macro_bodies = true
# empty_item_single_line = true
# struct_lit_single_line = true
# fn_single_line = false
# where_single_line = false
# imports_indent = "Block"
# imports_layout = "Mixed"
# merge_imports = false
# reorder_imports = true
# reorder_modules = true
# reorder_impl_items = false
# type_punctuation_density = "Wide"
# space_before_colon = false
# space_after_colon = true
# spaces_around_ranges = false
# binop_separator = "Front"
# remove_nested_parens = true
# combine_control_expr = true
# overflow_delimited_expr = false
# struct_field_align_threshold = 0
# enum_discrim_align_threshold = 0
# match_arm_blocks = true
# force_multiline_blocks = false
# fn_args_layout = "Tall"
# brace_style = "SameLineWhere"
# control_brace_style = "AlwaysSameLine"
# trailing_semicolon = true
# trailing_comma = "Vertical"
# match_block_trailing_comma = false
# blank_lines_upper_bound = 1
# blank_lines_lower_bound = 0
edition = "2018"
# version = "One"
# inline_attribute_width = 0
# merge_derives = true
# use_try_shorthand = false
# use_field_init_shorthand = false
# force_explicit_abi = true
# condense_wildcard_suffixes = false
# color = "Auto"
# required_version = "1.4.21"
# unstable_features = false
# disable_all_formatting = false
# skip_children = false
# hide_parse_errors = false
# error_on_line_overflow = false
# error_on_unformatted = false
# report_todo = "Never"
# report_fixme = "Never"
# ignore = []
# emit_mode = "Files"
# make_backup = false

View File

@@ -10,9 +10,7 @@ use crate::system::{StoppableTask, StoppableTaskPtr, Subscriber, SubscriberPtr,
/// Atomic pointer to Acceptor class.
pub type AcceptorPtr = Arc<Acceptor>;
/// Handles the acceptance of inbound socket connections. Used to start
/// listening on a local socket address, to accept incoming connections and to
/// handle network errors.
/// Create inbound socket connections.
pub struct Acceptor {
channel_subscriber: SubscriberPtr<NetResult<ChannelPtr>>,
task: StoppableTaskPtr,

View File

@@ -18,10 +18,7 @@ use crate::system::{StoppableTask, StoppableTaskPtr, Subscriber, SubscriberPtr,
/// Atomic pointer to async channel.
pub type ChannelPtr = Arc<Channel>;
/// Async channel interface that handles the sending of messages across the
/// network. Public interface is used to create new channels, to stop and start
/// a channel, send messages. Also implements message functionality. Implements
/// the message subscriber subsystem.
/// Async channel for communication between nodes.
pub struct Channel {
reader: Mutex<ReadHalf<Async<TcpStream>>>,
writer: Mutex<WriteHalf<Async<TcpStream>>>,
@@ -33,7 +30,9 @@ pub struct Channel {
}
impl Channel {
/// Create a new channel.
/// Sets up a new channel. Creates a reader and writer TCP stream and
/// summons the message subscriber subsystem. Performs a network
/// handshake on the subsystem dispatchers.
pub async fn new(stream: Async<TcpStream>, address: SocketAddr) -> Arc<Self> {
let (reader, writer) = stream.split();
let reader = Mutex::new(reader);
@@ -53,7 +52,8 @@ impl Channel {
})
}
/// Start the channel.
/// Starts the channel. Runs a receive loop to start receiving messages or
/// handles a network failure.
pub fn start(self: Arc<Self>, executor: Arc<Executor<'_>>) {
debug!(target: "net", "Channel::start() [START, address={}]", self.address());
let self2 = self.clone();
@@ -67,10 +67,13 @@ impl Channel {
debug!(target: "net", "Channel::start() [END, address={}]", self.address());
}
/// Stop the channel.
/// Stops the channel. Steps through each component of the channel
/// connection and sends a stop signal. Notifies all subscribers that
/// the channel has been closed.
pub async fn stop(&self) {
debug!(target: "net", "Channel::stop() [START, address={}]", self.address());
assert_eq!(self.stopped.load(Ordering::Relaxed), false);
// Changes memory ordering to relaxed. We don't need strict thread locking here.
self.stopped.store(false, Ordering::Relaxed);
self.stop_subscriber.notify(NetError::ChannelStopped).await;
self.receive_task.stop().await;
@@ -80,7 +83,7 @@ impl Channel {
debug!(target: "net", "Channel::stop() [END, address={}]", self.address());
}
/// Stop the channel and create a new sub.
/// Creates a subscription to a stopped signal.
pub async fn subscribe_stop(&self) -> Subscription<NetError> {
debug!(target: "net",
"Channel::subscribe_stop() [START, address={}]",
@@ -96,7 +99,9 @@ impl Channel {
sub
}
/// Send a message across a channel.
/// Sends a message across a channel. Calls function 'send_message' that
/// creates a new payload and sends it over the TCP connection as a
/// packet. Returns an error if something goes wrong.
pub async fn send<M: messages::Message>(&self, message: M) -> NetResult<()> {
debug!(target: "net",
"Channel::send() [START, command={:?}, address={}]",
@@ -124,7 +129,10 @@ impl Channel {
result
}
/// Implements send message functionality.
/// Implements send message functionality. Creates a new payload and encodes
/// it. Then creates a message packet- the base type of the network- and
/// copies the payload into it. Then we send the packet over the TCP
/// stream.
async fn send_message<M: messages::Message>(&self, message: M) -> error::Result<()> {
let mut payload = Vec::new();
message.encode(&mut payload)?;
@@ -137,7 +145,7 @@ impl Channel {
messages::send_packet(stream, packet).await
}
/// Subscribe to a message type.
/// Subscribe to a messages on the message subsystem.
pub async fn subscribe_msg<M: messages::Message>(&self) -> NetResult<MessageSubscription<M>> {
debug!(target: "net",
"Channel::subscribe_msg() [START, command={:?}, address={}]",

View File

@@ -6,7 +6,7 @@ use crate::net::error::{NetError, NetResult};
use crate::net::utility::sleep;
use crate::net::{Channel, ChannelPtr, SettingsPtr};
/// Handles the creation of outbound connections.
/// Create outbound socket connections.
pub struct Connector {
settings: SettingsPtr,
}

View File

@@ -3,7 +3,7 @@ use std::fmt;
/// Returns the relevant network error if a program fails.
pub type NetResult<T> = std::result::Result<T, NetError>;
/// Defines a set of common network errors. Used for error handling.
/// An enum representing the main network errors.
#[derive(Debug, Copy, Clone)]
pub enum NetError {
OperationFailed,

View File

@@ -18,8 +18,7 @@ pub type MessageSubscriptionID = u64;
type MessageResult<M> = NetResult<Arc<M>>;
/// Handles message subscriptions through a subscription ID and a receiver
/// channel. Inherits from Message Dispatcher: a class that maintains a list of
/// active subscribers and handles sending messages across subscriptions.
/// channel.
pub struct MessageSubscription<M: Message> {
id: MessageSubscriptionID,
recv_queue: async_channel::Receiver<MessageResult<M>>,
@@ -166,22 +165,8 @@ impl<M: Message> MessageDispatcherInterface for MessageDispatcher<M> {
}
}
/// Generic publish/subscribe class that can dispatch any kind of message to a
/// subscribed list of dispatchers. Dispatchers subscribe to a single
/// message format of any type. This is a generalized version of the simple
/// publish-subscribe class in system::Subscriber.
///
/// Message Subsystem maintains a list of dispatchers. Dispatchers belong to
/// a class of subscribers called Message Dispatcher. Message Dispatcher
/// implements a generic trait called Message Dispatcher Interface.
///
/// Pub-sub is called on dispatchers through the functions 'subscribe' and
/// 'notify'. Whereas system::Subscriber only allows messages of a single type,
/// dispatchers can handle any kind of message. This generic message is called a
/// a payload and is processed and decoded by the Message Dispatcher.
///
/// Message Subsystem also enables the creation of new message subsystems,
/// adding new dispatchers and clearing inactive channels.
/// Publish/subscribe class that can dispatch any kind of message to a
/// list of dispatchers.
pub struct MessageSubsystem {
dispatchers: Mutex<HashMap<&'static str, Arc<dyn MessageDispatcherInterface>>>,
}

View File

@@ -1,14 +1,94 @@
/// Acceptor class handles the acceptance of inbound socket connections. It's
/// used to start listening on a local socket address, to accept incoming
/// connections and to handle network errors.
pub mod acceptor;
/// Async channel that handles the sending of messages across the network.
/// Public interface is used to create new channels, to stop and start
/// a channel, and to send messages.
///
/// Implements message functionality and the message subscriber subsystem.
pub mod channel;
/// Handles the creation of outbound connections. Used to establish an outbound
/// connection.
pub mod connector;
/// Defines a set of common network errors. Used for error handling.
pub mod error;
/// Hosts are a list of network addresses used when establishing an outbound
/// connection. Hosts are shared across the network through the address
/// protocol. When attempting to connect, a node will loop through addresses in
/// the host store until it finds ones to connect to.
pub mod hosts;
/// Generic publish/subscribe class that can dispatch any kind of message to a
/// subscribed list of dispatchers. Dispatchers subscribe to a single
/// message format of any type. This is a generalized version of the simple
/// publish-subscribe class in system::Subscriber.
///
/// Message Subsystem also enables the creation of new message subsystems,
/// adding new dispatchers and clearing inactive channels.
///
/// Message Subsystem maintains a list of dispatchers, which is a generalized
/// version of a subscriber. Pub-sub is called on dispatchers through the
/// functions 'subscribe' and 'notify'. Whereas system::Subscriber only allows
/// messages of a single type, dispatchers can handle any kind of message. This
/// generic message is called a payload and is processed and decoded by the
/// Message Dispatcher.
///
/// The Message Dispatcher is a class of subscribers that implements a
/// generic trait called Message Dispatcher Interface, which allows us to
/// process any kind of payload as a message.
pub mod message_subscriber;
/// Defines how to decode generic messages as well as implementing the common
/// network messages that are sent between nodes as described by the Protocol
/// submodule.
///
/// Implements a type called Packet which is the base message type. Packets are
/// converted into messages and passed to an event loop.
pub mod messages;
/// P2P provides all core functionality to interact with the peer-to-peer
/// network.
///
/// Used to create a network, to start and run it, to broadcast messages across
/// all channels, and to manage the channel store.
///
/// The channel store is a hashmap of channel address that we can use to add and
/// remove channels or check whether a channel is already is in the store.
pub mod p2p;
/// Defines the networking protocol used at each stage in a connection. Consists
/// of a series of messages that are sent across the network at the different
/// connection stages.
///
/// When a node connects to a network for the first time, it must follow a seed
/// protocol, which provides it with a list of network hosts to connect to. To
/// establish a connection to another node, nodes must send version and version
/// acknowledgement messages. During a connection, nodes continually get address
/// and get-address messages to inform eachother about what nodes are on the
/// network. Nodes also send out a ping and pong message which keeps the network
/// from shutting down.
///
/// Protocol submodule also implements a jobs manager than handles the
/// asynchronous execution of the protocols.
pub mod protocols;
/// Defines the interaction between nodes during a connection. Consists of an
/// inbound session, which describes how to set up an incoming connection, and
/// an outbound session, which describes setting up an outbound connection. Also
/// describes the seed session, which is the type of connection used when a node
/// connects to the network for the first time. Implements the session trait
/// which describes the common functions across all sessions.
pub mod sessions;
/// Network configuration settings.
pub mod settings;
/// Utility module that defines a sleep function used throughout the network.
pub mod utility;
pub use acceptor::{Acceptor, AcceptorPtr};

View File

@@ -137,7 +137,7 @@ impl P2p {
self.channel_subscriber.clone().subscribe().await
}
/// Stop a subscription.
/// Subscribe to a stop signal.
pub async fn subscribe_stop(&self) -> Subscription<NetError> {
self.stop_subscriber.clone().subscribe().await
}

View File

@@ -1,7 +1,49 @@
/// Protocol for address and get-address messages. Implements how nodes exchange
/// connection information about other nodes on the network. Address and
/// get-address messages are exchanged continually alongside ping-pong messages
/// as part of a network connection.
///
/// Protocol starts by creating a subscription to address and get address
/// messages. Then the protocol sends out a get address message and waits for an
/// address message. Upon receiving an address messages, nodes add the
/// address information to their local store.
pub mod protocol_address;
/// Manages the tasks for the network protocol. Used by other connection
/// protocols to handle asynchronous task execution across the network. Runs all
/// tasks that are handed to it on an executor that has stopping functionality.
pub mod protocol_jobs_manager;
/// Protocol for ping-pong keep-alive messages. Implements ping message and pong
/// response. These messages are like the network heartbeat- they are sent
/// continually between nodes, to ensure each node is still alive and active.
/// Ping-pong messages ensure that the network doesn't
/// time out.
///
/// Protocol starts by creating a subscription to ping and pong messages. Then
/// it starts a loop with a timer and runs ping-pong in the task manager. It
/// sends out a ping and waits for pong reply. Then waits for ping and replies
/// with a pong.
pub mod protocol_ping;
/// Seed server protocol. Seed server is used when connecting to the network for
/// the first time. Returns a list of IP addresses that nodes can connect to.
///
/// To start the seed protocol, we create a subscription to the address message,
/// and send our address to the seed server. Then we send a get-address message
/// and receive an address message. We add these addresses to our internal
/// store.
pub mod protocol_seed;
/// Protocol for version information handshake between nodes at the start of a
/// connection. Implements the process for exchanging version information
/// between nodes. This is the first step when establishing a p2p connection.
///
/// The version protocol starts of by instantiating the protocol and creating a
/// new subscription to version and version acknowledgement messages. Then we
/// run the protocol. Nodes send a version message and wait for a version
/// acknowledgement, while asynchronously waiting for version info from the
/// other node and sending the version acknowledgement.
pub mod protocol_version;
pub use protocol_address::ProtocolAddress;

View File

@@ -8,15 +8,12 @@ use crate::net::messages;
use crate::net::protocols::{ProtocolJobsManager, ProtocolJobsManagerPtr};
use crate::net::{ChannelPtr, HostsPtr};
/// Protocol for address and get-address messages.
/// Defines address and get-address messages.
pub struct ProtocolAddress {
channel: ChannelPtr,
addrs_sub: MessageSubscription<messages::AddrsMessage>,
get_addrs_sub: MessageSubscription<messages::GetAddrsMessage>,
hosts: HostsPtr,
jobsman: ProtocolJobsManagerPtr,
}

View File

@@ -11,7 +11,9 @@ use crate::system::ExecutorPtr;
/// Pointer to protocol jobs manager.
pub type ProtocolJobsManagerPtr = Arc<ProtocolJobsManager>;
/// Manages the tasks for the network protocol.
/// Manages the tasks for the network protocol. Used by other connection
/// protocols to handle asynchronous task execution across the network. Runs all
/// tasks that are handed to it on an executor that has stopping functionality.
pub struct ProtocolJobsManager {
name: &'static str,
channel: ChannelPtr,

View File

@@ -10,11 +10,10 @@ use crate::net::protocols::{ProtocolJobsManager, ProtocolJobsManagerPtr};
use crate::net::utility::sleep;
use crate::net::{ChannelPtr, SettingsPtr};
/// Protocol for ping-pong keep-alive messages.
/// Defines ping and pong messages.
pub struct ProtocolPing {
channel: ChannelPtr,
settings: SettingsPtr,
jobsman: ProtocolJobsManagerPtr,
}

View File

@@ -6,8 +6,7 @@ use crate::net::error::NetResult;
use crate::net::messages;
use crate::net::{ChannelPtr, HostsPtr, SettingsPtr};
/// Seed server protocol. Seed server is used when connecting to the network for
/// the first time. Returns a list of IP addresses that nodes can connect to.
/// Implements the seed protocol.
pub struct ProtocolSeed {
channel: ChannelPtr,
hosts: HostsPtr,

View File

@@ -9,8 +9,8 @@ use crate::net::messages;
use crate::net::utility::sleep;
use crate::net::{ChannelPtr, SettingsPtr};
/// Protocol for version information handshake between nodes at the start of a
/// connection.
/// Implements the protocol version handshake sent out by nodes at the beginning
/// of a connection.
pub struct ProtocolVersion {
channel: ChannelPtr,
version_sub: MessageSubscription<messages::VersionMessage>,

View File

@@ -10,7 +10,7 @@ use crate::net::{Acceptor, AcceptorPtr};
use crate::net::{ChannelPtr, P2p};
use crate::system::{StoppableTask, StoppableTaskPtr};
/// Inbound connections session.
/// Defines inbound connections session.
pub struct InboundSession {
p2p: Weak<P2p>,
acceptor: AcceptorPtr,

View File

@@ -1,6 +1,28 @@
/// Inbound connections session. Manages the creation of inbound sessions. Used
/// to create an inbound session and start and stop the session.
///
/// Class consists of 3 pointers: a weak pointer to the peer-to-peer class, an
/// acceptor pointer, and a stoppable task pointer. Using a weak pointer to P2P
/// allows us to avoid circular dependencies.
pub mod inbound_session;
/// Outbound connections session. Manages the creation of outbound sessions.
/// Used to create an outbound session and stop and start the session.
///
/// Class consists of a weak pointer to the peer-to-peer interface and a vector
/// of outbound connection slots. Using a weak pointer to p2p allows us to avoid
/// circular dependencies. The vector of slots is wrapped in a mutex lock. This
/// is switched on everytime we instantiate a connection slot and insures that
/// no other part of the program uses the slots at the same time.
pub mod outbound_session;
/// Seed connections session. Manages the creation of seed sessions. Used on
/// first time connecting to the network. The seed node stores a list of other
/// nodes in the network.
pub mod seed_session;
/// Defines methods that are used across sessions. Implements registering the
/// channel and initializing the channel by performing a network handshake.
pub mod session;
pub use inbound_session::InboundSession;

View File

@@ -10,7 +10,7 @@ use crate::net::sessions::Session;
use crate::net::{ChannelPtr, Connector, P2p};
use crate::system::{StoppableTask, StoppableTaskPtr};
/// Outbound connections session.
/// Defines outbound connections session.
pub struct OutboundSession {
p2p: Weak<P2p>,
connect_slots: Mutex<Vec<StoppableTaskPtr>>,
@@ -28,6 +28,7 @@ impl OutboundSession {
pub async fn start(self: Arc<Self>, executor: Arc<Executor<'_>>) -> NetResult<()> {
let slots_count = self.p2p().settings().outbound_connections;
info!("Starting {} outbound connection slots.", slots_count);
// Activate mutex lock on connection slots.
let mut connect_slots = self.connect_slots.lock().await;
for i in 0..slots_count {

View File

@@ -10,7 +10,7 @@ use crate::net::sessions::Session;
use crate::net::utility::sleep;
use crate::net::{ChannelPtr, Connector, HostsPtr, P2p, SettingsPtr};
/// Seed connections session.
/// Defines seed connections session.
pub struct SeedSession {
p2p: Weak<P2p>,
}

View File

@@ -26,9 +26,7 @@ async fn remove_sub_on_stop(p2p: P2pPtr, channel: ChannelPtr) {
}
#[async_trait]
/// Session trait. Defines methods that are used across sessions. Implements
/// registering the channel and initializing the channel by performing a network
/// handshake.
/// Session trait.
pub trait Session: Sync {
/// Registers a new channel with the session. Performs a network handshake
/// and starts the channel.

View File

@@ -4,7 +4,7 @@ use std::sync::Arc;
/// Atomic pointer to network settings.
pub type SettingsPtr = Arc<Settings>;
/// Network configuration settings.
/// Defines the network settings.
#[derive(Clone)]
pub struct Settings {
pub inbound: Option<SocketAddr>,