set_data_from_slice (#15854)

* data_ensure_equal_to_slice

* rename and change to copy
This commit is contained in:
Jeff Washington (jwash) 2021-03-16 16:56:26 -05:00 committed by GitHub
parent 654449ce91
commit 806bfdd67b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 38 additions and 6 deletions

View File

@ -136,8 +136,7 @@ pub fn deserialize_parameters_unaligned(
let end = start + keyed_account.data_len()?;
keyed_account
.try_account_ref_mut()?
.data_as_mut_slice()
.clone_from_slice(&buffer[start..end]);
.set_data_from_slice(&buffer[start..end]);
start += keyed_account.data_len()? // data
+ size_of::<Pubkey>() // owner
+ size_of::<u8>() // executable
@ -263,12 +262,10 @@ pub fn deserialize_parameters_aligned(
if post_len != pre_len
&& (post_len.saturating_sub(pre_len)) <= MAX_PERMITTED_DATA_INCREASE
{
account.data.resize(post_len, 0);
data_end = start + post_len;
}
account
.data_as_mut_slice()
.clone_from_slice(&buffer[start..data_end]);
account.set_data_from_slice(&buffer[start..data_end]);
start += pre_len + MAX_PERMITTED_DATA_INCREASE; // data
start += (start as *const u8).align_offset(align_of::<u128>());
start += size_of::<u64>(); // rent_epoch

View File

@ -394,6 +394,20 @@ impl Account {
}
impl AccountSharedData {
/// make account's data equal to 'data'. This may require resizing and copying data.
pub fn set_data_from_slice(&mut self, data: &[u8]) {
let len = self.data.len();
let len_different = len != data.len();
if len_different {
// if the resize causes a reallocation and copy, it would be better to create a new copy of the final data
// rather than resize (+ copy current) and then copy over below.
// however, the implementation of account's data is soon to be copy on write, so the tradeoffs will soon be different.
self.data.resize(data.len(), 0);
}
// we could compare here to determine whether we need to modify the original data or not. In the current implementation, that would
// not make a positive difference.
self.data.copy_from_slice(data);
}
pub fn set_data(&mut self, data: Vec<u8>) {
self.data = data;
}
@ -533,6 +547,27 @@ pub mod tests {
(account1, account2)
}
#[test]
fn test_account_set_data_from_slice() {
let key = Pubkey::new_unique();
let (_, mut account) = make_two_accounts(&key);
assert_eq!(account.data(), &vec![0, 0]);
account.set_data_from_slice(&[1, 2]);
assert_eq!(account.data(), &vec![1, 2]);
account.set_data_from_slice(&[1, 2, 3]);
assert_eq!(account.data(), &vec![1, 2, 3]);
account.set_data_from_slice(&[4, 5, 6]);
assert_eq!(account.data(), &vec![4, 5, 6]);
account.set_data_from_slice(&[4, 5, 6, 0]);
assert_eq!(account.data(), &vec![4, 5, 6, 0]);
account.set_data_from_slice(&[]);
assert_eq!(account.data().len(), 0);
account.set_data_from_slice(&[44]);
assert_eq!(account.data(), &vec![44]);
account.set_data_from_slice(&[44]);
assert_eq!(account.data(), &vec![44]);
}
#[test]
fn test_account_data_set_data() {
let key = Pubkey::new_unique();