Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds stable layout types to pass to the runtime #30192

Merged
merged 13 commits into from
Feb 16, 2023
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 8 additions & 4 deletions program-runtime/src/invoke_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@ use {
bpf_loader_upgradeable::{self, UpgradeableLoaderState},
feature_set::{enable_early_verification_of_account_modifications, FeatureSet},
hash::Hash,
instruction::{AccountMeta, Instruction, InstructionError},
instruction::{AccountMeta, InstructionError},
native_loader,
pubkey::Pubkey,
rent::Rent,
saturating_add_assign,
stable_layout::stable_instruction::StableInstruction,
transaction_context::{
IndexOfAccount, InstructionAccount, TransactionAccount, TransactionContext,
},
Expand Down Expand Up @@ -489,7 +490,7 @@ impl<'a> InvokeContext<'a> {
/// Entrypoint for a cross-program invocation from a builtin program
pub fn native_invoke(
&mut self,
instruction: Instruction,
instruction: StableInstruction,
signers: &[Pubkey],
) -> Result<(), InstructionError> {
let (instruction_accounts, program_indices) =
Expand All @@ -509,7 +510,7 @@ impl<'a> InvokeContext<'a> {
#[allow(clippy::type_complexity)]
pub fn prepare_instruction(
&mut self,
instruction: &Instruction,
instruction: &StableInstruction,
signers: &[Pubkey],
) -> Result<(Vec<InstructionAccount>, Vec<IndexOfAccount>), InstructionError> {
// Finds the index of each account in the instruction by its pubkey.
Expand Down Expand Up @@ -1036,7 +1037,7 @@ mod tests {
super::*,
crate::compute_budget,
serde::{Deserialize, Serialize},
solana_sdk::account::WritableAccount,
solana_sdk::{account::WritableAccount, instruction::Instruction},
};

#[derive(Debug, Serialize, Deserialize)]
Expand Down Expand Up @@ -1152,6 +1153,7 @@ mod tests {
&MockInstruction::NoopSuccess,
metas,
);
let inner_instruction = StableInstruction::from(inner_instruction);
invoke_context
.transaction_context
.get_next_instruction_context()
Expand Down Expand Up @@ -1335,6 +1337,7 @@ mod tests {
invoke_context.push().unwrap();
let inner_instruction =
Instruction::new_with_bincode(callee_program_id, &case.0, metas.clone());
let inner_instruction = StableInstruction::from(inner_instruction);
let result = invoke_context
.native_invoke(inner_instruction, &[])
.and(invoke_context.pop());
Expand All @@ -1359,6 +1362,7 @@ mod tests {
},
metas.clone(),
);
let inner_instruction = StableInstruction::from(inner_instruction);
let (inner_instruction_accounts, program_indices) = invoke_context
.prepare_instruction(&inner_instruction, &[])
.unwrap();
Expand Down
4 changes: 3 additions & 1 deletion program-test/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ use {
pubkey::Pubkey,
rent::Rent,
signature::{Keypair, Signer},
stable_layout::stable_instruction::StableInstruction,
sysvar::{Sysvar, SysvarId},
},
solana_vote_program::vote_state::{self, VoteState, VoteStateVersions},
Expand Down Expand Up @@ -227,6 +228,7 @@ impl solana_sdk::program_stubs::SyscallStubs for SyscallStubs {
account_infos: &[AccountInfo],
signers_seeds: &[&[&[u8]]],
) -> ProgramResult {
let instruction = StableInstruction::from(instruction.clone());
let invoke_context = get_invoke_context();
let log_collector = invoke_context.get_log_collector();
let transaction_context = &invoke_context.transaction_context;
Expand All @@ -249,7 +251,7 @@ impl solana_sdk::program_stubs::SyscallStubs for SyscallStubs {
.collect::<Vec<_>>();

let (instruction_accounts, program_indices) = invoke_context
.prepare_instruction(instruction, &signers)
.prepare_instruction(&instruction, &signers)
.unwrap();

// Copy caller's account_info modifications into invoke_context accounts
Expand Down
20 changes: 16 additions & 4 deletions programs/address-lookup-table/src/processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use {
instruction::InstructionError,
program_utils::limited_deserialize,
pubkey::{Pubkey, PUBKEY_BYTES},
stable_layout::stable_instruction::StableInstruction,
system_instruction,
transaction_context::IndexOfAccount,
},
Expand Down Expand Up @@ -144,18 +145,25 @@ impl Processor {

if required_lamports > 0 {
invoke_context.native_invoke(
system_instruction::transfer(&payer_key, &table_key, required_lamports),
StableInstruction::from(system_instruction::transfer(
&payer_key,
&table_key,
required_lamports,
)),
brooksprumo marked this conversation as resolved.
Show resolved Hide resolved
&[payer_key],
)?;
}

invoke_context.native_invoke(
system_instruction::allocate(&table_key, table_account_data_len as u64),
StableInstruction::from(system_instruction::allocate(
&table_key,
table_account_data_len as u64,
)),
&[table_key],
)?;

invoke_context.native_invoke(
system_instruction::assign(&table_key, &crate::id()),
StableInstruction::from(system_instruction::assign(&table_key, &crate::id())),
&[table_key],
)?;

Expand Down Expand Up @@ -332,7 +340,11 @@ impl Processor {
drop(payer_account);

invoke_context.native_invoke(
system_instruction::transfer(&payer_key, &table_key, required_lamports),
StableInstruction::from(system_instruction::transfer(
&payer_key,
&table_key,
required_lamports,
)),
&[payer_key],
)?;
}
Expand Down
3 changes: 3 additions & 0 deletions programs/bpf_loader/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ solana-zk-token-sdk = { path = "../../zk-token-sdk", version = "=1.16.0" }
solana_rbpf = "=0.2.38"
thiserror = "1.0"

[dev-dependencies]
memoffset = "0.8"

[lib]
crate-type = ["lib"]
name = "solana_bpf_loader_program"
Expand Down
8 changes: 7 additions & 1 deletion programs/bpf_loader/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ use {
program_utils::limited_deserialize,
pubkey::Pubkey,
saturating_add_assign,
stable_layout::stable_instruction::StableInstruction,
system_instruction::{self, MAX_PERMITTED_DATA_LENGTH},
transaction_context::{
BorrowedAccount, IndexOfAccount, InstructionContext, TransactionContext,
Expand Down Expand Up @@ -675,6 +676,7 @@ fn process_loader_upgradeable_instruction(
.iter()
.map(|seeds| Pubkey::create_program_address(seeds, caller_program_id))
.collect::<Result<Vec<Pubkey>, solana_sdk::pubkey::PubkeyError>>()?;
let instruction = StableInstruction::from(instruction);
brooksprumo marked this conversation as resolved.
Show resolved Hide resolved
invoke_context.native_invoke(instruction, signers.as_slice())?;
brooksprumo marked this conversation as resolved.
Show resolved Hide resolved

// Load and verify the program bits
Expand Down Expand Up @@ -1299,7 +1301,11 @@ fn process_loader_upgradeable_instruction(
)?;

invoke_context.native_invoke(
system_instruction::transfer(&payer_key, &programdata_key, required_payment),
StableInstruction::from(system_instruction::transfer(
&payer_key,
&programdata_key,
required_payment,
)),
&[],
)?;
}
Expand Down
29 changes: 19 additions & 10 deletions programs/bpf_loader/src/syscalls/cpi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use {
crate::declare_syscall,
solana_sdk::{
feature_set::enable_bpf_loader_set_authority_checked_ix,
stable_layout::{stable_instruction::StableInstruction, stable_vec::StableVec},
syscalls::{
MAX_CPI_ACCOUNT_INFOS, MAX_CPI_INSTRUCTION_ACCOUNTS, MAX_CPI_INSTRUCTION_DATA_LEN,
},
Expand Down Expand Up @@ -211,7 +212,7 @@ trait SyscallInvokeSigned {
addr: u64,
memory_mapping: &mut MemoryMapping,
invoke_context: &mut InvokeContext,
) -> Result<Instruction, EbpfError>;
) -> Result<StableInstruction, EbpfError>;
fn translate_accounts<'a>(
instruction_accounts: &[InstructionAccount],
program_indices: &[IndexOfAccount],
Expand Down Expand Up @@ -258,8 +259,8 @@ impl SyscallInvokeSigned for SyscallInvokeSignedRust {
addr: u64,
memory_mapping: &mut MemoryMapping,
invoke_context: &mut InvokeContext,
) -> Result<Instruction, EbpfError> {
let ix = translate_type::<Instruction>(
) -> Result<StableInstruction, EbpfError> {
let ix = translate_type::<StableInstruction>(
memory_mapping,
addr,
invoke_context.get_check_aligned(),
Expand All @@ -275,6 +276,7 @@ impl SyscallInvokeSigned for SyscallInvokeSignedRust {
invoke_context.get_check_size(),
)?
.to_vec();
let accounts = StableVec::from(accounts);

let ix_data_len = ix.data.len() as u64;
if invoke_context
Expand All @@ -296,10 +298,12 @@ impl SyscallInvokeSigned for SyscallInvokeSignedRust {
invoke_context.get_check_size(),
)?
.to_vec();
Ok(Instruction {
program_id: ix.program_id,
let data = StableVec::from(data);
brooksprumo marked this conversation as resolved.
Show resolved Hide resolved

Ok(StableInstruction {
accounts,
data,
program_id: ix.program_id,
})
}

Expand Down Expand Up @@ -469,7 +473,7 @@ impl SyscallInvokeSigned for SyscallInvokeSignedC {
addr: u64,
memory_mapping: &mut MemoryMapping,
invoke_context: &mut InvokeContext,
) -> Result<Instruction, EbpfError> {
) -> Result<StableInstruction, EbpfError> {
let ix_c = translate_type::<SolInstruction>(
memory_mapping,
addr,
Expand Down Expand Up @@ -514,6 +518,8 @@ impl SyscallInvokeSigned for SyscallInvokeSignedC {
invoke_context.get_check_size(),
)?
.to_vec();
let data = StableVec::from(data);
brooksprumo marked this conversation as resolved.
Show resolved Hide resolved

let accounts = meta_cs
.iter()
.map(|meta_c| {
Expand All @@ -529,11 +535,12 @@ impl SyscallInvokeSigned for SyscallInvokeSignedC {
})
})
.collect::<Result<Vec<AccountMeta>, EbpfError>>()?;
let accounts = StableVec::from(accounts);

Ok(Instruction {
program_id: *program_id,
Ok(StableInstruction {
accounts,
data,
program_id: *program_id,
})
}

Expand Down Expand Up @@ -1128,6 +1135,7 @@ mod tests {
solana_sdk::{
account::{Account, AccountSharedData},
clock::Epoch,
instruction::Instruction,
rent::Rent,
transaction_context::{TransactionAccount, TransactionContext},
},
Expand Down Expand Up @@ -1693,12 +1701,12 @@ mod tests {
fn into_region(self, vm_addr: u64) -> (Vec<u8>, MemoryRegion) {
let accounts_len = mem::size_of::<AccountMeta>() * self.accounts.len();

let size = mem::size_of::<Instruction>() + accounts_len + self.data.len();
let size = mem::size_of::<StableInstruction>() + accounts_len + self.data.len();

let mut data = vec![0; size];

let vm_addr = vm_addr as usize;
let accounts_addr = vm_addr + mem::size_of::<Instruction>();
let accounts_addr = vm_addr + mem::size_of::<StableInstruction>();
let data_addr = accounts_addr + accounts_len;

let ins = Instruction {
Expand All @@ -1714,6 +1722,7 @@ mod tests {
Vec::from_raw_parts(data_addr as *mut _, self.data.len(), self.data.len())
},
};
let ins = StableInstruction::from(ins);

unsafe {
ptr::write_unaligned(data.as_mut_ptr().cast(), ins);
Expand Down
11 changes: 7 additions & 4 deletions programs/bpf_loader/src/syscalls/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ use {
},
hash::{Hasher, HASH_BYTES},
instruction::{
AccountMeta, Instruction, InstructionError, ProcessedSiblingInstruction,
AccountMeta, InstructionError, ProcessedSiblingInstruction,
TRANSACTION_LEVEL_STACK_HEIGHT,
},
keccak, native_loader,
Expand Down Expand Up @@ -1821,7 +1821,9 @@ mod tests {
bpf_loader,
fee_calculator::FeeCalculator,
hash::hashv,
instruction::Instruction,
program::check_type_assumptions,
stable_layout::stable_instruction::StableInstruction,
sysvar::{clock::Clock, epoch_schedule::EpochSchedule, rent::Rent},
transaction_context::TransactionContext,
},
Expand Down Expand Up @@ -1936,17 +1938,18 @@ mod tests {
&"foobar",
vec![AccountMeta::new(solana_sdk::pubkey::new_rand(), false)],
);
let instruction = StableInstruction::from(instruction);
let addr = &instruction as *const _ as u64;
let mut memory_region = MemoryRegion {
host_addr: addr,
vm_addr: 0x100000000,
len: std::mem::size_of::<Instruction>() as u64,
len: std::mem::size_of::<StableInstruction>() as u64,
vm_gap_shift: 63,
is_writable: false,
};
let mut memory_mapping = MemoryMapping::new(vec![memory_region.clone()], &config).unwrap();
let translated_instruction =
translate_type::<Instruction>(&memory_mapping, 0x100000000, true).unwrap();
translate_type::<StableInstruction>(&memory_mapping, 0x100000000, true).unwrap();
assert_eq!(instruction, *translated_instruction);
memory_region.len = 1;
let memory_region_index = memory_mapping
Expand All @@ -1957,7 +1960,7 @@ mod tests {
memory_mapping
.replace_region(memory_region_index, memory_region)
.unwrap();
assert!(translate_type::<Instruction>(&memory_mapping, 0x100000000, true).is_err());
assert!(translate_type::<StableInstruction>(&memory_mapping, 0x100000000, true).is_err());
}

#[test]
Expand Down
1 change: 1 addition & 0 deletions sdk/program/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,7 @@ pub mod serialize_utils;
pub mod short_vec;
pub mod slot_hashes;
pub mod slot_history;
pub mod stable_layout;
pub mod stake;
pub mod stake_history;
pub mod syscalls;
Expand Down
Loading