Banish stdin/stdout for ledger

step one: accept a "ledger file" argument instead of "outfile"
This commit is contained in:
Rob Walker 2018-07-12 14:29:36 -07:00
parent 4cca3ff454
commit a3ff40476e
3 changed files with 44 additions and 92 deletions

View File

@ -9,7 +9,7 @@ extern crate solana;
use atty::{is, Stream}; use atty::{is, Stream};
use clap::{App, Arg}; use clap::{App, Arg};
use solana::crdt::{NodeInfo, TestNode}; use solana::crdt::{NodeInfo, TestNode};
use solana::fullnode::{Config, FullNode, InFile, OutFile}; use solana::fullnode::{Config, FullNode, Ledger};
use solana::service::Service; use solana::service::Service;
use solana::signature::{KeyPair, KeyPairUtil}; use solana::signature::{KeyPair, KeyPairUtil};
use std::fs::File; use std::fs::File;
@ -37,12 +37,12 @@ fn main() -> () {
.help("testnet; connect to the network at this gossip entry point"), .help("testnet; connect to the network at this gossip entry point"),
) )
.arg( .arg(
Arg::with_name("output") Arg::with_name("ledger")
.short("o") .short("L")
.long("output") .long("ledger")
.value_name("FILE") .value_name("FILE")
.takes_value(true) .takes_value(true)
.help("output log to FILE, defaults to stdout (ignored by validators)"), .help("use FILE as persistent ledger (defaults to stdin/stdout)"),
) )
.get_matches(); .get_matches();
if is(Stream::Stdin) { if is(Stream::Stdin) {
@ -69,27 +69,22 @@ fn main() -> () {
exit(1); exit(1);
} }
} }
let ledger = if let Some(l) = matches.value_of("ledger") {
Ledger::Path(l.to_string())
} else {
Ledger::StdInOut
};
let mut node = TestNode::new_with_bind_addr(repl_data, bind_addr); let mut node = TestNode::new_with_bind_addr(repl_data, bind_addr);
let fullnode = if let Some(t) = matches.value_of("testnet") { let fullnode = if let Some(t) = matches.value_of("testnet") {
let testnet_address_string = t.to_string(); let testnet_address_string = t.to_string();
let testnet_addr = testnet_address_string.parse().unwrap(); let testnet_addr = testnet_address_string.parse().unwrap();
FullNode::new(
node, FullNode::new(node, false, ledger, Some(keypair), Some(testnet_addr))
false,
InFile::StdIn,
Some(keypair),
Some(testnet_addr),
None,
)
} else { } else {
node.data.leader_id = node.data.id; node.data.leader_id = node.data.id;
let outfile = if let Some(o) = matches.value_of("output") { FullNode::new(node, true, ledger, None, None)
OutFile::Path(o.to_string())
} else {
OutFile::StdOut
};
FullNode::new(node, true, InFile::StdIn, None, None, Some(outfile))
}; };
fullnode.join().expect("join"); fullnode.join().expect("join");
} }

View File

@ -12,7 +12,7 @@ use service::Service;
use signature::{KeyPair, KeyPairUtil}; use signature::{KeyPair, KeyPairUtil};
use std::collections::VecDeque; use std::collections::VecDeque;
use std::fs::{File, OpenOptions}; use std::fs::{File, OpenOptions};
use std::io::{sink, stdin, stdout, BufReader}; use std::io::{stdin, stdout, BufReader};
use std::io::{Read, Write}; use std::io::{Read, Write};
use std::net::SocketAddr; use std::net::SocketAddr;
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
@ -30,13 +30,8 @@ pub struct FullNode {
thread_hdls: Vec<JoinHandle<()>>, thread_hdls: Vec<JoinHandle<()>>,
} }
pub enum InFile { pub enum Ledger {
StdIn, StdInOut,
Path(String),
}
pub enum OutFile {
StdOut,
Path(String), Path(String),
} }
@ -66,16 +61,24 @@ impl FullNode {
pub fn new( pub fn new(
mut node: TestNode, mut node: TestNode,
leader: bool, leader: bool,
infile: InFile, ledger: Ledger,
keypair_for_validator: Option<KeyPair>, keypair_for_validator: Option<KeyPair>,
network_entry_for_validator: Option<SocketAddr>, network_entry_for_validator: Option<SocketAddr>,
outfile_for_leader: Option<OutFile>,
) -> FullNode { ) -> FullNode {
info!("creating bank..."); info!("creating bank...");
let bank = Bank::default(); let bank = Bank::default();
let infile: Box<Read> = match infile { let (infile, outfile): (Box<Read>, Box<Write + Send>) = match ledger {
InFile::Path(path) => Box::new(File::open(path).unwrap()), Ledger::Path(path) => (
InFile::StdIn => Box::new(stdin()), Box::new(File::open(path.clone()).expect("opening ledger file")),
Box::new(
OpenOptions::new()
.create(true)
.append(true)
.open(path)
.expect("opening ledger file"),
),
),
Ledger::StdInOut => (Box::new(stdin()), Box::new(stdout())),
}; };
let reader = BufReader::new(infile); let reader = BufReader::new(infile);
let entries = entry_writer::read_entries(reader).map(|e| e.expect("failed to parse entry")); let entries = entry_writer::read_entries(reader).map(|e| e.expect("failed to parse entry"));
@ -117,17 +120,6 @@ impl FullNode {
server server
} else { } else {
node.data.leader_id = node.data.id; node.data.leader_id = node.data.id;
let outfile_for_leader: Box<Write + Send> = match outfile_for_leader {
Some(OutFile::Path(file)) => Box::new(
OpenOptions::new()
.create(true)
.append(true)
.open(file)
.expect("opening ledger file"),
),
Some(OutFile::StdOut) => Box::new(stdout()),
None => Box::new(sink()),
};
let server = FullNode::new_leader( let server = FullNode::new_leader(
bank, bank,
@ -137,7 +129,7 @@ impl FullNode {
None, None,
node, node,
exit.clone(), exit.clone(),
outfile_for_leader, outfile,
); );
info!( info!(
"leader ready... local request address: {} (advertising {})", "leader ready... local request address: {} (advertising {})",

View File

@ -7,7 +7,7 @@ extern crate solana;
use solana::crdt::TestNode; use solana::crdt::TestNode;
use solana::crdt::{Crdt, NodeInfo}; use solana::crdt::{Crdt, NodeInfo};
use solana::entry_writer::EntryWriter; use solana::entry_writer::EntryWriter;
use solana::fullnode::{FullNode, InFile, OutFile}; use solana::fullnode::{FullNode, Ledger};
use solana::logger; use solana::logger;
use solana::mint::Mint; use solana::mint::Mint;
use solana::ncp::Ncp; use solana::ncp::Ncp;
@ -91,14 +91,7 @@ fn test_multi_node_validator_catchup_from_zero() {
let bob_pubkey = KeyPair::new().pubkey(); let bob_pubkey = KeyPair::new().pubkey();
let (alice, ledger_path) = genesis(10_000); let (alice, ledger_path) = genesis(10_000);
let server = FullNode::new( let server = FullNode::new(leader, true, Ledger::Path(ledger_path.clone()), None, None);
leader,
true,
InFile::Path(ledger_path.clone()),
None,
None,
None,
);
let mut nodes = vec![server]; let mut nodes = vec![server];
for _ in 0..N { for _ in 0..N {
let keypair = KeyPair::new(); let keypair = KeyPair::new();
@ -106,10 +99,9 @@ fn test_multi_node_validator_catchup_from_zero() {
let mut val = FullNode::new( let mut val = FullNode::new(
validator, validator,
false, false,
InFile::Path(ledger_path.clone()), Ledger::Path(ledger_path.clone()),
Some(keypair), Some(keypair),
Some(leader_data.contact_info.ncp), Some(leader_data.contact_info.ncp),
None,
); );
nodes.push(val); nodes.push(val);
} }
@ -141,10 +133,9 @@ fn test_multi_node_validator_catchup_from_zero() {
let val = FullNode::new( let val = FullNode::new(
validator, validator,
false, false,
InFile::Path(ledger_path.clone()), Ledger::Path(ledger_path.clone()),
Some(keypair), Some(keypair),
Some(leader_data.contact_info.ncp), Some(leader_data.contact_info.ncp),
None,
); );
nodes.push(val); nodes.push(val);
//contains the leader and new node //contains the leader and new node
@ -193,14 +184,7 @@ fn test_multi_node_basic() {
let leader_data = leader.data.clone(); let leader_data = leader.data.clone();
let bob_pubkey = KeyPair::new().pubkey(); let bob_pubkey = KeyPair::new().pubkey();
let (alice, ledger_path) = genesis(10_000); let (alice, ledger_path) = genesis(10_000);
let server = FullNode::new( let server = FullNode::new(leader, true, Ledger::Path(ledger_path.clone()), None, None);
leader,
true,
InFile::Path(ledger_path.clone()),
None,
None,
None,
);
let mut nodes = vec![server]; let mut nodes = vec![server];
for _ in 0..N { for _ in 0..N {
let keypair = KeyPair::new(); let keypair = KeyPair::new();
@ -208,10 +192,9 @@ fn test_multi_node_basic() {
let val = FullNode::new( let val = FullNode::new(
validator, validator,
false, false,
InFile::Path(ledger_path.clone()), Ledger::Path(ledger_path.clone()),
Some(keypair), Some(keypair),
Some(leader_data.contact_info.ncp), Some(leader_data.contact_info.ncp),
None,
); );
nodes.push(val); nodes.push(val);
} }
@ -248,14 +231,8 @@ fn test_boot_validator_from_file() {
let bob_pubkey = KeyPair::new().pubkey(); let bob_pubkey = KeyPair::new().pubkey();
let (alice, ledger_path) = genesis(100_000); let (alice, ledger_path) = genesis(100_000);
let leader_data = leader.data.clone(); let leader_data = leader.data.clone();
let leader_fullnode = FullNode::new( let leader_fullnode =
leader, FullNode::new(leader, true, Ledger::Path(ledger_path.clone()), None, None);
true,
InFile::Path(ledger_path.clone()),
None,
None,
Some(OutFile::Path(ledger_path.clone())),
);
let leader_balance = let leader_balance =
send_tx_and_retry_get_balance(&leader_data, &alice, &bob_pubkey, Some(500)).unwrap(); send_tx_and_retry_get_balance(&leader_data, &alice, &bob_pubkey, Some(500)).unwrap();
assert_eq!(leader_balance, 500); assert_eq!(leader_balance, 500);
@ -269,12 +246,10 @@ fn test_boot_validator_from_file() {
let val_fullnode = FullNode::new( let val_fullnode = FullNode::new(
validator, validator,
false, false,
InFile::Path(ledger_path.clone()), Ledger::Path(ledger_path.clone()),
Some(keypair), Some(keypair),
Some(leader_data.contact_info.ncp), Some(leader_data.contact_info.ncp),
None,
); );
let mut client = mk_client(&validator_data); let mut client = mk_client(&validator_data);
let getbal = retry_get_balance(&mut client, &bob_pubkey, Some(leader_balance)); let getbal = retry_get_balance(&mut client, &bob_pubkey, Some(leader_balance));
assert!(getbal == Some(leader_balance)); assert!(getbal == Some(leader_balance));
@ -290,10 +265,9 @@ fn create_leader(ledger_path: &str) -> (NodeInfo, FullNode) {
let leader_fullnode = FullNode::new( let leader_fullnode = FullNode::new(
leader, leader,
true, true,
InFile::Path(ledger_path.to_string()), Ledger::Path(ledger_path.to_string()),
None, None,
None, None,
Some(OutFile::Path(ledger_path.to_string())),
); );
(leader_data, leader_fullnode) (leader_data, leader_fullnode)
} }
@ -342,10 +316,9 @@ fn test_leader_restart_validator_start_from_old_ledger() {
let val_fullnode = FullNode::new( let val_fullnode = FullNode::new(
validator, validator,
false, false,
InFile::Path(stale_ledger_path.clone()), Ledger::Path(stale_ledger_path.clone()),
Some(keypair), Some(keypair),
Some(leader_data.contact_info.ncp), Some(leader_data.contact_info.ncp),
None,
); );
// trigger broadcast, validator should catch up from leader, whose window contains // trigger broadcast, validator should catch up from leader, whose window contains
@ -383,14 +356,7 @@ fn test_multi_node_dynamic_network() {
let bob_pubkey = KeyPair::new().pubkey(); let bob_pubkey = KeyPair::new().pubkey();
let (alice, ledger_path) = genesis(100_000); let (alice, ledger_path) = genesis(100_000);
let leader_data = leader.data.clone(); let leader_data = leader.data.clone();
let server = FullNode::new( let server = FullNode::new(leader, true, Ledger::Path(ledger_path.clone()), None, None);
leader,
true,
InFile::Path(ledger_path.clone()),
None,
None,
Some(OutFile::Path(ledger_path.clone())),
);
info!("{:x} LEADER", leader_data.debug_id()); info!("{:x} LEADER", leader_data.debug_id());
let leader_balance = let leader_balance =
send_tx_and_retry_get_balance(&leader_data, &alice, &bob_pubkey, Some(500)).unwrap(); send_tx_and_retry_get_balance(&leader_data, &alice, &bob_pubkey, Some(500)).unwrap();
@ -412,10 +378,9 @@ fn test_multi_node_dynamic_network() {
let val = FullNode::new( let val = FullNode::new(
validator, validator,
false, false,
InFile::Path(ledger_path.clone()), Ledger::Path(ledger_path.clone()),
Some(keypair), Some(keypair),
Some(leader_data.contact_info.ncp), Some(leader_data.contact_info.ncp),
Some(OutFile::Path(ledger_path.clone())),
); );
info!("started[{}/{}] {:x}", n, N, rd.debug_id()); info!("started[{}/{}] {:x}", n, N, rd.debug_id());
(rd, val) (rd, val)