Seperate RefCells lamports and data (#8021)
This commit is contained in:
parent
d5ff5f4739
commit
b19f730527
|
@ -16,32 +16,32 @@ fn process_instruction(
|
||||||
match instruction_data[0] {
|
match instruction_data[0] {
|
||||||
1 => {
|
1 => {
|
||||||
info!("modify first account data");
|
info!("modify first account data");
|
||||||
accounts[2].borrow_mut().data[0] = 1;
|
accounts[2].data.borrow_mut()[0] = 1;
|
||||||
}
|
}
|
||||||
2 => {
|
2 => {
|
||||||
info!("modify first account data");
|
info!("modify first account data");
|
||||||
accounts[3].borrow_mut().data[0] = 2;
|
accounts[3].data.borrow_mut()[0] = 2;
|
||||||
}
|
}
|
||||||
3 => {
|
3 => {
|
||||||
info!("modify both account data");
|
info!("modify both account data");
|
||||||
accounts[2].borrow_mut().data[0] += 1;
|
accounts[2].data.borrow_mut()[0] += 1;
|
||||||
accounts[3].borrow_mut().data[0] += 2;
|
accounts[3].data.borrow_mut()[0] += 2;
|
||||||
}
|
}
|
||||||
4 => {
|
4 => {
|
||||||
info!("modify first account lamports");
|
info!("modify first account lamports");
|
||||||
*accounts[1].borrow_mut().lamports -= 1;
|
**accounts[1].lamports.borrow_mut() -= 1;
|
||||||
*accounts[2].borrow_mut().lamports += 1;
|
**accounts[2].lamports.borrow_mut() += 1;
|
||||||
}
|
}
|
||||||
5 => {
|
5 => {
|
||||||
info!("modify first account lamports");
|
info!("modify first account lamports");
|
||||||
*accounts[1].borrow_mut().lamports -= 2;
|
**accounts[1].lamports.borrow_mut() -= 2;
|
||||||
*accounts[3].borrow_mut().lamports += 2;
|
**accounts[3].lamports.borrow_mut() += 2;
|
||||||
}
|
}
|
||||||
6 => {
|
6 => {
|
||||||
info!("modify both account lamports");
|
info!("modify both account lamports");
|
||||||
*accounts[1].borrow_mut().lamports -= 3;
|
**accounts[1].lamports.borrow_mut() -= 3;
|
||||||
*accounts[2].borrow_mut().lamports += 1;
|
**accounts[2].lamports.borrow_mut() += 1;
|
||||||
*accounts[3].borrow_mut().lamports += 2;
|
**accounts[3].lamports.borrow_mut() += 2;
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
info!("Unrecognized command");
|
info!("Unrecognized command");
|
||||||
|
|
|
@ -12,7 +12,7 @@ fn process_instruction(
|
||||||
// account 0 is the mint and not owned by this program, any debit of its lamports
|
// account 0 is the mint and not owned by this program, any debit of its lamports
|
||||||
// should result in a failed program execution. Test to ensure that this debit
|
// should result in a failed program execution. Test to ensure that this debit
|
||||||
// is seen by the runtime and fails as expected
|
// is seen by the runtime and fails as expected
|
||||||
*accounts[0].borrow_mut().lamports -= 1;
|
**accounts[0].lamports.borrow_mut() -= 1;
|
||||||
|
|
||||||
SUCCESS
|
SUCCESS
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,6 @@
|
||||||
use crate::{account::Account, pubkey::Pubkey};
|
use crate::{account::Account, pubkey::Pubkey};
|
||||||
use std::{
|
use std::{cell::RefCell, cmp, fmt, rc::Rc};
|
||||||
cell::{Ref, RefCell, RefMut},
|
|
||||||
cmp, fmt,
|
|
||||||
rc::Rc,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Account information that is mutable by a program
|
|
||||||
pub struct AccountInfoMut<'a> {
|
|
||||||
/// Number of lamports owned by this account
|
|
||||||
pub lamports: &'a mut u64,
|
|
||||||
/// On-chain data within this account
|
|
||||||
pub data: &'a mut [u8],
|
|
||||||
}
|
|
||||||
/// Account information
|
/// Account information
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct AccountInfo<'a> {
|
pub struct AccountInfo<'a> {
|
||||||
|
@ -20,7 +9,9 @@ pub struct AccountInfo<'a> {
|
||||||
// Was the transaction signed by this account's public key?
|
// Was the transaction signed by this account's public key?
|
||||||
pub is_signer: bool,
|
pub is_signer: bool,
|
||||||
/// Account members that are mutable by the program
|
/// Account members that are mutable by the program
|
||||||
pub m: Rc<RefCell<AccountInfoMut<'a>>>,
|
pub lamports: Rc<RefCell<&'a mut u64>>,
|
||||||
|
/// Account members that are mutable by the program
|
||||||
|
pub data: Rc<RefCell<&'a mut [u8]>>,
|
||||||
/// Program that owns this account
|
/// Program that owns this account
|
||||||
pub owner: &'a Pubkey,
|
pub owner: &'a Pubkey,
|
||||||
}
|
}
|
||||||
|
@ -31,7 +22,7 @@ impl<'a> fmt::Debug for AccountInfo<'a> {
|
||||||
let data_str = if data_len > 0 {
|
let data_str = if data_len > 0 {
|
||||||
format!(
|
format!(
|
||||||
" data: {}",
|
" data: {}",
|
||||||
hex::encode(self.borrow().data[..data_len].to_vec())
|
hex::encode(self.data.borrow()[..data_len].to_vec())
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
"".to_string()
|
"".to_string()
|
||||||
|
@ -61,23 +52,15 @@ impl<'a> AccountInfo<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lamports(&self) -> u64 {
|
pub fn lamports(&self) -> u64 {
|
||||||
*self.borrow().lamports
|
**self.lamports.borrow()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn data_len(&self) -> usize {
|
pub fn data_len(&self) -> usize {
|
||||||
self.borrow().data.len()
|
self.data.borrow().len()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn data_is_empty(&self) -> bool {
|
pub fn data_is_empty(&self) -> bool {
|
||||||
self.borrow().data.is_empty()
|
self.data.borrow().is_empty()
|
||||||
}
|
|
||||||
|
|
||||||
pub fn borrow(&self) -> Ref<AccountInfoMut> {
|
|
||||||
self.m.borrow()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn borrow_mut(&self) -> RefMut<AccountInfoMut<'a>> {
|
|
||||||
self.m.borrow_mut()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(
|
pub fn new(
|
||||||
|
@ -90,20 +73,21 @@ impl<'a> AccountInfo<'a> {
|
||||||
Self {
|
Self {
|
||||||
key,
|
key,
|
||||||
is_signer,
|
is_signer,
|
||||||
m: Rc::new(RefCell::new(AccountInfoMut { lamports, data })),
|
lamports: Rc::new(RefCell::new(lamports)),
|
||||||
|
data: Rc::new(RefCell::new(data)),
|
||||||
owner,
|
owner,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deserialize_data<T: serde::de::DeserializeOwned>(&self) -> Result<T, bincode::Error> {
|
pub fn deserialize_data<T: serde::de::DeserializeOwned>(&self) -> Result<T, bincode::Error> {
|
||||||
bincode::deserialize(&self.borrow().data)
|
bincode::deserialize(&self.data.borrow())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn serialize_data<T: serde::Serialize>(&mut self, state: &T) -> Result<(), bincode::Error> {
|
pub fn serialize_data<T: serde::Serialize>(&mut self, state: &T) -> Result<(), bincode::Error> {
|
||||||
if bincode::serialized_size(state)? > self.data_len() as u64 {
|
if bincode::serialized_size(state)? > self.data_len() as u64 {
|
||||||
return Err(Box::new(bincode::ErrorKind::SizeLimit));
|
return Err(Box::new(bincode::ErrorKind::SizeLimit));
|
||||||
}
|
}
|
||||||
bincode::serialize_into(&mut self.borrow_mut().data[..], state)
|
bincode::serialize_into(&mut self.data.borrow_mut()[..], state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,11 +3,7 @@
|
||||||
#![cfg(feature = "program")]
|
#![cfg(feature = "program")]
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
use crate::{account_info::AccountInfo, pubkey::Pubkey};
|
||||||
use crate::{
|
|
||||||
account_info::{AccountInfo, AccountInfoMut},
|
|
||||||
pubkey::Pubkey,
|
|
||||||
};
|
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use std::{
|
use std::{
|
||||||
cell::RefCell,
|
cell::RefCell,
|
||||||
|
@ -79,25 +75,26 @@ pub unsafe fn deserialize<'a>(input: *mut u8) -> (&'a Pubkey, Vec<AccountInfo<'a
|
||||||
offset += size_of::<Pubkey>();
|
offset += size_of::<Pubkey>();
|
||||||
|
|
||||||
#[allow(clippy::cast_ptr_alignment)]
|
#[allow(clippy::cast_ptr_alignment)]
|
||||||
let lamports = &mut *(input.add(offset) as *mut u64);
|
let lamports = Rc::new(RefCell::new(&mut *(input.add(offset) as *mut u64)));
|
||||||
offset += size_of::<u64>();
|
offset += size_of::<u64>();
|
||||||
|
|
||||||
#[allow(clippy::cast_ptr_alignment)]
|
#[allow(clippy::cast_ptr_alignment)]
|
||||||
let data_len = *(input.add(offset) as *const u64) as usize;
|
let data_len = *(input.add(offset) as *const u64) as usize;
|
||||||
offset += size_of::<u64>();
|
offset += size_of::<u64>();
|
||||||
|
|
||||||
let data = { from_raw_parts_mut(input.add(offset), data_len) };
|
let data = Rc::new(RefCell::new({
|
||||||
|
from_raw_parts_mut(input.add(offset), data_len)
|
||||||
|
}));
|
||||||
offset += data_len;
|
offset += data_len;
|
||||||
|
|
||||||
let owner: &Pubkey = &*(input.add(offset) as *const Pubkey);
|
let owner: &Pubkey = &*(input.add(offset) as *const Pubkey);
|
||||||
offset += size_of::<Pubkey>();
|
offset += size_of::<Pubkey>();
|
||||||
|
|
||||||
let m = Rc::new(RefCell::new(AccountInfoMut { lamports, data }));
|
|
||||||
|
|
||||||
accounts.push(AccountInfo {
|
accounts.push(AccountInfo {
|
||||||
is_signer,
|
is_signer,
|
||||||
key,
|
key,
|
||||||
m,
|
lamports,
|
||||||
|
data,
|
||||||
owner,
|
owner,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -71,10 +71,10 @@ pub trait Sysvar:
|
||||||
bincode::serialize_into(&mut account.data[..], self).ok()
|
bincode::serialize_into(&mut account.data[..], self).ok()
|
||||||
}
|
}
|
||||||
fn from_account_info(account_info: &AccountInfo) -> Option<Self> {
|
fn from_account_info(account_info: &AccountInfo) -> Option<Self> {
|
||||||
bincode::deserialize(&account_info.m.borrow().data).ok()
|
bincode::deserialize(&account_info.data.borrow()).ok()
|
||||||
}
|
}
|
||||||
fn to_account_info(&self, account_info: &mut AccountInfo) -> Option<()> {
|
fn to_account_info(&self, account_info: &mut AccountInfo) -> Option<()> {
|
||||||
bincode::serialize_into(&mut account_info.m.borrow_mut().data[..], self).ok()
|
bincode::serialize_into(&mut account_info.data.borrow_mut()[..], self).ok()
|
||||||
}
|
}
|
||||||
fn from_keyed_account(keyed_account: &KeyedAccount) -> Result<Self, InstructionError> {
|
fn from_keyed_account(keyed_account: &KeyedAccount) -> Result<Self, InstructionError> {
|
||||||
if !Self::check_id(keyed_account.unsigned_key()) {
|
if !Self::check_id(keyed_account.unsigned_key()) {
|
||||||
|
|
Loading…
Reference in New Issue