diff --git a/programs/bpf_loader/src/lib.rs b/programs/bpf_loader/src/lib.rs index 720d9038ed..4a5fcfc529 100644 --- a/programs/bpf_loader/src/lib.rs +++ b/programs/bpf_loader/src/lib.rs @@ -97,6 +97,9 @@ pub fn serialize_parameters( .unwrap(); v.write_all(&keyed_account.try_account_ref()?.data).unwrap(); v.write_all(keyed_account.owner()?.as_ref()).unwrap(); + v.write_u8(keyed_account.executable()? as u8).unwrap(); + v.write_u64::(keyed_account.rent_epoch()? as u64) + .unwrap(); } } v.write_u64::(data.len() as u64).unwrap(); @@ -129,7 +132,9 @@ pub fn deserialize_parameters( .data .clone_from_slice(&buffer[start..end]); start += keyed_account.data_len()? // data - + mem::size_of::(); // owner + + mem::size_of::() // owner + + mem::size_of::() // executable + + mem::size_of::(); // rent_epoch } } Ok(()) diff --git a/sdk/bpf/c/inc/solana_sdk.h b/sdk/bpf/c/inc/solana_sdk.h index d4a06890b3..340d58fbc5 100644 --- a/sdk/bpf/c/inc/solana_sdk.h +++ b/sdk/bpf/c/inc/solana_sdk.h @@ -170,12 +170,14 @@ SOL_FN_PREFIX bool SolPubkey_same(const SolPubkey *one, const SolPubkey *two) { */ typedef struct { SolPubkey *key; /** Public key of the account */ - bool is_signer; /** Transaction was signed by this account's key? */ - bool is_writable; /** Is the account writable? */ uint64_t *lamports; /** Number of lamports owned by this account */ uint64_t data_len; /** Length of data in bytes */ uint8_t *data; /** On-chain data within this account */ SolPubkey *owner; /** Program that owns this account */ + uint64_t rent_epoch; /** The epoch at which this account will next owe rent */ + bool is_signer; /** Transaction was signed by this account's key? */ + bool is_writable; /** Is the account writable? */ + bool executable; /** This account's data contains a loaded program (and is now read-only) */ } SolKeyedAccount; /** @@ -315,6 +317,14 @@ SOL_FN_PREFIX bool sol_deserialize( // owner params->ka[i].owner = (SolPubkey *) input; input += sizeof(SolPubkey); + + // executable? + params->ka[i].executable = *(uint8_t *) input; + input += sizeof(uint8_t); + + // rent epoch + params->ka[i].rent_epoch = *(uint64_t *) input; + input += sizeof(uint64_t); } else { params->ka[i].is_signer = params->ka[dup_info].is_signer; params->ka[i].key = params->ka[dup_info].key; @@ -322,6 +332,8 @@ SOL_FN_PREFIX bool sol_deserialize( params->ka[i].data_len = params->ka[dup_info].data_len; params->ka[i].data = params->ka[dup_info].data; params->ka[i].owner = params->ka[dup_info].owner; + params->ka[i].executable = params->ka[dup_info].executable; + params->ka[i].rent_epoch = params->ka[dup_info].rent_epoch; } } @@ -387,6 +399,10 @@ SOL_FN_PREFIX void sol_log_params(const SolParameters *params) { sol_log_array(params->ka[i].data, params->ka[i].data_len); sol_log(" - Owner"); sol_log_key(params->ka[i].owner); + sol_log(" - Executable"); + sol_log_64(0, 0, 0, 0, params->ka[i].executable); + sol_log(" - Rent Epoch"); + sol_log_64(0, 0, 0, 0, params->ka[i].rent_epoch); } sol_log("- Instruction data\0"); sol_log_array(params->data, params->data_len); diff --git a/sdk/src/account.rs b/sdk/src/account.rs index f10db11550..7d6e8378c7 100644 --- a/sdk/src/account.rs +++ b/sdk/src/account.rs @@ -1,8 +1,4 @@ -use crate::{ - hash::Hash, - instruction::InstructionError, - {clock::Epoch, pubkey::Pubkey}, -}; +use crate::{clock::Epoch, hash::Hash, instruction::InstructionError, pubkey::Pubkey}; use std::{ cell::{Ref, RefCell, RefMut}, cmp, fmt, @@ -183,6 +179,10 @@ impl<'a> KeyedAccount<'a> { Ok(self.try_borrow()?.executable) } + pub fn rent_epoch(&self) -> Result { + Ok(self.try_borrow()?.rent_epoch) + } + pub fn try_account_ref(&'a self) -> Result, InstructionError> { self.try_borrow() } diff --git a/sdk/src/account_info.rs b/sdk/src/account_info.rs index 90f036eede..f0f355cef1 100644 --- a/sdk/src/account_info.rs +++ b/sdk/src/account_info.rs @@ -1,4 +1,4 @@ -use crate::{account::Account, program_error::ProgramError, pubkey::Pubkey}; +use crate::{account::Account, clock::Epoch, program_error::ProgramError, pubkey::Pubkey}; use std::{ cell::{Ref, RefCell, RefMut}, cmp, fmt, @@ -20,6 +20,10 @@ pub struct AccountInfo<'a> { pub data: Rc>, /// Program that owns this account pub owner: &'a Pubkey, + /// This account's data contains a loaded program (and is now read-only) + pub executable: bool, + /// The epoch at which this account will next owe rent + pub rent_epoch: Epoch, } impl<'a> fmt::Debug for AccountInfo<'a> { @@ -27,7 +31,7 @@ impl<'a> fmt::Debug for AccountInfo<'a> { let data_len = cmp::min(64, self.data_len()); let data_str = if data_len > 0 { format!( - " data: {}", + " data: {} ...", hex::encode(self.data.borrow()[..data_len].to_vec()) ) } else { @@ -35,10 +39,15 @@ impl<'a> fmt::Debug for AccountInfo<'a> { }; write!( f, - "AccountInfo {{ lamports: {} data.len: {} owner: {} {} }}", + "AccountInfo {{ key: {} owner: {} is_signer: {} is_writable: {} executable: {} rent_epoch: {} lamports: {} data.len: {} {} }}", + self.key, + self.owner, + self.is_signer, + self.is_writable, + self.executable, + self.rent_epoch, self.lamports(), self.data_len(), - self.owner, data_str, ) } @@ -57,10 +66,6 @@ impl<'a> AccountInfo<'a> { self.key } - pub fn is_writable(&self) -> bool { - self.is_writable - } - pub fn lamports(&self) -> u64 { **self.lamports.borrow() } @@ -116,6 +121,8 @@ impl<'a> AccountInfo<'a> { lamports: &'a mut u64, data: &'a mut [u8], owner: &'a Pubkey, + executable: bool, + rent_epoch: Epoch, ) -> Self { Self { key, @@ -124,6 +131,8 @@ impl<'a> AccountInfo<'a> { lamports: Rc::new(RefCell::new(lamports)), data: Rc::new(RefCell::new(data)), owner, + executable, + rent_epoch, } } @@ -148,6 +157,8 @@ impl<'a> From<(&'a Pubkey, &'a mut Account)> for AccountInfo<'a> { &mut account.lamports, &mut account.data, &account.owner, + account.executable, + account.rent_epoch, ) } } @@ -161,6 +172,8 @@ impl<'a> From<(&'a Pubkey, bool, &'a mut Account)> for AccountInfo<'a> { &mut account.lamports, &mut account.data, &account.owner, + account.executable, + account.rent_epoch, ) } } @@ -174,6 +187,8 @@ impl<'a> From<&'a mut (Pubkey, Account)> for AccountInfo<'a> { &mut account.lamports, &mut account.data, &account.owner, + account.executable, + account.rent_epoch, ) } } @@ -195,6 +210,8 @@ pub fn create_is_signer_account_infos<'a>( &mut account.lamports, &mut account.data, &account.owner, + account.executable, + account.rent_epoch, ) }) .collect() diff --git a/sdk/src/entrypoint.rs b/sdk/src/entrypoint.rs index 2ae5bf2d94..4a726f72a2 100644 --- a/sdk/src/entrypoint.rs +++ b/sdk/src/entrypoint.rs @@ -67,18 +67,12 @@ pub unsafe fn deserialize<'a>(input: *mut u8) -> (&'a Pubkey, Vec(); if dup_info == std::u8::MAX { - let is_signer = { - #[allow(clippy::cast_ptr_alignment)] - let is_signer = *(input.add(offset) as *const u8); - is_signer != 0 - }; + #[allow(clippy::cast_ptr_alignment)] + let is_signer = *(input.add(offset) as *const u8) != 0; offset += size_of::(); - let is_writable = { - #[allow(clippy::cast_ptr_alignment)] - let is_writable = *(input.add(offset) as *const u8); - is_writable != 0 - }; + #[allow(clippy::cast_ptr_alignment)] + let is_writable = *(input.add(offset) as *const u8) != 0; offset += size_of::(); let key: &Pubkey = &*(input.add(offset) as *const Pubkey); @@ -100,6 +94,14 @@ pub unsafe fn deserialize<'a>(input: *mut u8) -> (&'a Pubkey, Vec(); + #[allow(clippy::cast_ptr_alignment)] + let executable = *(input.add(offset) as *const u8) != 0; + offset += size_of::(); + + #[allow(clippy::cast_ptr_alignment)] + let rent_epoch = *(input.add(offset) as *const u64); + offset += size_of::(); + accounts.push(AccountInfo { is_signer, is_writable, @@ -107,6 +109,8 @@ pub unsafe fn deserialize<'a>(input: *mut u8) -> (&'a Pubkey, Vec