diff --git a/programs/bpf_loader/src/serialization.rs b/programs/bpf_loader/src/serialization.rs index 16888702d4..beaa41e1a5 100644 --- a/programs/bpf_loader/src/serialization.rs +++ b/programs/bpf_loader/src/serialization.rs @@ -1,8 +1,12 @@ use byteorder::{ByteOrder, LittleEndian, WriteBytesExt}; use solana_rbpf::{aligned_memory::AlignedMemory, ebpf::HOST_ALIGN}; use solana_sdk::{ - account::ReadableAccount, bpf_loader_deprecated, entrypoint::MAX_PERMITTED_DATA_INCREASE, - instruction::InstructionError, keyed_account::KeyedAccount, pubkey::Pubkey, + account::{ReadableAccount, WritableAccount}, + bpf_loader_deprecated, + entrypoint::MAX_PERMITTED_DATA_INCREASE, + instruction::InstructionError, + keyed_account::KeyedAccount, + pubkey::Pubkey, }; use std::{ io::prelude::*, @@ -263,10 +267,7 @@ pub fn deserialize_parameters_aligned( + size_of::() // executable + 4 // padding to 128-bit aligned + size_of::(); // key - account - .owner - .as_mut() - .copy_from_slice(&buffer[start..start + size_of::()]); + account.copy_into_owner_from_slice(&buffer[start..start + size_of::()]); start += size_of::(); // owner account.lamports = LittleEndian::read_u64(&buffer[start..]); start += size_of::(); // lamports diff --git a/sdk/src/account.rs b/sdk/src/account.rs index 0261ed2def..fc673977c2 100644 --- a/sdk/src/account.rs +++ b/sdk/src/account.rs @@ -81,6 +81,7 @@ pub trait WritableAccount: ReadableAccount { fn set_lamports(&mut self, lamports: u64); fn data_as_mut_slice(&mut self) -> &mut [u8]; fn set_owner(&mut self, owner: Pubkey); + fn copy_into_owner_from_slice(&mut self, source: &[u8]); fn set_executable(&mut self, executable: bool); fn set_rent_epoch(&mut self, epoch: Epoch); fn create( @@ -128,6 +129,9 @@ impl WritableAccount for Account { fn set_owner(&mut self, owner: Pubkey) { self.owner = owner; } + fn copy_into_owner_from_slice(&mut self, source: &[u8]) { + self.owner.as_mut().copy_from_slice(source); + } fn set_executable(&mut self, executable: bool) { self.executable = executable; } @@ -162,6 +166,9 @@ impl WritableAccount for AccountSharedData { fn set_owner(&mut self, owner: Pubkey) { self.owner = owner; } + fn copy_into_owner_from_slice(&mut self, source: &[u8]) { + self.owner.as_mut().copy_from_slice(source); + } fn set_executable(&mut self, executable: bool) { self.executable = executable; } @@ -565,6 +572,17 @@ pub mod tests { (account1, account2) } + #[test] + fn test_account_data_copy_as_slice() { + let key = Pubkey::new_unique(); + let key2 = Pubkey::new_unique(); + let (mut account1, mut account2) = make_two_accounts(&key); + account1.copy_into_owner_from_slice(key2.as_ref()); + account2.copy_into_owner_from_slice(key2.as_ref()); + assert!(accounts_equal(&account1, &account2)); + assert_eq!(account1.owner(), &key2); + } + #[test] fn test_account_set_data_from_slice() { let key = Pubkey::new_unique();