Skip to content

Commit

Permalink
Only allow votes when root distance gets too high (#19933)
Browse files Browse the repository at this point in the history
  • Loading branch information
sakridge authored Sep 16, 2021
1 parent 54ad080 commit ca83167
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 4 deletions.
41 changes: 41 additions & 0 deletions core/src/banking_stage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -978,12 +978,18 @@ impl BankingStage {
msgs: &Packets,
transaction_indexes: &[usize],
libsecp256k1_0_5_upgrade_enabled: bool,
votes_only: bool,
) -> (Vec<HashedTransaction<'static>>, Vec<usize>) {
transaction_indexes
.iter()
.filter_map(|tx_index| {
let p = &msgs.packets[*tx_index];
let tx: Transaction = limited_deserialize(&p.data[0..p.meta.size]).ok()?;

if votes_only && !solana_runtime::bank::is_simple_vote_transaction(&tx) {
return None;
}

tx.verify_precompiles(libsecp256k1_0_5_upgrade_enabled)
.ok()?;
let message_bytes = Self::packet_message(p)?;
Expand Down Expand Up @@ -1050,6 +1056,7 @@ impl BankingStage {
msgs,
&packet_indexes,
bank.libsecp256k1_0_5_upgrade_enabled(),
bank.vote_only_bank(),
);
packet_conversion_time.stop();

Expand Down Expand Up @@ -1121,6 +1128,7 @@ impl BankingStage {
msgs,
&transaction_indexes,
bank.libsecp256k1_0_5_upgrade_enabled(),
bank.vote_only_bank(),
);

let tx_count = transaction_to_packet_indexes.len();
Expand Down Expand Up @@ -2786,4 +2794,37 @@ mod tests {
transaction.message_data()
);
}

#[test]
fn test_transactions_from_packets() {
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 (transactions, _transaction_to_packet_indexes) =
BankingStage::transactions_from_packets(&msgs, &packet_indexes, false, true);
assert_eq!(transactions.len(), 1);
assert!(!transactions[0].transaction().signatures.is_empty());

let (transactions, _transaction_to_packet_indexes) =
BankingStage::transactions_from_packets(&msgs, &packet_indexes, false, false);
assert_eq!(transactions.len(), 2);
}
}
14 changes: 13 additions & 1 deletion core/src/replay_stage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1181,12 +1181,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,
subscriptions,
vote_only_bank,
);

let tpu_bank = bank_forks.write().unwrap().insert(tpu_bank);
Expand Down Expand Up @@ -2442,6 +2452,7 @@ impl ReplayStage {
forks.root(),
&leader,
subscriptions,
false,
);
let empty: Vec<Pubkey> = vec![];
Self::update_fork_propagated_threshold_from_votes(
Expand All @@ -2468,9 +2479,10 @@ impl ReplayStage {
root_slot: u64,
leader: &Pubkey,
subscriptions: &Arc<RpcSubscriptions>,
vote_only_bank: bool,
) -> Bank {
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>) {
Expand Down
36 changes: 33 additions & 3 deletions runtime/src/bank.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1005,6 +1005,8 @@ pub struct Bank {
pub drop_callback: RwLock<OptionalDropCallback>,

pub freeze_started: AtomicBool,

vote_only_bank: bool,
}

impl Default for BlockhashQueue {
Expand Down Expand Up @@ -1119,7 +1121,22 @@ impl Bank {

/// Create a new bank that points to an immutable checkpoint of another bank.
pub fn new_from_parent(parent: &Arc<Bank>, collector_id: &Pubkey, slot: Slot) -> Self {
Self::_new_from_parent(parent, collector_id, slot, &mut null_tracer())
Self::_new_from_parent(parent, collector_id, slot, &mut null_tracer(), false)
}

pub fn new_from_parent_with_vote_only(
parent: &Arc<Bank>,
collector_id: &Pubkey,
slot: Slot,
vote_only_bank: bool,
) -> Self {
Self::_new_from_parent(
parent,
collector_id,
slot,
&mut null_tracer(),
vote_only_bank,
)
}

pub fn new_from_parent_with_tracer(
Expand All @@ -1128,14 +1145,21 @@ impl Bank {
slot: Slot,
reward_calc_tracer: impl FnMut(&RewardCalculationEvent),
) -> Self {
Self::_new_from_parent(parent, collector_id, slot, &mut Some(reward_calc_tracer))
Self::_new_from_parent(
parent,
collector_id,
slot,
&mut Some(reward_calc_tracer),
false,
)
}

fn _new_from_parent(
parent: &Arc<Bank>,
collector_id: &Pubkey,
slot: Slot,
reward_calc_tracer: &mut Option<impl FnMut(&RewardCalculationEvent)>,
vote_only_bank: bool,
) -> Self {
parent.freeze();
assert_ne!(slot, parent.slot());
Expand Down Expand Up @@ -1184,6 +1208,7 @@ impl Bank {
fee_calculator: fee_rate_governor.create_fee_calculator(),
fee_rate_governor,
capitalization: AtomicU64::new(parent.capitalization()),
vote_only_bank,
inflation: parent.inflation.clone(),
transaction_count: AtomicU64::new(parent.transaction_count()),
transaction_error_count: AtomicU64::new(0),
Expand Down Expand Up @@ -1278,6 +1303,10 @@ impl Bank {
*self.drop_callback.write().unwrap() = OptionalDropCallback(callback);
}

pub fn vote_only_bank(&self) -> bool {
self.vote_only_bank
}

/// Like `new_from_parent` but additionally:
/// * Doesn't assume that the parent is anywhere near `slot`, parent could be millions of slots
/// in the past
Expand Down Expand Up @@ -1373,6 +1402,7 @@ impl Bank {
feature_set: new(),
drop_callback: RwLock::new(OptionalDropCallback(None)),
freeze_started: AtomicBool::new(fields.hash != Hash::default()),
vote_only_bank: false,
};
bank.finish_init(
genesis_config,
Expand Down Expand Up @@ -5412,7 +5442,7 @@ pub fn goto_end_of_slot(bank: &mut Bank) {
}
}

fn is_simple_vote_transaction(transaction: &Transaction) -> bool {
pub fn is_simple_vote_transaction(transaction: &Transaction) -> bool {
if transaction.message.instructions.len() == 1 {
let instruction = &transaction.message.instructions[0];
let program_pubkey =
Expand Down

0 comments on commit ca83167

Please sign in to comment.