Simplify replay vote tracking by using packet metadata (#21112)
This commit is contained in:
		@@ -489,7 +489,6 @@ pub type TransactionExecutionResult = (Result<()>, Option<NonceRollbackFull>);
 | 
			
		||||
pub struct TransactionResults {
 | 
			
		||||
    pub fee_collection_results: Vec<Result<()>>,
 | 
			
		||||
    pub execution_results: Vec<TransactionExecutionResult>,
 | 
			
		||||
    pub overwritten_vote_accounts: Vec<OverwrittenVoteAccount>,
 | 
			
		||||
    pub rent_debits: Vec<RentDebits>,
 | 
			
		||||
}
 | 
			
		||||
pub struct TransactionSimulationResult {
 | 
			
		||||
@@ -502,11 +501,6 @@ pub struct TransactionBalancesSet {
 | 
			
		||||
    pub pre_balances: TransactionBalances,
 | 
			
		||||
    pub post_balances: TransactionBalances,
 | 
			
		||||
}
 | 
			
		||||
pub struct OverwrittenVoteAccount {
 | 
			
		||||
    pub account: VoteAccount,
 | 
			
		||||
    pub transaction_index: usize,
 | 
			
		||||
    pub transaction_result_index: usize,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl TransactionBalancesSet {
 | 
			
		||||
    pub fn new(pre_balances: TransactionBalances, post_balances: TransactionBalances) -> Self {
 | 
			
		||||
@@ -3273,7 +3267,7 @@ impl Bank {
 | 
			
		||||
            .into_iter()
 | 
			
		||||
            .map(|tx| {
 | 
			
		||||
                let message_hash = tx.message.hash();
 | 
			
		||||
                SanitizedTransaction::try_create(tx, message_hash, |_| {
 | 
			
		||||
                SanitizedTransaction::try_create(tx, message_hash, None, |_| {
 | 
			
		||||
                    Err(TransactionError::UnsupportedVersion)
 | 
			
		||||
                })
 | 
			
		||||
            })
 | 
			
		||||
@@ -4133,8 +4127,7 @@ impl Bank {
 | 
			
		||||
        let rent_debits = self.collect_rent(executed, loaded_txs);
 | 
			
		||||
 | 
			
		||||
        let mut update_stakes_cache_time = Measure::start("update_stakes_cache_time");
 | 
			
		||||
        let overwritten_vote_accounts =
 | 
			
		||||
            self.update_stakes_cache(sanitized_txs, executed, loaded_txs);
 | 
			
		||||
        self.update_stakes_cache(sanitized_txs, executed, loaded_txs);
 | 
			
		||||
        update_stakes_cache_time.stop();
 | 
			
		||||
 | 
			
		||||
        // once committed there is no way to unroll
 | 
			
		||||
@@ -4155,7 +4148,6 @@ impl Bank {
 | 
			
		||||
        TransactionResults {
 | 
			
		||||
            fee_collection_results,
 | 
			
		||||
            execution_results: executed.to_vec(),
 | 
			
		||||
            overwritten_vote_accounts,
 | 
			
		||||
            rent_debits,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -5486,7 +5478,7 @@ impl Bank {
 | 
			
		||||
                tx.message.hash()
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            SanitizedTransaction::try_create(tx, message_hash, |_| {
 | 
			
		||||
            SanitizedTransaction::try_create(tx, message_hash, None, |_| {
 | 
			
		||||
                Err(TransactionError::UnsupportedVersion)
 | 
			
		||||
            })
 | 
			
		||||
        }?;
 | 
			
		||||
@@ -5721,8 +5713,7 @@ impl Bank {
 | 
			
		||||
        txs: &[SanitizedTransaction],
 | 
			
		||||
        res: &[TransactionExecutionResult],
 | 
			
		||||
        loaded_txs: &[TransactionLoadResult],
 | 
			
		||||
    ) -> Vec<OverwrittenVoteAccount> {
 | 
			
		||||
        let mut overwritten_vote_accounts = vec![];
 | 
			
		||||
    ) {
 | 
			
		||||
        for (i, ((raccs, _load_nonce_rollback), tx)) in loaded_txs.iter().zip(txs).enumerate() {
 | 
			
		||||
            let (res, _res_nonce_rollback) = &res[i];
 | 
			
		||||
            if res.is_err() || raccs.is_err() {
 | 
			
		||||
@@ -5736,22 +5727,13 @@ impl Bank {
 | 
			
		||||
                .zip(loaded_transaction.accounts.iter())
 | 
			
		||||
                .filter(|(_i, (_pubkey, account))| (Stakes::is_stake(account)))
 | 
			
		||||
            {
 | 
			
		||||
                if let Some(old_vote_account) = self.stakes.write().unwrap().store(
 | 
			
		||||
                self.stakes.write().unwrap().store(
 | 
			
		||||
                    pubkey,
 | 
			
		||||
                    account,
 | 
			
		||||
                    self.stakes_remove_delegation_if_inactive_enabled(),
 | 
			
		||||
                ) {
 | 
			
		||||
                    // TODO: one of the indices is redundant.
 | 
			
		||||
                    overwritten_vote_accounts.push(OverwrittenVoteAccount {
 | 
			
		||||
                        account: old_vote_account,
 | 
			
		||||
                        transaction_index: i,
 | 
			
		||||
                        transaction_result_index: i,
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        overwritten_vote_accounts
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// current stake delegations for this bank
 | 
			
		||||
 
 | 
			
		||||
@@ -35,21 +35,21 @@ pub fn find_and_send_votes(
 | 
			
		||||
    vote_sender: Option<&ReplayVoteSender>,
 | 
			
		||||
) {
 | 
			
		||||
    let TransactionResults {
 | 
			
		||||
        execution_results,
 | 
			
		||||
        overwritten_vote_accounts,
 | 
			
		||||
        ..
 | 
			
		||||
        execution_results, ..
 | 
			
		||||
    } = tx_results;
 | 
			
		||||
    if let Some(vote_sender) = vote_sender {
 | 
			
		||||
        for old_account in overwritten_vote_accounts {
 | 
			
		||||
            assert!(execution_results[old_account.transaction_result_index]
 | 
			
		||||
                .0
 | 
			
		||||
                .is_ok());
 | 
			
		||||
            let tx = &sanitized_txs[old_account.transaction_index];
 | 
			
		||||
            if let Some(parsed_vote) = vote_transaction::parse_sanitized_vote_transaction(tx) {
 | 
			
		||||
                if parsed_vote.1.slots.last().is_some() {
 | 
			
		||||
                    let _ = vote_sender.send(parsed_vote);
 | 
			
		||||
        sanitized_txs.iter().zip(execution_results.iter()).for_each(
 | 
			
		||||
            |(tx, (result, _nonce_rollback))| {
 | 
			
		||||
                if tx.is_simple_vote_transaction() && result.is_ok() {
 | 
			
		||||
                    if let Some(parsed_vote) =
 | 
			
		||||
                        vote_transaction::parse_sanitized_vote_transaction(tx)
 | 
			
		||||
                    {
 | 
			
		||||
                        if parsed_vote.1.slots.last().is_some() {
 | 
			
		||||
                            let _ = vote_sender.send(parsed_vote);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
            },
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -196,7 +196,7 @@ impl Stakes {
 | 
			
		||||
        pubkey: &Pubkey,
 | 
			
		||||
        account: &AccountSharedData,
 | 
			
		||||
        remove_delegation_on_inactive: bool,
 | 
			
		||||
    ) -> Option<VoteAccount> {
 | 
			
		||||
    ) {
 | 
			
		||||
        if solana_vote_program::check_id(account.owner()) {
 | 
			
		||||
            // unconditionally remove existing at first; there is no dependent calculated state for
 | 
			
		||||
            // votes, not like stakes (stake codepath maintains calculated stake value grouped by
 | 
			
		||||
@@ -213,7 +213,6 @@ impl Stakes {
 | 
			
		||||
                self.vote_accounts
 | 
			
		||||
                    .insert(*pubkey, (stake, VoteAccount::from(account.clone())));
 | 
			
		||||
            }
 | 
			
		||||
            old.map(|(_, account)| account)
 | 
			
		||||
        } else if stake::program::check_id(account.owner()) {
 | 
			
		||||
            //  old_stake is stake lamports and voter_pubkey from the pre-store() version
 | 
			
		||||
            let old_stake = self.stake_delegations.get(pubkey).map(|delegation| {
 | 
			
		||||
@@ -263,13 +262,11 @@ impl Stakes {
 | 
			
		||||
            } else if let Some(delegation) = delegation {
 | 
			
		||||
                self.stake_delegations.insert(*pubkey, delegation);
 | 
			
		||||
            }
 | 
			
		||||
            None
 | 
			
		||||
        } else {
 | 
			
		||||
            // there is no need to remove possibly existing Stakes cache entries with given
 | 
			
		||||
            // `pubkey` because this isn't possible, first of all.
 | 
			
		||||
            // Runtime always enforces an intermediary write of account.lamports == 0,
 | 
			
		||||
            // when not-System111-owned account.owner is swapped.
 | 
			
		||||
            None
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user