Bank::get_fee_for_message is now nonce aware (backport #22494) (#22499)

* `Bank::get_fee_for_message` is now nonce aware

(cherry picked from commit 4c577d7f8c)

# Conflicts:
#	runtime/src/bank.rs
#	sdk/program/src/message/sanitized.rs

* Resolve conflicts

Co-authored-by: Michael Vines <mvines@gmail.com>
This commit is contained in:
mergify[bot]
2022-01-14 03:25:10 +00:00
committed by GitHub
parent 4f82a4ba1f
commit 9d69f2b324
8 changed files with 106 additions and 52 deletions

View File

@@ -1,4 +1,4 @@
use {crate::instruction::InstructionError, bincode::config::Options};
use crate::instruction::InstructionError;
/// Deserialize with a limit based the maximum amount of data a program can expect to get.
/// This function should be used in place of direct deserialization to help prevent OOM errors
@@ -6,13 +6,10 @@ pub fn limited_deserialize<T>(instruction_data: &[u8]) -> Result<T, InstructionE
where
T: serde::de::DeserializeOwned,
{
let limit = crate::packet::PACKET_DATA_SIZE as u64;
bincode::options()
.with_limit(limit)
.with_fixint_encoding() // As per https://github.com/servo/bincode/issues/333, these two options are needed
.allow_trailing_bytes() // to retain the behavior of bincode::deserialize with the new `options()` method
.deserialize_from(instruction_data)
.map_err(|_| InstructionError::InvalidInstructionData)
solana_program::program_utils::limited_deserialize(
instruction_data,
crate::packet::PACKET_DATA_SIZE as u64,
)
}
#[cfg(test)]

View File

@@ -6,16 +6,13 @@ use {
v0::{self, LoadedAddresses, MessageAddressTableLookup},
SanitizedMessage, VersionedMessage,
},
nonce::NONCED_TX_MARKER_IX_INDEX,
precompiles::verify_if_precompile,
program_utils::limited_deserialize,
pubkey::Pubkey,
sanitize::Sanitize,
signature::Signature,
solana_sdk::feature_set,
transaction::{Result, Transaction, TransactionError, VersionedTransaction},
},
solana_program::{system_instruction::SystemInstruction, system_program},
std::sync::Arc,
};
@@ -181,31 +178,7 @@ impl SanitizedTransaction {
/// If the transaction uses a durable nonce, return the pubkey of the nonce account
pub fn get_durable_nonce(&self, nonce_must_be_writable: bool) -> Option<&Pubkey> {
self.message
.instructions()
.get(NONCED_TX_MARKER_IX_INDEX as usize)
.filter(
|ix| match self.message.get_account_key(ix.program_id_index as usize) {
Some(program_id) => system_program::check_id(program_id),
_ => false,
},
)
.filter(|ix| {
matches!(
limited_deserialize(&ix.data),
Ok(SystemInstruction::AdvanceNonceAccount)
)
})
.and_then(|ix| {
ix.accounts.get(0).and_then(|idx| {
let idx = *idx as usize;
if nonce_must_be_writable && !self.message.is_writable(idx) {
None
} else {
self.message.get_account_key(idx)
}
})
})
self.message.get_durable_nonce(nonce_must_be_writable)
}
/// Return the serialized message data to sign.