Vote contract (#1552)

* Add Vote Contract

* Move ownership of LeaderScheduler from Fullnode to the bank

* Modified ReplicateStage to consume leader information from bank

* Restart RPC Services in Leader To Validator Transition

* Make VoteContract Context Free

* Remove voting from ClusterInfo and Tpu

* Remove dependency on ActiveValidators in LeaderScheduler

* Switch VoteContract to have two steps 1) Register 2) Vote. Change thin client to create + register a voting account on fullnode startup

* Remove check in leader_to_validator transition for unique references to bank, b/c jsonrpc service and rpcpubsub hold references through jsonhttpserver
This commit is contained in:
carllin
2018-10-25 16:58:40 -07:00
committed by GitHub
parent 160cff4a30
commit f6c8e1a4bf
27 changed files with 1190 additions and 1195 deletions

View File

@ -109,7 +109,7 @@ fn make_tiny_test_entries(start_hash: Hash, num: usize) -> Vec<Entry> {
fn test_multi_node_ledger_window() -> result::Result<()> {
logger::setup();
let leader_keypair = Keypair::new();
let leader_keypair = Arc::new(Keypair::new());
let leader_pubkey = leader_keypair.pubkey().clone();
let leader = Node::new_localhost_with_pubkey(leader_keypair.pubkey());
let leader_data = leader.info.clone();
@ -136,6 +136,7 @@ fn test_multi_node_ledger_window() -> result::Result<()> {
leader,
&leader_ledger_path,
leader_keypair,
Arc::new(Keypair::new()),
None,
false,
LeaderScheduler::from_bootstrap_leader(leader_pubkey),
@ -148,7 +149,7 @@ fn test_multi_node_ledger_window() -> result::Result<()> {
// start up another validator from zero, converge and then check
// balances
let keypair = Keypair::new();
let keypair = Arc::new(Keypair::new());
let validator_pubkey = keypair.pubkey().clone();
let validator = Node::new_localhost_with_pubkey(keypair.pubkey());
let validator_data = validator.info.clone();
@ -156,6 +157,7 @@ fn test_multi_node_ledger_window() -> result::Result<()> {
validator,
&zero_ledger_path,
keypair,
Arc::new(Keypair::new()),
Some(leader_data.contact_info.ncp),
false,
LeaderScheduler::from_bootstrap_leader(leader_pubkey),
@ -206,7 +208,7 @@ fn test_multi_node_validator_catchup_from_zero() -> result::Result<()> {
logger::setup();
const N: usize = 5;
trace!("test_multi_node_validator_catchup_from_zero");
let leader_keypair = Keypair::new();
let leader_keypair = Arc::new(Keypair::new());
let leader_pubkey = leader_keypair.pubkey().clone();
let leader = Node::new_localhost_with_pubkey(leader_keypair.pubkey());
let leader_data = leader.info.clone();
@ -227,6 +229,7 @@ fn test_multi_node_validator_catchup_from_zero() -> result::Result<()> {
leader,
&leader_ledger_path,
leader_keypair,
Arc::new(Keypair::new()),
None,
false,
LeaderScheduler::from_bootstrap_leader(leader_pubkey),
@ -239,7 +242,7 @@ fn test_multi_node_validator_catchup_from_zero() -> result::Result<()> {
let mut nodes = vec![server];
for _ in 0..N {
let keypair = Keypair::new();
let keypair = Arc::new(Keypair::new());
let validator_pubkey = keypair.pubkey().clone();
let validator = Node::new_localhost_with_pubkey(keypair.pubkey());
let ledger_path = tmp_copy_ledger(
@ -258,6 +261,7 @@ fn test_multi_node_validator_catchup_from_zero() -> result::Result<()> {
validator,
&ledger_path,
keypair,
Arc::new(Keypair::new()),
Some(leader_data.contact_info.ncp),
false,
LeaderScheduler::from_bootstrap_leader(leader_pubkey),
@ -288,12 +292,13 @@ fn test_multi_node_validator_catchup_from_zero() -> result::Result<()> {
success = 0;
// start up another validator from zero, converge and then check everyone's
// balances
let keypair = Keypair::new();
let keypair = Arc::new(Keypair::new());
let validator = Node::new_localhost_with_pubkey(keypair.pubkey());
let val = Fullnode::new(
validator,
&zero_ledger_path,
keypair,
Arc::new(Keypair::new()),
Some(leader_data.contact_info.ncp),
false,
LeaderScheduler::from_bootstrap_leader(leader_pubkey),
@ -347,7 +352,7 @@ fn test_multi_node_basic() {
logger::setup();
const N: usize = 5;
trace!("test_multi_node_basic");
let leader_keypair = Keypair::new();
let leader_keypair = Arc::new(Keypair::new());
let leader_pubkey = leader_keypair.pubkey().clone();
let leader = Node::new_localhost_with_pubkey(leader_keypair.pubkey());
let leader_data = leader.info.clone();
@ -360,6 +365,7 @@ fn test_multi_node_basic() {
leader,
&leader_ledger_path,
leader_keypair,
Arc::new(Keypair::new()),
None,
false,
LeaderScheduler::from_bootstrap_leader(leader_pubkey),
@ -372,7 +378,7 @@ fn test_multi_node_basic() {
let mut nodes = vec![server];
for _ in 0..N {
let keypair = Keypair::new();
let keypair = Arc::new(Keypair::new());
let validator_pubkey = keypair.pubkey().clone();
let validator = Node::new_localhost_with_pubkey(keypair.pubkey());
let ledger_path = tmp_copy_ledger(&leader_ledger_path, "multi_node_basic");
@ -388,6 +394,7 @@ fn test_multi_node_basic() {
validator,
&ledger_path,
keypair,
Arc::new(Keypair::new()),
Some(leader_data.contact_info.ncp),
false,
LeaderScheduler::from_bootstrap_leader(leader_pubkey),
@ -426,7 +433,7 @@ fn test_multi_node_basic() {
#[ignore]
fn test_boot_validator_from_file() -> result::Result<()> {
logger::setup();
let leader_keypair = Keypair::new();
let leader_keypair = Arc::new(Keypair::new());
let leader_pubkey = leader_keypair.pubkey();
let leader = Node::new_localhost_with_pubkey(leader_keypair.pubkey());
let bob_pubkey = Keypair::new().pubkey();
@ -439,6 +446,7 @@ fn test_boot_validator_from_file() -> result::Result<()> {
leader,
&leader_ledger_path,
leader_keypair,
Arc::new(Keypair::new()),
None,
false,
LeaderScheduler::from_bootstrap_leader(leader_pubkey),
@ -450,7 +458,7 @@ fn test_boot_validator_from_file() -> result::Result<()> {
send_tx_and_retry_get_balance(&leader_data, &alice, &bob_pubkey, 500, Some(1000)).unwrap();
assert_eq!(leader_balance, 1000);
let keypair = Keypair::new();
let keypair = Arc::new(Keypair::new());
let validator = Node::new_localhost_with_pubkey(keypair.pubkey());
let validator_data = validator.info.clone();
let ledger_path = tmp_copy_ledger(&leader_ledger_path, "boot_validator_from_file");
@ -459,6 +467,7 @@ fn test_boot_validator_from_file() -> result::Result<()> {
validator,
&ledger_path,
keypair,
Arc::new(Keypair::new()),
Some(leader_data.contact_info.ncp),
false,
LeaderScheduler::from_bootstrap_leader(leader_pubkey),
@ -477,13 +486,14 @@ fn test_boot_validator_from_file() -> result::Result<()> {
}
fn create_leader(ledger_path: &str) -> (NodeInfo, Fullnode) {
let leader_keypair = Keypair::new();
let leader_keypair = Arc::new(Keypair::new());
let leader = Node::new_localhost_with_pubkey(leader_keypair.pubkey());
let leader_data = leader.info.clone();
let leader_fullnode = Fullnode::new(
leader,
&ledger_path,
leader_keypair,
Arc::new(Keypair::new()),
None,
false,
LeaderScheduler::from_bootstrap_leader(leader_data.id),
@ -532,7 +542,7 @@ fn test_leader_restart_validator_start_from_old_ledger() -> result::Result<()> {
let (leader_data, leader_fullnode) = create_leader(&ledger_path);
// start validator from old ledger
let keypair = Keypair::new();
let keypair = Arc::new(Keypair::new());
let validator = Node::new_localhost_with_pubkey(keypair.pubkey());
let validator_data = validator.info.clone();
@ -540,6 +550,7 @@ fn test_leader_restart_validator_start_from_old_ledger() -> result::Result<()> {
validator,
&stale_ledger_path,
keypair,
Arc::new(Keypair::new()),
Some(leader_data.contact_info.ncp),
false,
LeaderScheduler::from_bootstrap_leader(leader_data.id),
@ -588,7 +599,7 @@ fn test_multi_node_dynamic_network() {
Err(_) => 120,
};
let leader_keypair = Keypair::new();
let leader_keypair = Arc::new(Keypair::new());
let leader_pubkey = leader_keypair.pubkey().clone();
let leader = Node::new_localhost_with_pubkey(leader_keypair.pubkey());
let bob_pubkey = Keypair::new().pubkey();
@ -604,6 +615,7 @@ fn test_multi_node_dynamic_network() {
leader,
&leader_ledger_path,
leader_keypair,
Arc::new(Keypair::new()),
None,
true,
LeaderScheduler::from_bootstrap_leader(leader_pubkey),
@ -675,7 +687,8 @@ fn test_multi_node_dynamic_network() {
let val = Fullnode::new(
validator,
&ledger_path,
keypair,
Arc::new(keypair),
Arc::new(Keypair::new()),
Some(leader_data.contact_info.ncp),
true,
LeaderScheduler::from_bootstrap_leader(leader_pubkey),
@ -780,7 +793,7 @@ fn test_leader_to_validator_transition() {
let validator_keypair = Keypair::new();
// Create the leader node information
let leader_keypair = Keypair::new();
let leader_keypair = Arc::new(Keypair::new());
let leader_node = Node::new_localhost_with_pubkey(leader_keypair.pubkey());
let leader_info = leader_node.info.clone();
@ -801,7 +814,7 @@ fn test_leader_to_validator_transition() {
// Write the bootstrap entries to the ledger that will cause leader rotation
// after the bootstrap height
let mut ledger_writer = LedgerWriter::open(&leader_ledger_path, false).unwrap();
let bootstrap_entries =
let (bootstrap_entries, _) =
make_active_set_entries(&validator_keypair, &mint.keypair(), &last_id, &last_id, 0);
ledger_writer.write_entries(&bootstrap_entries).unwrap();
@ -819,6 +832,7 @@ fn test_leader_to_validator_transition() {
leader_node,
&leader_ledger_path,
leader_keypair,
Arc::new(Keypair::new()),
Some(leader_info.contact_info.ncp),
false,
LeaderScheduler::new(&leader_scheduler_config),
@ -871,7 +885,7 @@ fn test_leader_to_validator_transition() {
_ => panic!("Expected reason for exit to be leader rotation"),
}
// Query newly transitioned validator to make sure that he has the proper balances in
// Query newly transitioned validator to make sure that they have the proper balances in
// the after the transitions
let mut leader_client = mk_client(&leader_info);
@ -883,8 +897,10 @@ fn test_leader_to_validator_transition() {
// Check the ledger to make sure it's the right height, we should've
// transitioned after tick_height == bootstrap_height
let (_, tick_height, _, _) =
Fullnode::new_bank_from_ledger(&leader_ledger_path, &mut LeaderScheduler::default());
let (_, tick_height, _, _) = Fullnode::new_bank_from_ledger(
&leader_ledger_path,
Arc::new(RwLock::new(LeaderScheduler::default())),
);
assert_eq!(tick_height, bootstrap_height);
@ -903,12 +919,12 @@ fn test_leader_validator_basic() {
let bob_pubkey = Keypair::new().pubkey();
// Create the leader node information
let leader_keypair = Keypair::new();
let leader_keypair = Arc::new(Keypair::new());
let leader_node = Node::new_localhost_with_pubkey(leader_keypair.pubkey());
let leader_info = leader_node.info.clone();
// Create the validator node information
let validator_keypair = Keypair::new();
let validator_keypair = Arc::new(Keypair::new());
let validator_node = Node::new_localhost_with_pubkey(validator_keypair.pubkey());
// Make a common mint and a genesis entry for both leader + validator ledgers
@ -931,7 +947,7 @@ fn test_leader_validator_basic() {
// Write the bootstrap entries to the ledger that will cause leader rotation
// after the bootstrap height
let mut ledger_writer = LedgerWriter::open(&leader_ledger_path, false).unwrap();
let active_set_entries =
let (active_set_entries, vote_account_keypair) =
make_active_set_entries(&validator_keypair, &mint.keypair(), &last_id, &last_id, 0);
ledger_writer.write_entries(&active_set_entries).unwrap();
@ -946,21 +962,23 @@ fn test_leader_validator_basic() {
Some(bootstrap_height),
);
// Start the leader fullnode
let mut leader = Fullnode::new(
leader_node,
&leader_ledger_path,
leader_keypair,
Some(leader_info.contact_info.ncp),
false,
LeaderScheduler::new(&leader_scheduler_config),
);
// Start the validator node
let mut validator = Fullnode::new(
validator_node,
&validator_ledger_path,
validator_keypair,
Arc::new(vote_account_keypair),
Some(leader_info.contact_info.ncp),
false,
LeaderScheduler::new(&leader_scheduler_config),
);
// Start the leader fullnode
let mut leader = Fullnode::new(
leader_node,
&leader_ledger_path,
leader_keypair,
Arc::new(Keypair::new()),
Some(leader_info.contact_info.ncp),
false,
LeaderScheduler::new(&leader_scheduler_config),
@ -999,7 +1017,7 @@ fn test_leader_validator_basic() {
_ => panic!("Expected reason for exit to be leader rotation"),
}
// Query newly transitioned validator to make sure that he has the proper balances
// Query newly transitioned validator to make sure they have the proper balances
// in the bank after the transitions
let mut leader_client = mk_client(&leader_info);
@ -1071,7 +1089,7 @@ fn test_dropped_handoff_recovery() {
logger::setup();
// Create the bootstrap leader node information
let bootstrap_leader_keypair = Keypair::new();
let bootstrap_leader_keypair = Arc::new(Keypair::new());
let bootstrap_leader_node = Node::new_localhost_with_pubkey(bootstrap_leader_keypair.pubkey());
let bootstrap_leader_info = bootstrap_leader_node.info.clone();
@ -1086,17 +1104,17 @@ fn test_dropped_handoff_recovery() {
.id;
// Create the validator keypair that will be the next leader in line
let next_leader_keypair = Keypair::new();
let next_leader_keypair = Arc::new(Keypair::new());
// Create a common ledger with entries in the beginning that will add only
// the "next_leader" validator to the active set for leader election, guaranteeing
// he is the next leader after bootstrap_height
// they are the next leader after bootstrap_height
let mut ledger_paths = Vec::new();
ledger_paths.push(bootstrap_leader_ledger_path.clone());
// Make the entries to give the next_leader validator some stake so that he will be in
// Make the entries to give the next_leader validator some stake so that they will be in
// leader election active set
let active_set_entries =
let (active_set_entries, vote_account_keypair) =
make_active_set_entries(&next_leader_keypair, &mint.keypair(), &last_id, &last_id, 0);
// Write the entries
@ -1131,6 +1149,7 @@ fn test_dropped_handoff_recovery() {
bootstrap_leader_node,
&bootstrap_leader_ledger_path,
bootstrap_leader_keypair,
Arc::new(Keypair::new()),
Some(bootstrap_leader_info.contact_info.ncp),
false,
LeaderScheduler::new(&leader_scheduler_config),
@ -1140,7 +1159,7 @@ fn test_dropped_handoff_recovery() {
// Start up the validators other than the "next_leader" validator
for _ in 0..(N - 1) {
let kp = Keypair::new();
let kp = Arc::new(Keypair::new());
let validator_ledger_path = tmp_copy_ledger(
&bootstrap_leader_ledger_path,
"test_dropped_handoff_recovery",
@ -1152,6 +1171,7 @@ fn test_dropped_handoff_recovery() {
validator_node,
&validator_ledger_path,
kp,
Arc::new(Keypair::new()),
Some(bootstrap_leader_info.contact_info.ncp),
false,
LeaderScheduler::new(&leader_scheduler_config),
@ -1176,6 +1196,7 @@ fn test_dropped_handoff_recovery() {
next_leader_node,
&next_leader_ledger_path,
next_leader_keypair,
Arc::new(vote_account_keypair),
Some(bootstrap_leader_info.contact_info.ncp),
false,
LeaderScheduler::new(&leader_scheduler_config),
@ -1247,10 +1268,11 @@ fn test_full_leader_validator_network() {
let mut ledger_paths = Vec::new();
ledger_paths.push(bootstrap_leader_ledger_path.clone());
let mut vote_account_keypairs = VecDeque::new();
for node_keypair in node_keypairs.iter() {
// Make entries to give the validator some stake so that he will be in
// Make entries to give each node some stake so that they will be in the
// leader election active set
let bootstrap_entries = make_active_set_entries(
let (bootstrap_entries, vote_account_keypair) = make_active_set_entries(
node_keypair,
&mint.keypair(),
&last_entry_id,
@ -1258,6 +1280,8 @@ fn test_full_leader_validator_network() {
0,
);
vote_account_keypairs.push_back(vote_account_keypair);
// Write the entries
let mut ledger_writer = LedgerWriter::open(&bootstrap_leader_ledger_path, false).unwrap();
last_entry_id = bootstrap_entries
@ -1286,7 +1310,8 @@ fn test_full_leader_validator_network() {
let bootstrap_leader = Arc::new(RwLock::new(Fullnode::new(
bootstrap_leader_node,
&bootstrap_leader_ledger_path,
node_keypairs.pop_front().unwrap(),
Arc::new(node_keypairs.pop_front().unwrap()),
Arc::new(vote_account_keypairs.pop_front().unwrap()),
Some(bootstrap_leader_info.contact_info.ncp),
false,
LeaderScheduler::new(&leader_scheduler_config),
@ -1311,7 +1336,8 @@ fn test_full_leader_validator_network() {
let validator = Arc::new(RwLock::new(Fullnode::new(
validator_node,
&validator_ledger_path,
kp,
Arc::new(kp),
Arc::new(vote_account_keypairs.pop_front().unwrap()),
Some(bootstrap_leader_info.contact_info.ncp),
false,
LeaderScheduler::new(&leader_scheduler_config),
@ -1338,7 +1364,7 @@ fn test_full_leader_validator_network() {
num_reached_target_height = 0;
for n in nodes.iter() {
let node_lock = n.read().unwrap();
let ls_lock = &node_lock.leader_scheduler;
let ls_lock = node_lock.get_leader_scheduler();
if let Some(sh) = ls_lock.read().unwrap().last_seed_height {
if sh >= target_height {
num_reached_target_height += 1;