Skip to content

Commit

Permalink
Create edge case for call args
Browse files Browse the repository at this point in the history
  • Loading branch information
LucasSte committed Aug 5, 2024
1 parent 51208f8 commit 2a622f3
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 0 deletions.
9 changes: 9 additions & 0 deletions programs/sbf/Cargo.lock

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

3 changes: 3 additions & 0 deletions programs/sbf/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ edition = "2021"
array-bytes = "=1.4.1"
bincode = { version = "1.1.4", default-features = false }
blake3 = "1.0.0"
borsh = "1.5.1"
byteorder = "1.3.2"
elf = "0.0.10"
getrandom = "0.2.10"
Expand Down Expand Up @@ -90,6 +91,7 @@ frozen-abi = []
[dev-dependencies]
agave-validator = { workspace = true }
bincode = { workspace = true }
borsh = { workspace = true }
byteorder = { workspace = true }
elf = { workspace = true }
itertools = { workspace = true }
Expand Down Expand Up @@ -131,6 +133,7 @@ members = [
"rust/alt_bn128",
"rust/alt_bn128_compression",
"rust/big_mod_exp",
"rust/call_args",
"rust/call_depth",
"rust/caller_access",
"rust/curve25519",
Expand Down
146 changes: 146 additions & 0 deletions programs/sbf/tests/programs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#[cfg(feature = "sbf_rust")]
use {
borsh::{from_slice, to_vec, BorshDeserialize, BorshSerialize},
itertools::izip,
solana_account_decoder::parse_bpf_loader::{
parse_bpf_upgradeable_loader, BpfUpgradeableLoaderAccountType,
Expand Down Expand Up @@ -70,6 +71,7 @@ use {
map_inner_instructions, ConfirmedTransactionWithStatusMeta, TransactionStatusMeta,
TransactionWithStatusMeta, VersionedTransactionWithStatusMeta,
},
solana_type_overrides::rand,
std::{
assert_eq,
cell::RefCell,
Expand Down Expand Up @@ -5126,3 +5128,147 @@ fn test_stack_heap_zeroed() {
);
}
}

#[test]
fn test_function_call_args() {
// This function tests edge compiler edge cases when calling functions with more than five
// arguments and passing by value arguments with more than 16 bytes.
solana_logger::setup();

let GenesisConfigInfo {
genesis_config,
mint_keypair,
..
} = create_genesis_config(100_123_456_789);

let (bank, bank_forks) = Bank::new_with_bank_forks_for_tests(&genesis_config);
let mut bank_client = BankClient::new_shared(bank);
let authority_keypair = Keypair::new();

let (bank, program_id) = load_upgradeable_program_and_advance_slot(
&mut bank_client,
bank_forks.as_ref(),
&mint_keypair,
&authority_keypair,
"solana_sbf_rust_call_args",
);

#[derive(BorshSerialize, BorshDeserialize, PartialEq, Eq, Debug)]
struct Test128 {
a: u128,
b: u128,
}

#[derive(BorshSerialize)]
struct InputData {
test_128: Test128,
arg1: i64,
arg2: i64,
arg3: i64,
arg4: i64,
arg5: i64,
arg6: i64,
arg7: i64,
arg8: i64,
}

#[derive(BorshDeserialize)]
struct OutputData {
res_128: u128,
res_256: Test128,
many_args_1: i64,
many_args_2: i64,
}

let input_data = InputData {
test_128: Test128 {
a: rand::random::<u128>(),
b: rand::random::<u128>(),
},
arg1: rand::random::<i64>(),
arg2: rand::random::<i64>(),
arg3: rand::random::<i64>(),
arg4: rand::random::<i64>(),
arg5: rand::random::<i64>(),
arg6: rand::random::<i64>(),
arg7: rand::random::<i64>(),
arg8: rand::random::<i64>(),
};

let instruction_data = to_vec(&input_data).unwrap();
let account_metas = vec![
AccountMeta::new(mint_keypair.pubkey(), true),
AccountMeta::new(Keypair::new().pubkey(), false),
];

let instruction = Instruction::new_with_bytes(program_id, &instruction_data, account_metas);
let message = Message::new(&[instruction], Some(&mint_keypair.pubkey()));

let tx = Transaction::new(&[&mint_keypair], message.clone(), bank.last_blockhash());

let txs = vec![tx];
let tx_batch = bank.prepare_batch_for_tests(txs);
let result = bank
.load_execute_and_commit_transactions(
&tx_batch,
MAX_PROCESSING_AGE,
false,
ExecutionRecordingConfig {
enable_cpi_recording: false,
enable_log_recording: false,
enable_return_data_recording: true,
},
&mut ExecuteTimings::default(),
None,
)
.0;

fn verify_many_args(input: &InputData) -> i64 {
let a = input
.arg1
.overflowing_add(input.arg2)
.0
.overflowing_sub(input.arg3)
.0
.overflowing_add(input.arg4)
.0
.overflowing_sub(input.arg5)
.0;
(a % input.arg6)
.overflowing_sub(input.arg7)
.0
.overflowing_add(input.arg8)
.0
}

let return_data = &result[0]
.as_ref()
.unwrap()
.execution_details
.return_data
.as_ref()
.unwrap()
.data;
let decoded: OutputData = from_slice::<OutputData>(return_data).unwrap();
assert_eq!(
decoded.res_128,
input_data.test_128.a % input_data.test_128.b
);
assert_eq!(
decoded.res_256,
Test128 {
a: input_data
.test_128
.a
.overflowing_add(input_data.test_128.b)
.0,
b: input_data
.test_128
.a
.overflowing_sub(input_data.test_128.b)
.0
}
);
assert_eq!(decoded.many_args_1, verify_many_args(&input_data));
assert_eq!(decoded.many_args_2, verify_many_args(&input_data));
}

0 comments on commit 2a622f3

Please sign in to comment.