Add SystemInstruction::CreateAccount support to CPI (#11649)
This commit is contained in:
@ -36,21 +36,62 @@ extern uint64_t entrypoint(const uint8_t *input) {
|
||||
|
||||
switch (params.data[0]) {
|
||||
case TEST_SUCCESS: {
|
||||
sol_log("Call system program");
|
||||
sol_log("Call system program create account");
|
||||
{
|
||||
sol_assert(*accounts[FROM_INDEX].lamports = 43);
|
||||
sol_assert(*accounts[ARGUMENT_INDEX].lamports = 41);
|
||||
uint64_t from_lamports = *accounts[FROM_INDEX].lamports;
|
||||
uint64_t to_lamports = *accounts[DERIVED_KEY1_INDEX].lamports;
|
||||
SolAccountMeta arguments[] = {
|
||||
{accounts[FROM_INDEX].key, false, true},
|
||||
{accounts[ARGUMENT_INDEX].key, false, false}};
|
||||
{accounts[FROM_INDEX].key, true, true},
|
||||
{accounts[DERIVED_KEY1_INDEX].key, true, true}};
|
||||
uint8_t data[4 + 8 + 8 + 32];
|
||||
*(uint64_t *)(data + 4) = 42;
|
||||
*(uint64_t *)(data + 4 + 8) = MAX_PERMITTED_DATA_INCREASE;
|
||||
sol_memcpy(data + 4 + 8 + 8, params.program_id, SIZE_PUBKEY);
|
||||
const SolInstruction instruction = {accounts[SYSTEM_PROGRAM_INDEX].key,
|
||||
arguments, SOL_ARRAY_SIZE(arguments),
|
||||
data, SOL_ARRAY_SIZE(data)};
|
||||
uint8_t seed1[] = {'Y', 'o', 'u', ' ', 'p', 'a', 's', 's',
|
||||
' ', 'b', 'u', 't', 't', 'e', 'r'};
|
||||
const SolSignerSeed seeds1[] = {{seed1, SOL_ARRAY_SIZE(seed1)},
|
||||
{&nonce1, 1}};
|
||||
const SolSignerSeeds signers_seeds[] = {{seeds1, SOL_ARRAY_SIZE(seeds1)}};
|
||||
sol_assert(SUCCESS == sol_invoke_signed(&instruction, accounts,
|
||||
SOL_ARRAY_SIZE(accounts),
|
||||
signers_seeds,
|
||||
SOL_ARRAY_SIZE(signers_seeds)));
|
||||
sol_assert(*accounts[FROM_INDEX].lamports == from_lamports - 42);
|
||||
sol_assert(*accounts[DERIVED_KEY1_INDEX].lamports == to_lamports + 42);
|
||||
sol_assert(SolPubkey_same(accounts[DERIVED_KEY1_INDEX].owner,
|
||||
params.program_id));
|
||||
sol_assert(accounts[DERIVED_KEY1_INDEX].data_len ==
|
||||
MAX_PERMITTED_DATA_INCREASE);
|
||||
sol_assert(
|
||||
accounts[DERIVED_KEY1_INDEX].data[MAX_PERMITTED_DATA_INCREASE - 1] ==
|
||||
0);
|
||||
accounts[DERIVED_KEY1_INDEX].data[MAX_PERMITTED_DATA_INCREASE - 1] = 0x0f;
|
||||
sol_assert(
|
||||
accounts[DERIVED_KEY1_INDEX].data[MAX_PERMITTED_DATA_INCREASE - 1] ==
|
||||
0x0f);
|
||||
for (uint8_t i = 0; i < 20; i++) {
|
||||
accounts[DERIVED_KEY1_INDEX].data[i] = i;
|
||||
}
|
||||
}
|
||||
|
||||
sol_log("Call system program transfer");
|
||||
{
|
||||
uint64_t from_lamports = *accounts[FROM_INDEX].lamports;
|
||||
uint64_t to_lamports = *accounts[DERIVED_KEY1_INDEX].lamports;
|
||||
SolAccountMeta arguments[] = {
|
||||
{accounts[FROM_INDEX].key, true, true},
|
||||
{accounts[DERIVED_KEY1_INDEX].key, true, false}};
|
||||
uint8_t data[] = {2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0};
|
||||
const SolInstruction instruction = {accounts[SYSTEM_PROGRAM_INDEX].key,
|
||||
arguments, SOL_ARRAY_SIZE(arguments),
|
||||
data, SOL_ARRAY_SIZE(data)};
|
||||
sol_assert(SUCCESS ==
|
||||
sol_invoke(&instruction, accounts, SOL_ARRAY_SIZE(accounts)));
|
||||
sol_assert(*accounts[FROM_INDEX].lamports = 42);
|
||||
sol_assert(*accounts[ARGUMENT_INDEX].lamports = 42);
|
||||
sol_assert(*accounts[FROM_INDEX].lamports == from_lamports - 1);
|
||||
sol_assert(*accounts[DERIVED_KEY1_INDEX].lamports == to_lamports + 1);
|
||||
}
|
||||
|
||||
sol_log("Test data translation");
|
||||
@ -92,8 +133,9 @@ extern uint64_t entrypoint(const uint8_t *input) {
|
||||
const SolSignerSeed seeds1[] = {{seed1, SOL_ARRAY_SIZE(seed1)},
|
||||
{&nonce1, 1}};
|
||||
SolPubkey address;
|
||||
sol_assert(SUCCESS == sol_create_program_address(seeds1, SOL_ARRAY_SIZE(seeds1),
|
||||
params.program_id, &address));
|
||||
sol_assert(SUCCESS ==
|
||||
sol_create_program_address(seeds1, SOL_ARRAY_SIZE(seeds1),
|
||||
params.program_id, &address));
|
||||
sol_assert(SolPubkey_same(&address, accounts[DERIVED_KEY1_INDEX].key));
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@ use solana_bpf_rust_invoked::instruction::*;
|
||||
use solana_sdk::{
|
||||
account_info::AccountInfo,
|
||||
entrypoint,
|
||||
entrypoint::ProgramResult,
|
||||
entrypoint::{ProgramResult, MAX_PERMITTED_DATA_INCREASE},
|
||||
info,
|
||||
program::{invoke, invoke_signed},
|
||||
program_error::ProgramError,
|
||||
@ -46,18 +46,52 @@ fn process_instruction(
|
||||
|
||||
match instruction_data[0] {
|
||||
TEST_SUCCESS => {
|
||||
info!("Call system program");
|
||||
info!("Call system program create account");
|
||||
{
|
||||
assert_eq!(accounts[FROM_INDEX].lamports(), 43);
|
||||
assert_eq!(accounts[ARGUMENT_INDEX].lamports(), 41);
|
||||
let from_lamports = accounts[FROM_INDEX].lamports();
|
||||
let to_lamports = accounts[DERIVED_KEY1_INDEX].lamports();
|
||||
assert_eq!(accounts[DERIVED_KEY1_INDEX].data_len(), 0);
|
||||
assert!(solana_sdk::system_program::check_id(
|
||||
accounts[DERIVED_KEY1_INDEX].owner
|
||||
));
|
||||
|
||||
let instruction = system_instruction::create_account(
|
||||
accounts[FROM_INDEX].key,
|
||||
accounts[DERIVED_KEY1_INDEX].key,
|
||||
42,
|
||||
MAX_PERMITTED_DATA_INCREASE as u64,
|
||||
program_id,
|
||||
);
|
||||
invoke_signed(&instruction, accounts, &[&[b"You pass butter", &[nonce1]]])?;
|
||||
|
||||
assert_eq!(accounts[FROM_INDEX].lamports(), from_lamports - 42);
|
||||
assert_eq!(accounts[DERIVED_KEY1_INDEX].lamports(), to_lamports + 42);
|
||||
assert_eq!(program_id, accounts[DERIVED_KEY1_INDEX].owner);
|
||||
assert_eq!(
|
||||
accounts[DERIVED_KEY1_INDEX].data_len(),
|
||||
MAX_PERMITTED_DATA_INCREASE
|
||||
);
|
||||
let mut data = accounts[DERIVED_KEY1_INDEX].try_borrow_mut_data()?;
|
||||
assert_eq!(data[MAX_PERMITTED_DATA_INCREASE - 1], 0);
|
||||
data[MAX_PERMITTED_DATA_INCREASE - 1] = 0x0f;
|
||||
assert_eq!(data[MAX_PERMITTED_DATA_INCREASE - 1], 0x0f);
|
||||
for i in 0..20 {
|
||||
data[i] = i as u8;
|
||||
}
|
||||
}
|
||||
|
||||
info!("Call system program transfer");
|
||||
{
|
||||
let from_lamports = accounts[FROM_INDEX].lamports();
|
||||
let to_lamports = accounts[DERIVED_KEY1_INDEX].lamports();
|
||||
let instruction = system_instruction::transfer(
|
||||
accounts[FROM_INDEX].key,
|
||||
accounts[ARGUMENT_INDEX].key,
|
||||
accounts[DERIVED_KEY1_INDEX].key,
|
||||
1,
|
||||
);
|
||||
invoke(&instruction, accounts)?;
|
||||
assert_eq!(accounts[FROM_INDEX].lamports(), 42);
|
||||
assert_eq!(accounts[ARGUMENT_INDEX].lamports(), 42);
|
||||
assert_eq!(accounts[FROM_INDEX].lamports(), from_lamports - 1);
|
||||
assert_eq!(accounts[DERIVED_KEY1_INDEX].lamports(), to_lamports + 1);
|
||||
}
|
||||
|
||||
info!("Test data translation");
|
||||
|
@ -14,6 +14,7 @@ use solana_sdk::{
|
||||
bpf_loader,
|
||||
client::SyncClient,
|
||||
clock::DEFAULT_SLOTS_PER_EPOCH,
|
||||
entrypoint::MAX_PERMITTED_DATA_INCREASE,
|
||||
instruction::{AccountMeta, Instruction, InstructionError},
|
||||
message::Message,
|
||||
pubkey::Pubkey,
|
||||
@ -345,7 +346,7 @@ fn test_program_bpf_invoke() {
|
||||
let invoked_program_id = load_bpf_program(&bank_client, &mint_keypair, program.1);
|
||||
|
||||
let argument_keypair = Keypair::new();
|
||||
let account = Account::new(41, 100, &invoke_program_id);
|
||||
let account = Account::new(42, 100, &invoke_program_id);
|
||||
bank.store_account(&argument_keypair.pubkey(), &account);
|
||||
|
||||
let invoked_argument_keypair = Keypair::new();
|
||||
@ -353,7 +354,7 @@ fn test_program_bpf_invoke() {
|
||||
bank.store_account(&invoked_argument_keypair.pubkey(), &account);
|
||||
|
||||
let from_keypair = Keypair::new();
|
||||
let account = Account::new(43, 0, &solana_sdk::system_program::id());
|
||||
let account = Account::new(84, 0, &solana_sdk::system_program::id());
|
||||
bank.store_account(&from_keypair.pubkey(), &account);
|
||||
|
||||
let (derived_key1, nonce1) =
|
||||
@ -443,5 +444,16 @@ fn test_program_bpf_invoke() {
|
||||
.unwrap(),
|
||||
TransactionError::InstructionError(0, InstructionError::Custom(194969602))
|
||||
);
|
||||
|
||||
assert_eq!(43, bank.get_balance(&derived_key1));
|
||||
let account = bank.get_account(&derived_key1).unwrap();
|
||||
assert_eq!(invoke_program_id, account.owner);
|
||||
assert_eq!(
|
||||
MAX_PERMITTED_DATA_INCREASE,
|
||||
bank.get_account(&derived_key1).unwrap().data.len()
|
||||
);
|
||||
for i in 0..20 {
|
||||
assert_eq!(i as u8, account.data[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user