Stop caching sysvars, instead load them ahead of time. (#21108)
This commit is contained in:
parent
692cd5a2f8
commit
29ad081555
|
@ -1400,9 +1400,9 @@ fn assert_instruction_count() {
|
||||||
("solana_bpf_rust_noop", 480),
|
("solana_bpf_rust_noop", 480),
|
||||||
("solana_bpf_rust_param_passing", 146),
|
("solana_bpf_rust_param_passing", 146),
|
||||||
("solana_bpf_rust_rand", 487),
|
("solana_bpf_rust_rand", 487),
|
||||||
("solana_bpf_rust_sanity", 8406),
|
("solana_bpf_rust_sanity", 8454),
|
||||||
("solana_bpf_rust_secp256k1_recover", 25216),
|
("solana_bpf_rust_secp256k1_recover", 25216),
|
||||||
("solana_bpf_rust_sha", 30704),
|
("solana_bpf_rust_sha", 30692),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3284,10 +3284,8 @@ mod tests {
|
||||||
let mut invoke_context = MockInvokeContext::new(&Pubkey::default(), vec![]);
|
let mut invoke_context = MockInvokeContext::new(&Pubkey::default(), vec![]);
|
||||||
let mut data = vec![];
|
let mut data = vec![];
|
||||||
bincode::serialize_into(&mut data, &src_clock).unwrap();
|
bincode::serialize_into(&mut data, &src_clock).unwrap();
|
||||||
invoke_context
|
let sysvars = &[(sysvar::clock::id(), data)];
|
||||||
.get_sysvars()
|
invoke_context.sysvars = sysvars;
|
||||||
.borrow_mut()
|
|
||||||
.push((sysvar::clock::id(), Some(Rc::new(data))));
|
|
||||||
|
|
||||||
let mut syscall = SyscallGetClockSysvar {
|
let mut syscall = SyscallGetClockSysvar {
|
||||||
invoke_context: Rc::new(RefCell::new(&mut invoke_context)),
|
invoke_context: Rc::new(RefCell::new(&mut invoke_context)),
|
||||||
|
@ -3330,10 +3328,8 @@ mod tests {
|
||||||
let mut invoke_context = MockInvokeContext::new(&Pubkey::default(), vec![]);
|
let mut invoke_context = MockInvokeContext::new(&Pubkey::default(), vec![]);
|
||||||
let mut data = vec![];
|
let mut data = vec![];
|
||||||
bincode::serialize_into(&mut data, &src_epochschedule).unwrap();
|
bincode::serialize_into(&mut data, &src_epochschedule).unwrap();
|
||||||
invoke_context
|
let sysvars = &[(sysvar::epoch_schedule::id(), data)];
|
||||||
.get_sysvars()
|
invoke_context.sysvars = sysvars;
|
||||||
.borrow_mut()
|
|
||||||
.push((sysvar::epoch_schedule::id(), Some(Rc::new(data))));
|
|
||||||
|
|
||||||
let mut syscall = SyscallGetEpochScheduleSysvar {
|
let mut syscall = SyscallGetEpochScheduleSysvar {
|
||||||
invoke_context: Rc::new(RefCell::new(&mut invoke_context)),
|
invoke_context: Rc::new(RefCell::new(&mut invoke_context)),
|
||||||
|
@ -3383,10 +3379,8 @@ mod tests {
|
||||||
let mut invoke_context = MockInvokeContext::new(&Pubkey::default(), vec![]);
|
let mut invoke_context = MockInvokeContext::new(&Pubkey::default(), vec![]);
|
||||||
let mut data = vec![];
|
let mut data = vec![];
|
||||||
bincode::serialize_into(&mut data, &src_fees).unwrap();
|
bincode::serialize_into(&mut data, &src_fees).unwrap();
|
||||||
invoke_context
|
let sysvars = &[(sysvar::fees::id(), data)];
|
||||||
.get_sysvars()
|
invoke_context.sysvars = sysvars;
|
||||||
.borrow_mut()
|
|
||||||
.push((sysvar::fees::id(), Some(Rc::new(data))));
|
|
||||||
|
|
||||||
let mut syscall = SyscallGetFeesSysvar {
|
let mut syscall = SyscallGetFeesSysvar {
|
||||||
invoke_context: Rc::new(RefCell::new(&mut invoke_context)),
|
invoke_context: Rc::new(RefCell::new(&mut invoke_context)),
|
||||||
|
@ -3427,10 +3421,8 @@ mod tests {
|
||||||
let mut invoke_context = MockInvokeContext::new(&Pubkey::default(), vec![]);
|
let mut invoke_context = MockInvokeContext::new(&Pubkey::default(), vec![]);
|
||||||
let mut data = vec![];
|
let mut data = vec![];
|
||||||
bincode::serialize_into(&mut data, &src_rent).unwrap();
|
bincode::serialize_into(&mut data, &src_rent).unwrap();
|
||||||
invoke_context
|
let sysvars = &[(sysvar::rent::id(), data)];
|
||||||
.get_sysvars()
|
invoke_context.sysvars = sysvars;
|
||||||
.borrow_mut()
|
|
||||||
.push((sysvar::rent::id(), Some(Rc::new(data))));
|
|
||||||
|
|
||||||
let mut syscall = SyscallGetRentSysvar {
|
let mut syscall = SyscallGetRentSysvar {
|
||||||
invoke_context: Rc::new(RefCell::new(&mut invoke_context)),
|
invoke_context: Rc::new(RefCell::new(&mut invoke_context)),
|
||||||
|
|
|
@ -340,7 +340,7 @@ mod tests {
|
||||||
},
|
},
|
||||||
sysvar::{stake_history::StakeHistory, Sysvar},
|
sysvar::{stake_history::StakeHistory, Sysvar},
|
||||||
};
|
};
|
||||||
use std::{cell::RefCell, rc::Rc, str::FromStr};
|
use std::{cell::RefCell, str::FromStr};
|
||||||
|
|
||||||
fn create_default_account() -> RefCell<AccountSharedData> {
|
fn create_default_account() -> RefCell<AccountSharedData> {
|
||||||
RefCell::new(AccountSharedData::default())
|
RefCell::new(AccountSharedData::default())
|
||||||
|
@ -444,10 +444,8 @@ mod tests {
|
||||||
);
|
);
|
||||||
let mut data = Vec::with_capacity(sysvar::clock::Clock::size_of());
|
let mut data = Vec::with_capacity(sysvar::clock::Clock::size_of());
|
||||||
bincode::serialize_into(&mut data, &sysvar::clock::Clock::default()).unwrap();
|
bincode::serialize_into(&mut data, &sysvar::clock::Clock::default()).unwrap();
|
||||||
invoke_context
|
let sysvars = &[(sysvar::clock::id(), data)];
|
||||||
.get_sysvars()
|
invoke_context.sysvars = sysvars;
|
||||||
.borrow_mut()
|
|
||||||
.push((sysvar::clock::id(), Some(Rc::new(data))));
|
|
||||||
super::process_instruction(1, &instruction.data, &mut invoke_context)
|
super::process_instruction(1, &instruction.data, &mut invoke_context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1102,10 +1100,8 @@ mod tests {
|
||||||
MockInvokeContext::new(&id(), create_keyed_accounts_unified(&keyed_accounts));
|
MockInvokeContext::new(&id(), create_keyed_accounts_unified(&keyed_accounts));
|
||||||
let mut data = Vec::with_capacity(sysvar::clock::Clock::size_of());
|
let mut data = Vec::with_capacity(sysvar::clock::Clock::size_of());
|
||||||
bincode::serialize_into(&mut data, &sysvar::clock::Clock::default()).unwrap();
|
bincode::serialize_into(&mut data, &sysvar::clock::Clock::default()).unwrap();
|
||||||
invoke_context
|
let sysvars = &[(sysvar::clock::id(), data)];
|
||||||
.get_sysvars()
|
invoke_context.sysvars = sysvars;
|
||||||
.borrow_mut()
|
|
||||||
.push((sysvar::clock::id(), Some(Rc::new(data))));
|
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
super::process_instruction(
|
super::process_instruction(
|
||||||
|
|
|
@ -1006,6 +1006,8 @@ pub struct Bank {
|
||||||
vote_only_bank: bool,
|
vote_only_bank: bool,
|
||||||
|
|
||||||
pub cost_tracker: RwLock<CostTracker>,
|
pub cost_tracker: RwLock<CostTracker>,
|
||||||
|
|
||||||
|
sysvar_cache: RwLock<Vec<(Pubkey, Vec<u8>)>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for BlockhashQueue {
|
impl Default for BlockhashQueue {
|
||||||
|
@ -1145,6 +1147,7 @@ impl Bank {
|
||||||
freeze_started: AtomicBool::default(),
|
freeze_started: AtomicBool::default(),
|
||||||
vote_only_bank: false,
|
vote_only_bank: false,
|
||||||
cost_tracker: RwLock::<CostTracker>::default(),
|
cost_tracker: RwLock::<CostTracker>::default(),
|
||||||
|
sysvar_cache: RwLock::new(Vec::new()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1254,6 +1257,7 @@ impl Bank {
|
||||||
bank.update_rent();
|
bank.update_rent();
|
||||||
bank.update_epoch_schedule();
|
bank.update_epoch_schedule();
|
||||||
bank.update_recent_blockhashes();
|
bank.update_recent_blockhashes();
|
||||||
|
bank.fill_sysvar_cache();
|
||||||
bank
|
bank
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1402,6 +1406,7 @@ impl Bank {
|
||||||
)),
|
)),
|
||||||
freeze_started: AtomicBool::new(false),
|
freeze_started: AtomicBool::new(false),
|
||||||
cost_tracker: RwLock::new(CostTracker::default()),
|
cost_tracker: RwLock::new(CostTracker::default()),
|
||||||
|
sysvar_cache: RwLock::new(Vec::new()),
|
||||||
};
|
};
|
||||||
|
|
||||||
datapoint_info!(
|
datapoint_info!(
|
||||||
|
@ -1458,6 +1463,7 @@ impl Bank {
|
||||||
new.update_stake_history(Some(parent_epoch));
|
new.update_stake_history(Some(parent_epoch));
|
||||||
new.update_clock(Some(parent_epoch));
|
new.update_clock(Some(parent_epoch));
|
||||||
new.update_fees();
|
new.update_fees();
|
||||||
|
new.fill_sysvar_cache();
|
||||||
|
|
||||||
return new;
|
return new;
|
||||||
}
|
}
|
||||||
|
@ -1473,6 +1479,7 @@ impl Bank {
|
||||||
new.update_stake_history(Some(parent_epoch));
|
new.update_stake_history(Some(parent_epoch));
|
||||||
new.update_clock(Some(parent_epoch));
|
new.update_clock(Some(parent_epoch));
|
||||||
new.update_fees();
|
new.update_fees();
|
||||||
|
new.fill_sysvar_cache();
|
||||||
new
|
new
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1589,6 +1596,7 @@ impl Bank {
|
||||||
freeze_started: AtomicBool::new(fields.hash != Hash::default()),
|
freeze_started: AtomicBool::new(fields.hash != Hash::default()),
|
||||||
vote_only_bank: false,
|
vote_only_bank: false,
|
||||||
cost_tracker: RwLock::new(CostTracker::default()),
|
cost_tracker: RwLock::new(CostTracker::default()),
|
||||||
|
sysvar_cache: RwLock::new(Vec::new()),
|
||||||
};
|
};
|
||||||
bank.finish_init(
|
bank.finish_init(
|
||||||
genesis_config,
|
genesis_config,
|
||||||
|
@ -1767,6 +1775,14 @@ impl Bank {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.store_account_and_update_capitalization(pubkey, &new_account);
|
self.store_account_and_update_capitalization(pubkey, &new_account);
|
||||||
|
|
||||||
|
// Update the entry in the cache
|
||||||
|
let mut sysvar_cache = self.sysvar_cache.write().unwrap();
|
||||||
|
if let Some(position) = sysvar_cache.iter().position(|(id, _data)| id == pubkey) {
|
||||||
|
sysvar_cache[position].1 = new_account.data().to_vec();
|
||||||
|
} else {
|
||||||
|
sysvar_cache.push((*pubkey, new_account.data().to_vec()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inherit_specially_retained_account_fields(
|
fn inherit_specially_retained_account_fields(
|
||||||
|
@ -1904,6 +1920,17 @@ impl Bank {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn fill_sysvar_cache(&mut self) {
|
||||||
|
let mut sysvar_cache = self.sysvar_cache.write().unwrap();
|
||||||
|
for id in sysvar::ALL_IDS.iter() {
|
||||||
|
if !sysvar_cache.iter().any(|(key, _data)| key == id) {
|
||||||
|
if let Some(account) = self.get_account_with_fixed_root(id) {
|
||||||
|
sysvar_cache.push((*id, account.data().to_vec()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_slot_history(&self) -> SlotHistory {
|
pub fn get_slot_history(&self) -> SlotHistory {
|
||||||
from_account(&self.get_account(&sysvar::slot_history::id()).unwrap()).unwrap()
|
from_account(&self.get_account(&sysvar::slot_history::id()).unwrap()).unwrap()
|
||||||
}
|
}
|
||||||
|
@ -3858,8 +3885,7 @@ impl Bank {
|
||||||
compute_budget,
|
compute_budget,
|
||||||
compute_meter,
|
compute_meter,
|
||||||
&mut timings.details,
|
&mut timings.details,
|
||||||
self.rc.accounts.clone(),
|
&*self.sysvar_cache.read().unwrap(),
|
||||||
&self.ancestors,
|
|
||||||
blockhash,
|
blockhash,
|
||||||
lamports_per_signature,
|
lamports_per_signature,
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
accounts::Accounts, ancestors::Ancestors, instruction_recorder::InstructionRecorder,
|
instruction_recorder::InstructionRecorder, log_collector::LogCollector,
|
||||||
log_collector::LogCollector, rent_collector::RentCollector,
|
rent_collector::RentCollector,
|
||||||
};
|
};
|
||||||
use log::*;
|
use log::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -80,6 +80,7 @@ pub struct ThisInvokeContext<'a> {
|
||||||
pre_accounts: Vec<PreAccount>,
|
pre_accounts: Vec<PreAccount>,
|
||||||
accounts: &'a [(Pubkey, Rc<RefCell<AccountSharedData>>)],
|
accounts: &'a [(Pubkey, Rc<RefCell<AccountSharedData>>)],
|
||||||
programs: &'a [(Pubkey, ProcessInstructionWithContext)],
|
programs: &'a [(Pubkey, ProcessInstructionWithContext)],
|
||||||
|
sysvars: &'a [(Pubkey, Vec<u8>)],
|
||||||
logger: Rc<RefCell<dyn Logger>>,
|
logger: Rc<RefCell<dyn Logger>>,
|
||||||
compute_budget: ComputeBudget,
|
compute_budget: ComputeBudget,
|
||||||
compute_meter: Rc<RefCell<dyn ComputeMeter>>,
|
compute_meter: Rc<RefCell<dyn ComputeMeter>>,
|
||||||
|
@ -87,10 +88,6 @@ pub struct ThisInvokeContext<'a> {
|
||||||
instruction_recorders: Option<&'a [InstructionRecorder]>,
|
instruction_recorders: Option<&'a [InstructionRecorder]>,
|
||||||
feature_set: Arc<FeatureSet>,
|
feature_set: Arc<FeatureSet>,
|
||||||
pub timings: ExecuteDetailsTimings,
|
pub timings: ExecuteDetailsTimings,
|
||||||
account_db: Arc<Accounts>,
|
|
||||||
ancestors: Option<&'a Ancestors>,
|
|
||||||
#[allow(clippy::type_complexity)]
|
|
||||||
sysvars: RefCell<Vec<(Pubkey, Option<Rc<Vec<u8>>>)>>,
|
|
||||||
blockhash: Hash,
|
blockhash: Hash,
|
||||||
lamports_per_signature: u64,
|
lamports_per_signature: u64,
|
||||||
return_data: (Pubkey, Vec<u8>),
|
return_data: (Pubkey, Vec<u8>),
|
||||||
|
@ -101,14 +98,13 @@ impl<'a> ThisInvokeContext<'a> {
|
||||||
rent: Rent,
|
rent: Rent,
|
||||||
accounts: &'a [(Pubkey, Rc<RefCell<AccountSharedData>>)],
|
accounts: &'a [(Pubkey, Rc<RefCell<AccountSharedData>>)],
|
||||||
programs: &'a [(Pubkey, ProcessInstructionWithContext)],
|
programs: &'a [(Pubkey, ProcessInstructionWithContext)],
|
||||||
|
sysvars: &'a [(Pubkey, Vec<u8>)],
|
||||||
log_collector: Option<Rc<LogCollector>>,
|
log_collector: Option<Rc<LogCollector>>,
|
||||||
compute_budget: ComputeBudget,
|
compute_budget: ComputeBudget,
|
||||||
compute_meter: Rc<RefCell<dyn ComputeMeter>>,
|
compute_meter: Rc<RefCell<dyn ComputeMeter>>,
|
||||||
executors: Rc<RefCell<Executors>>,
|
executors: Rc<RefCell<Executors>>,
|
||||||
instruction_recorders: Option<&'a [InstructionRecorder]>,
|
instruction_recorders: Option<&'a [InstructionRecorder]>,
|
||||||
feature_set: Arc<FeatureSet>,
|
feature_set: Arc<FeatureSet>,
|
||||||
account_db: Arc<Accounts>,
|
|
||||||
ancestors: Option<&'a Ancestors>,
|
|
||||||
blockhash: Hash,
|
blockhash: Hash,
|
||||||
lamports_per_signature: u64,
|
lamports_per_signature: u64,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
@ -119,6 +115,7 @@ impl<'a> ThisInvokeContext<'a> {
|
||||||
pre_accounts: Vec::new(),
|
pre_accounts: Vec::new(),
|
||||||
accounts,
|
accounts,
|
||||||
programs,
|
programs,
|
||||||
|
sysvars,
|
||||||
logger: ThisLogger::new_ref(log_collector),
|
logger: ThisLogger::new_ref(log_collector),
|
||||||
compute_budget,
|
compute_budget,
|
||||||
compute_meter,
|
compute_meter,
|
||||||
|
@ -126,32 +123,29 @@ impl<'a> ThisInvokeContext<'a> {
|
||||||
instruction_recorders,
|
instruction_recorders,
|
||||||
feature_set,
|
feature_set,
|
||||||
timings: ExecuteDetailsTimings::default(),
|
timings: ExecuteDetailsTimings::default(),
|
||||||
account_db,
|
|
||||||
ancestors,
|
|
||||||
sysvars: RefCell::new(Vec::new()),
|
|
||||||
blockhash,
|
blockhash,
|
||||||
lamports_per_signature,
|
lamports_per_signature,
|
||||||
return_data: (Pubkey::default(), Vec::new()),
|
return_data: (Pubkey::default(), Vec::new()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_mock_with_features(
|
pub fn new_mock_with_sysvars_and_features(
|
||||||
accounts: &'a [(Pubkey, Rc<RefCell<AccountSharedData>>)],
|
accounts: &'a [(Pubkey, Rc<RefCell<AccountSharedData>>)],
|
||||||
programs: &'a [(Pubkey, ProcessInstructionWithContext)],
|
programs: &'a [(Pubkey, ProcessInstructionWithContext)],
|
||||||
|
sysvars: &'a [(Pubkey, Vec<u8>)],
|
||||||
feature_set: Arc<FeatureSet>,
|
feature_set: Arc<FeatureSet>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self::new(
|
Self::new(
|
||||||
Rent::default(),
|
Rent::default(),
|
||||||
accounts,
|
accounts,
|
||||||
programs,
|
programs,
|
||||||
|
sysvars,
|
||||||
None,
|
None,
|
||||||
ComputeBudget::default(),
|
ComputeBudget::default(),
|
||||||
ThisComputeMeter::new_ref(std::i64::MAX as u64),
|
ThisComputeMeter::new_ref(std::i64::MAX as u64),
|
||||||
Rc::new(RefCell::new(Executors::default())),
|
Rc::new(RefCell::new(Executors::default())),
|
||||||
None,
|
None,
|
||||||
feature_set,
|
feature_set,
|
||||||
Arc::new(Accounts::default_for_tests()),
|
|
||||||
None,
|
|
||||||
Hash::default(),
|
Hash::default(),
|
||||||
0,
|
0,
|
||||||
)
|
)
|
||||||
|
@ -161,7 +155,12 @@ impl<'a> ThisInvokeContext<'a> {
|
||||||
accounts: &'a [(Pubkey, Rc<RefCell<AccountSharedData>>)],
|
accounts: &'a [(Pubkey, Rc<RefCell<AccountSharedData>>)],
|
||||||
programs: &'a [(Pubkey, ProcessInstructionWithContext)],
|
programs: &'a [(Pubkey, ProcessInstructionWithContext)],
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self::new_mock_with_features(accounts, programs, Arc::new(FeatureSet::all_enabled()))
|
Self::new_mock_with_sysvars_and_features(
|
||||||
|
accounts,
|
||||||
|
programs,
|
||||||
|
&[],
|
||||||
|
Arc::new(FeatureSet::all_enabled()),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'a> InvokeContext for ThisInvokeContext<'a> {
|
impl<'a> InvokeContext for ThisInvokeContext<'a> {
|
||||||
|
@ -452,31 +451,8 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> {
|
||||||
self.timings.execute_us += execute_us;
|
self.timings.execute_us += execute_us;
|
||||||
self.timings.deserialize_us += deserialize_us;
|
self.timings.deserialize_us += deserialize_us;
|
||||||
}
|
}
|
||||||
#[allow(clippy::type_complexity)]
|
fn get_sysvars(&self) -> &[(Pubkey, Vec<u8>)] {
|
||||||
fn get_sysvars(&self) -> &RefCell<Vec<(Pubkey, Option<Rc<Vec<u8>>>)>> {
|
self.sysvars
|
||||||
&self.sysvars
|
|
||||||
}
|
|
||||||
fn get_sysvar_data(&self, id: &Pubkey) -> Option<Rc<Vec<u8>>> {
|
|
||||||
if let Ok(mut sysvars) = self.sysvars.try_borrow_mut() {
|
|
||||||
// Try share from cache
|
|
||||||
let mut result = sysvars
|
|
||||||
.iter()
|
|
||||||
.find_map(|(key, sysvar)| if id == key { sysvar.clone() } else { None });
|
|
||||||
if result.is_none() {
|
|
||||||
if let Some(ancestors) = self.ancestors {
|
|
||||||
// Load it
|
|
||||||
result = self
|
|
||||||
.account_db
|
|
||||||
.load_with_fixed_root(ancestors, id)
|
|
||||||
.map(|(account, _)| Rc::new(account.data().to_vec()));
|
|
||||||
// Cache it
|
|
||||||
sysvars.push((*id, result.clone()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
fn get_compute_budget(&self) -> &ComputeBudget {
|
fn get_compute_budget(&self) -> &ComputeBudget {
|
||||||
&self.compute_budget
|
&self.compute_budget
|
||||||
|
@ -604,7 +580,6 @@ impl MessageProcessor {
|
||||||
/// the call does not violate the bank's accounting rules.
|
/// the call does not violate the bank's accounting rules.
|
||||||
/// The accounts are committed back to the bank only if every instruction succeeds.
|
/// The accounts are committed back to the bank only if every instruction succeeds.
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
#[allow(clippy::type_complexity)]
|
|
||||||
pub fn process_message(
|
pub fn process_message(
|
||||||
instruction_processor: &InstructionProcessor,
|
instruction_processor: &InstructionProcessor,
|
||||||
message: &Message,
|
message: &Message,
|
||||||
|
@ -618,8 +593,7 @@ impl MessageProcessor {
|
||||||
compute_budget: ComputeBudget,
|
compute_budget: ComputeBudget,
|
||||||
compute_meter: Rc<RefCell<dyn ComputeMeter>>,
|
compute_meter: Rc<RefCell<dyn ComputeMeter>>,
|
||||||
timings: &mut ExecuteDetailsTimings,
|
timings: &mut ExecuteDetailsTimings,
|
||||||
account_db: Arc<Accounts>,
|
sysvars: &[(Pubkey, Vec<u8>)],
|
||||||
ancestors: &Ancestors,
|
|
||||||
blockhash: Hash,
|
blockhash: Hash,
|
||||||
lamports_per_signature: u64,
|
lamports_per_signature: u64,
|
||||||
) -> Result<(), TransactionError> {
|
) -> Result<(), TransactionError> {
|
||||||
|
@ -627,14 +601,13 @@ impl MessageProcessor {
|
||||||
rent_collector.rent,
|
rent_collector.rent,
|
||||||
accounts,
|
accounts,
|
||||||
instruction_processor.programs(),
|
instruction_processor.programs(),
|
||||||
|
sysvars,
|
||||||
log_collector,
|
log_collector,
|
||||||
compute_budget,
|
compute_budget,
|
||||||
compute_meter,
|
compute_meter,
|
||||||
executors,
|
executors,
|
||||||
instruction_recorders,
|
instruction_recorders,
|
||||||
feature_set,
|
feature_set,
|
||||||
account_db,
|
|
||||||
Some(ancestors),
|
|
||||||
blockhash,
|
blockhash,
|
||||||
lamports_per_signature,
|
lamports_per_signature,
|
||||||
);
|
);
|
||||||
|
@ -979,7 +952,6 @@ mod tests {
|
||||||
let program_indices = vec![vec![2]];
|
let program_indices = vec![vec![2]];
|
||||||
|
|
||||||
let executors = Rc::new(RefCell::new(Executors::default()));
|
let executors = Rc::new(RefCell::new(Executors::default()));
|
||||||
let ancestors = Ancestors::default();
|
|
||||||
|
|
||||||
let account_metas = vec![
|
let account_metas = vec![
|
||||||
AccountMeta::new(accounts[0].0, true),
|
AccountMeta::new(accounts[0].0, true),
|
||||||
|
@ -1007,8 +979,7 @@ mod tests {
|
||||||
ComputeBudget::new(),
|
ComputeBudget::new(),
|
||||||
ThisComputeMeter::new_ref(std::i64::MAX as u64),
|
ThisComputeMeter::new_ref(std::i64::MAX as u64),
|
||||||
&mut ExecuteDetailsTimings::default(),
|
&mut ExecuteDetailsTimings::default(),
|
||||||
Arc::new(Accounts::default_for_tests()),
|
&[],
|
||||||
&ancestors,
|
|
||||||
Hash::default(),
|
Hash::default(),
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
|
@ -1038,8 +1009,7 @@ mod tests {
|
||||||
ComputeBudget::new(),
|
ComputeBudget::new(),
|
||||||
ThisComputeMeter::new_ref(std::i64::MAX as u64),
|
ThisComputeMeter::new_ref(std::i64::MAX as u64),
|
||||||
&mut ExecuteDetailsTimings::default(),
|
&mut ExecuteDetailsTimings::default(),
|
||||||
Arc::new(Accounts::default_for_tests()),
|
&[],
|
||||||
&ancestors,
|
|
||||||
Hash::default(),
|
Hash::default(),
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
|
@ -1073,8 +1043,7 @@ mod tests {
|
||||||
ComputeBudget::new(),
|
ComputeBudget::new(),
|
||||||
ThisComputeMeter::new_ref(std::i64::MAX as u64),
|
ThisComputeMeter::new_ref(std::i64::MAX as u64),
|
||||||
&mut ExecuteDetailsTimings::default(),
|
&mut ExecuteDetailsTimings::default(),
|
||||||
Arc::new(Accounts::default_for_tests()),
|
&[],
|
||||||
&ancestors,
|
|
||||||
Hash::default(),
|
Hash::default(),
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
|
@ -1188,7 +1157,6 @@ mod tests {
|
||||||
let program_indices = vec![vec![2]];
|
let program_indices = vec![vec![2]];
|
||||||
|
|
||||||
let executors = Rc::new(RefCell::new(Executors::default()));
|
let executors = Rc::new(RefCell::new(Executors::default()));
|
||||||
let ancestors = Ancestors::default();
|
|
||||||
|
|
||||||
let account_metas = vec![
|
let account_metas = vec![
|
||||||
AccountMeta::new(accounts[0].0, true),
|
AccountMeta::new(accounts[0].0, true),
|
||||||
|
@ -1218,8 +1186,7 @@ mod tests {
|
||||||
ComputeBudget::new(),
|
ComputeBudget::new(),
|
||||||
ThisComputeMeter::new_ref(std::i64::MAX as u64),
|
ThisComputeMeter::new_ref(std::i64::MAX as u64),
|
||||||
&mut ExecuteDetailsTimings::default(),
|
&mut ExecuteDetailsTimings::default(),
|
||||||
Arc::new(Accounts::default_for_tests()),
|
&[],
|
||||||
&ancestors,
|
|
||||||
Hash::default(),
|
Hash::default(),
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
|
@ -1253,8 +1220,7 @@ mod tests {
|
||||||
ComputeBudget::new(),
|
ComputeBudget::new(),
|
||||||
ThisComputeMeter::new_ref(std::i64::MAX as u64),
|
ThisComputeMeter::new_ref(std::i64::MAX as u64),
|
||||||
&mut ExecuteDetailsTimings::default(),
|
&mut ExecuteDetailsTimings::default(),
|
||||||
Arc::new(Accounts::default_for_tests()),
|
&[],
|
||||||
&ancestors,
|
|
||||||
Hash::default(),
|
Hash::default(),
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
|
@ -1272,7 +1238,6 @@ mod tests {
|
||||||
)],
|
)],
|
||||||
Some(&accounts[0].0),
|
Some(&accounts[0].0),
|
||||||
);
|
);
|
||||||
let ancestors = Ancestors::default();
|
|
||||||
let result = MessageProcessor::process_message(
|
let result = MessageProcessor::process_message(
|
||||||
&instruction_processor,
|
&instruction_processor,
|
||||||
&message,
|
&message,
|
||||||
|
@ -1286,8 +1251,7 @@ mod tests {
|
||||||
ComputeBudget::new(),
|
ComputeBudget::new(),
|
||||||
ThisComputeMeter::new_ref(std::i64::MAX as u64),
|
ThisComputeMeter::new_ref(std::i64::MAX as u64),
|
||||||
&mut ExecuteDetailsTimings::default(),
|
&mut ExecuteDetailsTimings::default(),
|
||||||
Arc::new(Accounts::default_for_tests()),
|
&[],
|
||||||
&ancestors,
|
|
||||||
Hash::default(),
|
Hash::default(),
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
|
@ -1578,8 +1542,7 @@ mod tests {
|
||||||
ComputeBudget::new(),
|
ComputeBudget::new(),
|
||||||
ThisComputeMeter::new_ref(std::i64::MAX as u64),
|
ThisComputeMeter::new_ref(std::i64::MAX as u64),
|
||||||
&mut ExecuteDetailsTimings::default(),
|
&mut ExecuteDetailsTimings::default(),
|
||||||
Arc::new(Accounts::default_for_tests()),
|
&[],
|
||||||
&Ancestors::default(),
|
|
||||||
Hash::default(),
|
Hash::default(),
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
//! named accounts for synthesized data accounts for bank state, etc.
|
//! named accounts for synthesized data accounts for bank state, etc.
|
||||||
//!
|
//!
|
||||||
use crate::{account_info::AccountInfo, program_error::ProgramError, pubkey::Pubkey};
|
use crate::{account_info::AccountInfo, program_error::ProgramError, pubkey::Pubkey};
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
|
||||||
pub mod clock;
|
pub mod clock;
|
||||||
pub mod epoch_schedule;
|
pub mod epoch_schedule;
|
||||||
|
@ -13,18 +14,25 @@ pub mod slot_hashes;
|
||||||
pub mod slot_history;
|
pub mod slot_history;
|
||||||
pub mod stake_history;
|
pub mod stake_history;
|
||||||
|
|
||||||
#[allow(deprecated)]
|
lazy_static! {
|
||||||
|
pub static ref ALL_IDS: Vec<Pubkey> = vec![
|
||||||
|
clock::id(),
|
||||||
|
epoch_schedule::id(),
|
||||||
|
#[allow(deprecated)]
|
||||||
|
fees::id(),
|
||||||
|
#[allow(deprecated)]
|
||||||
|
recent_blockhashes::id(),
|
||||||
|
rent::id(),
|
||||||
|
rewards::id(),
|
||||||
|
slot_hashes::id(),
|
||||||
|
slot_history::id(),
|
||||||
|
stake_history::id(),
|
||||||
|
instructions::id(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
pub fn is_sysvar_id(id: &Pubkey) -> bool {
|
pub fn is_sysvar_id(id: &Pubkey) -> bool {
|
||||||
clock::check_id(id)
|
ALL_IDS.iter().any(|key| key == id)
|
||||||
|| epoch_schedule::check_id(id)
|
|
||||||
|| fees::check_id(id)
|
|
||||||
|| recent_blockhashes::check_id(id)
|
|
||||||
|| rent::check_id(id)
|
|
||||||
|| rewards::check_id(id)
|
|
||||||
|| slot_hashes::check_id(id)
|
|
||||||
|| slot_history::check_id(id)
|
|
||||||
|| stake_history::check_id(id)
|
|
||||||
|| instructions::check_id(id)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
|
|
|
@ -121,10 +121,7 @@ pub trait InvokeContext {
|
||||||
deserialize_us: u64,
|
deserialize_us: u64,
|
||||||
);
|
);
|
||||||
/// Get sysvars
|
/// Get sysvars
|
||||||
#[allow(clippy::type_complexity)]
|
fn get_sysvars(&self) -> &[(Pubkey, Vec<u8>)];
|
||||||
fn get_sysvars(&self) -> &RefCell<Vec<(Pubkey, Option<Rc<Vec<u8>>>)>>;
|
|
||||||
/// Get sysvar data
|
|
||||||
fn get_sysvar_data(&self, id: &Pubkey) -> Option<Rc<Vec<u8>>>;
|
|
||||||
/// Get this invocation's compute budget
|
/// Get this invocation's compute budget
|
||||||
fn get_compute_budget(&self) -> &ComputeBudget;
|
fn get_compute_budget(&self) -> &ComputeBudget;
|
||||||
/// Set this invocation's blockhash
|
/// Set this invocation's blockhash
|
||||||
|
@ -175,15 +172,20 @@ pub fn get_sysvar<T: Sysvar>(
|
||||||
invoke_context: &dyn InvokeContext,
|
invoke_context: &dyn InvokeContext,
|
||||||
id: &Pubkey,
|
id: &Pubkey,
|
||||||
) -> Result<T, InstructionError> {
|
) -> Result<T, InstructionError> {
|
||||||
let sysvar_data = invoke_context.get_sysvar_data(id).ok_or_else(|| {
|
invoke_context
|
||||||
ic_msg!(invoke_context, "Unable to get sysvar {}", id);
|
.get_sysvars()
|
||||||
InstructionError::UnsupportedSysvar
|
.iter()
|
||||||
})?;
|
.find_map(|(key, data)| {
|
||||||
|
if id == key {
|
||||||
bincode::deserialize(&sysvar_data).map_err(|err| {
|
bincode::deserialize(data).ok()
|
||||||
ic_msg!(invoke_context, "Unable to get sysvar {}: {:?}", id, err);
|
} else {
|
||||||
InstructionError::UnsupportedSysvar
|
None
|
||||||
})
|
}
|
||||||
|
})
|
||||||
|
.ok_or_else(|| {
|
||||||
|
ic_msg!(invoke_context, "Unable to get sysvar {}", id);
|
||||||
|
InstructionError::UnsupportedSysvar
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compute meter
|
/// Compute meter
|
||||||
|
@ -356,8 +358,7 @@ pub struct MockInvokeContext<'a> {
|
||||||
pub compute_meter: Rc<RefCell<dyn ComputeMeter>>,
|
pub compute_meter: Rc<RefCell<dyn ComputeMeter>>,
|
||||||
pub programs: Vec<(Pubkey, ProcessInstructionWithContext)>,
|
pub programs: Vec<(Pubkey, ProcessInstructionWithContext)>,
|
||||||
pub accounts: Vec<(Pubkey, Rc<RefCell<AccountSharedData>>)>,
|
pub accounts: Vec<(Pubkey, Rc<RefCell<AccountSharedData>>)>,
|
||||||
#[allow(clippy::type_complexity)]
|
pub sysvars: &'a [(Pubkey, Vec<u8>)],
|
||||||
pub sysvars: RefCell<Vec<(Pubkey, Option<Rc<Vec<u8>>>)>>,
|
|
||||||
pub disabled_features: HashSet<Pubkey>,
|
pub disabled_features: HashSet<Pubkey>,
|
||||||
pub blockhash: Hash,
|
pub blockhash: Hash,
|
||||||
pub lamports_per_signature: u64,
|
pub lamports_per_signature: u64,
|
||||||
|
@ -376,7 +377,7 @@ impl<'a> MockInvokeContext<'a> {
|
||||||
})),
|
})),
|
||||||
programs: vec![],
|
programs: vec![],
|
||||||
accounts: vec![],
|
accounts: vec![],
|
||||||
sysvars: RefCell::new(Vec::new()),
|
sysvars: &[],
|
||||||
disabled_features: HashSet::default(),
|
disabled_features: HashSet::default(),
|
||||||
blockhash: Hash::default(),
|
blockhash: Hash::default(),
|
||||||
lamports_per_signature: 0,
|
lamports_per_signature: 0,
|
||||||
|
@ -490,15 +491,8 @@ impl<'a> InvokeContext for MockInvokeContext<'a> {
|
||||||
_deserialize_us: u64,
|
_deserialize_us: u64,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
#[allow(clippy::type_complexity)]
|
fn get_sysvars(&self) -> &[(Pubkey, Vec<u8>)] {
|
||||||
fn get_sysvars(&self) -> &RefCell<Vec<(Pubkey, Option<Rc<Vec<u8>>>)>> {
|
|
||||||
&self.sysvars
|
|
||||||
}
|
|
||||||
fn get_sysvar_data(&self, id: &Pubkey) -> Option<Rc<Vec<u8>>> {
|
|
||||||
self.sysvars
|
self.sysvars
|
||||||
.borrow()
|
|
||||||
.iter()
|
|
||||||
.find_map(|(key, sysvar)| if id == key { sysvar.clone() } else { None })
|
|
||||||
}
|
}
|
||||||
fn get_compute_budget(&self) -> &ComputeBudget {
|
fn get_compute_budget(&self) -> &ComputeBudget {
|
||||||
&self.compute_budget
|
&self.compute_budget
|
||||||
|
|
Loading…
Reference in New Issue