diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index 9021555063..5f4a54e7c6 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -24,6 +24,7 @@ use solana_sdk::hash::{extend_and_hash, Hash}; use solana_sdk::native_loader; use solana_sdk::pubkey::Pubkey; use solana_sdk::signature::{Keypair, Signature}; +use solana_sdk::syscall::fees::{self, Fees}; use solana_sdk::syscall::slot_hashes::{self, SlotHashes}; use solana_sdk::system_transaction; use solana_sdk::timing::{duration_as_ms, duration_as_us, MAX_RECENT_BLOCKHASHES}; @@ -215,6 +216,18 @@ impl Bank { self.store(&slot_hashes::id(), &account); } + fn update_fees(&self) { + let mut account = self + .get_account(&fees::id()) + .unwrap_or_else(|| fees::create_account(1)); + + let mut fees = Fees::from(&account).unwrap(); + fees.fee_calculator = self.fee_calculator.clone(); + fees.to(&mut account).unwrap(); + + self.store(&fees::id(), &account); + } + fn set_hash(&self) -> bool { let mut hash = self.hash.write().unwrap(); @@ -274,6 +287,7 @@ impl Bank { // Bootstrap leader collects fees until `new_from_parent` is called. self.collector_id = genesis_block.bootstrap_leader_pubkey; self.fee_calculator = genesis_block.fee_calculator.clone(); + self.update_fees(); for (pubkey, account) in genesis_block.accounts.iter() { self.store(pubkey, account); @@ -1931,6 +1945,21 @@ mod tests { assert!(bank.is_votable()); } + #[test] + fn test_bank_fees_account() { + let (mut genesis_block, _) = create_genesis_block(500); + genesis_block.fee_calculator.lamports_per_signature = 12345; + let bank = Arc::new(Bank::new(&genesis_block)); + + let fees_account = bank.get_account(&fees::id()).unwrap(); + let fees = Fees::from(&fees_account).unwrap(); + assert_eq!( + bank.fee_calculator.lamports_per_signature, + fees.fee_calculator.lamports_per_signature + ); + assert_eq!(fees.fee_calculator.lamports_per_signature, 12345); + } + #[test] fn test_is_delta_with_no_committables() { let (genesis_block, mint_keypair) = create_genesis_block(8000); diff --git a/sdk/src/syscall/fees.rs b/sdk/src/syscall/fees.rs new file mode 100644 index 0000000000..6ab4b69e34 --- /dev/null +++ b/sdk/src/syscall/fees.rs @@ -0,0 +1,71 @@ +//! This account contains the current cluster fees +//! +use crate::account::Account; +use crate::account_utils::State; +use crate::fee_calculator::FeeCalculator; +use crate::pubkey::Pubkey; +use crate::syscall; +use bincode::serialized_size; + +/// "Sysca11Fees11111111111111111111111111" +/// fees account pubkey +const ID: [u8; 32] = [ + 6, 167, 211, 138, 69, 218, 104, 33, 3, 92, 89, 173, 16, 89, 109, 253, 49, 97, 98, 165, 87, 222, + 119, 112, 253, 90, 76, 184, 0, 0, 0, 0, +]; + +pub fn id() -> Pubkey { + Pubkey::new(&ID) +} + +pub fn check_id(pubkey: &Pubkey) -> bool { + pubkey.as_ref() == ID +} + +#[repr(C)] +#[derive(Serialize, Deserialize, Debug, Default)] +pub struct Fees { + pub fee_calculator: FeeCalculator, +} + +impl Fees { + pub fn from(account: &Account) -> Option { + account.state().ok() + } + pub fn to(&self, account: &mut Account) -> Option<()> { + account.set_state(self).ok() + } + + pub fn size_of() -> usize { + serialized_size(&Fees::default()).unwrap() as usize + } +} + +pub fn create_account(lamports: u64) -> Account { + Account::new(lamports, Fees::size_of(), &syscall::id()) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_fees_id() { + let name = "Sysca11Fees11111111111111111111111111111111"; + // To get the bytes above: + // dbg!((name, bs58::decode(name).into_vec().unwrap())); + assert_eq!(name, id().to_string()); + assert!(check_id(&id())); + } + + #[test] + fn test_fees_create_account() { + let lamports = 42; + let account = create_account(lamports); + let fees = Fees::from(&account).unwrap(); + assert_eq!( + fees.fee_calculator.lamports_per_signature, + FeeCalculator::default().lamports_per_signature + ); + } +} diff --git a/sdk/src/syscall/mod.rs b/sdk/src/syscall/mod.rs index 4e6c39e636..7c9ba18001 100644 --- a/sdk/src/syscall/mod.rs +++ b/sdk/src/syscall/mod.rs @@ -2,6 +2,7 @@ //! use crate::pubkey::Pubkey; +pub mod fees; pub mod slot_hashes; /// "Sysca11111111111111111111111111111111111111"