diff --git a/programs/librapay/Cargo.lock b/programs/librapay/Cargo.lock index 77802f5b0..54c1f3a8d 100644 --- a/programs/librapay/Cargo.lock +++ b/programs/librapay/Cargo.lock @@ -2593,7 +2593,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "solana-bpf-loader-program" -version = "0.24.0" +version = "1.0.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)", @@ -2601,28 +2601,28 @@ dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "num-derive 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-logger 0.24.0", - "solana-sdk 0.24.0", + "solana-logger 1.0.0", + "solana-sdk 1.0.0", "solana_rbpf 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "thiserror 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-config-program" -version = "0.24.0" +version = "1.0.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.24.0", - "solana-sdk 0.24.0", + "solana-logger 1.0.0", + "solana-sdk 1.0.0", ] [[package]] name = "solana-crate-features" -version = "0.24.0" +version = "1.0.0" dependencies = [ "backtrace 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2645,20 +2645,20 @@ dependencies = [ [[package]] name = "solana-librapay" -version = "0.24.0" +version = "1.0.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)", - "solana-logger 0.24.0", - "solana-move-loader-program 0.24.0", - "solana-runtime 0.24.0", - "solana-sdk 0.24.0", + "solana-logger 1.0.0", + "solana-move-loader-program 1.0.0", + "solana-runtime 1.0.0", + "solana-sdk 1.0.0", "solana_libra_types 0.0.1-sol4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-logger" -version = "0.24.0" +version = "1.0.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)", @@ -2667,30 +2667,30 @@ dependencies = [ [[package]] name = "solana-measure" -version = "0.24.0" +version = "1.0.0" dependencies = [ "jemalloc-ctl 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "jemallocator 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-metrics 0.24.0", - "solana-sdk 0.24.0", + "solana-metrics 1.0.0", + "solana-sdk 1.0.0", ] [[package]] name = "solana-metrics" -version = "0.24.0" +version = "1.0.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.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-sdk 0.24.0", + "solana-sdk 1.0.0", "sys-info 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-move-loader-program" -version = "0.24.0" +version = "1.0.0" dependencies = [ "bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2701,8 +2701,8 @@ dependencies = [ "serde_bytes 0.11.2 (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.46 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-logger 0.24.0", - "solana-sdk 0.24.0", + "solana-logger 1.0.0", + "solana-sdk 1.0.0", "solana_libra_bytecode_verifier 0.0.1-sol4 (registry+https://github.com/rust-lang/crates.io-index)", "solana_libra_canonical_serialization 0.0.1-sol4 (registry+https://github.com/rust-lang/crates.io-index)", "solana_libra_compiler 0.0.1-sol4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2719,7 +2719,7 @@ dependencies = [ [[package]] name = "solana-rayon-threadlimit" -version = "0.24.0" +version = "1.0.0" dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "sys-info 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2727,7 +2727,7 @@ dependencies = [ [[package]] name = "solana-runtime" -version = "0.24.0" +version = "1.0.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)", @@ -2745,15 +2745,15 @@ dependencies = [ "rayon 1.2.0 (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-bpf-loader-program 0.24.0", - "solana-logger 0.24.0", - "solana-measure 0.24.0", - "solana-metrics 0.24.0", - "solana-rayon-threadlimit 0.24.0", - "solana-sdk 0.24.0", - "solana-stake-program 0.24.0", - "solana-storage-program 0.24.0", - "solana-vote-program 0.24.0", + "solana-bpf-loader-program 1.0.0", + "solana-logger 1.0.0", + "solana-measure 1.0.0", + "solana-metrics 1.0.0", + "solana-rayon-threadlimit 1.0.0", + "solana-sdk 1.0.0", + "solana-stake-program 1.0.0", + "solana-storage-program 1.0.0", + "solana-vote-program 1.0.0", "sys-info 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "thiserror 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2761,7 +2761,7 @@ dependencies = [ [[package]] name = "solana-sdk" -version = "0.24.0" +version = "1.0.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)", @@ -2785,15 +2785,15 @@ dependencies = [ "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-crate-features 0.24.0", - "solana-logger 0.24.0", - "solana-sdk-macro 0.24.0", + "solana-crate-features 1.0.0", + "solana-logger 1.0.0", + "solana-sdk-macro 1.0.0", "thiserror 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-sdk-macro" -version = "0.24.0" +version = "1.0.0" dependencies = [ "bs58 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2803,7 +2803,7 @@ dependencies = [ [[package]] name = "solana-stake-program" -version = "0.24.0" +version = "1.0.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)", @@ -2811,17 +2811,17 @@ 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-config-program 0.24.0", - "solana-logger 0.24.0", - "solana-metrics 0.24.0", - "solana-sdk 0.24.0", - "solana-vote-program 0.24.0", + "solana-config-program 1.0.0", + "solana-logger 1.0.0", + "solana-metrics 1.0.0", + "solana-sdk 1.0.0", + "solana-vote-program 1.0.0", "thiserror 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "solana-storage-program" -version = "0.24.0" +version = "1.0.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)", @@ -2830,13 +2830,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.24.0", - "solana-sdk 0.24.0", + "solana-logger 1.0.0", + "solana-sdk 1.0.0", ] [[package]] name = "solana-vote-program" -version = "0.24.0" +version = "1.0.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)", @@ -2844,9 +2844,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.24.0", - "solana-metrics 0.24.0", - "solana-sdk 0.24.0", + "solana-logger 1.0.0", + "solana-metrics 1.0.0", + "solana-sdk 1.0.0", "thiserror 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/runtime/src/message_processor.rs b/runtime/src/message_processor.rs index 8f3b0b66c..578407e74 100644 --- a/runtime/src/message_processor.rs +++ b/runtime/src/message_processor.rs @@ -19,7 +19,6 @@ use libloading::os::windows::*; // The relevant state of an account before an Instruction executes, used // to verify account integrity after the Instruction completes -#[derive(Clone, Debug, PartialEq)] pub struct PreAccount { pub is_writable: bool, pub lamports: u64, @@ -54,8 +53,6 @@ impl PreAccount { } pub fn verify(&self, program_id: &Pubkey, post: &Account) -> Result<(), InstructionError> { - // Verify the transaction - // Only the owner of the account may change owner and // only if the account is writable and // only if the data is zero-initialized or empty @@ -221,6 +218,35 @@ impl MessageProcessor { ) } + /// Record the initial state of the accounts so that it can be compared + // after the instruction is processed + pub fn create_pre_accounts( + // program_id: &Pubkey, + message: &Message, + instruction: &CompiledInstruction, + program_accounts: &[Rc>], + ) -> Vec> { + let program_id = instruction.program_id(&message.account_keys); + + // Copy only what we need to verify after instruction processing + let mut pre_accounts = Vec::with_capacity(program_accounts.len()); + 'root: for (i, account) in program_accounts.iter().enumerate() { + // Note: This is an O(n^2) algorithm, + // but performed on a very small slice and requires no heap allocations + for account_after in program_accounts.iter().skip(i + 1) { + if Rc::ptr_eq(account, account_after) { + pre_accounts.push(None); + continue 'root; // don't verify duplicates + } + } + let is_writable = message.is_writable(instruction.accounts[i] as usize); + let account = account.borrow(); + pre_accounts.push(Some(PreAccount::new(&account, is_writable, program_id))) + } + pre_accounts + } + + /// Verify there are no outstanding borrows pub fn verify_account_references( executable_accounts: &[(Pubkey, RefCell)], program_accounts: &[Rc>], @@ -238,33 +264,30 @@ impl MessageProcessor { Ok(()) } + /// Verify the results of an instruction pub fn verify( - program_id: &Pubkey, - pre_accounts: &[PreAccount], + message: &Message, + instruction: &CompiledInstruction, + pre_accounts: &[Option], executable_accounts: &[(Pubkey, RefCell)], program_accounts: &[Rc>], ) -> Result<(), InstructionError> { + let program_id = instruction.program_id(&message.account_keys); + // Verify all accounts have zero outstanding refs Self::verify_account_references(executable_accounts, program_accounts)?; // Verify the per-account instruction results let (mut pre_sum, mut post_sum) = (0_u128, 0_u128); - 'root: for (i, (pre_account, account)) in - pre_accounts.iter().zip(program_accounts).enumerate() - { - // Note: This is an O(n^2) algorithm, - // but performed on a very small slice and requires no heap allocations - for account_after in program_accounts.iter().skip(i + 1) { - if Rc::ptr_eq(account, account_after) { - continue 'root; // don't verify duplicates - } + for (pre_account, account) in pre_accounts.iter().zip(program_accounts) { + if let Some(pre_account) = pre_account { + let account = account + .try_borrow() + .map_err(|_| InstructionError::AccountBorrowFailed)?; + pre_account.verify(&program_id, &account)?; + pre_sum += u128::from(pre_account.lamports); + post_sum += u128::from(account.lamports); } - let account = account - .try_borrow() - .map_err(|_| InstructionError::AccountBorrowFailed)?; - pre_account.verify(&program_id, &account)?; - pre_sum += u128::from(pre_account.lamports); - post_sum += u128::from(account.lamports); } // Verify that the total sum of all the lamports did not change @@ -286,28 +309,15 @@ impl MessageProcessor { program_accounts: &[Rc>], ) -> Result<(), InstructionError> { assert_eq!(instruction.accounts.len(), program_accounts.len()); - let program_id = instruction.program_id(&message.account_keys); - // Copy only what we need to verify after instruction processing - let pre_accounts: Vec<_> = program_accounts - .iter() - .enumerate() - .map(|(i, account)| { - let is_writable = message.is_writable(instruction.accounts[i] as usize); - let account = account.borrow(); - PreAccount::new(&account, is_writable, program_id) - }) - .collect(); - + let pre_accounts = Self::create_pre_accounts(message, instruction, program_accounts); self.process_instruction(message, instruction, executable_accounts, program_accounts)?; - - // Verify the instruction results Self::verify( - &program_id, + message, + instruction, &pre_accounts, executable_accounts, program_accounts, )?; - Ok(()) }