Add more duplicate account tests (#15746)
This commit is contained in:
parent
d09112fa6d
commit
efcb58092e
|
@ -1,5 +1,5 @@
|
||||||
/**
|
/**
|
||||||
* @brief Example C-based BPF program that exercises duplicate keyed ka
|
* @brief Example C-based BPF program that exercises duplicate keyed accounts
|
||||||
* passed to it
|
* passed to it
|
||||||
*/
|
*/
|
||||||
#include <solana_sdk.h>
|
#include <solana_sdk.h>
|
||||||
|
@ -9,42 +9,83 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
extern uint64_t entrypoint(const uint8_t *input) {
|
extern uint64_t entrypoint(const uint8_t *input) {
|
||||||
SolAccountInfo ka[4];
|
SolAccountInfo accounts[5];
|
||||||
SolParameters params = (SolParameters) { .ka = ka };
|
SolParameters params = (SolParameters){.ka = accounts};
|
||||||
|
|
||||||
if (!sol_deserialize(input, ¶ms, SOL_ARRAY_SIZE(ka))) {
|
if (!sol_deserialize(input, ¶ms, SOL_ARRAY_SIZE(accounts))) {
|
||||||
return ERROR_INVALID_ARGUMENT;
|
return ERROR_INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (params.data[0]) {
|
switch (params.data[0]) {
|
||||||
case(1):
|
case (1):
|
||||||
sol_log("modify first account data");
|
sol_log("modify first account data");
|
||||||
ka[2].data[0] = 1;
|
accounts[2].data[0] = 1;
|
||||||
break;
|
break;
|
||||||
case(2):
|
case (2):
|
||||||
sol_log("modify first account data");
|
sol_log("modify first account data");
|
||||||
ka[3].data[0] = 2;
|
accounts[3].data[0] = 2;
|
||||||
break;
|
break;
|
||||||
case(3):
|
case (3):
|
||||||
sol_log("modify both account data");
|
sol_log("modify both account data");
|
||||||
ka[2].data[0] += 1;
|
accounts[2].data[0] += 1;
|
||||||
ka[3].data[0] += 2;
|
accounts[3].data[0] += 2;
|
||||||
break;
|
break;
|
||||||
case(4):
|
case (4):
|
||||||
sol_log("modify first account lamports");
|
sol_log("modify first account lamports");
|
||||||
*ka[1].lamports -= 1;
|
*accounts[1].lamports -= 1;
|
||||||
*ka[2].lamports += 1;
|
*accounts[2].lamports += 1;
|
||||||
break;
|
break;
|
||||||
case(5):
|
case (5):
|
||||||
sol_log("modify first account lamports");
|
sol_log("modify first account lamports");
|
||||||
*ka[1].lamports -= 2;
|
*accounts[1].lamports -= 2;
|
||||||
*ka[3].lamports += 2;
|
*accounts[3].lamports += 2;
|
||||||
break;
|
break;
|
||||||
case(6):
|
case (6):
|
||||||
sol_log("modify both account lamports");
|
sol_log("modify both account lamports");
|
||||||
*ka[1].lamports -= 3;
|
*accounts[1].lamports -= 3;
|
||||||
*ka[2].lamports += 1;
|
*accounts[2].lamports += 1;
|
||||||
*ka[3].lamports += 2;
|
*accounts[3].lamports += 2;
|
||||||
|
break;
|
||||||
|
case (7):
|
||||||
|
sol_log("check account (0,1,2,3) privs");
|
||||||
|
sol_assert(accounts[0].is_signer);
|
||||||
|
sol_assert(!accounts[1].is_signer);
|
||||||
|
sol_assert(accounts[2].is_signer);
|
||||||
|
sol_assert(accounts[3].is_signer);
|
||||||
|
|
||||||
|
sol_assert(accounts[0].is_writable);
|
||||||
|
sol_assert(accounts[1].is_writable);
|
||||||
|
sol_assert(accounts[2].is_writable);
|
||||||
|
sol_assert(accounts[3].is_writable);
|
||||||
|
|
||||||
|
if (params.ka_num > 4) {
|
||||||
|
{
|
||||||
|
SolAccountMeta arguments[] = {{accounts[0].key, true, true},
|
||||||
|
{accounts[1].key, true, false},
|
||||||
|
{accounts[2].key, true, false},
|
||||||
|
{accounts[3].key, false, true}};
|
||||||
|
uint8_t data[] = {7};
|
||||||
|
const SolInstruction instruction = {
|
||||||
|
(SolPubkey *)params.program_id, arguments,
|
||||||
|
SOL_ARRAY_SIZE(arguments), data, SOL_ARRAY_SIZE(data)};
|
||||||
|
sol_assert(SUCCESS ==
|
||||||
|
sol_invoke(&instruction, accounts, params.ka_num));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
SolAccountMeta arguments[] = {{accounts[0].key, true, true},
|
||||||
|
{accounts[1].key, true, false},
|
||||||
|
{accounts[2].key, true, false},
|
||||||
|
{accounts[3].key, true, false}};
|
||||||
|
uint8_t data[] = {3};
|
||||||
|
const SolInstruction instruction = {
|
||||||
|
(SolPubkey *)params.program_id, arguments,
|
||||||
|
SOL_ARRAY_SIZE(arguments), data, SOL_ARRAY_SIZE(data)};
|
||||||
|
sol_assert(SUCCESS ==
|
||||||
|
sol_invoke(&instruction, accounts, params.ka_num));
|
||||||
|
}
|
||||||
|
sol_assert(accounts[2].data[0] == 3);
|
||||||
|
sol_assert(accounts[3].data[0] == 3);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
sol_log("Unrecognized command");
|
sol_log("Unrecognized command");
|
||||||
|
|
|
@ -2,46 +2,92 @@
|
||||||
|
|
||||||
extern crate solana_program;
|
extern crate solana_program;
|
||||||
use solana_program::{
|
use solana_program::{
|
||||||
account_info::AccountInfo, entrypoint, entrypoint::ProgramResult, msg,
|
account_info::AccountInfo,
|
||||||
program_error::ProgramError, pubkey::Pubkey,
|
entrypoint,
|
||||||
|
entrypoint::ProgramResult,
|
||||||
|
instruction::{AccountMeta, Instruction},
|
||||||
|
msg,
|
||||||
|
program::invoke,
|
||||||
|
program_error::ProgramError,
|
||||||
|
pubkey::Pubkey,
|
||||||
};
|
};
|
||||||
|
|
||||||
entrypoint!(process_instruction);
|
entrypoint!(process_instruction);
|
||||||
fn process_instruction(
|
fn process_instruction(
|
||||||
_program_id: &Pubkey,
|
program_id: &Pubkey,
|
||||||
accounts: &[AccountInfo],
|
accounts: &[AccountInfo],
|
||||||
instruction_data: &[u8],
|
instruction_data: &[u8],
|
||||||
) -> ProgramResult {
|
) -> ProgramResult {
|
||||||
match instruction_data[0] {
|
match instruction_data[0] {
|
||||||
1 => {
|
1 => {
|
||||||
msg!("modify first account data");
|
msg!("modify account (2) data");
|
||||||
accounts[2].data.borrow_mut()[0] = 1;
|
accounts[2].data.borrow_mut()[0] = 1;
|
||||||
}
|
}
|
||||||
2 => {
|
2 => {
|
||||||
msg!("modify first account data");
|
msg!("modify account (3) data");
|
||||||
accounts[3].data.borrow_mut()[0] = 2;
|
accounts[3].data.borrow_mut()[0] = 2;
|
||||||
}
|
}
|
||||||
3 => {
|
3 => {
|
||||||
msg!("modify both account data");
|
msg!("modify account (2,3) data");
|
||||||
accounts[2].data.borrow_mut()[0] += 1;
|
accounts[2].data.borrow_mut()[0] += 1;
|
||||||
accounts[3].data.borrow_mut()[0] += 2;
|
accounts[3].data.borrow_mut()[0] += 2;
|
||||||
}
|
}
|
||||||
4 => {
|
4 => {
|
||||||
msg!("modify first account lamports");
|
msg!("modify account (1,2) lamports");
|
||||||
**accounts[1].lamports.borrow_mut() -= 1;
|
**accounts[1].lamports.borrow_mut() -= 1;
|
||||||
**accounts[2].lamports.borrow_mut() += 1;
|
**accounts[2].lamports.borrow_mut() += 1;
|
||||||
}
|
}
|
||||||
5 => {
|
5 => {
|
||||||
msg!("modify first account lamports");
|
msg!("modify account (1,3) lamports");
|
||||||
**accounts[1].lamports.borrow_mut() -= 2;
|
**accounts[1].lamports.borrow_mut() -= 2;
|
||||||
**accounts[3].lamports.borrow_mut() += 2;
|
**accounts[3].lamports.borrow_mut() += 2;
|
||||||
}
|
}
|
||||||
6 => {
|
6 => {
|
||||||
msg!("modify both account lamports");
|
msg!("modify account (1,2,3) lamports");
|
||||||
**accounts[1].lamports.borrow_mut() -= 3;
|
**accounts[1].lamports.borrow_mut() -= 3;
|
||||||
**accounts[2].lamports.borrow_mut() += 1;
|
**accounts[2].lamports.borrow_mut() += 1;
|
||||||
**accounts[3].lamports.borrow_mut() += 2;
|
**accounts[3].lamports.borrow_mut() += 2;
|
||||||
}
|
}
|
||||||
|
7 => {
|
||||||
|
msg!("check account (0,1,2,3) privs");
|
||||||
|
assert!(accounts[0].is_signer);
|
||||||
|
assert!(!accounts[1].is_signer);
|
||||||
|
assert!(accounts[2].is_signer);
|
||||||
|
assert!(accounts[3].is_signer);
|
||||||
|
|
||||||
|
assert!(accounts[0].is_writable);
|
||||||
|
assert!(accounts[1].is_writable);
|
||||||
|
assert!(accounts[2].is_writable);
|
||||||
|
assert!(accounts[3].is_writable);
|
||||||
|
|
||||||
|
if accounts.len() > 4 {
|
||||||
|
let instruction = Instruction::new_with_bytes(
|
||||||
|
*program_id,
|
||||||
|
&[7],
|
||||||
|
vec![
|
||||||
|
AccountMeta::new(*accounts[0].key, true),
|
||||||
|
AccountMeta::new(*accounts[1].key, false),
|
||||||
|
AccountMeta::new(*accounts[2].key, false),
|
||||||
|
AccountMeta::new_readonly(*accounts[3].key, true),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
invoke(&instruction, &accounts)?;
|
||||||
|
|
||||||
|
let instruction = Instruction::new_with_bytes(
|
||||||
|
*program_id,
|
||||||
|
&[3],
|
||||||
|
vec![
|
||||||
|
AccountMeta::new(*accounts[0].key, true),
|
||||||
|
AccountMeta::new(*accounts[1].key, false),
|
||||||
|
AccountMeta::new(*accounts[2].key, false),
|
||||||
|
AccountMeta::new(*accounts[3].key, false),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
invoke(&instruction, &accounts)?;
|
||||||
|
assert_eq!(accounts[2].try_borrow_mut_data()?[0], 3);
|
||||||
|
assert_eq!(accounts[3].try_borrow_mut_data()?[0], 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
msg!("Unrecognized command");
|
msg!("Unrecognized command");
|
||||||
return Err(ProgramError::InvalidArgument);
|
return Err(ProgramError::InvalidArgument);
|
||||||
|
|
|
@ -547,8 +547,8 @@ fn test_program_bpf_duplicate_accounts() {
|
||||||
let payee_account = Account::new(10, 1, &program_id);
|
let payee_account = Account::new(10, 1, &program_id);
|
||||||
let payee_pubkey = solana_sdk::pubkey::new_rand();
|
let payee_pubkey = solana_sdk::pubkey::new_rand();
|
||||||
bank.store_account(&payee_pubkey, &payee_account);
|
bank.store_account(&payee_pubkey, &payee_account);
|
||||||
|
|
||||||
let account = Account::new(10, 1, &program_id);
|
let account = Account::new(10, 1, &program_id);
|
||||||
|
|
||||||
let pubkey = solana_sdk::pubkey::new_rand();
|
let pubkey = solana_sdk::pubkey::new_rand();
|
||||||
let account_metas = vec![
|
let account_metas = vec![
|
||||||
AccountMeta::new(mint_keypair.pubkey(), true),
|
AccountMeta::new(mint_keypair.pubkey(), true),
|
||||||
|
@ -598,6 +598,21 @@ fn test_program_bpf_duplicate_accounts() {
|
||||||
let lamports = bank_client.get_balance(&pubkey).unwrap();
|
let lamports = bank_client.get_balance(&pubkey).unwrap();
|
||||||
assert!(result.is_ok());
|
assert!(result.is_ok());
|
||||||
assert_eq!(lamports, 13);
|
assert_eq!(lamports, 13);
|
||||||
|
|
||||||
|
let keypair = Keypair::new();
|
||||||
|
let pubkey = keypair.pubkey();
|
||||||
|
let account_metas = vec![
|
||||||
|
AccountMeta::new(mint_keypair.pubkey(), true),
|
||||||
|
AccountMeta::new(payee_pubkey, false),
|
||||||
|
AccountMeta::new(pubkey, false),
|
||||||
|
AccountMeta::new_readonly(pubkey, true),
|
||||||
|
AccountMeta::new_readonly(program_id, false),
|
||||||
|
];
|
||||||
|
bank.store_account(&pubkey, &account);
|
||||||
|
let instruction = Instruction::new_with_bytes(program_id, &[7], account_metas.clone());
|
||||||
|
let message = Message::new(&[instruction], Some(&mint_keypair.pubkey()));
|
||||||
|
let result = bank_client.send_and_confirm_message(&[&mint_keypair, &keypair], message);
|
||||||
|
assert!(result.is_ok());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue