Divorce the runtime from FeeCalculator (#20737)

This commit is contained in:
Jack May
2021-10-22 14:32:40 -07:00
committed by GitHub
parent 613c7b8444
commit bfbbc53dac
24 changed files with 503 additions and 563 deletions

View File

@ -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()

View File

@ -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,
}
}

View File

@ -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,

View File

@ -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);

View File

@ -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();