Divorce the runtime from FeeCalculator (#20737)
This commit is contained in:
@ -5,8 +5,6 @@ use {
|
||||
message::{MappedAddresses, MappedMessage, Message, MessageHeader},
|
||||
pubkey::Pubkey,
|
||||
sanitize::{Sanitize, SanitizeError},
|
||||
secp256k1_program,
|
||||
ed25519_program,
|
||||
serialize_utils::{append_slice, append_u16, append_u8},
|
||||
},
|
||||
bitflags::bitflags,
|
||||
@ -291,21 +289,6 @@ impl SanitizedMessage {
|
||||
})
|
||||
}
|
||||
|
||||
/// Calculate the total fees for a transaction given a fee calculator
|
||||
pub fn calculate_fee(&self, lamports_per_signature: u64) -> u64 {
|
||||
let mut num_signatures = u64::from(self.header().num_required_signatures);
|
||||
for (program_id, instruction) in self.program_instructions_iter() {
|
||||
if secp256k1_program::check_id(program_id) || ed25519_program::check_id(program_id) {
|
||||
if let Some(num_verifies) = instruction.data.get(0) {
|
||||
num_signatures =
|
||||
num_signatures.saturating_add(u64::from(*num_verifies));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lamports_per_signature.saturating_mul(num_signatures)
|
||||
}
|
||||
|
||||
/// Inspect all message keys for the bpf upgradeable loader
|
||||
pub fn is_upgradeable_loader_present(&self) -> bool {
|
||||
match self {
|
||||
@ -321,7 +304,6 @@ mod tests {
|
||||
use crate::{
|
||||
instruction::{AccountMeta, Instruction},
|
||||
message::v0,
|
||||
secp256k1_program, system_instruction,
|
||||
};
|
||||
|
||||
#[test]
|
||||
@ -460,25 +442,6 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_calculate_fee() {
|
||||
// Default: no fee.
|
||||
let message =
|
||||
SanitizedMessage::try_from(Message::new(&[], Some(&Pubkey::new_unique()))).unwrap();
|
||||
assert_eq!(message.calculate_fee(0), 0);
|
||||
|
||||
// One signature, a fee.
|
||||
assert_eq!(message.calculate_fee(1), 1);
|
||||
|
||||
// Two signatures, double the fee.
|
||||
let key0 = Pubkey::new_unique();
|
||||
let key1 = Pubkey::new_unique();
|
||||
let ix0 = system_instruction::transfer(&key0, &key1, 1);
|
||||
let ix1 = system_instruction::transfer(&key1, &key0, 1);
|
||||
let message = SanitizedMessage::try_from(Message::new(&[ix0, ix1], Some(&key0))).unwrap();
|
||||
assert_eq!(message.calculate_fee(2), 4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_try_compile_instruction() {
|
||||
let key0 = Pubkey::new_unique();
|
||||
@ -561,80 +524,4 @@ mod tests {
|
||||
.is_none());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_calculate_fee_secp256k1() {
|
||||
let key0 = Pubkey::new_unique();
|
||||
let key1 = Pubkey::new_unique();
|
||||
let ix0 = system_instruction::transfer(&key0, &key1, 1);
|
||||
|
||||
let mut secp_instruction1 = Instruction {
|
||||
program_id: secp256k1_program::id(),
|
||||
accounts: vec![],
|
||||
data: vec![],
|
||||
};
|
||||
let mut secp_instruction2 = Instruction {
|
||||
program_id: secp256k1_program::id(),
|
||||
accounts: vec![],
|
||||
data: vec![1],
|
||||
};
|
||||
|
||||
let message = SanitizedMessage::try_from(Message::new(
|
||||
&[
|
||||
ix0.clone(),
|
||||
secp_instruction1.clone(),
|
||||
secp_instruction2.clone(),
|
||||
],
|
||||
Some(&key0),
|
||||
))
|
||||
.unwrap();
|
||||
assert_eq!(message.calculate_fee(1), 2);
|
||||
|
||||
secp_instruction1.data = vec![0];
|
||||
secp_instruction2.data = vec![10];
|
||||
let message = SanitizedMessage::try_from(Message::new(
|
||||
&[ix0, secp_instruction1, secp_instruction2],
|
||||
Some(&key0),
|
||||
))
|
||||
.unwrap();
|
||||
assert_eq!(message.calculate_fee(1), 11);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_calculate_fee_ed25519() {
|
||||
let key0 = Pubkey::new_unique();
|
||||
let key1 = Pubkey::new_unique();
|
||||
let ix0 = system_instruction::transfer(&key0, &key1, 1);
|
||||
|
||||
let mut instruction1 = Instruction {
|
||||
program_id: ed25519_program::id(),
|
||||
accounts: vec![],
|
||||
data: vec![],
|
||||
};
|
||||
let mut instruction2 = Instruction {
|
||||
program_id: ed25519_program::id(),
|
||||
accounts: vec![],
|
||||
data: vec![1],
|
||||
};
|
||||
|
||||
let message = SanitizedMessage::try_from(Message::new(
|
||||
&[
|
||||
ix0.clone(),
|
||||
instruction1.clone(),
|
||||
instruction2.clone(),
|
||||
],
|
||||
Some(&key0),
|
||||
))
|
||||
.unwrap();
|
||||
assert_eq!(message.calculate_fee(1), 2);
|
||||
|
||||
instruction1.data = vec![0];
|
||||
instruction2.data = vec![10];
|
||||
let message = SanitizedMessage::try_from(Message::new(
|
||||
&[ix0, instruction1, instruction2],
|
||||
Some(&key0),
|
||||
))
|
||||
.unwrap();
|
||||
assert_eq!(message.calculate_fee(1), 11);
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,19 @@ pub struct Data {
|
||||
pub fee_calculator: FeeCalculator,
|
||||
}
|
||||
|
||||
impl Data {
|
||||
pub fn new(authority: Pubkey, blockhash: Hash, lamports_per_signature: u64) -> Self {
|
||||
Data {
|
||||
authority,
|
||||
blockhash,
|
||||
fee_calculator: FeeCalculator::new(lamports_per_signature),
|
||||
}
|
||||
}
|
||||
pub fn get_lamports_per_signature(&self) -> u64 {
|
||||
self.fee_calculator.lamports_per_signature
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
|
||||
pub enum State {
|
||||
Uninitialized,
|
||||
|
@ -30,10 +30,10 @@ pub struct Entry {
|
||||
pub fee_calculator: FeeCalculator,
|
||||
}
|
||||
impl Entry {
|
||||
pub fn new(blockhash: &Hash, fee_calculator: &FeeCalculator) -> Self {
|
||||
pub fn new(blockhash: &Hash, lamports_per_signature: u64) -> Self {
|
||||
Self {
|
||||
blockhash: *blockhash,
|
||||
fee_calculator: fee_calculator.clone(),
|
||||
fee_calculator: FeeCalculator::new(lamports_per_signature),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -43,7 +43,7 @@ impl Entry {
|
||||
note = "Please do not use, will no longer be available in the future"
|
||||
)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct IterItem<'a>(pub u64, pub &'a Hash, pub &'a FeeCalculator);
|
||||
pub struct IterItem<'a>(pub u64, pub &'a Hash, pub u64);
|
||||
|
||||
impl<'a> Eq for IterItem<'a> {}
|
||||
|
||||
@ -149,13 +149,13 @@ pub fn create_test_recent_blockhashes(start: usize) -> RecentBlockhashes {
|
||||
(
|
||||
i as u64,
|
||||
hash(&bincode::serialize(&i).unwrap()),
|
||||
FeeCalculator::new(i as u64 * 100),
|
||||
i as u64 * 100,
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
blocks
|
||||
.iter()
|
||||
.map(|(i, hash, fee_calc)| IterItem(*i, hash, fee_calc))
|
||||
.map(|(i, hash, lamports_per_signature)| IterItem(*i, hash, *lamports_per_signature))
|
||||
.collect()
|
||||
}
|
||||
|
||||
@ -173,7 +173,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_size_of() {
|
||||
let entry = Entry::new(&Hash::default(), &FeeCalculator::default());
|
||||
let entry = Entry::new(&Hash::default(), 0);
|
||||
assert_eq!(
|
||||
bincode::serialized_size(&RecentBlockhashes(vec![entry; MAX_ENTRIES])).unwrap()
|
||||
as usize,
|
||||
|
@ -249,6 +249,10 @@ pub mod requestable_heap_size {
|
||||
solana_sdk::declare_id!("CCu4boMmfLuqcmfTLPHQiUo22ZdUsXjgzPAURYaWt1Bw");
|
||||
}
|
||||
|
||||
pub mod disable_fee_calculator {
|
||||
solana_sdk::declare_id!("2jXx2yDmGysmBKfKYNgLj2DQyAQv6mMk2BPh4eSbyB4H");
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
/// Map of feature identifiers to user-visible description
|
||||
pub static ref FEATURE_NAMES: HashMap<Pubkey, &'static str> = [
|
||||
@ -300,12 +304,13 @@ lazy_static! {
|
||||
(sol_log_data_syscall_enabled::id(), "enable sol_log_data syscall"),
|
||||
(stakes_remove_delegation_if_inactive::id(), "remove delegations from stakes cache when inactive"),
|
||||
(do_support_realloc::id(), "support account data reallocation"),
|
||||
(prevent_calling_precompiles_as_programs::id(), "Prevent calling precompiles as programs"),
|
||||
(optimize_epoch_boundary_updates::id(), "Optimize epoch boundary updates"),
|
||||
(remove_native_loader::id(), "Remove support for the native loader"),
|
||||
(send_to_tpu_vote_port::id(), "Send votes to the tpu vote port"),
|
||||
(prevent_calling_precompiles_as_programs::id(), "prevent calling precompiles as programs"),
|
||||
(optimize_epoch_boundary_updates::id(), "optimize epoch boundary updates"),
|
||||
(remove_native_loader::id(), "remove support for the native loader"),
|
||||
(send_to_tpu_vote_port::id(), "send votes to the tpu vote port"),
|
||||
(turbine_peers_shuffle::id(), "turbine peers shuffle patch"),
|
||||
(requestable_heap_size::id(), "Requestable heap frame size"),
|
||||
(disable_fee_calculator::id(), "deprecate fee calculator"),
|
||||
/*************** ADD NEW FEATURES HERE ***************/
|
||||
]
|
||||
.iter()
|
||||
|
@ -1,7 +1,6 @@
|
||||
use crate::{
|
||||
account::{AccountSharedData, ReadableAccount},
|
||||
account_utils::StateMut,
|
||||
fee_calculator::FeeCalculator,
|
||||
hash::Hash,
|
||||
nonce::{state::Versions, State},
|
||||
};
|
||||
@ -29,12 +28,12 @@ pub fn verify_nonce_account(acc: &AccountSharedData, hash: &Hash) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fee_calculator_of(account: &AccountSharedData) -> Option<FeeCalculator> {
|
||||
pub fn lamports_per_signature_of(account: &AccountSharedData) -> Option<u64> {
|
||||
let state = StateMut::<Versions>::state(account)
|
||||
.ok()?
|
||||
.convert_to_current();
|
||||
match state {
|
||||
State::Initialized(data) => Some(data.fee_calculator),
|
||||
State::Initialized(data) => Some(data.fee_calculator.lamports_per_signature),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -76,11 +76,11 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> {
|
||||
));
|
||||
}
|
||||
|
||||
let new_data = nonce::state::Data {
|
||||
blockhash: recent_blockhash,
|
||||
fee_calculator: invoke_context.get_fee_calculator().clone(),
|
||||
..data
|
||||
};
|
||||
let new_data = nonce::state::Data::new(
|
||||
data.authority,
|
||||
recent_blockhash,
|
||||
invoke_context.get_lamports_per_signature(),
|
||||
);
|
||||
self.set_state(&Versions::new_current(State::Initialized(new_data)))
|
||||
}
|
||||
_ => {
|
||||
@ -195,11 +195,11 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> {
|
||||
);
|
||||
return Err(InstructionError::InsufficientFunds);
|
||||
}
|
||||
let data = nonce::state::Data {
|
||||
authority: *nonce_authority,
|
||||
blockhash: *invoke_context.get_blockhash(),
|
||||
fee_calculator: invoke_context.get_fee_calculator().clone(),
|
||||
};
|
||||
let data = nonce::state::Data::new(
|
||||
*nonce_authority,
|
||||
*invoke_context.get_blockhash(),
|
||||
invoke_context.get_lamports_per_signature(),
|
||||
);
|
||||
self.set_state(&Versions::new_current(State::Initialized(data)))
|
||||
}
|
||||
_ => {
|
||||
@ -234,10 +234,11 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> {
|
||||
);
|
||||
return Err(InstructionError::MissingRequiredSignature);
|
||||
}
|
||||
let new_data = nonce::state::Data {
|
||||
authority: *nonce_authority,
|
||||
..data
|
||||
};
|
||||
let new_data = nonce::state::Data::new(
|
||||
*nonce_authority,
|
||||
data.blockhash,
|
||||
data.get_lamports_per_signature(),
|
||||
);
|
||||
self.set_state(&Versions::new_current(State::Initialized(new_data)))
|
||||
}
|
||||
_ => {
|
||||
@ -272,7 +273,6 @@ mod test {
|
||||
use crate::{
|
||||
account::ReadableAccount,
|
||||
account_utils::State as AccountUtilsState,
|
||||
fee_calculator::FeeCalculator,
|
||||
keyed_account::KeyedAccount,
|
||||
nonce::{self, State},
|
||||
nonce_account::verify_nonce_account,
|
||||
@ -281,18 +281,18 @@ mod test {
|
||||
};
|
||||
use solana_program::hash::{hash, Hash};
|
||||
|
||||
fn create_test_blockhash(seed: usize) -> (Hash, FeeCalculator) {
|
||||
fn create_test_blockhash(seed: usize) -> (Hash, u64) {
|
||||
(
|
||||
hash(&bincode::serialize(&seed).unwrap()),
|
||||
FeeCalculator::new((seed as u64).saturating_mul(100)),
|
||||
(seed as u64).saturating_mul(100),
|
||||
)
|
||||
}
|
||||
|
||||
fn create_invoke_context_with_blockhash<'a>(seed: usize) -> MockInvokeContext<'a> {
|
||||
let mut invoke_context = MockInvokeContext::new(&Pubkey::default(), vec![]);
|
||||
let (blockhash, fee_calculator) = create_test_blockhash(seed);
|
||||
let (blockhash, lamports_per_signature) = create_test_blockhash(seed);
|
||||
invoke_context.blockhash = blockhash;
|
||||
invoke_context.fee_calculator = fee_calculator;
|
||||
invoke_context.lamports_per_signature = lamports_per_signature;
|
||||
invoke_context
|
||||
}
|
||||
|
||||
@ -328,11 +328,11 @@ mod test {
|
||||
let state = AccountUtilsState::<Versions>::state(keyed_account)
|
||||
.unwrap()
|
||||
.convert_to_current();
|
||||
let data = nonce::state::Data {
|
||||
blockhash: *invoke_context.get_blockhash(),
|
||||
fee_calculator: invoke_context.get_fee_calculator().clone(),
|
||||
..data
|
||||
};
|
||||
let data = nonce::state::Data::new(
|
||||
data.authority,
|
||||
*invoke_context.get_blockhash(),
|
||||
invoke_context.get_lamports_per_signature(),
|
||||
);
|
||||
// First nonce instruction drives state from Uninitialized to Initialized
|
||||
assert_eq!(state, State::Initialized(data.clone()));
|
||||
let invoke_context = create_invoke_context_with_blockhash(63);
|
||||
@ -342,11 +342,11 @@ mod test {
|
||||
let state = AccountUtilsState::<Versions>::state(keyed_account)
|
||||
.unwrap()
|
||||
.convert_to_current();
|
||||
let data = nonce::state::Data {
|
||||
blockhash: *invoke_context.get_blockhash(),
|
||||
fee_calculator: invoke_context.get_fee_calculator().clone(),
|
||||
..data
|
||||
};
|
||||
let data = nonce::state::Data::new(
|
||||
data.authority,
|
||||
*invoke_context.get_blockhash(),
|
||||
invoke_context.get_lamports_per_signature(),
|
||||
);
|
||||
// Second nonce instruction consumes and replaces stored nonce
|
||||
assert_eq!(state, State::Initialized(data.clone()));
|
||||
let invoke_context = create_invoke_context_with_blockhash(31);
|
||||
@ -356,11 +356,11 @@ mod test {
|
||||
let state = AccountUtilsState::<Versions>::state(keyed_account)
|
||||
.unwrap()
|
||||
.convert_to_current();
|
||||
let data = nonce::state::Data {
|
||||
blockhash: *invoke_context.get_blockhash(),
|
||||
fee_calculator: invoke_context.get_fee_calculator().clone(),
|
||||
..data
|
||||
};
|
||||
let data = nonce::state::Data::new(
|
||||
data.authority,
|
||||
*invoke_context.get_blockhash(),
|
||||
invoke_context.get_lamports_per_signature(),
|
||||
);
|
||||
// Third nonce instruction for fun and profit
|
||||
assert_eq!(state, State::Initialized(data));
|
||||
with_test_keyed_account(42, false, |to_keyed| {
|
||||
@ -412,11 +412,11 @@ mod test {
|
||||
let state = AccountUtilsState::<Versions>::state(&nonce_account)
|
||||
.unwrap()
|
||||
.convert_to_current();
|
||||
let data = nonce::state::Data {
|
||||
let data = nonce::state::Data::new(
|
||||
authority,
|
||||
blockhash: *invoke_context.get_blockhash(),
|
||||
fee_calculator: invoke_context.get_fee_calculator().clone(),
|
||||
};
|
||||
*invoke_context.get_blockhash(),
|
||||
invoke_context.get_lamports_per_signature(),
|
||||
);
|
||||
assert_eq!(state, State::Initialized(data));
|
||||
let signers = HashSet::new();
|
||||
let invoke_context = create_invoke_context_with_blockhash(0);
|
||||
@ -690,11 +690,11 @@ mod test {
|
||||
let state = AccountUtilsState::<Versions>::state(nonce_keyed)
|
||||
.unwrap()
|
||||
.convert_to_current();
|
||||
let data = nonce::state::Data {
|
||||
let data = nonce::state::Data::new(
|
||||
authority,
|
||||
blockhash: *invoke_context.get_blockhash(),
|
||||
fee_calculator: invoke_context.get_fee_calculator().clone(),
|
||||
};
|
||||
*invoke_context.get_blockhash(),
|
||||
invoke_context.get_lamports_per_signature(),
|
||||
);
|
||||
assert_eq!(state, State::Initialized(data.clone()));
|
||||
with_test_keyed_account(42, false, |to_keyed| {
|
||||
let withdraw_lamports = nonce_keyed.account.borrow().lamports() - min_lamports;
|
||||
@ -713,11 +713,11 @@ mod test {
|
||||
let state = AccountUtilsState::<Versions>::state(nonce_keyed)
|
||||
.unwrap()
|
||||
.convert_to_current();
|
||||
let data = nonce::state::Data {
|
||||
blockhash: *invoke_context.get_blockhash(),
|
||||
fee_calculator: invoke_context.get_fee_calculator().clone(),
|
||||
..data.clone()
|
||||
};
|
||||
let data = nonce::state::Data::new(
|
||||
data.authority,
|
||||
*invoke_context.get_blockhash(),
|
||||
invoke_context.get_lamports_per_signature(),
|
||||
);
|
||||
assert_eq!(state, State::Initialized(data));
|
||||
assert_eq!(
|
||||
nonce_keyed.account.borrow().lamports(),
|
||||
@ -887,11 +887,11 @@ mod test {
|
||||
let invoke_context = create_invoke_context_with_blockhash(0);
|
||||
let authority = *keyed_account.unsigned_key();
|
||||
let result = keyed_account.initialize_nonce_account(&authority, &rent, &invoke_context);
|
||||
let data = nonce::state::Data {
|
||||
let data = nonce::state::Data::new(
|
||||
authority,
|
||||
blockhash: *invoke_context.get_blockhash(),
|
||||
fee_calculator: invoke_context.get_fee_calculator().clone(),
|
||||
};
|
||||
*invoke_context.get_blockhash(),
|
||||
invoke_context.get_lamports_per_signature(),
|
||||
);
|
||||
assert_eq!(result, Ok(()));
|
||||
let state = AccountUtilsState::<Versions>::state(keyed_account)
|
||||
.unwrap()
|
||||
@ -952,11 +952,11 @@ mod test {
|
||||
.initialize_nonce_account(&authorized, &rent, &invoke_context)
|
||||
.unwrap();
|
||||
let authority = Pubkey::default();
|
||||
let data = nonce::state::Data {
|
||||
let data = nonce::state::Data::new(
|
||||
authority,
|
||||
blockhash: *invoke_context.get_blockhash(),
|
||||
fee_calculator: invoke_context.get_fee_calculator().clone(),
|
||||
};
|
||||
*invoke_context.get_blockhash(),
|
||||
invoke_context.get_lamports_per_signature(),
|
||||
);
|
||||
let result = nonce_account.authorize_nonce_account(
|
||||
&Pubkey::default(),
|
||||
&signers,
|
||||
|
@ -5,7 +5,6 @@ use solana_sdk::{
|
||||
account::AccountSharedData,
|
||||
compute_budget::ComputeBudget,
|
||||
feature_set::remove_native_loader,
|
||||
fee_calculator::FeeCalculator,
|
||||
hash::Hash,
|
||||
instruction::{CompiledInstruction, Instruction, InstructionError},
|
||||
keyed_account::{create_keyed_accounts_unified, KeyedAccount},
|
||||
@ -132,10 +131,10 @@ pub trait InvokeContext {
|
||||
fn set_blockhash(&mut self, hash: Hash);
|
||||
/// Get this invocation's blockhash
|
||||
fn get_blockhash(&self) -> &Hash;
|
||||
/// Set this invocation's `FeeCalculator`
|
||||
fn set_fee_calculator(&mut self, fee_calculator: FeeCalculator);
|
||||
/// Get this invocation's `FeeCalculator`
|
||||
fn get_fee_calculator(&self) -> &FeeCalculator;
|
||||
/// Set this invocation's lamports_per_signature value
|
||||
fn set_lamports_per_signature(&mut self, lamports_per_signature: u64);
|
||||
/// Get this invocation's lamports_per_signature value
|
||||
fn get_lamports_per_signature(&self) -> u64;
|
||||
/// Set the return data
|
||||
fn set_return_data(&mut self, data: Vec<u8>) -> Result<(), InstructionError>;
|
||||
/// Get the return data
|
||||
@ -361,7 +360,7 @@ pub struct MockInvokeContext<'a> {
|
||||
pub sysvars: RefCell<Vec<(Pubkey, Option<Rc<Vec<u8>>>)>>,
|
||||
pub disabled_features: HashSet<Pubkey>,
|
||||
pub blockhash: Hash,
|
||||
pub fee_calculator: FeeCalculator,
|
||||
pub lamports_per_signature: u64,
|
||||
pub return_data: (Pubkey, Vec<u8>),
|
||||
}
|
||||
|
||||
@ -380,7 +379,7 @@ impl<'a> MockInvokeContext<'a> {
|
||||
sysvars: RefCell::new(Vec::new()),
|
||||
disabled_features: HashSet::default(),
|
||||
blockhash: Hash::default(),
|
||||
fee_calculator: FeeCalculator::default(),
|
||||
lamports_per_signature: 0,
|
||||
return_data: (Pubkey::default(), Vec::new()),
|
||||
};
|
||||
let number_of_program_accounts = keyed_accounts
|
||||
@ -510,11 +509,11 @@ impl<'a> InvokeContext for MockInvokeContext<'a> {
|
||||
fn get_blockhash(&self) -> &Hash {
|
||||
&self.blockhash
|
||||
}
|
||||
fn set_fee_calculator(&mut self, fee_calculator: FeeCalculator) {
|
||||
self.fee_calculator = fee_calculator;
|
||||
fn set_lamports_per_signature(&mut self, lamports_per_signature: u64) {
|
||||
self.lamports_per_signature = lamports_per_signature;
|
||||
}
|
||||
fn get_fee_calculator(&self) -> &FeeCalculator {
|
||||
&self.fee_calculator
|
||||
fn get_lamports_per_signature(&self) -> u64 {
|
||||
self.lamports_per_signature
|
||||
}
|
||||
fn set_return_data(&mut self, data: Vec<u8>) -> Result<(), InstructionError> {
|
||||
self.return_data = (*self.get_caller()?, data);
|
||||
|
@ -83,7 +83,6 @@ mod tests {
|
||||
use crate::account::from_account;
|
||||
use rand::{seq::SliceRandom, thread_rng};
|
||||
use solana_program::{
|
||||
fee_calculator::FeeCalculator,
|
||||
hash::{Hash, HASH_BYTES},
|
||||
sysvar::recent_blockhashes::Entry,
|
||||
};
|
||||
@ -98,9 +97,9 @@ mod tests {
|
||||
#[test]
|
||||
fn test_create_account_full() {
|
||||
let def_hash = Hash::default();
|
||||
let def_fees = FeeCalculator::default();
|
||||
let def_lamports_per_signature = 0;
|
||||
let account = create_account_with_data_for_test(
|
||||
vec![IterItem(0u64, &def_hash, &def_fees); MAX_ENTRIES].into_iter(),
|
||||
vec![IterItem(0u64, &def_hash, def_lamports_per_signature); MAX_ENTRIES].into_iter(),
|
||||
);
|
||||
let recent_blockhashes = from_account::<RecentBlockhashes, _>(&account).unwrap();
|
||||
assert_eq!(recent_blockhashes.len(), MAX_ENTRIES);
|
||||
@ -109,9 +108,10 @@ mod tests {
|
||||
#[test]
|
||||
fn test_create_account_truncate() {
|
||||
let def_hash = Hash::default();
|
||||
let def_fees = FeeCalculator::default();
|
||||
let def_lamports_per_signature = 0;
|
||||
let account = create_account_with_data_for_test(
|
||||
vec![IterItem(0u64, &def_hash, &def_fees); MAX_ENTRIES + 1].into_iter(),
|
||||
vec![IterItem(0u64, &def_hash, def_lamports_per_signature); MAX_ENTRIES + 1]
|
||||
.into_iter(),
|
||||
);
|
||||
let recent_blockhashes = from_account::<RecentBlockhashes, _>(&account).unwrap();
|
||||
assert_eq!(recent_blockhashes.len(), MAX_ENTRIES);
|
||||
@ -119,7 +119,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_create_account_unsorted() {
|
||||
let def_fees = FeeCalculator::default();
|
||||
let def_lamports_per_signature = 0;
|
||||
let mut unsorted_blocks: Vec<_> = (0..MAX_ENTRIES)
|
||||
.map(|i| {
|
||||
(i as u64, {
|
||||
@ -135,13 +135,13 @@ mod tests {
|
||||
let account = create_account_with_data_for_test(
|
||||
unsorted_blocks
|
||||
.iter()
|
||||
.map(|(i, hash)| IterItem(*i, hash, &def_fees)),
|
||||
.map(|(i, hash)| IterItem(*i, hash, def_lamports_per_signature)),
|
||||
);
|
||||
let recent_blockhashes = from_account::<RecentBlockhashes, _>(&account).unwrap();
|
||||
|
||||
let mut unsorted_recent_blockhashes: Vec<_> = unsorted_blocks
|
||||
.iter()
|
||||
.map(|(i, hash)| IterItem(*i, hash, &def_fees))
|
||||
.map(|(i, hash)| IterItem(*i, hash, def_lamports_per_signature))
|
||||
.collect();
|
||||
unsorted_recent_blockhashes.sort();
|
||||
unsorted_recent_blockhashes.reverse();
|
||||
|
Reference in New Issue
Block a user