Only allow votes when root distance gets too high (#19917)

This commit is contained in:
sakridge
2021-09-16 16:12:26 +03:00
committed by GitHub
parent 2762f6f96f
commit dc69cc1ae4
3 changed files with 107 additions and 4 deletions

View File

@ -1065,6 +1065,7 @@ impl BankingStage {
cost_tracker: &Arc<RwLock<CostTracker>>,
banking_stage_stats: &BankingStageStats,
demote_program_write_locks: bool,
votes_only: bool,
) -> (Vec<SanitizedTransaction>, Vec<usize>, Vec<usize>) {
let mut retryable_transaction_packet_indexes: Vec<usize> = vec![];
@ -1079,6 +1080,9 @@ impl BankingStage {
Err(TransactionError::UnsupportedVersion)
})
.ok()?;
if votes_only && !solana_runtime::bank::is_simple_vote_transaction(&tx) {
return None;
}
tx.verify_precompiles(feature_set).ok()?;
Some((tx, *tx_index))
})
@ -1178,6 +1182,7 @@ impl BankingStage {
cost_tracker,
banking_stage_stats,
bank.demote_program_write_locks(),
bank.vote_only_bank(),
);
packet_conversion_time.stop();
inc_new_counter_info!("banking_stage-packet_conversion", 1);
@ -1284,6 +1289,7 @@ impl BankingStage {
cost_tracker,
banking_stage_stats,
bank.demote_program_write_locks(),
bank.vote_only_bank(),
);
unprocessed_packet_conversion_time.stop();
@ -2963,4 +2969,58 @@ mod tests {
transaction.message_data()
);
}
#[test]
fn test_transactions_from_packets() {
use solana_sdk::feature_set::FeatureSet;
use solana_vote_program::vote_state::Vote;
solana_logger::setup();
let mut vote_packet = Packet::default();
let vote_instruction = solana_vote_program::vote_instruction::vote(
&Pubkey::new_unique(),
&Pubkey::new_unique(),
Vote::default(),
);
let vote_transaction =
Transaction::new_with_payer(&[vote_instruction], Some(&Pubkey::new_unique()));
Packet::populate_packet(&mut vote_packet, None, &vote_transaction).unwrap();
let mut non_vote = Packet::default();
let tx = system_transaction::transfer(
&Keypair::new(),
&Pubkey::new_unique(),
2,
Hash::default(),
);
Packet::populate_packet(&mut non_vote, None, &tx).unwrap();
let msgs = Packets::new(vec![non_vote, vote_packet]);
let packet_indexes = [0, 1];
let feature_set = Arc::new(FeatureSet::default());
let cost_model = Arc::new(RwLock::new(CostModel::default()));
let cost_tracker = Arc::new(RwLock::new(CostTracker::new(cost_model)));
let banking_stage_stats = BankingStageStats::default();
let (transactions, _transaction_to_packet_indexes, _retryable_packet_indexes) =
BankingStage::transactions_from_packets(
&msgs,
&packet_indexes,
&feature_set,
&cost_tracker,
&banking_stage_stats,
false,
true,
);
assert_eq!(transactions.len(), 1);
assert!(!transactions[0].signatures().is_empty());
let (transactions, _transaction_to_packet_indexes, _retryable_packet_indexes) =
BankingStage::transactions_from_packets(
&msgs,
&packet_indexes,
&feature_set,
&cost_tracker,
&banking_stage_stats,
false,
false,
);
assert_eq!(transactions.len(), 2);
}
}

View File

@ -1453,12 +1453,22 @@ impl ReplayStage {
poh_slot, parent_slot, root_slot
);
let root_distance = poh_slot - root_slot;
const MAX_ROOT_DISTANCE_FOR_VOTE_ONLY: Slot = 500;
let vote_only_bank = if root_distance > MAX_ROOT_DISTANCE_FOR_VOTE_ONLY {
datapoint_info!("vote-only-bank", ("slot", poh_slot, i64));
true
} else {
false
};
let tpu_bank = Self::new_bank_from_parent_with_notify(
&parent,
poh_slot,
root_slot,
my_pubkey,
rpc_subscriptions,
vote_only_bank,
);
let tpu_bank = bank_forks.write().unwrap().insert(tpu_bank);
@ -2784,6 +2794,7 @@ impl ReplayStage {
forks.root(),
&leader,
rpc_subscriptions,
false,
);
let empty: Vec<Pubkey> = vec![];
Self::update_fork_propagated_threshold_from_votes(
@ -2810,9 +2821,10 @@ impl ReplayStage {
root_slot: u64,
leader: &Pubkey,
rpc_subscriptions: &Arc<RpcSubscriptions>,
vote_only_bank: bool,
) -> Bank {
rpc_subscriptions.notify_slot(slot, parent.slot(), root_slot);
Bank::new_from_parent(parent, leader, slot)
Bank::new_from_parent_with_vote_only(parent, leader, slot, vote_only_bank)
}
fn record_rewards(bank: &Bank, rewards_recorder_sender: &Option<RewardsRecorderSender>) {