Fix parsing CreateAccountWithSeed instructions (#13513)

* Reduce required num_system_accounts and handle 2-account instructions properly

* Update CreateAccountWithSeed account docs to be correct

* Add CreateAccountWithSeed test
This commit is contained in:
Tyera Eulberg 2020-11-10 16:51:53 -07:00 committed by GitHub
parent 9ca8e98525
commit 91f4e99b4c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 67 additions and 7 deletions

View File

@ -479,6 +479,43 @@ mod tests {
assert_eq!(to_account.borrow().data, [0, 0]);
}
#[test]
fn test_create_account_with_seed_separate_base_account() {
let new_owner = Pubkey::new(&[9; 32]);
let from = solana_sdk::pubkey::new_rand();
let base = solana_sdk::pubkey::new_rand();
let seed = "shiny pepper";
let to = Pubkey::create_with_seed(&base, seed, &new_owner).unwrap();
let from_account = Account::new_ref(100, 0, &system_program::id());
let to_account = Account::new_ref(0, 0, &Pubkey::default());
let base_account = Account::new_ref(0, 0, &Pubkey::default());
assert_eq!(
process_instruction(
&Pubkey::default(),
&[
KeyedAccount::new(&from, true, &from_account),
KeyedAccount::new(&to, false, &to_account),
KeyedAccount::new(&base, true, &base_account)
],
&bincode::serialize(&SystemInstruction::CreateAccountWithSeed {
base,
seed: seed.to_string(),
lamports: 50,
space: 2,
owner: new_owner
})
.unwrap()
),
Ok(())
);
assert_eq!(from_account.borrow().lamports, 50);
assert_eq!(to_account.borrow().lamports, 50);
assert_eq!(to_account.borrow().owner, new_owner);
assert_eq!(to_account.borrow().data, [0, 0]);
}
#[test]
fn test_address_create_with_seed_mismatch() {
let from = solana_sdk::pubkey::new_rand();

View File

@ -92,7 +92,9 @@ pub enum SystemInstruction {
/// # Account references
/// 0. [WRITE, SIGNER] Funding account
/// 1. [WRITE] Created account
/// 2. [SIGNER] Base account
/// 2. [SIGNER] (optional) Base account; the account matching the base Pubkey below must be
/// provided as a signer, but may be the same as the funding account
/// and provided as account 0
CreateAccountWithSeed {
/// Base public key
base: Pubkey,

View File

@ -68,12 +68,12 @@ pub fn parse_system(
space,
owner,
} => {
check_num_system_accounts(&instruction.accounts, 3)?;
check_num_system_accounts(&instruction.accounts, 2)?;
Ok(ParsedInstructionEnum {
instruction_type: "createAccountWithSeed".to_string(),
info: json!({
"source": account_keys[instruction.accounts[0] as usize].to_string(),
"newAccount": account_keys[instruction.accounts[2] as usize].to_string(),
"newAccount": account_keys[instruction.accounts[1] as usize].to_string(),
"base": base.to_string(),
"seed": seed,
"lamports": lamports,
@ -260,7 +260,7 @@ mod test {
let seed = "test_seed";
let instruction = system_instruction::create_account_with_seed(
&keys[0], &keys[1], &keys[2], seed, lamports, space, &keys[3],
&keys[0], &keys[2], &keys[1], seed, lamports, space, &keys[3],
);
let message = Message::new(&[instruction], None);
assert_eq!(
@ -269,16 +269,37 @@ mod test {
instruction_type: "createAccountWithSeed".to_string(),
info: json!({
"source": keys[0].to_string(),
"newAccount": keys[1].to_string(),
"newAccount": keys[2].to_string(),
"lamports": lamports,
"base": keys[2].to_string(),
"base": keys[1].to_string(),
"seed": seed,
"owner": keys[3].to_string(),
"space": space,
}),
}
);
assert!(parse_system(&message.instructions[0], &keys[0..2]).is_err());
let seed = "test_seed";
let instruction = system_instruction::create_account_with_seed(
&keys[0], &keys[1], &keys[0], seed, lamports, space, &keys[3],
);
let message = Message::new(&[instruction], None);
assert_eq!(
parse_system(&message.instructions[0], &keys[0..2]).unwrap(),
ParsedInstructionEnum {
instruction_type: "createAccountWithSeed".to_string(),
info: json!({
"source": keys[0].to_string(),
"newAccount": keys[1].to_string(),
"lamports": lamports,
"base": keys[0].to_string(),
"seed": seed,
"owner": keys[3].to_string(),
"space": space,
}),
}
);
assert!(parse_system(&message.instructions[0], &keys[0..1]).is_err());
let instruction = system_instruction::allocate(&keys[0], space);
let message = Message::new(&[instruction], None);