From 2de45a4da5b8ebd4bb346798450c1a0c777f8277 Mon Sep 17 00:00:00 2001 From: Sathish <44555499+sambley@users.noreply.github.com> Date: Sat, 8 Dec 2018 16:54:42 -0800 Subject: [PATCH] Update airdrop tokens to 3 for fullnode (#2051) Filter out leader while computing the super majority stake --- benches/banking_stage.rs | 6 ++++- multinode-demo/fullnode.sh | 7 ++--- src/banking_stage.rs | 21 +++++++++++++-- src/compute_leader_finality_service.rs | 37 ++++++++++++++++++++------ src/fullnode.rs | 2 ++ src/tpu.rs | 3 +++ 6 files changed, 62 insertions(+), 14 deletions(-) diff --git a/benches/banking_stage.rs b/benches/banking_stage.rs index 169954512..26cf54692 100644 --- a/benches/banking_stage.rs +++ b/benches/banking_stage.rs @@ -15,7 +15,7 @@ use solana::mint::Mint; use solana::packet::to_packets_chunked; use solana_sdk::hash::hash; use solana_sdk::pubkey::Pubkey; -use solana_sdk::signature::{KeypairUtil, Signature}; +use solana_sdk::signature::{Keypair, KeypairUtil, Signature}; use solana_sdk::system_transaction::SystemTransaction; use solana_sdk::transaction::Transaction; use std::iter; @@ -50,6 +50,7 @@ fn bench_banking_stage_multi_accounts(bencher: &mut Bencher) { let (verified_sender, verified_receiver) = channel(); let bank = Arc::new(Bank::new(&mint)); + let dummy_leader_id = Keypair::new().pubkey(); let dummy = Transaction::system_move( &mint.keypair(), mint.keypair().pubkey(), @@ -107,6 +108,7 @@ fn bench_banking_stage_multi_accounts(bencher: &mut Bencher) { Default::default(), &mint.last_id(), None, + dummy_leader_id, ); let mut id = mint.last_id(); @@ -137,6 +139,7 @@ fn bench_banking_stage_multi_programs(bencher: &mut Bencher) { let (verified_sender, verified_receiver) = channel(); let bank = Arc::new(Bank::new(&mint)); + let dummy_leader_id = Keypair::new().pubkey(); let dummy = Transaction::system_move( &mint.keypair(), mint.keypair().pubkey(), @@ -209,6 +212,7 @@ fn bench_banking_stage_multi_programs(bencher: &mut Bencher) { Default::default(), &mint.last_id(), None, + dummy_leader_id, ); let mut id = mint.last_id(); diff --git a/multinode-demo/fullnode.sh b/multinode-demo/fullnode.sh index 02bd83bdc..445701375 100755 --- a/multinode-demo/fullnode.sh +++ b/multinode-demo/fullnode.sh @@ -163,13 +163,14 @@ $rsync -vPr "$rsync_leader_url"/config/ "$ledger_config_dir" exit 1 } -# A fullnode requires 2 tokens to function: +# A fullnode requires 3 tokens to function: # - one token to create an instance of the vote_program with -# - one second token to keep the node identity public key valid. +# - one token for the transaction fee +# - one token to keep the node identity public key valid. $solana_wallet \ --keypair "$fullnode_id_path" \ --network "$leader_address" \ - airdrop 2 + airdrop 3 trap 'kill "$pid" && wait "$pid"' INT TERM $program \ diff --git a/src/banking_stage.rs b/src/banking_stage.rs index 94c91f9ff..0e5832599 100644 --- a/src/banking_stage.rs +++ b/src/banking_stage.rs @@ -15,6 +15,7 @@ use result::{Error, Result}; use service::Service; use sigverify_stage::VerifiedPackets; use solana_sdk::hash::Hash; +use solana_sdk::pubkey::Pubkey; use solana_sdk::timing; use solana_sdk::transaction::Transaction; use std::net::SocketAddr; @@ -51,6 +52,7 @@ impl BankingStage { config: Config, last_entry_id: &Hash, max_tick_height: Option, + leader_id: Pubkey, ) -> (Self, Receiver>) { let (entry_sender, entry_receiver) = channel(); let shared_verified_receiver = Arc::new(Mutex::new(verified_receiver)); @@ -63,8 +65,11 @@ impl BankingStage { let poh_service = PohService::new(poh_recorder.clone(), config); // Single thread to compute finality - let compute_finality_service = - ComputeLeaderFinalityService::new(bank.clone(), poh_service.poh_exit.clone()); + let compute_finality_service = ComputeLeaderFinalityService::new( + bank.clone(), + leader_id, + poh_service.poh_exit.clone(), + ); // Many banks that process transactions in parallel. let bank_thread_hdls: Vec>> = (0..NUM_THREADS) @@ -268,6 +273,7 @@ mod tests { #[test] fn test_banking_stage_shutdown1() { let bank = Arc::new(Bank::new(&Mint::new(2))); + let dummy_leader_id = Keypair::new().pubkey(); let (verified_sender, verified_receiver) = channel(); let (banking_stage, _entry_receiver) = BankingStage::new( &bank, @@ -275,6 +281,7 @@ mod tests { Default::default(), &bank.last_id(), None, + dummy_leader_id, ); drop(verified_sender); assert_eq!( @@ -286,6 +293,7 @@ mod tests { #[test] fn test_banking_stage_shutdown2() { let bank = Arc::new(Bank::new(&Mint::new(2))); + let dummy_leader_id = Keypair::new().pubkey(); let (_verified_sender, verified_receiver) = channel(); let (banking_stage, entry_receiver) = BankingStage::new( &bank, @@ -293,6 +301,7 @@ mod tests { Default::default(), &bank.last_id(), None, + dummy_leader_id, ); drop(entry_receiver); assert_eq!( @@ -304,6 +313,7 @@ mod tests { #[test] fn test_banking_stage_tick() { let bank = Arc::new(Bank::new(&Mint::new(2))); + let dummy_leader_id = Keypair::new().pubkey(); let start_hash = bank.last_id(); let (verified_sender, verified_receiver) = channel(); let (banking_stage, entry_receiver) = BankingStage::new( @@ -312,6 +322,7 @@ mod tests { Config::Sleep(Duration::from_millis(1)), &bank.last_id(), None, + dummy_leader_id, ); sleep(Duration::from_millis(500)); drop(verified_sender); @@ -330,6 +341,7 @@ mod tests { fn test_banking_stage_entries_only() { let mint = Mint::new(2); let bank = Arc::new(Bank::new(&mint)); + let dummy_leader_id = Keypair::new().pubkey(); let start_hash = bank.last_id(); let (verified_sender, verified_receiver) = channel(); let (banking_stage, entry_receiver) = BankingStage::new( @@ -338,6 +350,7 @@ mod tests { Default::default(), &bank.last_id(), None, + dummy_leader_id, ); // good tx @@ -385,6 +398,7 @@ mod tests { // Entry OR if the verifier tries to parallelize across multiple Entries. let mint = Mint::new(2); let bank = Arc::new(Bank::new(&mint)); + let dummy_leader_id = Keypair::new().pubkey(); let (verified_sender, verified_receiver) = channel(); let (banking_stage, entry_receiver) = BankingStage::new( &bank, @@ -392,6 +406,7 @@ mod tests { Default::default(), &bank.last_id(), None, + dummy_leader_id, ); // Process a batch that includes a transaction that receives two tokens. @@ -437,6 +452,7 @@ mod tests { #[test] fn test_max_tick_height_shutdown() { let bank = Arc::new(Bank::new(&Mint::new(2))); + let dummy_leader_id = Keypair::new().pubkey(); let (_verified_sender_, verified_receiver) = channel(); let max_tick_height = 10; let (banking_stage, _entry_receiver) = BankingStage::new( @@ -445,6 +461,7 @@ mod tests { Default::default(), &bank.last_id(), Some(max_tick_height), + dummy_leader_id, ); assert_eq!( banking_stage.join().unwrap(), diff --git a/src/compute_leader_finality_service.rs b/src/compute_leader_finality_service.rs index 172eea7ec..13f0f2b54 100644 --- a/src/compute_leader_finality_service.rs +++ b/src/compute_leader_finality_service.rs @@ -6,6 +6,7 @@ use bank::Bank; use service::Service; use solana_metrics::{influxdb, submit}; +use solana_sdk::pubkey::Pubkey; use solana_sdk::timing; use solana_sdk::vote_program::{self, VoteProgram}; use std::result; @@ -29,6 +30,7 @@ pub struct ComputeLeaderFinalityService { impl ComputeLeaderFinalityService { fn get_last_supermajority_timestamp( bank: &Arc, + leader_id: Pubkey, now: u64, last_valid_validator_timestamp: u64, ) -> result::Result { @@ -48,6 +50,9 @@ impl ComputeLeaderFinalityService { // by returning None if vote_program::check_id(&account.owner) { if let Ok(vote_state) = VoteProgram::deserialize(&account.userdata) { + if leader_id == vote_state.node_id { + return None; + } let validator_stake = bank.get_stake(&vote_state.node_id); total_stake += validator_stake; // Filter out any validators that don't have at least one vote @@ -86,11 +91,18 @@ impl ComputeLeaderFinalityService { Err(FinalityError::NoValidSupermajority) } - pub fn compute_finality(bank: &Arc, last_valid_validator_timestamp: &mut u64) { + pub fn compute_finality( + bank: &Arc, + leader_id: Pubkey, + last_valid_validator_timestamp: &mut u64, + ) { let now = timing::timestamp(); - if let Ok(super_majority_timestamp) = - Self::get_last_supermajority_timestamp(bank, now, *last_valid_validator_timestamp) - { + if let Ok(super_majority_timestamp) = Self::get_last_supermajority_timestamp( + bank, + leader_id, + now, + *last_valid_validator_timestamp, + ) { let finality_ms = now - super_majority_timestamp; *last_valid_validator_timestamp = super_majority_timestamp; @@ -105,7 +117,7 @@ impl ComputeLeaderFinalityService { } /// Create a new ComputeLeaderFinalityService for computing finality. - pub fn new(bank: Arc, exit: Arc) -> Self { + pub fn new(bank: Arc, leader_id: Pubkey, exit: Arc) -> Self { let compute_finality_thread = Builder::new() .name("solana-leader-finality-stage".to_string()) .spawn(move || { @@ -114,7 +126,7 @@ impl ComputeLeaderFinalityService { if exit.load(Ordering::Relaxed) { break; } - Self::compute_finality(&bank, &mut last_valid_validator_timestamp); + Self::compute_finality(&bank, leader_id, &mut last_valid_validator_timestamp); sleep(Duration::from_millis(COMPUTE_FINALITY_MS)); } }) @@ -156,6 +168,7 @@ pub mod tests { logger::setup(); let mint = Mint::new(1234); + let dummy_leader_id = Keypair::new().pubkey(); let bank = Arc::new(Bank::new(&mint)); // generate 10 validators, but only vote for the first 6 validators let ids: Vec<_> = (0..10) @@ -195,7 +208,11 @@ pub mod tests { // There isn't 2/3 consensus, so the bank's finality value should be the default let mut last_finality_time = 0; - ComputeLeaderFinalityService::compute_finality(&bank, &mut last_finality_time); + ComputeLeaderFinalityService::compute_finality( + &bank, + dummy_leader_id, + &mut last_finality_time, + ); assert_eq!(bank.finality(), std::usize::MAX); // Get another validator to vote, so we now have 2/3 consensus @@ -204,7 +221,11 @@ pub mod tests { let vote_tx = Transaction::vote_new(&vote_account, vote, ids[6], 0); bank.process_transaction(&vote_tx).unwrap(); - ComputeLeaderFinalityService::compute_finality(&bank, &mut last_finality_time); + ComputeLeaderFinalityService::compute_finality( + &bank, + dummy_leader_id, + &mut last_finality_time, + ); assert!(bank.finality() != std::usize::MAX); assert!(last_finality_time > 0); } diff --git a/src/fullnode.rs b/src/fullnode.rs index 904aea1c5..9667ec415 100644 --- a/src/fullnode.rs +++ b/src/fullnode.rs @@ -322,6 +322,7 @@ impl Fullnode { sigverify_disabled, max_tick_height, last_entry_id, + scheduled_leader, ); let broadcast_service = BroadcastService::new( @@ -486,6 +487,7 @@ impl Fullnode { // the window didn't overwrite the slot at for the last entry that the replicate stage // processed. We also want to avoid reading processing the ledger for the last id. &last_id, + self.keypair.pubkey(), ); let broadcast_service = BroadcastService::new( diff --git a/src/tpu.rs b/src/tpu.rs index a4dc7cfe1..8b524628a 100644 --- a/src/tpu.rs +++ b/src/tpu.rs @@ -10,6 +10,7 @@ use poh_service::Config; use service::Service; use sigverify_stage::SigVerifyStage; use solana_sdk::hash::Hash; +use solana_sdk::pubkey::Pubkey; use std::net::UdpSocket; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::mpsc::Receiver; @@ -38,6 +39,7 @@ impl Tpu { sigverify_disabled: bool, max_tick_height: Option, last_entry_id: &Hash, + leader_id: Pubkey, ) -> (Self, Receiver>, Arc) { let exit = Arc::new(AtomicBool::new(false)); @@ -52,6 +54,7 @@ impl Tpu { tick_duration, last_entry_id, max_tick_height, + leader_id, ); let (ledger_write_stage, entry_forwarder) =