solana/src/bin/drone.rs

160 lines
5.1 KiB
Rust
Raw Normal View History

2018-06-19 21:40:44 -07:00
extern crate bincode;
extern crate clap;
2018-06-19 21:40:44 -07:00
extern crate env_logger;
extern crate serde_json;
extern crate solana;
extern crate tokio;
extern crate tokio_codec;
extern crate tokio_io;
use bincode::deserialize;
use clap::{App, Arg};
2018-07-02 13:45:40 -07:00
use solana::crdt::ReplicatedData;
2018-06-19 21:40:44 -07:00
use solana::drone::{Drone, DroneRequest};
use solana::mint::Mint;
use std::error;
use std::fs::File;
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
2018-06-19 21:40:44 -07:00
use std::process::exit;
use std::sync::{Arc, Mutex};
use std::thread;
2018-06-19 21:40:44 -07:00
use tokio::net::TcpListener;
use tokio::prelude::*;
use tokio_codec::{BytesCodec, Decoder};
2018-06-19 21:40:44 -07:00
fn main() {
env_logger::init();
let matches = App::new("solana-client-demo")
.arg(
Arg::with_name("leader")
.short("l")
.long("leader")
.value_name("PATH")
.takes_value(true)
.help("/path/to/leader.json"),
)
.arg(
Arg::with_name("mint")
.short("m")
.long("mint")
.value_name("PATH")
.takes_value(true)
.help("/path/to/mint.json"),
)
.arg(
Arg::with_name("time")
.short("t")
.long("time")
.value_name("SECONDS")
.takes_value(true)
.help("time slice over which to limit requests to drone"),
)
.arg(
Arg::with_name("cap")
.short("c")
.long("cap")
.value_name("NUMBER")
.takes_value(true)
.help("request limit for time slice"),
)
.get_matches();
let leader: ReplicatedData;
if let Some(l) = matches.value_of("leader") {
leader = read_leader(l.to_string());
} else {
let server_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 8000);
leader = ReplicatedData::new_leader(&server_addr);
};
let mint: Mint;
if let Some(m) = matches.value_of("mint") {
mint = read_mint(m.to_string()).expect("client mint");
} else {
eprintln!("No mint found!");
exit(1);
2018-06-19 21:40:44 -07:00
};
let time_slice: Option<u64>;
if let Some(t) = matches.value_of("time") {
time_slice = Some(t.to_string().parse().expect("integer"));
} else {
2018-06-19 21:40:44 -07:00
time_slice = None;
}
let request_cap: Option<u64>;
if let Some(c) = matches.value_of("cap") {
request_cap = Some(c.to_string().parse().expect("integer"));
} else {
2018-06-19 21:40:44 -07:00
request_cap = None;
}
let mint_keypair = mint.keypair();
2018-06-19 21:40:44 -07:00
2018-07-02 13:45:40 -07:00
let drone_addr: SocketAddr = "0.0.0.0:9900".parse().unwrap();
let drone = Arc::new(Mutex::new(Drone::new(
mint_keypair,
drone_addr,
2018-07-09 15:53:49 -07:00
leader.addrs.transactions,
leader.addrs.requests,
time_slice,
request_cap,
)));
let drone1 = drone.clone();
thread::spawn(move || loop {
let time = drone1.lock().unwrap().time_slice;
thread::sleep(time);
drone1.lock().unwrap().clear_request_count();
});
2018-06-19 21:40:44 -07:00
let socket = TcpListener::bind(&drone_addr).unwrap();
println!("Drone started. Listening on: {}", drone_addr);
2018-06-19 21:40:44 -07:00
let done = socket
.incoming()
.map_err(|e| println!("failed to accept socket; error = {:?}", e))
.for_each(move |socket| {
let drone2 = drone.clone();
// let client_ip = socket.peer_addr().expect("drone peer_addr").ip();
2018-06-19 21:40:44 -07:00
let framed = BytesCodec::new().framed(socket);
let (_writer, reader) = framed.split();
let processor = reader
.for_each(move |bytes| {
let req: DroneRequest =
deserialize(&bytes).expect("deserialize packet in drone");
println!("Airdrop requested...");
// let res = drone2.lock().unwrap().check_rate_limit(client_ip);
let res1 = drone2.lock().unwrap().send_airdrop(req);
match res1 {
Ok(_) => println!("Airdrop sent!"),
Err(_) => println!("Request limit reached for this time slice"),
}
2018-06-19 21:40:44 -07:00
Ok(())
})
.and_then(|()| {
println!("Socket received FIN packet and closed connection");
Ok(())
})
.or_else(|err| {
println!("Socket closed with error: {:?}", err);
Err(err)
})
.then(|result| {
println!("Socket closed with result: {:?}", result);
Ok(())
});
tokio::spawn(processor)
});
tokio::run(done);
}
fn read_leader(path: String) -> ReplicatedData {
let file = File::open(path.clone()).expect(&format!("file not found: {}", path));
serde_json::from_reader(file).expect(&format!("failed to parse {}", path))
}
fn read_mint(path: String) -> Result<Mint, Box<error::Error>> {
let file = File::open(path.clone())?;
let mint = serde_json::from_reader(file)?;
Ok(mint)
}