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,
signature::KeypairUtil,
system_instruction::SystemError,
sysvar::stake_history::{self, StakeHistory},
sysvar::{
stake_history::{self, StakeHistory},
Sysvar,
},
transaction::Transaction,
};
use solana_stake_api::{

View File

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

View File

@ -10,7 +10,7 @@ use solana_sdk::{
rent,
sysvar::{
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_processor_utils::{limited_deserialize, next_keyed_account, DecodeError},
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
@ -330,7 +333,7 @@ pub fn process_instruction(
StakeInstruction::Initialize(authorized, lockup) => me.initialize(
&authorized,
&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) => {
me.authorize(&authorized_pubkey, stake_authorize, &signers)
@ -340,7 +343,7 @@ pub fn process_instruction(
me.delegate_stake(
&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)?)?,
&signers,
)
@ -352,8 +355,8 @@ pub fn process_instruction(
me.redeem_vote_credits(
vote,
rewards_pool,
&sysvar::rewards::from_keyed_account(next_keyed_account(keyed_accounts)?)?,
&sysvar::stake_history::from_keyed_account(next_keyed_account(keyed_accounts)?)?,
&Rewards::from_keyed_account(next_keyed_account(keyed_accounts)?)?,
&StakeHistory::from_keyed_account(next_keyed_account(keyed_accounts)?)?,
)
}
StakeInstruction::Split(lamports) => {
@ -366,13 +369,13 @@ pub fn process_instruction(
me.withdraw(
lamports,
to,
&sysvar::clock::from_keyed_account(next_keyed_account(keyed_accounts)?)?,
&sysvar::stake_history::from_keyed_account(next_keyed_account(keyed_accounts)?)?,
&Clock::from_keyed_account(next_keyed_account(keyed_accounts)?)?,
&StakeHistory::from_keyed_account(next_keyed_account(keyed_accounts)?)?,
&signers,
)
}
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,
),
}
@ -390,7 +393,7 @@ mod tests {
.iter()
.map(|meta| {
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) {
sysvar::rewards::create_account(1, 0.0, 0.0)
} else if sysvar::stake_history::check_id(&meta.pubkey) {
@ -614,7 +617,7 @@ mod tests {
KeyedAccount::new(
&sysvar::clock::id(),
false,
&mut sysvar::clock::new_account(1, 0, 0, 0, 0)
&mut sysvar::clock::create_account(1, 0, 0, 0, 0)
),
KeyedAccount::new(
&config::id(),

View File

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

View File

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

View File

@ -17,8 +17,11 @@ use solana_sdk::{
pubkey::Pubkey,
signature::{Keypair, KeypairUtil, Signature},
system_instruction,
sysvar::clock::{self, Clock},
sysvar::rewards::{self, Rewards},
sysvar::{
clock::{self, Clock},
rewards::{self, Rewards},
Sysvar,
},
};
use solana_storage_api::{
id,
@ -131,13 +134,12 @@ fn test_proof_bounds() {
Hash::default(),
);
// 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 {
slot: DEFAULT_SLOTS_PER_SEGMENT * 2,
segment: 2,
epoch: 0,
leader_schedule_epoch: 0,
..Clock::default()
},
&mut clock_account,
);
@ -159,7 +161,7 @@ fn test_serialize_overflow() {
let clock_id = clock::id();
let mut keyed_accounts = Vec::new();
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(&clock_id, false, &mut clock_account));
@ -184,13 +186,12 @@ fn test_invalid_accounts_len() {
Hash::default(),
);
// 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 {
slot: 16,
segment: 1,
epoch: 0,
leader_schedule_epoch: 0,
..Clock::default()
},
&mut clock_account,
);
@ -244,13 +245,12 @@ fn test_submit_mining_ok() {
Hash::default(),
);
// 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 {
slot: DEFAULT_SLOTS_PER_SEGMENT,
segment: 1,
epoch: 0,
leader_schedule_epoch: 0,
..Clock::default()
},
&mut clock_account,
);

View File

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

View File

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

View File

@ -4,65 +4,33 @@ pub use crate::clock::Clock;
use crate::{
account::Account,
account_info::AccountInfo,
clock::{Epoch, Segment, Slot},
sysvar,
sysvar::Sysvar,
};
use bincode::serialized_size;
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,
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 {
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()
}
}
impl Sysvar for Clock {}
pub fn new_account(
pub fn create_account(
lamports: u64,
slot: Slot,
segment: Segment,
epoch: Epoch,
leader_schedule_epoch: Epoch,
) -> Account {
Account::new_data(
lamports,
&Clock {
slot,
segment,
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 {
slot,
segment,
epoch,
leader_schedule_epoch,
}
Clock::from_account(account.account).ok_or(InstructionError::InvalidArgument)
.create_account(lamports)
}
#[cfg(test)]
@ -71,7 +39,7 @@ mod tests {
#[test]
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();
assert_eq!(clock, Clock::default());
}

View File

@ -1,12 +1,7 @@
//! This account contains the current cluster rent
//!
use crate::{
account::{Account, KeyedAccount},
account_info::AccountInfo,
epoch_schedule::EpochSchedule,
instruction::InstructionError,
sysvar,
};
pub use crate::epoch_schedule::EpochSchedule;
use crate::{account::Account, sysvar::Sysvar};
/// epoch_schedule account pubkey
const ID: [u8; 32] = [
@ -14,34 +9,16 @@ const ID: [u8; 32] = [
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 {
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)
}
}
impl Sysvar for EpochSchedule {}
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)]

View File

@ -1,10 +1,6 @@
//! This account contains the current cluster fees
//!
use crate::account::Account;
use crate::account_info::AccountInfo;
use crate::fee_calculator::FeeCalculator;
use crate::sysvar;
use bincode::serialized_size;
use crate::{account::Account, fee_calculator::FeeCalculator, sysvar::Sysvar};
/// fees account pubkey
const ID: [u8; 32] = [
@ -12,7 +8,7 @@ const ID: [u8; 32] = [
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)]
#[derive(Serialize, Deserialize, Debug, Default)]
@ -20,33 +16,13 @@ pub struct Fees {
pub fee_calculator: FeeCalculator,
}
impl 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
}
}
impl Sysvar for Fees {}
pub fn create_account(lamports: u64, fee_calculator: &FeeCalculator) -> Account {
Account::new_data(
lamports,
&Fees {
fee_calculator: fee_calculator.clone(),
},
&sysvar::id(),
)
.unwrap()
Fees {
fee_calculator: fee_calculator.clone(),
}
.create_account(lamports)
}
#[cfg(test)]

View File

@ -1,6 +1,11 @@
//! 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 epoch_schedule;
@ -24,9 +29,15 @@ pub fn is_sysvar_id(id: &Pubkey) -> bool {
#[macro_export]
macro_rules! solana_sysvar_id(
($id:ident, $name:expr) => (
($id:ident, $name:expr, $type:ty) => (
$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)]
#[test]
fn test_sysvar_id() {
@ -45,3 +56,42 @@ const ID: [u8; 32] = [
];
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 bincode::serialized_size;
use crate::{account::Account, hash::Hash, sysvar::Sysvar};
use std::collections::BinaryHeap;
use std::iter::FromIterator;
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,
];
crate::solana_sysvar_id!(ID, "SysvarRecentB1ockHashes11111111111111111111");
crate::solana_sysvar_id!(
ID,
"SysvarRecentB1ockHashes11111111111111111111",
RecentBlockhashes
);
#[repr(C)]
#[derive(Serialize, Deserialize, Debug, PartialEq)]
@ -35,22 +38,9 @@ impl<'a> FromIterator<&'a Hash> for RecentBlockhashes {
}
}
impl RecentBlockhashes {
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).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
impl Sysvar for RecentBlockhashes {
fn biggest() -> Self {
RecentBlockhashes(vec![Hash::default(); MAX_ENTRIES])
}
}
@ -62,7 +52,7 @@ impl Deref for RecentBlockhashes {
}
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<()>

View File

@ -4,11 +4,9 @@ pub use crate::rent::Rent;
use crate::{
account::{Account, KeyedAccount},
account_info::AccountInfo,
instruction::InstructionError,
sysvar,
sysvar::Sysvar,
};
use bincode::serialized_size;
/// rent account pubkey
const ID: [u8; 32] = [
@ -16,44 +14,20 @@ const ID: [u8; 32] = [
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 {
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
}
}
impl Sysvar for Rent {}
pub fn create_account(lamports: u64, rent: &Rent) -> Account {
Account::new_data(lamports, rent, &sysvar::id()).unwrap()
}
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)
rent.create_account(lamports)
}
pub fn verify_rent_exemption(
account: &KeyedAccount,
rent_sysvar_account: &KeyedAccount,
) -> Result<(), InstructionError> {
if !from_keyed_account(rent_sysvar_account)?
.is_exempt(account.account.lamports, account.account.data.len())
{
let rent = Rent::from_keyed_account(rent_sysvar_account)?;
if !rent.is_exempt(account.account.lamports, account.account.data.len()) {
Err(InstructionError::InsufficientFunds)
} else {
Ok(())

View File

@ -1,9 +1,6 @@
//! This account contains the current cluster rewards point values
//!
use crate::account::Account;
use crate::account_info::AccountInfo;
use crate::sysvar;
use bincode::serialized_size;
use crate::{account::Account, sysvar::Sysvar};
/// account pubkey
const ID: [u8; 32] = [
@ -11,7 +8,7 @@ const ID: [u8; 32] = [
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)]
#[derive(Serialize, Deserialize, Debug, Default, PartialEq)]
@ -20,47 +17,18 @@ pub struct Rewards {
pub storage_point_value: f64,
}
impl 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
}
}
impl Sysvar for Rewards {}
pub fn create_account(
lamports: u64,
validator_point_value: f64,
storage_point_value: f64,
) -> Account {
Account::new_data(
lamports,
&Rewards {
validator_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 {
validator_point_value,
storage_point_value,
}
Rewards::from_account(account.account).ok_or(InstructionError::InvalidAccountData)
.create_account(lamports)
}
#[cfg(test)]

View File

@ -3,51 +3,30 @@
//! this account carries the Bank's most recent blockhashes for some N parents
//!
pub use crate::slot_hashes::{SlotHash, SlotHashes};
use crate::{account::Account, account_info::AccountInfo, sysvar};
use bincode::serialized_size;
use crate::{account::Account, sysvar::Sysvar};
const ID: [u8; 32] = [
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,
];
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
impl SlotHashes {
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(&SlotHashes::new(&[SlotHash::default(); MAX_SLOT_HASHES])).unwrap() as usize
impl Sysvar for SlotHashes {
fn biggest() -> Self {
// override
SlotHashes::new(&[SlotHash::default(); MAX_SLOT_HASHES])
}
}
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)
.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)
SlotHashes::new(slot_hashes).create_account(lamports)
}
#[cfg(test)]

View File

@ -2,10 +2,9 @@
//!
//! this account carries history about stake activations and de-activations
//!
use crate::account_info::AccountInfo;
pub use crate::clock::Epoch;
use crate::{account::Account, sysvar};
use bincode::serialized_size;
use crate::{account::Account, sysvar::Sysvar};
use std::ops::Deref;
const ID: [u8; 32] = [
@ -13,7 +12,11 @@ const ID: [u8; 32] = [
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
@ -28,27 +31,13 @@ pub struct StakeHistoryEntry {
#[derive(Debug, Serialize, Deserialize, PartialEq, Default, Clone)]
pub struct StakeHistory(Vec<(Epoch, StakeHistoryEntry)>);
impl StakeHistory {
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(&StakeHistory(vec![
(0, StakeHistoryEntry::default());
MAX_STAKE_HISTORY
]))
.unwrap() as usize
impl Sysvar for StakeHistory {
fn biggest() -> Self {
StakeHistory(vec![(0, StakeHistoryEntry::default()); MAX_STAKE_HISTORY])
}
}
impl StakeHistory {
#[allow(clippy::trivially_copy_pass_by_ref)]
pub fn get(&self, epoch: &Epoch) -> Option<&StakeHistoryEntry> {
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 {
let mut account = Account::new(lamports, StakeHistory::size_of(), &sysvar::id());
stake_history.to_account(&mut account).unwrap();
account
stake_history.create_account(lamports)
}
use crate::account::KeyedAccount;