From e1ebaa902b79a570c2861ba673345a2d2ccf8149 Mon Sep 17 00:00:00 2001 From: Rob Walker Date: Sun, 29 Dec 2019 16:42:24 -0800 Subject: [PATCH] Add base pubkey to create_account_with_seed (#7636) --- programs/bpf/Cargo.lock | 178 ++++++++++---------- programs/stake/src/stake_instruction.rs | 4 + programs/vote/src/vote_instruction.rs | 2 + runtime/src/system_instruction_processor.rs | 53 ++++-- runtime/tests/stake.rs | 1 + sdk/src/system_instruction.rs | 3 + 6 files changed, 136 insertions(+), 105 deletions(-) diff --git a/programs/bpf/Cargo.lock b/programs/bpf/Cargo.lock index 8529bea563..d9b2fe7a74 100644 --- a/programs/bpf/Cargo.lock +++ b/programs/bpf/Cargo.lock @@ -1583,157 +1583,157 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "solana-bpf-loader-program" -version = "0.22.0" +version = "0.23.0" dependencies = [ "bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-logger 0.22.0", - "solana-sdk 0.22.0", + "solana-logger 0.23.0", + "solana-sdk 0.23.0", "solana_rbpf 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-bpf-programs" -version = "0.22.0" +version = "0.23.0" dependencies = [ "bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "elf 0.0.10 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-bpf-loader-program 0.22.0", - "solana-logger 0.22.0", - "solana-runtime 0.22.0", - "solana-sdk 0.22.0", + "solana-bpf-loader-program 0.23.0", + "solana-logger 0.23.0", + "solana-runtime 0.23.0", + "solana-sdk 0.23.0", "solana_rbpf 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-bpf-rust-128bit" -version = "0.22.0" +version = "0.23.0" dependencies = [ - "solana-bpf-rust-128bit-dep 0.22.0", - "solana-sdk 0.22.0", - "solana-sdk-bpf-test 0.22.0", + "solana-bpf-rust-128bit-dep 0.23.0", + "solana-sdk 0.23.0", + "solana-sdk-bpf-test 0.23.0", ] [[package]] name = "solana-bpf-rust-128bit-dep" -version = "0.22.0" +version = "0.23.0" dependencies = [ - "solana-sdk 0.22.0", - "solana-sdk-bpf-test 0.22.0", + "solana-sdk 0.23.0", + "solana-sdk-bpf-test 0.23.0", ] [[package]] name = "solana-bpf-rust-alloc" -version = "0.22.0" +version = "0.23.0" dependencies = [ - "solana-sdk 0.22.0", - "solana-sdk-bpf-test 0.22.0", + "solana-sdk 0.23.0", + "solana-sdk-bpf-test 0.23.0", ] [[package]] name = "solana-bpf-rust-dep-crate" -version = "0.22.0" +version = "0.23.0" dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-sdk 0.22.0", - "solana-sdk-bpf-test 0.22.0", + "solana-sdk 0.23.0", + "solana-sdk-bpf-test 0.23.0", ] [[package]] name = "solana-bpf-rust-external-spend" -version = "0.22.0" +version = "0.23.0" dependencies = [ - "solana-sdk 0.22.0", - "solana-sdk-bpf-test 0.22.0", + "solana-sdk 0.23.0", + "solana-sdk-bpf-test 0.23.0", ] [[package]] name = "solana-bpf-rust-iter" -version = "0.22.0" +version = "0.23.0" dependencies = [ - "solana-sdk 0.22.0", - "solana-sdk-bpf-test 0.22.0", + "solana-sdk 0.23.0", + "solana-sdk-bpf-test 0.23.0", ] [[package]] name = "solana-bpf-rust-many-args" -version = "0.22.0" +version = "0.23.0" dependencies = [ - "solana-bpf-rust-many-args-dep 0.22.0", - "solana-sdk 0.22.0", - "solana-sdk-bpf-test 0.22.0", + "solana-bpf-rust-many-args-dep 0.23.0", + "solana-sdk 0.23.0", + "solana-sdk-bpf-test 0.23.0", ] [[package]] name = "solana-bpf-rust-many-args-dep" -version = "0.22.0" +version = "0.23.0" dependencies = [ - "solana-sdk 0.22.0", - "solana-sdk-bpf-test 0.22.0", + "solana-sdk 0.23.0", + "solana-sdk-bpf-test 0.23.0", ] [[package]] name = "solana-bpf-rust-noop" -version = "0.22.0" +version = "0.23.0" dependencies = [ - "solana-sdk 0.22.0", - "solana-sdk-bpf-test 0.22.0", + "solana-sdk 0.23.0", + "solana-sdk-bpf-test 0.23.0", ] [[package]] name = "solana-bpf-rust-panic" -version = "0.22.0" +version = "0.23.0" dependencies = [ - "solana-sdk 0.22.0", - "solana-sdk-bpf-test 0.22.0", + "solana-sdk 0.23.0", + "solana-sdk-bpf-test 0.23.0", ] [[package]] name = "solana-bpf-rust-param-passing" -version = "0.22.0" +version = "0.23.0" dependencies = [ - "solana-bpf-rust-param-passing-dep 0.22.0", - "solana-sdk 0.22.0", - "solana-sdk-bpf-test 0.22.0", + "solana-bpf-rust-param-passing-dep 0.23.0", + "solana-sdk 0.23.0", + "solana-sdk-bpf-test 0.23.0", ] [[package]] name = "solana-bpf-rust-param-passing-dep" -version = "0.22.0" +version = "0.23.0" dependencies = [ - "solana-sdk 0.22.0", - "solana-sdk-bpf-test 0.22.0", + "solana-sdk 0.23.0", + "solana-sdk-bpf-test 0.23.0", ] [[package]] name = "solana-bpf-rust-sysval" -version = "0.22.0" +version = "0.23.0" dependencies = [ - "solana-sdk 0.22.0", - "solana-sdk-bpf-test 0.22.0", + "solana-sdk 0.23.0", + "solana-sdk-bpf-test 0.23.0", ] [[package]] name = "solana-config-program" -version = "0.22.0" +version = "0.23.0" dependencies = [ "bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-logger 0.22.0", - "solana-sdk 0.22.0", + "solana-logger 0.23.0", + "solana-sdk 0.23.0", ] [[package]] name = "solana-crate-features" -version = "0.22.0" +version = "0.23.0" dependencies = [ "backtrace 0.3.37 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1756,7 +1756,7 @@ dependencies = [ [[package]] name = "solana-logger" -version = "0.22.0" +version = "0.23.0" dependencies = [ "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1765,26 +1765,26 @@ dependencies = [ [[package]] name = "solana-measure" -version = "0.22.0" +version = "0.23.0" dependencies = [ - "solana-sdk 0.22.0", + "solana-sdk 0.23.0", ] [[package]] name = "solana-metrics" -version = "0.22.0" +version = "0.23.0" dependencies = [ "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "reqwest 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-sdk 0.22.0", + "solana-sdk 0.23.0", "sys-info 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-rayon-threadlimit" -version = "0.22.0" +version = "0.23.0" dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "sys-info 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1792,7 +1792,7 @@ dependencies = [ [[package]] name = "solana-runtime" -version = "0.22.0" +version = "0.23.0" dependencies = [ "bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "bv 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1810,22 +1810,22 @@ dependencies = [ "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-bpf-loader-program 0.22.0", - "solana-logger 0.22.0", - "solana-measure 0.22.0", - "solana-metrics 0.22.0", - "solana-rayon-threadlimit 0.22.0", - "solana-sdk 0.22.0", - "solana-stake-program 0.22.0", - "solana-storage-program 0.22.0", - "solana-vote-program 0.22.0", + "solana-bpf-loader-program 0.23.0", + "solana-logger 0.23.0", + "solana-measure 0.23.0", + "solana-metrics 0.23.0", + "solana-rayon-threadlimit 0.23.0", + "solana-sdk 0.23.0", + "solana-stake-program 0.23.0", + "solana-storage-program 0.23.0", + "solana-vote-program 0.23.0", "sys-info 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-sdk" -version = "0.22.0" +version = "0.23.0" dependencies = [ "assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1849,19 +1849,19 @@ dependencies = [ "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-crate-features 0.22.0", - "solana-logger 0.22.0", - "solana-sdk-macro 0.22.0", + "solana-crate-features 0.23.0", + "solana-logger 0.23.0", + "solana-sdk-macro 0.23.0", "thiserror 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-sdk-bpf-test" -version = "0.22.0" +version = "0.23.0" [[package]] name = "solana-sdk-macro" -version = "0.22.0" +version = "0.23.0" dependencies = [ "bs58 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1871,7 +1871,7 @@ dependencies = [ [[package]] name = "solana-stake-program" -version = "0.22.0" +version = "0.23.0" dependencies = [ "bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1880,17 +1880,17 @@ dependencies = [ "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-config-program 0.22.0", - "solana-logger 0.22.0", - "solana-metrics 0.22.0", - "solana-sdk 0.22.0", - "solana-vote-program 0.22.0", + "solana-config-program 0.23.0", + "solana-logger 0.23.0", + "solana-metrics 0.23.0", + "solana-sdk 0.23.0", + "solana-vote-program 0.23.0", "thiserror 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-storage-program" -version = "0.22.0" +version = "0.23.0" dependencies = [ "bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1899,13 +1899,13 @@ dependencies = [ "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-logger 0.22.0", - "solana-sdk 0.22.0", + "solana-logger 0.23.0", + "solana-sdk 0.23.0", ] [[package]] name = "solana-vote-program" -version = "0.22.0" +version = "0.23.0" dependencies = [ "bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1913,9 +1913,9 @@ dependencies = [ "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-logger 0.22.0", - "solana-metrics 0.22.0", - "solana-sdk 0.22.0", + "solana-logger 0.23.0", + "solana-metrics 0.23.0", + "solana-sdk 0.23.0", "thiserror 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/programs/stake/src/stake_instruction.rs b/programs/stake/src/stake_instruction.rs index 0234d42ece..7b0e0aa749 100644 --- a/programs/stake/src/stake_instruction.rs +++ b/programs/stake/src/stake_instruction.rs @@ -142,6 +142,7 @@ pub fn initialize(stake_pubkey: &Pubkey, authorized: &Authorized, lockup: &Locku pub fn create_account_with_seed( from_pubkey: &Pubkey, stake_pubkey: &Pubkey, + base: &Pubkey, seed: &str, authorized: &Authorized, lockup: &Lockup, @@ -151,6 +152,7 @@ pub fn create_account_with_seed( system_instruction::create_account_with_seed( from_pubkey, stake_pubkey, + base, seed, lamports, std::mem::size_of::() as u64, @@ -224,6 +226,7 @@ pub fn create_account_and_delegate_stake( pub fn create_account_with_seed_and_delegate_stake( from_pubkey: &Pubkey, stake_pubkey: &Pubkey, + base: &Pubkey, seed: &str, vote_pubkey: &Pubkey, authorized: &Authorized, @@ -233,6 +236,7 @@ pub fn create_account_with_seed_and_delegate_stake( let mut instructions = create_account_with_seed( from_pubkey, stake_pubkey, + base, seed, authorized, lockup, diff --git a/programs/vote/src/vote_instruction.rs b/programs/vote/src/vote_instruction.rs index 90b573baf7..e9c3195de0 100644 --- a/programs/vote/src/vote_instruction.rs +++ b/programs/vote/src/vote_instruction.rs @@ -90,6 +90,7 @@ pub fn create_account( pub fn create_account_with_seed( from_pubkey: &Pubkey, vote_pubkey: &Pubkey, + base: &Pubkey, seed: &str, vote_init: &VoteInit, lamports: u64, @@ -98,6 +99,7 @@ pub fn create_account_with_seed( let create_ix = system_instruction::create_account_with_seed( from_pubkey, vote_pubkey, + base, seed, lamports, space, diff --git a/runtime/src/system_instruction_processor.rs b/runtime/src/system_instruction_processor.rs index fff9f0fa5d..d6e291ef37 100644 --- a/runtime/src/system_instruction_processor.rs +++ b/runtime/src/system_instruction_processor.rs @@ -1,7 +1,7 @@ use log::*; use solana_sdk::{ - account::KeyedAccount, + account::{get_signers, KeyedAccount}, instruction::InstructionError, instruction_processor_utils::{limited_deserialize, next_keyed_account}, pubkey::Pubkey, @@ -11,27 +11,31 @@ use solana_sdk::{ system_program, sysvar, }; +use std::collections::HashSet; + fn create_account_with_seed( from: &mut KeyedAccount, to: &mut KeyedAccount, + base: &Pubkey, seed: &str, lamports: u64, data_length: u64, program_id: &Pubkey, + signers: &HashSet, ) -> Result<(), InstructionError> { - // `from` is the source of the derived address, the caller must have - // signed, even if no lamports will be transferred - if from.signer_key().is_none() { - debug!("CreateAccountWithSeed: from must sign"); + // `base` is the source of the derived address and must sign for + // rights to the address + if !signers.contains(&base) { + debug!("CreateAccountWithSeed: must carry signature of `base`"); return Err(InstructionError::MissingRequiredSignature); } - // re-derive the address, must match `to` - let address = create_address_with_seed(from.unsigned_key(), seed, program_id)?; + // re-derive the address, must match the `to` account + let address = create_address_with_seed(base, seed, program_id)?; if to.unsigned_key() != &address { debug!( - "CreateAccountWithSeed: invalid argument; generated {} does not match to {}", + "CreateAccountWithSeed: invalid argument; derived {} does not match `to` {}", address, to.unsigned_key() ); @@ -49,14 +53,8 @@ fn create_account( data_length: u64, program_id: &Pubkey, ) -> Result<(), InstructionError> { - // if lamports == 0, the `from` account isn't touched - if lamports != 0 && from.signer_key().is_none() { - debug!("CreateAccount: from must sign"); - return Err(InstructionError::MissingRequiredSignature); - } - if to.signer_key().is_none() { - debug!("CreateAccount: to must sign"); + debug!("CreateAccount: `to` must sign"); return Err(InstructionError::MissingRequiredSignature); } @@ -70,6 +68,12 @@ fn finish_create_account( data_length: u64, program_id: &Pubkey, ) -> Result<(), InstructionError> { + // if lamports == 0, the `from` account isn't touched + if lamports != 0 && from.signer_key().is_none() { + debug!("CreateAccount: `from` must sign transfer"); + return Err(InstructionError::MissingRequiredSignature); + } + // if it looks like the `to` account is already in use, bail if to.account.lamports != 0 || !to.account.data.is_empty() @@ -173,6 +177,7 @@ pub fn process_instruction( trace!("process_instruction: {:?}", instruction); trace!("keyed_accounts: {:?}", keyed_accounts); + let signers = get_signers(keyed_accounts); let keyed_accounts_iter = &mut keyed_accounts.iter_mut(); match instruction { @@ -186,6 +191,7 @@ pub fn process_instruction( create_account(from, to, lamports, space, &program_id) } SystemInstruction::CreateAccountWithSeed { + base, seed, lamports, space, @@ -193,7 +199,17 @@ pub fn process_instruction( } => { let from = next_keyed_account(keyed_accounts_iter)?; let to = next_keyed_account(keyed_accounts_iter)?; - create_account_with_seed(from, to, &seed, lamports, space, &program_id) + + create_account_with_seed( + from, + to, + &base, + &seed, + lamports, + space, + &program_id, + &signers, + ) } SystemInstruction::Assign { program_id } => { let account = next_keyed_account(keyed_accounts_iter)?; @@ -269,6 +285,7 @@ mod tests { KeyedAccount::new(&to, false, &mut to_account) ], &bincode::serialize(&SystemInstruction::CreateAccountWithSeed { + base: from, seed: seed.to_string(), lamports: 50, space: 2, @@ -298,10 +315,12 @@ mod tests { create_account_with_seed( &mut KeyedAccount::new(&from, true, &mut from_account), &mut KeyedAccount::new(&to, false, &mut to_account), + &from, seed, 50, 2, &new_program_owner, + &[from].iter().cloned().collect::>(), ), Err(SystemError::AddressWithSeedMismatch.into()) ); @@ -322,10 +341,12 @@ mod tests { create_account_with_seed( &mut KeyedAccount::new(&from, false, &mut from_account), &mut KeyedAccount::new(&to, false, &mut to_account), + &from, seed, 50, 2, &new_program_owner, + &[from].iter().cloned().collect::>(), ), Err(InstructionError::MissingRequiredSignature) ); diff --git a/runtime/tests/stake.rs b/runtime/tests/stake.rs index 283defd325..2d9fafebb4 100644 --- a/runtime/tests/stake.rs +++ b/runtime/tests/stake.rs @@ -384,6 +384,7 @@ fn test_create_stake_account_from_seed() { stake_instruction::create_account_with_seed_and_delegate_stake( &mint_pubkey, &stake_pubkey, + &mint_pubkey, seed, &vote_pubkey, &authorized, diff --git a/sdk/src/system_instruction.rs b/sdk/src/system_instruction.rs index c0790e3fc1..3a8ab4f7df 100644 --- a/sdk/src/system_instruction.rs +++ b/sdk/src/system_instruction.rs @@ -65,6 +65,7 @@ pub enum SystemInstruction { /// * space - memory to allocate if greater then zero /// * program_id - the program id of the new account CreateAccountWithSeed { + base: Pubkey, seed: String, lamports: u64, space: u64, @@ -97,6 +98,7 @@ pub fn create_account( pub fn create_account_with_seed( from_pubkey: &Pubkey, to_pubkey: &Pubkey, + base: &Pubkey, seed: &str, lamports: u64, space: u64, @@ -110,6 +112,7 @@ pub fn create_account_with_seed( Instruction::new( system_program::id(), &SystemInstruction::CreateAccountWithSeed { + base: *base, seed: seed.to_string(), lamports, space,