sysvar trait (#6667)

* sysvar trait

* get the new guy in on it
This commit is contained in:
Rob Walker 2019-11-04 12:31:24 -08:00 committed by GitHub
parent b9b535c30f
commit efe260f12e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 183 additions and 303 deletions

View File

@ -15,7 +15,10 @@ use solana_sdk::{
pubkey::Pubkey, pubkey::Pubkey,
signature::KeypairUtil, signature::KeypairUtil,
system_instruction::SystemError, system_instruction::SystemError,
sysvar::stake_history::{self, StakeHistory}, sysvar::{
stake_history::{self, StakeHistory},
Sysvar,
},
transaction::Transaction, transaction::Transaction,
}; };
use solana_stake_api::{ use solana_stake_api::{

View File

@ -105,7 +105,10 @@ pub(crate) mod tests {
instruction::Instruction, instruction::Instruction,
pubkey::Pubkey, pubkey::Pubkey,
signature::{Keypair, KeypairUtil}, signature::{Keypair, KeypairUtil},
sysvar::stake_history::{self, StakeHistory}, sysvar::{
stake_history::{self, StakeHistory},
Sysvar,
},
transaction::Transaction, transaction::Transaction,
}; };
use solana_stake_api::{ use solana_stake_api::{

View File

@ -10,7 +10,7 @@ use solana_sdk::{
rent, rent,
sysvar::{ sysvar::{
clock::Clock, fees::Fees, rent::Rent, rewards::Rewards, slot_hashes::SlotHashes, clock::Clock, fees::Fees, rent::Rent, rewards::Rewards, slot_hashes::SlotHashes,
stake_history::StakeHistory, stake_history::StakeHistory, Sysvar,
}, },
}; };

View File

@ -10,7 +10,10 @@ use solana_sdk::{
instruction::{AccountMeta, Instruction, InstructionError}, instruction::{AccountMeta, Instruction, InstructionError},
instruction_processor_utils::{limited_deserialize, next_keyed_account, DecodeError}, instruction_processor_utils::{limited_deserialize, next_keyed_account, DecodeError},
pubkey::Pubkey, pubkey::Pubkey,
system_instruction, sysvar, system_instruction,
sysvar::{
self, clock::Clock, rent::Rent, rewards::Rewards, stake_history::StakeHistory, Sysvar,
},
}; };
/// Reasons the stake might have had an error /// Reasons the stake might have had an error
@ -330,7 +333,7 @@ pub fn process_instruction(
StakeInstruction::Initialize(authorized, lockup) => me.initialize( StakeInstruction::Initialize(authorized, lockup) => me.initialize(
&authorized, &authorized,
&lockup, &lockup,
&sysvar::rent::from_keyed_account(next_keyed_account(keyed_accounts)?)?, &Rent::from_keyed_account(next_keyed_account(keyed_accounts)?)?,
), ),
StakeInstruction::Authorize(authorized_pubkey, stake_authorize) => { StakeInstruction::Authorize(authorized_pubkey, stake_authorize) => {
me.authorize(&authorized_pubkey, stake_authorize, &signers) me.authorize(&authorized_pubkey, stake_authorize, &signers)
@ -340,7 +343,7 @@ pub fn process_instruction(
me.delegate_stake( me.delegate_stake(
&vote, &vote,
&sysvar::clock::from_keyed_account(next_keyed_account(keyed_accounts)?)?, &Clock::from_keyed_account(next_keyed_account(keyed_accounts)?)?,
&config::from_keyed_account(next_keyed_account(keyed_accounts)?)?, &config::from_keyed_account(next_keyed_account(keyed_accounts)?)?,
&signers, &signers,
) )
@ -352,8 +355,8 @@ pub fn process_instruction(
me.redeem_vote_credits( me.redeem_vote_credits(
vote, vote,
rewards_pool, rewards_pool,
&sysvar::rewards::from_keyed_account(next_keyed_account(keyed_accounts)?)?, &Rewards::from_keyed_account(next_keyed_account(keyed_accounts)?)?,
&sysvar::stake_history::from_keyed_account(next_keyed_account(keyed_accounts)?)?, &StakeHistory::from_keyed_account(next_keyed_account(keyed_accounts)?)?,
) )
} }
StakeInstruction::Split(lamports) => { StakeInstruction::Split(lamports) => {
@ -366,13 +369,13 @@ pub fn process_instruction(
me.withdraw( me.withdraw(
lamports, lamports,
to, to,
&sysvar::clock::from_keyed_account(next_keyed_account(keyed_accounts)?)?, &Clock::from_keyed_account(next_keyed_account(keyed_accounts)?)?,
&sysvar::stake_history::from_keyed_account(next_keyed_account(keyed_accounts)?)?, &StakeHistory::from_keyed_account(next_keyed_account(keyed_accounts)?)?,
&signers, &signers,
) )
} }
StakeInstruction::Deactivate => me.deactivate_stake( StakeInstruction::Deactivate => me.deactivate_stake(
&sysvar::clock::from_keyed_account(next_keyed_account(keyed_accounts)?)?, &Clock::from_keyed_account(next_keyed_account(keyed_accounts)?)?,
&signers, &signers,
), ),
} }
@ -390,7 +393,7 @@ mod tests {
.iter() .iter()
.map(|meta| { .map(|meta| {
if sysvar::clock::check_id(&meta.pubkey) { if sysvar::clock::check_id(&meta.pubkey) {
sysvar::clock::new_account(1, 0, 0, 0, 0) sysvar::clock::create_account(1, 0, 0, 0, 0)
} else if sysvar::rewards::check_id(&meta.pubkey) { } else if sysvar::rewards::check_id(&meta.pubkey) {
sysvar::rewards::create_account(1, 0.0, 0.0) sysvar::rewards::create_account(1, 0.0, 0.0)
} else if sysvar::stake_history::check_id(&meta.pubkey) { } else if sysvar::stake_history::check_id(&meta.pubkey) {
@ -614,7 +617,7 @@ mod tests {
KeyedAccount::new( KeyedAccount::new(
&sysvar::clock::id(), &sysvar::clock::id(),
false, false,
&mut sysvar::clock::new_account(1, 0, 0, 0, 0) &mut sysvar::clock::create_account(1, 0, 0, 0, 0)
), ),
KeyedAccount::new( KeyedAccount::new(
&config::id(), &config::id(),

View File

@ -11,7 +11,7 @@ use solana_sdk::{
message::Message, message::Message,
pubkey::Pubkey, pubkey::Pubkey,
signature::{Keypair, KeypairUtil}, signature::{Keypair, KeypairUtil},
sysvar::{self, rewards::Rewards}, sysvar::{self, rewards::Rewards, Sysvar},
}; };
use solana_stake_api::{ use solana_stake_api::{
id, id,

View File

@ -1,13 +1,14 @@
//! storage program //! storage program
//! Receive mining proofs from miners, validate the answers //! Receive mining proofs from miners, validate the answers
//! and give reward for good proofs. //! and give reward for good proofs.
use crate::storage_contract::StorageAccount; use crate::{storage_contract::StorageAccount, storage_instruction::StorageInstruction};
use crate::storage_instruction::StorageInstruction; use solana_sdk::{
use solana_sdk::account::KeyedAccount; account::KeyedAccount,
use solana_sdk::instruction::InstructionError; instruction::InstructionError,
use solana_sdk::instruction_processor_utils::limited_deserialize; instruction_processor_utils::limited_deserialize,
use solana_sdk::pubkey::Pubkey; pubkey::Pubkey,
use solana_sdk::sysvar; sysvar::{clock::Clock, rewards::Rewards, Sysvar},
};
pub fn process_instruction( pub fn process_instruction(
_program_id: &Pubkey, _program_id: &Pubkey,
@ -40,7 +41,7 @@ pub fn process_instruction(
// This instruction must be signed by `me` // This instruction must be signed by `me`
return Err(InstructionError::InvalidArgument); return Err(InstructionError::InvalidArgument);
} }
let clock = sysvar::clock::from_keyed_account(&rest[0])?; let clock = Clock::from_keyed_account(&rest[0])?;
storage_account.submit_mining_proof( storage_account.submit_mining_proof(
sha_state, sha_state,
segment_index, segment_index,
@ -54,7 +55,7 @@ pub fn process_instruction(
// This instruction must be signed by `me` // This instruction must be signed by `me`
return Err(InstructionError::InvalidArgument); return Err(InstructionError::InvalidArgument);
} }
let clock = sysvar::clock::from_keyed_account(&rest[0])?; let clock = Clock::from_keyed_account(&rest[0])?;
storage_account.advertise_storage_recent_blockhash(hash, segment, clock) storage_account.advertise_storage_recent_blockhash(hash, segment, clock)
} }
StorageInstruction::ClaimStorageReward => { StorageInstruction::ClaimStorageReward => {
@ -65,8 +66,8 @@ pub fn process_instruction(
let (rewards, rest) = rest.split_at_mut(1); let (rewards, rest) = rest.split_at_mut(1);
let (rewards_pools, owner) = rest.split_at_mut(1); let (rewards_pools, owner) = rest.split_at_mut(1);
let rewards = sysvar::rewards::from_keyed_account(&rewards[0])?; let rewards = Rewards::from_keyed_account(&rewards[0])?;
let clock = sysvar::clock::from_keyed_account(&clock[0])?; let clock = Clock::from_keyed_account(&clock[0])?;
let mut owner = StorageAccount::new(*owner[0].unsigned_key(), &mut owner[0].account); let mut owner = StorageAccount::new(*owner[0].unsigned_key(), &mut owner[0].account);
storage_account.claim_storage_reward(&mut rewards_pools[0], clock, rewards, &mut owner) storage_account.claim_storage_reward(&mut rewards_pools[0], clock, rewards, &mut owner)
@ -82,7 +83,7 @@ pub fn process_instruction(
return Err(InstructionError::InvalidArgument); return Err(InstructionError::InvalidArgument);
} }
let me_id = storage_account.id; let me_id = storage_account.id;
let clock = sysvar::clock::from_keyed_account(&clock[0])?; let clock = Clock::from_keyed_account(&clock[0])?;
let mut rest: Vec<_> = rest let mut rest: Vec<_> = rest
.iter_mut() .iter_mut()
.map(|keyed_account| { .map(|keyed_account| {

View File

@ -17,8 +17,11 @@ use solana_sdk::{
pubkey::Pubkey, pubkey::Pubkey,
signature::{Keypair, KeypairUtil, Signature}, signature::{Keypair, KeypairUtil, Signature},
system_instruction, system_instruction,
sysvar::clock::{self, Clock}, sysvar::{
sysvar::rewards::{self, Rewards}, clock::{self, Clock},
rewards::{self, Rewards},
Sysvar,
},
}; };
use solana_storage_api::{ use solana_storage_api::{
id, id,
@ -131,13 +134,12 @@ fn test_proof_bounds() {
Hash::default(), Hash::default(),
); );
// the proof is for segment 0, need to move the slot into segment 2 // the proof is for segment 0, need to move the slot into segment 2
let mut clock_account = clock::new_account(1, 0, 0, 0, 0); let mut clock_account = clock::create_account(1, 0, 0, 0, 0);
Clock::to_account( Clock::to_account(
&Clock { &Clock {
slot: DEFAULT_SLOTS_PER_SEGMENT * 2, slot: DEFAULT_SLOTS_PER_SEGMENT * 2,
segment: 2, segment: 2,
epoch: 0, ..Clock::default()
leader_schedule_epoch: 0,
}, },
&mut clock_account, &mut clock_account,
); );
@ -159,7 +161,7 @@ fn test_serialize_overflow() {
let clock_id = clock::id(); let clock_id = clock::id();
let mut keyed_accounts = Vec::new(); let mut keyed_accounts = Vec::new();
let mut user_account = Account::default(); let mut user_account = Account::default();
let mut clock_account = clock::new_account(1, 0, 0, 0, 0); let mut clock_account = clock::create_account(1, 0, 0, 0, 0);
keyed_accounts.push(KeyedAccount::new(&pubkey, true, &mut user_account)); keyed_accounts.push(KeyedAccount::new(&pubkey, true, &mut user_account));
keyed_accounts.push(KeyedAccount::new(&clock_id, false, &mut clock_account)); keyed_accounts.push(KeyedAccount::new(&clock_id, false, &mut clock_account));
@ -184,13 +186,12 @@ fn test_invalid_accounts_len() {
Hash::default(), Hash::default(),
); );
// move tick height into segment 1 // move tick height into segment 1
let mut clock_account = clock::new_account(1, 0, 0, 0, 0); let mut clock_account = clock::create_account(1, 0, 0, 0, 0);
Clock::to_account( Clock::to_account(
&Clock { &Clock {
slot: 16, slot: 16,
segment: 1, segment: 1,
epoch: 0, ..Clock::default()
leader_schedule_epoch: 0,
}, },
&mut clock_account, &mut clock_account,
); );
@ -244,13 +245,12 @@ fn test_submit_mining_ok() {
Hash::default(), Hash::default(),
); );
// move slot into segment 1 // move slot into segment 1
let mut clock_account = clock::new_account(1, 0, 0, 0, 0); let mut clock_account = clock::create_account(1, 0, 0, 0, 0);
Clock::to_account( Clock::to_account(
&Clock { &Clock {
slot: DEFAULT_SLOTS_PER_SEGMENT, slot: DEFAULT_SLOTS_PER_SEGMENT,
segment: 1, segment: 1,
epoch: 0, ..Clock::default()
leader_schedule_epoch: 0,
}, },
&mut clock_account, &mut clock_account,
); );

View File

@ -15,7 +15,7 @@ use solana_sdk::{
instruction_processor_utils::{limited_deserialize, DecodeError}, instruction_processor_utils::{limited_deserialize, DecodeError},
pubkey::Pubkey, pubkey::Pubkey,
system_instruction, system_instruction,
sysvar::{self, rent}, sysvar::{self, clock::Clock, slot_hashes::SlotHashes, Sysvar},
}; };
/// Reasons the stake might have had an error /// Reasons the stake might have had an error
@ -182,7 +182,7 @@ pub fn process_instruction(
if rest.is_empty() { if rest.is_empty() {
return Err(InstructionError::InvalidInstructionData); return Err(InstructionError::InvalidInstructionData);
} }
rent::verify_rent_exemption(me, &rest[0])?; sysvar::rent::verify_rent_exemption(me, &rest[0])?;
vote_state::initialize_account(me, &vote_init) vote_state::initialize_account(me, &vote_init)
} }
VoteInstruction::Authorize(voter_pubkey, vote_authorize) => { VoteInstruction::Authorize(voter_pubkey, vote_authorize) => {
@ -197,8 +197,8 @@ pub fn process_instruction(
vote_state::process_vote( vote_state::process_vote(
me, me,
&sysvar::slot_hashes::from_keyed_account(&slot_hashes_and_clock[0])?, &SlotHashes::from_keyed_account(&slot_hashes_and_clock[0])?,
&sysvar::clock::from_keyed_account(&slot_hashes_and_clock[1])?, &Clock::from_keyed_account(&slot_hashes_and_clock[1])?,
other_signers, other_signers,
&vote, &vote,
) )
@ -236,11 +236,11 @@ mod tests {
.iter() .iter()
.map(|meta| { .map(|meta| {
if sysvar::clock::check_id(&meta.pubkey) { if sysvar::clock::check_id(&meta.pubkey) {
sysvar::clock::new_account(1, 0, 0, 0, 0) sysvar::clock::create_account(1, 0, 0, 0, 0)
} else if sysvar::slot_hashes::check_id(&meta.pubkey) { } else if sysvar::slot_hashes::check_id(&meta.pubkey) {
sysvar::slot_hashes::create_account(1, &[]) sysvar::slot_hashes::create_account(1, &[])
} else if sysvar::rent::check_id(&meta.pubkey) { } else if sysvar::rent::check_id(&meta.pubkey) {
sysvar::rent::create_account(1, &Rent::default()) Rent::default().create_account(1)
} else { } else {
Account::default() Account::default()
} }

View File

@ -39,7 +39,8 @@ use solana_sdk::{
pubkey::Pubkey, pubkey::Pubkey,
signature::{Keypair, Signature}, signature::{Keypair, Signature},
slot_hashes::SlotHashes, slot_hashes::SlotHashes,
system_transaction, sysvar, system_transaction,
sysvar::{self, Sysvar},
timing::duration_as_ns, timing::duration_as_ns,
transaction::{Result, Transaction, TransactionError}, transaction::{Result, Transaction, TransactionError},
}; };
@ -447,7 +448,7 @@ impl Bank {
fn update_clock(&self) { fn update_clock(&self) {
self.store_account( self.store_account(
&sysvar::clock::id(), &sysvar::clock::id(),
&sysvar::clock::new_account( &sysvar::clock::create_account(
1, 1,
self.slot, self.slot,
get_segment_from_slot(self.slot, self.slots_per_segment), get_segment_from_slot(self.slot, self.slots_per_segment),

View File

@ -4,65 +4,33 @@ pub use crate::clock::Clock;
use crate::{ use crate::{
account::Account, account::Account,
account_info::AccountInfo,
clock::{Epoch, Segment, Slot}, clock::{Epoch, Segment, Slot},
sysvar, sysvar::Sysvar,
}; };
use bincode::serialized_size;
const ID: [u8; 32] = [ const ID: [u8; 32] = [
6, 167, 213, 23, 24, 199, 116, 201, 40, 86, 99, 152, 105, 29, 94, 182, 139, 94, 184, 163, 155, 6, 167, 213, 23, 24, 199, 116, 201, 40, 86, 99, 152, 105, 29, 94, 182, 139, 94, 184, 163, 155,
75, 109, 92, 115, 85, 91, 33, 0, 0, 0, 0, 75, 109, 92, 115, 85, 91, 33, 0, 0, 0, 0,
]; ];
crate::solana_sysvar_id!(ID, "SysvarC1ock11111111111111111111111111111111"); crate::solana_sysvar_id!(ID, "SysvarC1ock11111111111111111111111111111111", Clock);
impl Clock { impl Sysvar for Clock {}
pub fn size_of() -> usize {
serialized_size(&Self::default()).unwrap() as usize
}
pub fn from_account(account: &Account) -> Option<Self> {
account.deserialize_data().ok()
}
pub fn to_account(&self, account: &mut Account) -> Option<()> {
account.serialize_data(self).ok()
}
pub fn from_account_info(account: &AccountInfo) -> Option<Self> {
account.deserialize_data().ok()
}
pub fn to_account_info(&self, account: &mut AccountInfo) -> Option<()> {
account.serialize_data(self).ok()
}
}
pub fn new_account( pub fn create_account(
lamports: u64, lamports: u64,
slot: Slot, slot: Slot,
segment: Segment, segment: Segment,
epoch: Epoch, epoch: Epoch,
leader_schedule_epoch: Epoch, leader_schedule_epoch: Epoch,
) -> Account { ) -> Account {
Account::new_data( Clock {
lamports,
&Clock {
slot, slot,
segment, segment,
epoch, epoch,
leader_schedule_epoch, leader_schedule_epoch,
},
&sysvar::id(),
)
.unwrap()
}
use crate::account::KeyedAccount;
use crate::instruction::InstructionError;
pub fn from_keyed_account(account: &KeyedAccount) -> Result<Clock, InstructionError> {
if !check_id(account.unsigned_key()) {
return Err(InstructionError::InvalidArgument);
} }
Clock::from_account(account.account).ok_or(InstructionError::InvalidArgument) .create_account(lamports)
} }
#[cfg(test)] #[cfg(test)]
@ -71,7 +39,7 @@ mod tests {
#[test] #[test]
fn test_new() { fn test_new() {
let account = new_account(1, 0, 0, 0, 0); let account = create_account(1, 0, 0, 0, 0);
let clock = Clock::from_account(&account).unwrap(); let clock = Clock::from_account(&account).unwrap();
assert_eq!(clock, Clock::default()); assert_eq!(clock, Clock::default());
} }

View File

@ -1,12 +1,7 @@
//! This account contains the current cluster rent //! This account contains the current cluster rent
//! //!
use crate::{ pub use crate::epoch_schedule::EpochSchedule;
account::{Account, KeyedAccount}, use crate::{account::Account, sysvar::Sysvar};
account_info::AccountInfo,
epoch_schedule::EpochSchedule,
instruction::InstructionError,
sysvar,
};
/// epoch_schedule account pubkey /// epoch_schedule account pubkey
const ID: [u8; 32] = [ const ID: [u8; 32] = [
@ -14,34 +9,16 @@ const ID: [u8; 32] = [
30, 63, 80, 135, 25, 168, 5, 0, 0, 0, 30, 63, 80, 135, 25, 168, 5, 0, 0, 0,
]; ];
crate::solana_sysvar_id!(ID, "SysvarEpochSchedu1e111111111111111111111111"); crate::solana_sysvar_id!(
ID,
"SysvarEpochSchedu1e111111111111111111111111",
EpochSchedule
);
impl EpochSchedule { impl Sysvar for EpochSchedule {}
pub fn deserialize(account: &Account) -> Result<Self, bincode::Error> {
account.deserialize_data()
}
pub fn from_account(account: &Account) -> Option<Self> {
account.deserialize_data().ok()
}
pub fn to_account(&self, account: &mut Account) -> Option<()> {
account.serialize_data(self).ok()
}
pub fn from_account_info(account: &AccountInfo) -> Option<Self> {
account.deserialize_data().ok()
}
pub fn to_account_info(&self, account: &mut AccountInfo) -> Option<()> {
account.serialize_data(self).ok()
}
pub fn from_keyed_account(account: &KeyedAccount) -> Result<EpochSchedule, InstructionError> {
if !check_id(account.unsigned_key()) {
return Err(InstructionError::InvalidArgument);
}
EpochSchedule::from_account(account.account).ok_or(InstructionError::InvalidArgument)
}
}
pub fn create_account(lamports: u64, epoch_schedule: &EpochSchedule) -> Account { pub fn create_account(lamports: u64, epoch_schedule: &EpochSchedule) -> Account {
Account::new_data(lamports, epoch_schedule, &sysvar::id()).unwrap() epoch_schedule.create_account(lamports)
} }
#[cfg(test)] #[cfg(test)]

View File

@ -1,10 +1,6 @@
//! This account contains the current cluster fees //! This account contains the current cluster fees
//! //!
use crate::account::Account; use crate::{account::Account, fee_calculator::FeeCalculator, sysvar::Sysvar};
use crate::account_info::AccountInfo;
use crate::fee_calculator::FeeCalculator;
use crate::sysvar;
use bincode::serialized_size;
/// fees account pubkey /// fees account pubkey
const ID: [u8; 32] = [ const ID: [u8; 32] = [
@ -12,7 +8,7 @@ const ID: [u8; 32] = [
111, 196, 237, 82, 106, 156, 144, 0, 0, 0, 0, 111, 196, 237, 82, 106, 156, 144, 0, 0, 0, 0,
]; ];
crate::solana_sysvar_id!(ID, "SysvarFees111111111111111111111111111111111"); crate::solana_sysvar_id!(ID, "SysvarFees111111111111111111111111111111111", Fees);
#[repr(C)] #[repr(C)]
#[derive(Serialize, Deserialize, Debug, Default)] #[derive(Serialize, Deserialize, Debug, Default)]
@ -20,33 +16,13 @@ pub struct Fees {
pub fee_calculator: FeeCalculator, pub fee_calculator: FeeCalculator,
} }
impl Fees { impl Sysvar for Fees {}
pub fn from_account(account: &Account) -> Option<Self> {
account.deserialize_data().ok()
}
pub fn to_account(&self, account: &mut Account) -> Option<()> {
account.serialize_data(self).ok()
}
pub fn from_account_info(account: &AccountInfo) -> Option<Self> {
account.deserialize_data().ok()
}
pub fn to_account_info(&self, account: &mut AccountInfo) -> Option<()> {
account.serialize_data(self).ok()
}
pub fn size_of() -> usize {
serialized_size(&Fees::default()).unwrap() as usize
}
}
pub fn create_account(lamports: u64, fee_calculator: &FeeCalculator) -> Account { pub fn create_account(lamports: u64, fee_calculator: &FeeCalculator) -> Account {
Account::new_data( Fees {
lamports,
&Fees {
fee_calculator: fee_calculator.clone(), fee_calculator: fee_calculator.clone(),
}, }
&sysvar::id(), .create_account(lamports)
)
.unwrap()
} }
#[cfg(test)] #[cfg(test)]

View File

@ -1,6 +1,11 @@
//! named accounts for synthesized data accounts for bank state, etc. //! named accounts for synthesized data accounts for bank state, etc.
//! //!
use crate::pubkey::Pubkey; use crate::{
account::{Account, KeyedAccount},
account_info::AccountInfo,
instruction::InstructionError,
pubkey::Pubkey,
};
pub mod clock; pub mod clock;
pub mod epoch_schedule; pub mod epoch_schedule;
@ -24,9 +29,15 @@ pub fn is_sysvar_id(id: &Pubkey) -> bool {
#[macro_export] #[macro_export]
macro_rules! solana_sysvar_id( macro_rules! solana_sysvar_id(
($id:ident, $name:expr) => ( ($id:ident, $name:expr, $type:ty) => (
$crate::solana_name_id!($id, $name); $crate::solana_name_id!($id, $name);
impl $crate::sysvar::SysvarId for $type {
fn check_id(pubkey: &$crate::pubkey::Pubkey) -> bool {
check_id(pubkey)
}
}
#[cfg(test)] #[cfg(test)]
#[test] #[test]
fn test_sysvar_id() { fn test_sysvar_id() {
@ -45,3 +56,42 @@ const ID: [u8; 32] = [
]; ];
crate::solana_name_id!(ID, "Sysvar1111111111111111111111111111111111111"); crate::solana_name_id!(ID, "Sysvar1111111111111111111111111111111111111");
pub trait SysvarId {
fn check_id(pubkey: &Pubkey) -> bool;
}
// utilities for moving into and out of Accounts
pub trait Sysvar:
SysvarId + Default + Sized + serde::Serialize + serde::de::DeserializeOwned
{
fn biggest() -> Self {
Self::default()
}
fn size_of() -> usize {
bincode::serialized_size(&Self::biggest()).unwrap() as usize
}
fn from_account(account: &Account) -> Option<Self> {
bincode::deserialize(&account.data).ok()
}
fn to_account(&self, account: &mut Account) -> Option<()> {
bincode::serialize_into(&mut account.data[..], self).ok()
}
fn from_account_info(account: &AccountInfo) -> Option<Self> {
bincode::deserialize(&account.data).ok()
}
fn to_account_info(&self, account: &mut AccountInfo) -> Option<()> {
bincode::serialize_into(&mut account.data[..], self).ok()
}
fn from_keyed_account(account: &KeyedAccount) -> Result<Self, InstructionError> {
if !Self::check_id(account.unsigned_key()) {
return Err(InstructionError::InvalidArgument);
}
Self::from_account(account.account).ok_or(InstructionError::InvalidArgument)
}
fn create_account(&self, lamports: u64) -> Account {
let mut account = Account::new(lamports, Self::size_of(), &id());
self.to_account(&mut account).unwrap();
account
}
}

View File

@ -1,5 +1,4 @@
use crate::{account::Account, account_info::AccountInfo, hash::Hash, sysvar}; use crate::{account::Account, hash::Hash, sysvar::Sysvar};
use bincode::serialized_size;
use std::collections::BinaryHeap; use std::collections::BinaryHeap;
use std::iter::FromIterator; use std::iter::FromIterator;
use std::ops::Deref; use std::ops::Deref;
@ -10,7 +9,11 @@ const ID: [u8; 32] = [
0xcf, 0x03, 0x5c, 0x31, 0x45, 0xb2, 0x1a, 0xb3, 0x44, 0xd8, 0x06, 0x2e, 0xa9, 0x40, 0x00, 0x00, 0xcf, 0x03, 0x5c, 0x31, 0x45, 0xb2, 0x1a, 0xb3, 0x44, 0xd8, 0x06, 0x2e, 0xa9, 0x40, 0x00, 0x00,
]; ];
crate::solana_sysvar_id!(ID, "SysvarRecentB1ockHashes11111111111111111111"); crate::solana_sysvar_id!(
ID,
"SysvarRecentB1ockHashes11111111111111111111",
RecentBlockhashes
);
#[repr(C)] #[repr(C)]
#[derive(Serialize, Deserialize, Debug, PartialEq)] #[derive(Serialize, Deserialize, Debug, PartialEq)]
@ -35,22 +38,9 @@ impl<'a> FromIterator<&'a Hash> for RecentBlockhashes {
} }
} }
impl RecentBlockhashes { impl Sysvar for RecentBlockhashes {
pub fn from_account(account: &Account) -> Option<Self> { fn biggest() -> Self {
account.deserialize_data().ok() RecentBlockhashes(vec![Hash::default(); MAX_ENTRIES])
}
pub fn to_account(&self, account: &mut Account) -> Option<()> {
account.serialize_data(self).unwrap();
Some(())
}
pub fn from_account_info(account: &AccountInfo) -> Option<Self> {
account.deserialize_data().ok()
}
pub fn to_account_info(&self, account: &mut AccountInfo) -> Option<()> {
account.serialize_data(self).ok()
}
pub fn size_of() -> usize {
serialized_size(&RecentBlockhashes(vec![Hash::default(); MAX_ENTRIES])).unwrap() as usize
} }
} }
@ -62,7 +52,7 @@ impl Deref for RecentBlockhashes {
} }
pub fn create_account(lamports: u64) -> Account { pub fn create_account(lamports: u64) -> Account {
Account::new(lamports, RecentBlockhashes::size_of(), &sysvar::id()) RecentBlockhashes::default().create_account(lamports)
} }
pub fn update_account<'a, I>(account: &mut Account, recent_blockhash_iter: I) -> Option<()> pub fn update_account<'a, I>(account: &mut Account, recent_blockhash_iter: I) -> Option<()>

View File

@ -4,11 +4,9 @@ pub use crate::rent::Rent;
use crate::{ use crate::{
account::{Account, KeyedAccount}, account::{Account, KeyedAccount},
account_info::AccountInfo,
instruction::InstructionError, instruction::InstructionError,
sysvar, sysvar::Sysvar,
}; };
use bincode::serialized_size;
/// rent account pubkey /// rent account pubkey
const ID: [u8; 32] = [ const ID: [u8; 32] = [
@ -16,44 +14,20 @@ const ID: [u8; 32] = [
253, 68, 227, 219, 217, 138, 0, 0, 0, 0, 253, 68, 227, 219, 217, 138, 0, 0, 0, 0,
]; ];
crate::solana_sysvar_id!(ID, "SysvarRent111111111111111111111111111111111"); crate::solana_sysvar_id!(ID, "SysvarRent111111111111111111111111111111111", Rent);
impl Rent { impl Sysvar for Rent {}
pub fn from_account(account: &Account) -> Option<Self> {
account.deserialize_data().ok()
}
pub fn to_account(&self, account: &mut Account) -> Option<()> {
account.serialize_data(self).ok()
}
pub fn from_account_info(account: &AccountInfo) -> Option<Self> {
account.deserialize_data().ok()
}
pub fn to_account_info(&self, account: &mut AccountInfo) -> Option<()> {
account.serialize_data(self).ok()
}
pub fn size_of() -> usize {
serialized_size(&Rent::default()).unwrap() as usize
}
}
pub fn create_account(lamports: u64, rent: &Rent) -> Account { pub fn create_account(lamports: u64, rent: &Rent) -> Account {
Account::new_data(lamports, rent, &sysvar::id()).unwrap() rent.create_account(lamports)
}
pub fn from_keyed_account(account: &KeyedAccount) -> Result<Rent, InstructionError> {
if !check_id(account.unsigned_key()) {
return Err(InstructionError::InvalidArgument);
}
Rent::from_account(account.account).ok_or(InstructionError::InvalidArgument)
} }
pub fn verify_rent_exemption( pub fn verify_rent_exemption(
account: &KeyedAccount, account: &KeyedAccount,
rent_sysvar_account: &KeyedAccount, rent_sysvar_account: &KeyedAccount,
) -> Result<(), InstructionError> { ) -> Result<(), InstructionError> {
if !from_keyed_account(rent_sysvar_account)? let rent = Rent::from_keyed_account(rent_sysvar_account)?;
.is_exempt(account.account.lamports, account.account.data.len()) if !rent.is_exempt(account.account.lamports, account.account.data.len()) {
{
Err(InstructionError::InsufficientFunds) Err(InstructionError::InsufficientFunds)
} else { } else {
Ok(()) Ok(())

View File

@ -1,9 +1,6 @@
//! This account contains the current cluster rewards point values //! This account contains the current cluster rewards point values
//! //!
use crate::account::Account; use crate::{account::Account, sysvar::Sysvar};
use crate::account_info::AccountInfo;
use crate::sysvar;
use bincode::serialized_size;
/// account pubkey /// account pubkey
const ID: [u8; 32] = [ const ID: [u8; 32] = [
@ -11,7 +8,7 @@ const ID: [u8; 32] = [
130, 184, 161, 97, 145, 87, 141, 128, 0, 0, 0, 130, 184, 161, 97, 145, 87, 141, 128, 0, 0, 0,
]; ];
crate::solana_sysvar_id!(ID, "SysvarRewards111111111111111111111111111111"); crate::solana_sysvar_id!(ID, "SysvarRewards111111111111111111111111111111", Rewards);
#[repr(C)] #[repr(C)]
#[derive(Serialize, Deserialize, Debug, Default, PartialEq)] #[derive(Serialize, Deserialize, Debug, Default, PartialEq)]
@ -20,47 +17,18 @@ pub struct Rewards {
pub storage_point_value: f64, pub storage_point_value: f64,
} }
impl Rewards { impl Sysvar for Rewards {}
pub fn from_account(account: &Account) -> Option<Self> {
account.deserialize_data().ok()
}
pub fn to_account(&self, account: &mut Account) -> Option<()> {
account.serialize_data(self).ok()
}
pub fn from_account_info(account: &AccountInfo) -> Option<Self> {
account.deserialize_data().ok()
}
pub fn to_account_info(&self, account: &mut AccountInfo) -> Option<()> {
account.serialize_data(self).ok()
}
pub fn size_of() -> usize {
serialized_size(&Self::default()).unwrap() as usize
}
}
pub fn create_account( pub fn create_account(
lamports: u64, lamports: u64,
validator_point_value: f64, validator_point_value: f64,
storage_point_value: f64, storage_point_value: f64,
) -> Account { ) -> Account {
Account::new_data( Rewards {
lamports,
&Rewards {
validator_point_value, validator_point_value,
storage_point_value, storage_point_value,
},
&sysvar::id(),
)
.unwrap()
}
use crate::account::KeyedAccount;
use crate::instruction::InstructionError;
pub fn from_keyed_account(account: &KeyedAccount) -> Result<Rewards, InstructionError> {
if !check_id(account.unsigned_key()) {
return Err(InstructionError::InvalidArgument);
} }
Rewards::from_account(account.account).ok_or(InstructionError::InvalidAccountData) .create_account(lamports)
} }
#[cfg(test)] #[cfg(test)]

View File

@ -3,51 +3,30 @@
//! this account carries the Bank's most recent blockhashes for some N parents //! this account carries the Bank's most recent blockhashes for some N parents
//! //!
pub use crate::slot_hashes::{SlotHash, SlotHashes}; pub use crate::slot_hashes::{SlotHash, SlotHashes};
use crate::{account::Account, account_info::AccountInfo, sysvar}; use crate::{account::Account, sysvar::Sysvar};
use bincode::serialized_size;
const ID: [u8; 32] = [ const ID: [u8; 32] = [
6, 167, 213, 23, 25, 47, 10, 175, 198, 242, 101, 227, 251, 119, 204, 122, 218, 130, 197, 41, 6, 167, 213, 23, 25, 47, 10, 175, 198, 242, 101, 227, 251, 119, 204, 122, 218, 130, 197, 41,
208, 190, 59, 19, 110, 45, 0, 85, 32, 0, 0, 0, 208, 190, 59, 19, 110, 45, 0, 85, 32, 0, 0, 0,
]; ];
crate::solana_sysvar_id!(ID, "SysvarS1otHashes111111111111111111111111111"); crate::solana_sysvar_id!(
ID,
"SysvarS1otHashes111111111111111111111111111",
SlotHashes
);
pub const MAX_SLOT_HASHES: usize = 512; // 512 slots to get your vote in pub const MAX_SLOT_HASHES: usize = 512; // 512 slots to get your vote in
impl SlotHashes { impl Sysvar for SlotHashes {
pub fn from_account(account: &Account) -> Option<Self> { fn biggest() -> Self {
account.deserialize_data().ok() // override
} SlotHashes::new(&[SlotHash::default(); MAX_SLOT_HASHES])
pub fn to_account(&self, account: &mut Account) -> Option<()> {
account.serialize_data(self).ok()
}
pub fn from_account_info(account: &AccountInfo) -> Option<Self> {
account.deserialize_data().ok()
}
pub fn to_account_info(&self, account: &mut AccountInfo) -> Option<()> {
account.serialize_data(self).ok()
}
pub fn size_of() -> usize {
serialized_size(&SlotHashes::new(&[SlotHash::default(); MAX_SLOT_HASHES])).unwrap() as usize
} }
} }
pub fn create_account(lamports: u64, slot_hashes: &[SlotHash]) -> Account { pub fn create_account(lamports: u64, slot_hashes: &[SlotHash]) -> Account {
let mut account = Account::new(lamports, SlotHashes::size_of(), &sysvar::id()); SlotHashes::new(slot_hashes).create_account(lamports)
SlotHashes::new(slot_hashes)
.to_account(&mut account)
.unwrap();
account
}
use crate::account::KeyedAccount;
use crate::instruction::InstructionError;
pub fn from_keyed_account(account: &KeyedAccount) -> Result<SlotHashes, InstructionError> {
if !check_id(account.unsigned_key()) {
return Err(InstructionError::InvalidArgument);
}
SlotHashes::from_account(account.account).ok_or(InstructionError::InvalidArgument)
} }
#[cfg(test)] #[cfg(test)]

View File

@ -2,10 +2,9 @@
//! //!
//! this account carries history about stake activations and de-activations //! this account carries history about stake activations and de-activations
//! //!
use crate::account_info::AccountInfo;
pub use crate::clock::Epoch; pub use crate::clock::Epoch;
use crate::{account::Account, sysvar};
use bincode::serialized_size; use crate::{account::Account, sysvar::Sysvar};
use std::ops::Deref; use std::ops::Deref;
const ID: [u8; 32] = [ const ID: [u8; 32] = [
@ -13,7 +12,11 @@ const ID: [u8; 32] = [
87, 184, 86, 108, 197, 55, 95, 244, 0, 0, 0, 87, 184, 86, 108, 197, 55, 95, 244, 0, 0, 0,
]; ];
crate::solana_sysvar_id!(ID, "SysvarStakeHistory1111111111111111111111111"); crate::solana_sysvar_id!(
ID,
"SysvarStakeHistory1111111111111111111111111",
StakeHistory
);
pub const MAX_STAKE_HISTORY: usize = 512; // it should never take as many as 512 epochs to warm up or cool down pub const MAX_STAKE_HISTORY: usize = 512; // it should never take as many as 512 epochs to warm up or cool down
@ -28,27 +31,13 @@ pub struct StakeHistoryEntry {
#[derive(Debug, Serialize, Deserialize, PartialEq, Default, Clone)] #[derive(Debug, Serialize, Deserialize, PartialEq, Default, Clone)]
pub struct StakeHistory(Vec<(Epoch, StakeHistoryEntry)>); pub struct StakeHistory(Vec<(Epoch, StakeHistoryEntry)>);
impl StakeHistory { impl Sysvar for StakeHistory {
pub fn from_account(account: &Account) -> Option<Self> { fn biggest() -> Self {
account.deserialize_data().ok() StakeHistory(vec![(0, StakeHistoryEntry::default()); MAX_STAKE_HISTORY])
}
pub fn to_account(&self, account: &mut Account) -> Option<()> {
account.serialize_data(self).ok()
}
pub fn from_account_info(account: &AccountInfo) -> Option<Self> {
account.deserialize_data().ok()
}
pub fn to_account_info(&self, account: &mut AccountInfo) -> Option<()> {
account.serialize_data(self).ok()
}
pub fn size_of() -> usize {
serialized_size(&StakeHistory(vec![
(0, StakeHistoryEntry::default());
MAX_STAKE_HISTORY
]))
.unwrap() as usize
} }
}
impl StakeHistory {
#[allow(clippy::trivially_copy_pass_by_ref)] #[allow(clippy::trivially_copy_pass_by_ref)]
pub fn get(&self, epoch: &Epoch) -> Option<&StakeHistoryEntry> { pub fn get(&self, epoch: &Epoch) -> Option<&StakeHistoryEntry> {
self.binary_search_by(|probe| epoch.cmp(&probe.0)) self.binary_search_by(|probe| epoch.cmp(&probe.0))
@ -73,9 +62,7 @@ impl Deref for StakeHistory {
} }
pub fn create_account(lamports: u64, stake_history: &StakeHistory) -> Account { pub fn create_account(lamports: u64, stake_history: &StakeHistory) -> Account {
let mut account = Account::new(lamports, StakeHistory::size_of(), &sysvar::id()); stake_history.create_account(lamports)
stake_history.to_account(&mut account).unwrap();
account
} }
use crate::account::KeyedAccount; use crate::account::KeyedAccount;