Skip to content
This repository has been archived by the owner on Feb 1, 2019. It is now read-only.

feat: Refactor notary. Detect when running cargo test to conditionally run thread termination code. Setup logger #32

Merged
merged 12 commits into from
Apr 16, 2018
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ path = "src/lib.rs"
ethereum-types = "0.3.0"
ethcore-bytes = "0.1.0"
tiny-keccak = "1.3"
log = { version = "0.4.1", features = ["max_level_debug", "release_max_level_warn"] }
chrono = { version = "0.4", features = ["serde"] }

[badges]
travis-ci = { repository = "Drops-of-Diamond/Diamond-drops", branch = "master" }
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,12 @@ See [here](https://github.com/Drops-of-Diamond/diamond_drops/wiki/Introduction-a
cargo test
```

* Build and show Docs
```bash
cargo build;
cargo doc --open
```

See this wiki article [here](https://github.com/Drops-of-Diamond/diamond_drops/wiki/Contributing-guidelines).

### View UML Diagram
Expand Down
40 changes: 40 additions & 0 deletions src/cli/config_env.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
use std::env;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you need to add

#[macro_use]
extern crate log;

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's ok, we only have to include #[macro_use] extern crate log; in main.rs and lib.rs

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK.


pub fn get_env() -> String {
let key = "RUST_ENV";
match env::var(key) {
Ok(val) => {
debug!("Found environment variable key {}: {:?}", key, val);
val.to_string()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may want to read the debug! log to a target.

https://docs.rs/log/0.4.1/log/macro.debug.html

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nevermind, it's OK to read to the terminal, a developer can use <command> -> logfile.log.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to have val.to_string()? It doesn't look like this serves any purpose.

},
Err(e) => {
error!("Error interpreting environment variable key {}: {}", key, e);
"".to_string()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to have "".to_string()? It doesn't look like this serves any purpose.

},
}
}

pub fn set_test_env() {
// Set the environment variable key `TEST` to value of "1"
// when `cargo test` has been run, otherwise set it to "0"
let key = "RUST_ENV";
let value_test = "TEST";
let value_development = "DEVELOPMENT";
if let Some(arg0) = env::args().nth(0) {
if arg0 == "target/debug/diamond_drops" {
env::set_var(key, value_development);
assert_eq!(env::var(key), Ok(value_development.to_string()));
} else {
env::set_var(key, value_test);
assert_eq!(env::var(key), Ok(value_test.to_string()));
}
}
}

pub fn is_running_with_cargo_test() -> bool {
if get_env() == "TEST" {
true
} else {
false
}
}
39 changes: 39 additions & 0 deletions src/cli/config_log.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use log;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you also need to add this here as well:

#[macro_use]
extern crate log;

use log::{Record, Level, Metadata, SetLoggerError, LevelFilter};
use chrono::Local;

static LOGGER: DiamondDropsLogger = DiamondDropsLogger;

struct DiamondDropsLogger;

impl log::Log for DiamondDropsLogger {
fn enabled(&self, metadata: &Metadata) -> bool {
metadata.level() <= Level::Trace
}

fn log(&self, record: &Record) {
if self.enabled(record.metadata()) {
println!("{} [{}] - {}", Local::now().format("%Y-%m-%dT%H:%M:%S"), record.level(), record.args());
}
}

fn flush(&self) {}
}

pub fn init() -> () {
/*! Initialisation of [Log Crate](https://crates.io/crates/log) with choice of logging level macros */
/*! from highest priority to lowest: `error!`, `warn!`, `info!`, `debug!` and `trace!`. */
/*! [Compile time filters](https://docs.rs/log/0.4.1/log/#compile-time-filters) are configured in Cargo.toml */

let logger = log::set_logger(&LOGGER);
match logger {
Ok(res) => {
log::set_max_level(LevelFilter::Trace);
eprintln!("Success initializing Rust Logger to max level: {}", log::max_level());
()
}
Err(e) => {
eprintln!("Error initializing Rust Logger: {}", e);
}
}
}
4 changes: 3 additions & 1 deletion src/cli/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
pub mod config;
pub mod args;
pub mod config_env;
pub mod config_log;
pub mod args;
27 changes: 14 additions & 13 deletions src/client_thread.rs
Original file line number Diff line number Diff line change
@@ -1,40 +1,41 @@
use std::sync::mpsc;
use std::thread;

use cli::config;
use notary;
use proposer;
use message;

use std::sync::mpsc;
use std::thread;

/// A request to terminate a running thread
#[derive(Debug)]
pub enum Command {
Terminate
}

pub struct ClientThread {
pub handle: Option<thread::JoinHandle<()>>,
mode: config::Mode,
pub manager: Option<mpsc::Sender<Command>>
pub manager: Option<mpsc::Sender<Command>>,
pub handle: Option<thread::JoinHandle<()>>
}

impl ClientThread {
pub fn new(mode: &config::Mode) -> ClientThread {
match *mode {
config::Mode::Notary => {
ClientThread {
handle: None,
mode: mode.clone(),
manager: None
mode: mode.clone(),
manager: None,
handle: None
}
},
config::Mode::Proposer => {
ClientThread {
handle: None,
mode: mode.clone(),
manager: None
manager: None,
handle: None
}
},
_ => { panic!() }
_ => { panic!("Invalid mode provided to generate client thread instance"); }
}
}

Expand All @@ -48,7 +49,7 @@ impl ClientThread {
self.handle = Some(thread::Builder::new()
.name(config::Mode::Notary.value())
.spawn(move || {
notary.run();
notary.run();
})
.expect("Failed to spawn a notary thread"));
},
Expand All @@ -64,7 +65,7 @@ impl ClientThread {
})
.expect("Failed to spawn a proposer thread"));
}
_ => { panic!() }
_ => { panic!("Invalid mode provided to spawn new child thread from client thread instance") }
}
}
}
36 changes: 18 additions & 18 deletions src/collation/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub struct Header {
}

impl Header {
pub fn new(shard_id: ethereum_types::U256,
pub fn new(shard_id: ethereum_types::U256,
//parent_hash: ethereum_types::H256,
chunk_root: ethereum_types::H256,
period: ethereum_types::U256,
Expand Down Expand Up @@ -88,49 +88,49 @@ mod tests {
fn it_produces_correct_hash() {
// Build the args for collation header creation
// Shard Id
let sid = ethereum_types::U256::from_dec_str("1").unwrap();
let sid_bytes = u256_to_bytes32(sid);
let shard_id = ethereum_types::U256::from_dec_str("1").unwrap();
let shard_id_bytes = u256_to_bytes32(shard_id);

/*
// Parent Hash
let ph_bytes: [u8; 32] = [0x50, 0xa1, 0xb3, 0xd5, 0x14, 0xd4, 0x99, 0x63,
let parent_hash_bytes: [u8; 32] = [0x50, 0xa1, 0xb3, 0xd5, 0x14, 0xd4, 0x99, 0x63,
0x54, 0x14, 0x7a, 0xd2, 0x89, 0x61, 0x75, 0xb0,
0x7d, 0x43, 0x7f, 0x9e, 0x58, 0xfa, 0x3c, 0x44,
0x86, 0xc0, 0x42, 0xf4, 0xc3, 0xd5, 0x05, 0x9b];
let ph = ethereum_types::H256::from_slice(&ph_bytes[..]);
let parent_hash = ethereum_types::H256::from_slice(&parent_hash_bytes[..]);
*/

// Chunk Root
let cr_bytes: [u8; 32] = [0x50, 0xce, 0xc0, 0x49, 0x54, 0x77, 0xfb, 0x7e,
0x65, 0x25, 0xc2, 0xa0, 0x39, 0xa3, 0xa9, 0x95,
0x34, 0x90, 0x35, 0xb2, 0xa8, 0x23, 0xa4, 0x99,
0x0b, 0x27, 0xf6, 0xd7, 0xd5, 0x5e, 0xec, 0x6b];
let cr = ethereum_types::H256::from_slice(&cr_bytes[..]);
let chunk_root_bytes: [u8; 32] = [0x50, 0xce, 0xc0, 0x49, 0x54, 0x77, 0xfb, 0x7e,
0x65, 0x25, 0xc2, 0xa0, 0x39, 0xa3, 0xa9, 0x95,
0x34, 0x90, 0x35, 0xb2, 0xa8, 0x23, 0xa4, 0x99,
0x0b, 0x27, 0xf6, 0xd7, 0xd5, 0x5e, 0xec, 0x6b];
let chunk_root = ethereum_types::H256::from_slice(&chunk_root_bytes[..]);

// Period
let period = ethereum_types::U256::from_dec_str("1").unwrap();
let period_bytes = u256_to_bytes32(period);

// Proposer Address
let proposer_bytes: [u8; 20] = [0x39, 0xa4, 0x2d, 0x47, 0x4a,
let proposer_address_bytes: [u8; 20] = [0x39, 0xa4, 0x2d, 0x47, 0x4a,
0x52, 0x96, 0xab, 0x98, 0x52,
0x3b, 0x1a, 0x3d, 0xef, 0x8f,
0x18, 0x67, 0xad, 0x32, 0xb0];
let proposer = ethereum_types::H160::from_slice(&proposer_bytes[..]);
let proposer_address = ethereum_types::H160::from_slice(&proposer_address_bytes[..]);

// Create the header
let header = Header::new(sid, /*ph,*/ cr, period, proposer);
let header = Header::new(shard_id, /*parent_hash,*/ chunk_root, period, proposer_address);

// Calculate its generated hash
let header_hash = header.hash();

// Calculate the expected hash
let mut sha3 = tiny_keccak::Keccak::new_sha3_256();
sha3.update(&sid_bytes[..]);
//sha3.update(&ph_bytes[..]);
sha3.update(&cr_bytes[..]);
sha3.update(&shard_id_bytes[..]);
//sha3.update(&parent_hash_bytes[..]);
sha3.update(&chunk_root_bytes[..]);
sha3.update(&period_bytes[..]);
sha3.update(&proposer_bytes[..]);
sha3.update(&proposer_address_bytes[..]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for renaming the variables.


let mut expected_bytes: [u8; 32] = [0; 32];
sha3.finalize(&mut expected_bytes);
Expand Down
43 changes: 24 additions & 19 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
// External crates
extern crate ethereum_types;
extern crate tiny_keccak;
#[macro_use]
extern crate log;
extern crate chrono;

// Module declarations
pub mod cli;
Expand All @@ -24,11 +27,11 @@ use std::sync::mpsc;
///
/// config - A struct containing the configuration values for the client
pub fn run(config: cli::config::Config) -> () {
println!("Client Mode: {:?}", config.mode);
debug!("Client Mode: {:?}", config.mode);

match config.mode {
cli::config::Mode::Proposer => {
println!("Running as a proposer");
debug!("Running as a proposer");

// Create the SMC Listener
let (smc_tx, smc_rx) = mpsc::channel();
Expand All @@ -38,18 +41,19 @@ pub fn run(config: cli::config::Config) -> () {
let mut proposer_thread = client_thread::ClientThread::new(&config.mode);
proposer_thread.run(smc_rx);

// TODO make this part only run when running 'cargo test'
thread::sleep(Duration::from_secs(1));
let _result = proposer_thread.manager.unwrap().send(client_thread::Command::Terminate);
if cli::config_env::is_running_with_cargo_test() {
thread::sleep(Duration::from_secs(1));
let _result = proposer_thread.manager.unwrap().send(client_thread::Command::Terminate);
}

// Wait for thread termination
match proposer_thread.handle.unwrap().join() {
Ok(x) => { println!("Successful proposer thread join {:?}", x); () },
Ok(x) => { debug!("Successful proposer thread join {:?}", x); () },
Err(e) => { panic!("Failed proposer thread join {:?}", e); }
}
},
cli::config::Mode::Notary => {
println!("Running as a notary");
debug!("Running as a notary");

// Create the SMC Listener
let (smc_tx, smc_rx) = mpsc::channel();
Expand All @@ -59,18 +63,19 @@ pub fn run(config: cli::config::Config) -> () {
let mut notary_thread = client_thread::ClientThread::new(&config.mode);
notary_thread.run(smc_rx);

// TODO make this part only run when running 'cargo test'
thread::sleep(Duration::from_secs(1));
let _result = notary_thread.manager.unwrap().send(client_thread::Command::Terminate);
if cli::config_env::is_running_with_cargo_test() {
thread::sleep(Duration::from_secs(1));
let _result = notary_thread.manager.unwrap().send(client_thread::Command::Terminate);
}

// Wait for thread termination
match notary_thread.handle.unwrap().join() {
Ok(x) => { println!("Successful notary thread join {:?}", x); () },
Ok(x) => { debug!("Successful notary thread join {:?}", x); () },
Err(e) => { panic!("Failed notary thread join {:?}", e); }
}
},
cli::config::Mode::Both => {
println!("Running as both a proposer and notary");
debug!("Running as both a proposer and notary");

// Create the SMC Listeners
let (notary_smc_tx, notary_smc_rx) = mpsc::channel();
Expand All @@ -85,22 +90,22 @@ pub fn run(config: cli::config::Config) -> () {
proposer_thread.run(proposer_smc_rx);
notary_thread.run(notary_smc_rx);

// TODO make this part only run when running 'cargo test'
thread::sleep(Duration::from_secs(1));
let _p_result = proposer_thread.manager.unwrap().send(client_thread::Command::Terminate);
let _n_result = notary_thread.manager.unwrap().send(client_thread::Command::Terminate);
if cli::config_env::is_running_with_cargo_test() {
thread::sleep(Duration::from_secs(1));
let _p_result = proposer_thread.manager.unwrap().send(client_thread::Command::Terminate);
let _n_result = notary_thread.manager.unwrap().send(client_thread::Command::Terminate);
}

// Wait for thread termination
match proposer_thread.handle.unwrap().join() {
Ok(x) => { println!("Successful proposer thread join {:?}", x); () },
Ok(x) => { debug!("Successful proposer thread join {:?}", x); () },
Err(e) => { panic!("Failed proposer thread join {:?}", e); }
}
match notary_thread.handle.unwrap().join() {
Ok(x) => { println!("Successful notary thread join {:?}", x); () },
Ok(x) => { debug!("Successful notary thread join {:?}", x); () },
Err(e) => { panic!("Failed notary thread join {:?}", e); }
}
}
}
}


Loading