generic array fail case
This commit is contained in:
committed by
Greg Fitzgerald
parent
d5be23dffe
commit
88503c2a09
@ -36,7 +36,12 @@ fn main() {
|
|||||||
let mut opts = Options::new();
|
let mut opts = Options::new();
|
||||||
opts.optflag("h", "help", "print help");
|
opts.optflag("h", "help", "print help");
|
||||||
opts.optopt("l", "", "run with the identity found in FILE", "FILE");
|
opts.optopt("l", "", "run with the identity found in FILE", "FILE");
|
||||||
opts.optopt("v", "", "validate; find leader's identity in FILE", "FILE");
|
opts.optopt(
|
||||||
|
"t",
|
||||||
|
"",
|
||||||
|
"testnet; connec to the network at this gossip entry point",
|
||||||
|
"host:port",
|
||||||
|
);
|
||||||
opts.optopt(
|
opts.optopt(
|
||||||
"o",
|
"o",
|
||||||
"",
|
"",
|
||||||
@ -119,14 +124,14 @@ fn main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let exit = Arc::new(AtomicBool::new(false));
|
let exit = Arc::new(AtomicBool::new(false));
|
||||||
let threads = if matches.opt_present("v") {
|
let threads = if matches.opt_present("t") {
|
||||||
let path = matches.opt_str("v").unwrap();
|
let testnet = matches.opt_str("t").unwrap();
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"starting validator... {} using {}",
|
"starting validator... {} connecting to {}",
|
||||||
repl_data.requests_addr, path
|
repl_data.requests_addr, testnet
|
||||||
);
|
);
|
||||||
let file = File::open(path.clone()).expect(&format!("file not found: {}", path));
|
let taddr = testnet.parse().unwrap();
|
||||||
let leader = serde_json::from_reader(file).expect("parse");
|
let entry = ReplicatedData::new_entry_point(taddr);
|
||||||
let s = Server::new_validator(
|
let s = Server::new_validator(
|
||||||
bank,
|
bank,
|
||||||
repl_data.clone(),
|
repl_data.clone(),
|
||||||
@ -135,7 +140,7 @@ fn main() {
|
|||||||
UdpSocket::bind(repl_data.replicate_addr).unwrap(),
|
UdpSocket::bind(repl_data.replicate_addr).unwrap(),
|
||||||
UdpSocket::bind(repl_data.gossip_addr).unwrap(),
|
UdpSocket::bind(repl_data.gossip_addr).unwrap(),
|
||||||
UdpSocket::bind(repl_data.repair_addr).unwrap(),
|
UdpSocket::bind(repl_data.repair_addr).unwrap(),
|
||||||
leader,
|
entry,
|
||||||
exit.clone(),
|
exit.clone(),
|
||||||
);
|
);
|
||||||
s.thread_hdls
|
s.thread_hdls
|
||||||
|
72
src/crdt.rs
72
src/crdt.rs
@ -551,6 +551,33 @@ impl Crdt {
|
|||||||
blob_sender.send(q)?;
|
blob_sender.send(q)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
/// FIXME: This is obviously the wrong way to do this. Need to implement leader selection
|
||||||
|
fn top_leader(&self) -> Option<PublicKey> {
|
||||||
|
let mut table = HashMap::new();
|
||||||
|
let def = PublicKey::default();
|
||||||
|
let cur = self.table.values().filter(|x| x.current_leader_id != def);
|
||||||
|
for v in cur {
|
||||||
|
let cnt = table.entry(&v.current_leader_id).or_insert(0);
|
||||||
|
//let cnt = table.get_mut(&v.current_leader_id).unwrap();
|
||||||
|
*cnt += 1;
|
||||||
|
println!("leader {:?} {}", &v.current_leader_id[..4], *cnt);
|
||||||
|
}
|
||||||
|
let mut sorted: Vec<_> = table.iter().collect();
|
||||||
|
sorted.sort_by_key(|a| a.1);
|
||||||
|
sorted.last().map(|a| *(*(*a).0))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// FIXME: This is obviously the wrong way to do this. Need to implement leader selection
|
||||||
|
/// A t-shirt for the first person to actually use this bad behavior to attack the alpha testnet
|
||||||
|
fn update_leader(&mut self) {
|
||||||
|
if let Some(lid) = self.top_leader() {
|
||||||
|
if self.my_data().current_leader_id != lid {
|
||||||
|
if self.table.get(&lid).is_some() {
|
||||||
|
self.set_leader(lid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Apply updates that we received from the identity `from`
|
/// Apply updates that we received from the identity `from`
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
@ -577,6 +604,7 @@ impl Crdt {
|
|||||||
Builder::new()
|
Builder::new()
|
||||||
.name("solana-gossip".to_string())
|
.name("solana-gossip".to_string())
|
||||||
.spawn(move || loop {
|
.spawn(move || loop {
|
||||||
|
let start = timestamp();
|
||||||
let _ = Self::run_gossip(&obj, &blob_sender, &blob_recycler);
|
let _ = Self::run_gossip(&obj, &blob_sender, &blob_recycler);
|
||||||
obj.write().unwrap().purge(timestamp());
|
obj.write().unwrap().purge(timestamp());
|
||||||
if exit.load(Ordering::Relaxed) {
|
if exit.load(Ordering::Relaxed) {
|
||||||
@ -584,7 +612,12 @@ impl Crdt {
|
|||||||
}
|
}
|
||||||
//TODO: possibly tune this parameter
|
//TODO: possibly tune this parameter
|
||||||
//we saw a deadlock passing an obj.read().unwrap().timeout into sleep
|
//we saw a deadlock passing an obj.read().unwrap().timeout into sleep
|
||||||
sleep(Duration::from_millis(GOSSIP_SLEEP_MILLIS));
|
let _ = obj.write().unwrap().update_leader();
|
||||||
|
let elapsed = timestamp() - start;
|
||||||
|
if GOSSIP_SLEEP_MILLIS > elapsed {
|
||||||
|
let left = GOSSIP_SLEEP_MILLIS - elapsed;
|
||||||
|
sleep(Duration::from_millis(left));
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
@ -825,6 +858,7 @@ mod tests {
|
|||||||
use packet::BlobRecycler;
|
use packet::BlobRecycler;
|
||||||
use result::Error;
|
use result::Error;
|
||||||
use signature::{KeyPair, KeyPairUtil};
|
use signature::{KeyPair, KeyPairUtil};
|
||||||
|
use std::collections::HashMap;
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::sync::mpsc::channel;
|
use std::sync::mpsc::channel;
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
@ -1166,4 +1200,40 @@ mod tests {
|
|||||||
assert_eq!(blob.get_id().unwrap(), id);
|
assert_eq!(blob.get_id().unwrap(), id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/// FIXME: This is obviously the wrong way to do this. Need to implement leader selection,
|
||||||
|
/// delete this test after leader selection is correctly implemented
|
||||||
|
#[test]
|
||||||
|
fn test_update_leader() {
|
||||||
|
let me = ReplicatedData::new_leader(&"127.0.0.1:1234".parse().unwrap());
|
||||||
|
let lead = ReplicatedData::new_leader(&"127.0.0.1:1234".parse().unwrap());
|
||||||
|
let lead2 = ReplicatedData::new_leader(&"127.0.0.1:1234".parse().unwrap());
|
||||||
|
let mut crdt = Crdt::new(me.clone());
|
||||||
|
assert_matches!(crdt.top_leader(), None);
|
||||||
|
crdt.set_leader(lead.id);
|
||||||
|
assert_eq!(crdt.top_leader().unwrap(), lead.id);
|
||||||
|
//add a bunch of nodes with a new leader
|
||||||
|
for _ in 0..10 {
|
||||||
|
let mut dum = ReplicatedData::new_entry_point("127.0.0.1:1234".parse().unwrap());
|
||||||
|
dum.current_leader_id = lead2.id;
|
||||||
|
crdt.insert(&dum);
|
||||||
|
}
|
||||||
|
assert_eq!(crdt.top_leader().unwrap(), lead2.id);
|
||||||
|
crdt.update_leader();
|
||||||
|
assert_eq!(crdt.my_data().current_leader_id, lead.id);
|
||||||
|
crdt.insert(&lead2);
|
||||||
|
crdt.update_leader();
|
||||||
|
assert_eq!(crdt.my_data().current_leader_id, lead2.id);
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn test_update_leader_pubkeys() {
|
||||||
|
let key1 = ReplicatedData::new_entry_point("127.0.0.1:1234".parse().unwrap());
|
||||||
|
let key2 = ReplicatedData::new_entry_point("127.0.0.1:1234".parse().unwrap());
|
||||||
|
let mut table = HashMap::new();
|
||||||
|
table.entry(&key1.current_leader_id).or_insert(0);
|
||||||
|
for _ in 0..1000 {
|
||||||
|
let a = table.entry(&key2.current_leader_id).or_insert(0);
|
||||||
|
*a += 1;
|
||||||
|
}
|
||||||
|
assert_eq!(table.len(), 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -134,7 +134,7 @@ impl Server {
|
|||||||
replicate_socket: UdpSocket,
|
replicate_socket: UdpSocket,
|
||||||
gossip_listen_socket: UdpSocket,
|
gossip_listen_socket: UdpSocket,
|
||||||
repair_socket: UdpSocket,
|
repair_socket: UdpSocket,
|
||||||
leader_repl_data: ReplicatedData,
|
entry_point: ReplicatedData,
|
||||||
exit: Arc<AtomicBool>,
|
exit: Arc<AtomicBool>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let bank = Arc::new(bank);
|
let bank = Arc::new(bank);
|
||||||
@ -143,12 +143,9 @@ impl Server {
|
|||||||
thread_hdls.extend(rpu.thread_hdls);
|
thread_hdls.extend(rpu.thread_hdls);
|
||||||
|
|
||||||
let crdt = Arc::new(RwLock::new(Crdt::new(me)));
|
let crdt = Arc::new(RwLock::new(Crdt::new(me)));
|
||||||
crdt.write()
|
|
||||||
.expect("'crdt' write lock in pub fn replicate")
|
|
||||||
.set_leader(leader_repl_data.id);
|
|
||||||
crdt.write()
|
crdt.write()
|
||||||
.expect("'crdt' write lock before insert() in pub fn replicate")
|
.expect("'crdt' write lock before insert() in pub fn replicate")
|
||||||
.insert(&leader_repl_data);
|
.insert(&entry_point);
|
||||||
let window = streamer::default_window();
|
let window = streamer::default_window();
|
||||||
let gossip_send_socket = UdpSocket::bind("0.0.0.0:0").expect("bind 0");
|
let gossip_send_socket = UdpSocket::bind("0.0.0.0:0").expect("bind 0");
|
||||||
let retransmit_socket = UdpSocket::bind("0.0.0.0:0").expect("bind 0");
|
let retransmit_socket = UdpSocket::bind("0.0.0.0:0").expect("bind 0");
|
||||||
|
Reference in New Issue
Block a user