From 38b44f2496181f44b43c3bc59c1eb2bb56ce8488 Mon Sep 17 00:00:00 2001 From: Pankaj Garg Date: Mon, 1 Jul 2019 13:21:00 -0700 Subject: [PATCH] Reduce slot duration and consecutive leader slots (#4838) * change consecutive leader slots to 4 * reduce polling frequency for transaction signature confirmation * adjust wait time for transaction signature confirmation * fix nominal test * fix flakiness in wallet pay test --- client/src/rpc_client.rs | 25 +++++++++++++++++++++---- ledger-tool/tests/basic.rs | 9 ++++++--- sdk/src/timing.rs | 16 ++++++++-------- wallet/tests/pay.rs | 14 ++++++++++++-- 4 files changed, 47 insertions(+), 17 deletions(-) diff --git a/client/src/rpc_client.rs b/client/src/rpc_client.rs index ee1aa73ea..c5b906595 100644 --- a/client/src/rpc_client.rs +++ b/client/src/rpc_client.rs @@ -446,17 +446,27 @@ impl RpcClient { ) -> io::Result<()> { let mut now = Instant::now(); let mut confirmed_blocks = 0; + let mut wait_time = 15; loop { let response = self.get_num_blocks_since_signature_confirmation(signature); match response { Ok(count) => { if confirmed_blocks != count { info!( - "signature {} confirmed {} out of {}", - signature, count, min_confirmed_blocks + "signature {} confirmed {} out of {} after {} ms", + signature, + count, + min_confirmed_blocks, + now.elapsed().as_millis() ); now = Instant::now(); confirmed_blocks = count; + // If the signature has been confirmed once, wait extra while reconfirming it + // One confirmation means the transaction has been seen by the network, so + // next confirmation (for a higher block count) should come through. + // Returning an error prematurely will cause a valid transaction to be deemed + // as failure. + wait_time = 30; } if count >= min_confirmed_blocks { break; @@ -466,11 +476,18 @@ impl RpcClient { debug!("check_confirmations request failed: {:?}", err); } }; - if now.elapsed().as_secs() > 15 { + if now.elapsed().as_secs() > wait_time { + info!( + "signature {} confirmed {} out of {} failed after {} ms", + signature, + confirmed_blocks, + min_confirmed_blocks, + now.elapsed().as_millis() + ); // TODO: Return a better error. return Err(io::Error::new(io::ErrorKind::Other, "signature not found")); } - sleep(Duration::from_millis(250)); + sleep(Duration::from_secs(1)); } Ok(()) } diff --git a/ledger-tool/tests/basic.rs b/ledger-tool/tests/basic.rs index b6be8e527..d3b631b00 100644 --- a/ledger-tool/tests/basic.rs +++ b/ledger-tool/tests/basic.rs @@ -4,6 +4,7 @@ extern crate solana; use assert_cmd::prelude::*; use solana::blocktree::create_new_tmp_ledger; use solana::genesis_utils::create_genesis_block; +use std::cmp; use std::process::Command; use std::process::Output; @@ -47,10 +48,12 @@ fn nominal() { assert!(output.status.success()); assert_eq!(count_newlines(&output.stdout), ticks); - // Only print the first 5 items - let output = run_ledger_tool(&["-l", &ledger_path, "-n", "5", "print"]); + // Only print the first N items + let count = cmp::min(genesis_block.ticks_per_slot, 5); + let output = run_ledger_tool(&["-l", &ledger_path, "-n", &count.to_string(), "print"]); + println!("{:?}", output); assert!(output.status.success()); - assert_eq!(count_newlines(&output.stdout), 5); + assert_eq!(count_newlines(&output.stdout), count as usize); // Skip entries with no hashes let output = run_ledger_tool(&["-l", &ledger_path, "-h", "1", "print"]); diff --git a/sdk/src/timing.rs b/sdk/src/timing.rs index 71bea4bc2..fa407e9e7 100644 --- a/sdk/src/timing.rs +++ b/sdk/src/timing.rs @@ -6,14 +6,14 @@ use std::time::{SystemTime, UNIX_EPOCH}; // rate at any given time should be expected to drift pub const DEFAULT_NUM_TICKS_PER_SECOND: u64 = 10; -// At 10 ticks/s, 8 ticks per slot implies that leader rotation and voting will happen -// every 800 ms. A fast voting cadence ensures faster finality and convergence -pub const DEFAULT_TICKS_PER_SLOT: u64 = 8; +// At 10 ticks/s, 4 ticks per slot implies that leader rotation and voting will happen +// every 400 ms. A fast voting cadence ensures faster finality and convergence +pub const DEFAULT_TICKS_PER_SLOT: u64 = 4; -// 1 Epoch = 800 * 4096 ms ~= 55 minutes -pub const DEFAULT_SLOTS_PER_EPOCH: u64 = 4096; +// 1 Epoch = 400 * 8192 ms ~= 55 minutes +pub const DEFAULT_SLOTS_PER_EPOCH: u64 = 8192; -pub const NUM_CONSECUTIVE_LEADER_SLOTS: u64 = 8; +pub const NUM_CONSECUTIVE_LEADER_SLOTS: u64 = 4; /// The time window of recent block hash values that the bank will track the signatures /// of over. Once the bank discards a block hash, it will reject any transactions that use @@ -32,11 +32,11 @@ pub const MAX_PROCESSING_AGE: usize = MAX_RECENT_BLOCKHASHES / 2; /// This is maximum time consumed in forwarding a transaction from one node to next, before /// it can be processed in the target node #[cfg(feature = "cuda")] -pub const MAX_TRANSACTION_FORWARDING_DELAY: usize = 4; +pub const MAX_TRANSACTION_FORWARDING_DELAY: usize = 2; /// More delay is expected if CUDA is not enabled (as signature verification takes longer) #[cfg(not(feature = "cuda"))] -pub const MAX_TRANSACTION_FORWARDING_DELAY: usize = 12; +pub const MAX_TRANSACTION_FORWARDING_DELAY: usize = 6; pub fn duration_as_ns(d: &Duration) -> u64 { d.as_secs() * 1_000_000_000 + u64::from(d.subsec_nanos()) diff --git a/wallet/tests/pay.rs b/wallet/tests/pay.rs index ab5cda4c2..8177d8615 100644 --- a/wallet/tests/pay.rs +++ b/wallet/tests/pay.rs @@ -12,10 +12,20 @@ use std::sync::mpsc::channel; #[cfg(test)] use solana::validator::new_validator_for_tests; +use std::thread::sleep; +use std::time::Duration; fn check_balance(expected_balance: u64, client: &RpcClient, pubkey: &Pubkey) { - let balance = client.retry_get_balance(pubkey, 1).unwrap().unwrap(); - assert_eq!(balance, expected_balance); + (0..5).for_each(|tries| { + let balance = client.retry_get_balance(pubkey, 1).unwrap().unwrap(); + if balance == expected_balance { + return; + } + if tries == 4 { + assert_eq!(balance, expected_balance); + } + sleep(Duration::from_millis(500)); + }); } #[test]