hydrabadger/src/bin/peer_node.rs

184 lines
6.1 KiB
Rust
Raw Permalink Normal View History

2018-07-02 19:36:12 -07:00
#![allow(unused_imports, dead_code, unused_variables)]
2018-09-28 06:13:31 -07:00
extern crate chrono;
2018-07-02 19:36:12 -07:00
extern crate clap;
extern crate env_logger;
extern crate hydrabadger;
extern crate rand;
#[macro_use]
extern crate serde_derive;
2018-07-02 19:36:12 -07:00
2018-09-28 06:13:31 -07:00
use chrono::Local;
use clap::{App, Arg, ArgMatches};
2018-12-13 20:19:19 -08:00
use hydrabadger::{Blockchain, Config, Hydrabadger, MiningError, Uid};
2019-08-13 00:38:55 -07:00
use rand::{distributions::Standard, Rng};
2018-07-02 19:36:12 -07:00
use std::collections::HashSet;
use std::env;
use std::io::Write;
2018-09-28 06:13:31 -07:00
use std::net::{SocketAddr, ToSocketAddrs};
2018-07-02 19:36:12 -07:00
/// Returns parsed command line arguments.
fn arg_matches<'a>() -> ArgMatches<'a> {
App::new("hydrabadger")
.version("0.1")
.author("Nick Sanders <cogciprocate@gmail.com>")
.about("Evaluation and testing for hbbft")
.arg(Arg::with_name("bind-address")
.short("b")
.long("bind-address")
.value_name("<HOST:PORT>")
.help("Specifies the local address to listen on.")
.takes_value(true)
.required(true))
.arg(Arg::with_name("remote-address")
.short("r")
.long("remote-address")
.help("Specifies a list of remote node addresses to connect to.")
.value_name("<HOST:PORT>")
.takes_value(true)
.multiple(true)
.number_of_values(1))
2018-07-23 09:04:10 -07:00
.arg(Arg::with_name("batch-size")
.long("batch-size")
.value_name("BATCH_SIZE")
.help("Specifies the number of transactions per batch.")
.takes_value(true))
.arg(Arg::with_name("txn-gen-count")
.long("txn-gen-count")
.value_name("TXN_GEN_COUNT")
.help("Specifies the number of random transactions to generate each interval.")
.takes_value(true))
.arg(Arg::with_name("txn-gen-interval")
.long("txn-gen-interval")
.value_name("TXN_GEN_INTERVAL")
.help("Specifies amount of time in milliseconds between each round of random \
transaction input generation.")
.takes_value(true))
.arg(Arg::with_name("txn-bytes")
.long("txn-bytes")
.value_name("TXN_BYTES")
.help("Specifies the size of each randomly generated transaction in bytes.")
.takes_value(true))
.arg(Arg::with_name("keygen-node-count")
.long("keygen-node-count")
.value_name("KEYGEN_NODE_COUNT")
.help("Specifies the minimum number of nodes that must be connected, including the \
local node, before a consensus network will initialize. All nodes participating in \
network bootstrapping must have the same value. This setting has no effect when \
when connecting to pre-existing networks which have already undergone the \
bootstrap process.")
.takes_value(true))
.arg(Arg::with_name("output-extra-delay")
.long("output-extra-delay")
.value_name("EXTRA_DELAY")
.help("Specifies the amount of time to wait after outputting a batch in \
milliseconds. This can make reading or parsing logs more managable.")
.takes_value(true))
2018-07-02 19:36:12 -07:00
.get_matches()
}
/// Begins mining.
fn mine() -> Result<(), MiningError> {
let mut chain = Blockchain::new()?;
println!("Send 1 Hydradollar to Bob");
chain.add_block("1HD->Bob")?;
chain.add_block("0.5HD->Bob")?;
chain.add_block("1.5HD->Bob")?;
println!("Traversing blockchain:\n");
chain.traverse();
Ok(())
}
/// A transaction.
#[derive(Serialize, Deserialize, Eq, PartialEq, Hash, Ord, PartialOrd, Debug, Clone)]
pub struct Transaction(pub Vec<u8>);
impl Transaction {
fn random(len: usize) -> Transaction {
2019-08-13 00:38:55 -07:00
Transaction(
rand::thread_rng()
.sample_iter(&Standard)
.take(len)
.collect(),
)
}
}
2018-07-02 19:36:12 -07:00
fn main() {
env_logger::Builder::new()
.format(|buf, record| {
writeln!(
2018-09-28 06:13:31 -07:00
buf,
"{} [{}]: {}",
Local::now().format("%Y-%m-%dT%H:%M:%S"),
record.level(),
record.args()
)
})
.parse(&env::var("HYDRABADGER_LOG").unwrap_or_default())
2018-09-28 06:13:31 -07:00
.try_init()
.ok();
2018-07-02 19:36:12 -07:00
let matches = arg_matches();
2018-09-28 06:13:31 -07:00
let bind_address: SocketAddr = matches
.value_of("bind-address")
2018-07-23 09:04:10 -07:00
// TODO: Consider providing a default (and add to help info above).
2018-07-02 19:36:12 -07:00
.expect("No bind address provided")
2018-07-23 09:04:10 -07:00
// .unwrap_or("localhost::3070")
2018-07-02 19:36:12 -07:00
.to_socket_addrs()
.expect("Invalid bind address")
2018-09-28 06:13:31 -07:00
.next()
.unwrap();
2018-07-02 19:36:12 -07:00
let remote_addresses: HashSet<SocketAddr> = match matches.values_of("remote-address") {
2018-09-28 06:13:31 -07:00
Some(addrs) => addrs
.flat_map(|addr| addr.to_socket_addrs().expect("Invalid remote address"))
2018-07-02 19:36:12 -07:00
.collect(),
None => HashSet::new(),
};
2018-08-04 18:54:30 -07:00
let mut cfg = Config::default();
2018-07-23 09:04:10 -07:00
if let Some(tgc) = matches.value_of("txn-gen-count") {
cfg.txn_gen_count = tgc.parse().expect("Invalid transaction generation count.");
}
if let Some(tgi) = matches.value_of("txn-gen-interval") {
2018-09-28 06:13:31 -07:00
cfg.txn_gen_interval = tgi
.parse()
.expect("Invalid transaction generation interval.");
2018-07-23 09:04:10 -07:00
}
if let Some(tgb) = matches.value_of("txn-bytes") {
cfg.txn_gen_bytes = tgb.parse().expect("Invalid transaction size (bytes).");
2018-07-23 09:04:10 -07:00
}
if let Some(knc) = matches.value_of("keygen-node-count") {
2018-09-28 06:13:31 -07:00
cfg.keygen_peer_count = knc
.parse::<usize>()
2018-07-23 09:04:10 -07:00
.expect("Invalid minimum keygen node count.")
- 1;
}
if let Some(oed) = matches.value_of("output-extra-delay") {
cfg.output_extra_delay_ms = oed.parse().expect("Invalid output extra delay.");
}
2018-07-02 19:36:12 -07:00
2018-12-13 20:19:19 -08:00
let hb = Hydrabadger::new(bind_address, cfg, Uid::new());
let gen_txn = |txn_gen_count, txn_gen_bytes| {
2018-09-28 06:13:31 -07:00
(0..txn_gen_count)
.map(|_| Transaction::random(txn_gen_bytes))
.collect::<Vec<_>>()
};
hb.run_node(Some(remote_addresses), Some(gen_txn));
2018-07-02 19:36:12 -07:00
// match mine() {
// Ok(_) => {},
// Err(err) => println!("Error: {}", err),
// }
2018-09-28 06:13:31 -07:00
}