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:
@ -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;
|
||||
|
Reference in New Issue
Block a user