set_data_from_slice (#15854)
* data_ensure_equal_to_slice * rename and change to copy
This commit is contained in:
committed by
GitHub
parent
654449ce91
commit
806bfdd67b
@ -136,8 +136,7 @@ pub fn deserialize_parameters_unaligned(
|
|||||||
let end = start + keyed_account.data_len()?;
|
let end = start + keyed_account.data_len()?;
|
||||||
keyed_account
|
keyed_account
|
||||||
.try_account_ref_mut()?
|
.try_account_ref_mut()?
|
||||||
.data_as_mut_slice()
|
.set_data_from_slice(&buffer[start..end]);
|
||||||
.clone_from_slice(&buffer[start..end]);
|
|
||||||
start += keyed_account.data_len()? // data
|
start += keyed_account.data_len()? // data
|
||||||
+ size_of::<Pubkey>() // owner
|
+ size_of::<Pubkey>() // owner
|
||||||
+ size_of::<u8>() // executable
|
+ size_of::<u8>() // executable
|
||||||
@ -263,12 +262,10 @@ pub fn deserialize_parameters_aligned(
|
|||||||
if post_len != pre_len
|
if post_len != pre_len
|
||||||
&& (post_len.saturating_sub(pre_len)) <= MAX_PERMITTED_DATA_INCREASE
|
&& (post_len.saturating_sub(pre_len)) <= MAX_PERMITTED_DATA_INCREASE
|
||||||
{
|
{
|
||||||
account.data.resize(post_len, 0);
|
|
||||||
data_end = start + post_len;
|
data_end = start + post_len;
|
||||||
}
|
}
|
||||||
account
|
|
||||||
.data_as_mut_slice()
|
account.set_data_from_slice(&buffer[start..data_end]);
|
||||||
.clone_from_slice(&buffer[start..data_end]);
|
|
||||||
start += pre_len + MAX_PERMITTED_DATA_INCREASE; // data
|
start += pre_len + MAX_PERMITTED_DATA_INCREASE; // data
|
||||||
start += (start as *const u8).align_offset(align_of::<u128>());
|
start += (start as *const u8).align_offset(align_of::<u128>());
|
||||||
start += size_of::<u64>(); // rent_epoch
|
start += size_of::<u64>(); // rent_epoch
|
||||||
|
@ -394,6 +394,20 @@ impl Account {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl AccountSharedData {
|
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>) {
|
pub fn set_data(&mut self, data: Vec<u8>) {
|
||||||
self.data = data;
|
self.data = data;
|
||||||
}
|
}
|
||||||
@ -533,6 +547,27 @@ pub mod tests {
|
|||||||
(account1, account2)
|
(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]
|
#[test]
|
||||||
fn test_account_data_set_data() {
|
fn test_account_data_set_data() {
|
||||||
let key = Pubkey::new_unique();
|
let key = Pubkey::new_unique();
|
||||||
|
Reference in New Issue
Block a user