Skip to content

Commit

Permalink
Refactor: move sysvar cache to new module
Browse files Browse the repository at this point in the history
  • Loading branch information
jstarry committed Jan 20, 2022
1 parent db94226 commit 71abcbb
Show file tree
Hide file tree
Showing 10 changed files with 178 additions and 99 deletions.
5 changes: 3 additions & 2 deletions programs/bpf_loader/src/lib.rs
Expand Up @@ -1115,9 +1115,10 @@ mod tests {
rent::Rent,
signature::{Keypair, Signer},
system_program, sysvar,
sysvar_cache::SysvarCache,
transaction::TransactionError,
},
std::{cell::RefCell, fs::File, io::Read, ops::Range, rc::Rc, sync::Arc},
std::{borrow::Cow, cell::RefCell, fs::File, io::Read, ops::Range, rc::Rc, sync::Arc},
};

struct TestInstructionMeter {
Expand Down Expand Up @@ -1374,7 +1375,7 @@ mod tests {
compute_meter: MockComputeMeter::default(),
programs: vec![],
accounts: vec![],
sysvars: vec![],
sysvar_cache: Cow::Owned(SysvarCache::default()),
disabled_features: vec![].into_iter().collect(),
return_data: None,
execute_timings: ExecuteDetailsTimings::default(),
Expand Down
77 changes: 40 additions & 37 deletions programs/bpf_loader/src/syscalls.rs
Expand Up @@ -2774,8 +2774,9 @@ mod tests {
fee_calculator::FeeCalculator,
hash::hashv,
process_instruction::{MockComputeMeter, MockInvokeContext, MockLogger},
sysvar_cache::SysvarCache,
},
std::str::FromStr,
std::{borrow::Cow, str::FromStr},
};

macro_rules! assert_access_violation {
Expand Down Expand Up @@ -3620,6 +3621,40 @@ mod tests {
#[test]
fn test_syscall_get_sysvar() {
let config = Config::default();
let src_clock = Clock {
slot: 1,
epoch_start_timestamp: 2,
epoch: 3,
leader_schedule_epoch: 4,
unix_timestamp: 5,
};
let src_epochschedule = EpochSchedule {
slots_per_epoch: 1,
leader_schedule_slot_offset: 2,
warmup: false,
first_normal_epoch: 3,
first_normal_slot: 4,
};
let src_fees = Fees {
fee_calculator: FeeCalculator {
lamports_per_signature: 1,
},
};
let src_rent = Rent {
lamports_per_byte_year: 1,
exemption_threshold: 2.0,
burn_percent: 3,
};

let mut sysvar_cache = SysvarCache::default();
sysvar_cache.push_entry(sysvar::clock::id(), bincode::serialize(&src_clock).unwrap());
sysvar_cache.push_entry(
sysvar::epoch_schedule::id(),
bincode::serialize(&src_epochschedule).unwrap(),
);
sysvar_cache.push_entry(sysvar::fees::id(), bincode::serialize(&src_fees).unwrap());
sysvar_cache.push_entry(sysvar::rent::id(), bincode::serialize(&src_rent).unwrap());

// Test clock sysvar
{
let got_clock = Clock::default();
Expand All @@ -3640,17 +3675,8 @@ mod tests {
)
.unwrap();

let src_clock = Clock {
slot: 1,
epoch_start_timestamp: 2,
epoch: 3,
leader_schedule_epoch: 4,
unix_timestamp: 5,
};
let mut invoke_context = MockInvokeContext::new(vec![]);
let mut data = vec![];
bincode::serialize_into(&mut data, &src_clock).unwrap();
invoke_context.sysvars = vec![(sysvar::clock::id(), data)];
invoke_context.sysvar_cache = Cow::Borrowed(&sysvar_cache);

let mut syscall = SyscallGetClockSysvar {
invoke_context: Rc::new(RefCell::new(&mut invoke_context)),
Expand Down Expand Up @@ -3683,17 +3709,8 @@ mod tests {
)
.unwrap();

let src_epochschedule = EpochSchedule {
slots_per_epoch: 1,
leader_schedule_slot_offset: 2,
warmup: false,
first_normal_epoch: 3,
first_normal_slot: 4,
};
let mut invoke_context = MockInvokeContext::new(vec![]);
let mut data = vec![];
bincode::serialize_into(&mut data, &src_epochschedule).unwrap();
invoke_context.sysvars = vec![(sysvar::epoch_schedule::id(), data)];
invoke_context.sysvar_cache = Cow::Borrowed(&sysvar_cache);

let mut syscall = SyscallGetEpochScheduleSysvar {
invoke_context: Rc::new(RefCell::new(&mut invoke_context)),
Expand Down Expand Up @@ -3734,15 +3751,8 @@ mod tests {
)
.unwrap();

let src_fees = Fees {
fee_calculator: FeeCalculator {
lamports_per_signature: 1,
},
};
let mut invoke_context = MockInvokeContext::new(vec![]);
let mut data = vec![];
bincode::serialize_into(&mut data, &src_fees).unwrap();
invoke_context.sysvars = vec![(sysvar::fees::id(), data)];
invoke_context.sysvar_cache = Cow::Borrowed(&sysvar_cache);

let mut syscall = SyscallGetFeesSysvar {
invoke_context: Rc::new(RefCell::new(&mut invoke_context)),
Expand Down Expand Up @@ -3775,15 +3785,8 @@ mod tests {
)
.unwrap();

let src_rent = Rent {
lamports_per_byte_year: 1,
exemption_threshold: 2.0,
burn_percent: 3,
};
let mut invoke_context = MockInvokeContext::new(vec![]);
let mut data = vec![];
bincode::serialize_into(&mut data, &src_rent).unwrap();
invoke_context.sysvars = vec![(sysvar::rent::id(), data)];
invoke_context.sysvar_cache = Cow::Borrowed(&sysvar_cache);

let mut syscall = SyscallGetRentSysvar {
invoke_context: Rc::new(RefCell::new(&mut invoke_context)),
Expand Down
23 changes: 15 additions & 8 deletions programs/stake/src/stake_instruction.rs
Expand Up @@ -288,9 +288,10 @@ mod tests {
instruction::{self, LockupArgs},
state::{Authorized, Lockup, StakeAuthorize},
},
sysvar::{stake_history::StakeHistory, Sysvar},
sysvar::stake_history::StakeHistory,
sysvar_cache::SysvarCache,
},
std::{cell::RefCell, str::FromStr},
std::{borrow::Cow, cell::RefCell, str::FromStr},
};

fn create_default_account() -> RefCell<AccountSharedData> {
Expand Down Expand Up @@ -370,9 +371,12 @@ mod tests {
.collect();

let mut invoke_context = MockInvokeContext::new(keyed_accounts);
let mut data = Vec::with_capacity(sysvar::clock::Clock::size_of());
bincode::serialize_into(&mut data, &sysvar::clock::Clock::default()).unwrap();
invoke_context.sysvars = vec![(sysvar::clock::id(), data)];
let mut sysvar_cache = SysvarCache::default();
sysvar_cache.push_entry(
sysvar::clock::id(),
bincode::serialize(&Clock::default()).unwrap(),
);
invoke_context.sysvar_cache = Cow::Owned(sysvar_cache);
super::process_instruction(&Pubkey::default(), &instruction.data, &mut invoke_context)
}
}
Expand Down Expand Up @@ -1035,9 +1039,12 @@ mod tests {
];

let mut invoke_context = MockInvokeContext::new(keyed_accounts);
let mut data = Vec::with_capacity(sysvar::clock::Clock::size_of());
bincode::serialize_into(&mut data, &sysvar::clock::Clock::default()).unwrap();
invoke_context.sysvars = vec![(sysvar::clock::id(), data)];
let mut sysvar_cache = SysvarCache::default();
sysvar_cache.push_entry(
sysvar::clock::id(),
bincode::serialize(&Clock::default()).unwrap(),
);
invoke_context.sysvar_cache = Cow::Owned(sysvar_cache);

assert_eq!(
super::process_instruction(
Expand Down
21 changes: 16 additions & 5 deletions programs/vote/src/vote_instruction.rs
Expand Up @@ -404,9 +404,9 @@ mod tests {
account::{self, Account, AccountSharedData},
process_instruction::MockInvokeContext,
rent::Rent,
sysvar::Sysvar,
sysvar_cache::SysvarCache,
},
std::{cell::RefCell, str::FromStr},
std::{borrow::Cow, cell::RefCell, str::FromStr},
};

fn create_default_account() -> RefCell<AccountSharedData> {
Expand Down Expand Up @@ -463,9 +463,20 @@ mod tests {
.map(|(meta, account)| KeyedAccount::new(&meta.pubkey, meta.is_signer, account))
.collect();
let mut invoke_context = MockInvokeContext::new(keyed_accounts);
let mut data = Vec::with_capacity(sysvar::rent::Rent::size_of());
bincode::serialize_into(&mut data, &sysvar::rent::Rent::default()).unwrap();
invoke_context.sysvars = vec![(sysvar::rent::id(), data)];
let mut sysvar_cache = SysvarCache::default();
sysvar_cache.push_entry(
sysvar::rent::id(),
bincode::serialize(&Rent::default()).unwrap(),
);
sysvar_cache.push_entry(
sysvar::clock::id(),
bincode::serialize(&Clock::default()).unwrap(),
);
sysvar_cache.push_entry(
sysvar::slot_hashes::id(),
bincode::serialize(&SlotHashes::default()).unwrap(),
);
invoke_context.sysvar_cache = Cow::Owned(sysvar_cache);
super::process_instruction(&Pubkey::default(), &instruction.data, &mut invoke_context)
}
}
Expand Down
26 changes: 7 additions & 19 deletions runtime/src/bank.rs
Expand Up @@ -116,6 +116,7 @@ use {
slot_history::SlotHistory,
system_transaction,
sysvar::{self},
sysvar_cache::SysvarCache,
timing::years_as_slots,
transaction::{self, Result, Transaction, TransactionError},
},
Expand Down Expand Up @@ -144,6 +145,8 @@ use {
},
};

mod sysvar_cache;

pub const SECONDS_PER_YEAR: f64 = 365.25 * 24.0 * 60.0 * 60.0;

pub const MAX_LEADER_SCHEDULE_STAKES: Epoch = 5;
Expand Down Expand Up @@ -1159,7 +1162,7 @@ pub struct Bank {

pub cost_tracker: RwLock<CostTracker>,

sysvar_cache: RwLock<Vec<(Pubkey, Vec<u8>)>>,
sysvar_cache: RwLock<SysvarCache>,
}

impl Default for BlockhashQueue {
Expand Down Expand Up @@ -1433,7 +1436,7 @@ impl Bank {
)),
freeze_started: AtomicBool::new(false),
cost_tracker: RwLock::new(CostTracker::default()),
sysvar_cache: RwLock::new(Vec::new()),
sysvar_cache: RwLock::new(SysvarCache::default()),
};

let mut ancestors = Vec::with_capacity(1 + new.parents().len());
Expand Down Expand Up @@ -1610,7 +1613,7 @@ impl Bank {
freeze_started: AtomicBool::new(fields.hash != Hash::default()),
vote_only_bank: false,
cost_tracker: RwLock::new(CostTracker::default()),
sysvar_cache: RwLock::new(Vec::new()),
sysvar_cache: RwLock::new(SysvarCache::default()),
};
bank.finish_init(
genesis_config,
Expand Down Expand Up @@ -1789,11 +1792,7 @@ impl Bank {

// 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()));
}
sysvar_cache.update_entry(pubkey, &new_account);
}

fn inherit_specially_retained_account_fields(
Expand Down Expand Up @@ -1931,17 +1930,6 @@ 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 {
from_account(&self.get_account(&sysvar::slot_history::id()).unwrap()).unwrap()
}
Expand Down
21 changes: 21 additions & 0 deletions runtime/src/bank/sysvar_cache.rs
@@ -0,0 +1,21 @@
use {
super::Bank,
solana_sdk::{
account::ReadableAccount,
pubkey::Pubkey,
sysvar::{self, Sysvar},
},
};

impl Bank {
pub(crate) 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_entry(*id, account.data().to_vec());
}
}
}
}
}

0 comments on commit 71abcbb

Please sign in to comment.