Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lang: new internal writer to use bpf mem syscalls #1589

Merged
merged 5 commits into from
Mar 12, 2022
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ incremented for features.

### Fixes

* lang: Replace `std::io::Cursor` with a custom `Write` impl that uses the Solana mem syscalls ([#1589](https://github.com/project-serum/anchor/pull/1589)).
callensm marked this conversation as resolved.
Show resolved Hide resolved
* ts: Fix the loss of strict typing using the `methods` namespace on builder functions ([#1539](https://github.com/project-serum/anchor/pull/1539)).

### Breaking
Expand Down
5 changes: 3 additions & 2 deletions lang/src/accounts/account.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! Account container that checks ownership on deserialization.

use crate::bpf_writer::BpfWriter;
use crate::error::ErrorCode;
use crate::*;
use solana_program::account_info::AccountInfo;
Expand Down Expand Up @@ -333,8 +334,8 @@ impl<'info, T: AccountSerialize + AccountDeserialize + Owner + Clone> AccountsEx
let info = self.to_account_info();
let mut data = info.try_borrow_mut_data()?;
let dst: &mut [u8] = &mut data;
let mut cursor = std::io::Cursor::new(dst);
self.account.try_serialize(&mut cursor)?;
let mut writer = BpfWriter::new(dst);
self.account.try_serialize(&mut writer)?;
}
Ok(())
}
Expand Down
5 changes: 3 additions & 2 deletions lang/src/accounts/account_loader.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! Type facilitating on demand zero copy deserialization.

use crate::bpf_writer::BpfWriter;
use crate::error::ErrorCode;
use crate::{
Accounts, AccountsClose, AccountsExit, Owner, Result, ToAccountInfo, ToAccountInfos,
Expand Down Expand Up @@ -225,8 +226,8 @@ impl<'info, T: ZeroCopy + Owner> AccountsExit<'info> for AccountLoader<'info, T>
fn exit(&self, _program_id: &Pubkey) -> Result<()> {
let mut data = self.acc_info.try_borrow_mut_data()?;
let dst: &mut [u8] = &mut data;
let mut cursor = std::io::Cursor::new(dst);
cursor.write_all(&T::discriminator()).unwrap();
let mut writer = BpfWriter::new(dst);
writer.write_all(&T::discriminator()).unwrap();
Ok(())
}
}
Expand Down
3 changes: 2 additions & 1 deletion lang/src/accounts/loader.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::bpf_writer::BpfWriter;
use crate::error::ErrorCode;
use crate::{
Accounts, AccountsClose, AccountsExit, Result, ToAccountInfo, ToAccountInfos, ToAccountMetas,
Expand Down Expand Up @@ -168,7 +169,7 @@ impl<'info, T: ZeroCopy> AccountsExit<'info> for Loader<'info, T> {
fn exit(&self, _program_id: &Pubkey) -> Result<()> {
let mut data = self.acc_info.try_borrow_mut_data()?;
let dst: &mut [u8] = &mut data;
let mut cursor = std::io::Cursor::new(dst);
let mut cursor = BpfWriter::new(dst);
callensm marked this conversation as resolved.
Show resolved Hide resolved
cursor.write_all(&T::discriminator()).unwrap();
Ok(())
}
Expand Down
5 changes: 3 additions & 2 deletions lang/src/accounts/program_account.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#[allow(deprecated)]
use crate::accounts::cpi_account::CpiAccount;
use crate::bpf_writer::BpfWriter;
use crate::error::ErrorCode;
use crate::{
AccountDeserialize, AccountSerialize, Accounts, AccountsClose, AccountsExit, Result,
Expand Down Expand Up @@ -98,8 +99,8 @@ impl<'info, T: AccountSerialize + AccountDeserialize + Clone> AccountsExit<'info
let info = self.to_account_info();
let mut data = info.try_borrow_mut_data()?;
let dst: &mut [u8] = &mut data;
let mut cursor = std::io::Cursor::new(dst);
self.inner.account.try_serialize(&mut cursor)?;
let mut writer = BpfWriter::new(dst);
self.inner.account.try_serialize(&mut writer)?;
Ok(())
}
}
Expand Down
5 changes: 3 additions & 2 deletions lang/src/accounts/state.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#[allow(deprecated)]
use crate::accounts::cpi_account::CpiAccount;
use crate::bpf_writer::BpfWriter;
use crate::error::ErrorCode;
use crate::{
AccountDeserialize, AccountSerialize, Accounts, AccountsExit, Result, ToAccountInfo,
Expand Down Expand Up @@ -148,8 +149,8 @@ impl<'info, T: AccountSerialize + AccountDeserialize + Clone> AccountsExit<'info
let info = self.to_account_info();
let mut data = info.try_borrow_mut_data()?;
let dst: &mut [u8] = &mut data;
let mut cursor = std::io::Cursor::new(dst);
self.inner.account.try_serialize(&mut cursor)?;
let mut writer = BpfWriter::new(dst);
self.inner.account.try_serialize(&mut writer)?;
Ok(())
}
}
Expand Down
28 changes: 28 additions & 0 deletions lang/src/bpf_writer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
use solana_program::program_memory::sol_memcpy;
use std::cmp;
use std::io::{self, Write};

#[derive(Debug, Default)]
pub struct BpfWriter<T> {
inner: T,
pos: u64,
}

impl<T> BpfWriter<T> {
pub fn new(inner: T) -> Self {
Self { inner, pos: 0 }
}
}

impl Write for BpfWriter<&mut [u8]> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
let pos = cmp::min(self.pos, self.inner.len() as u64);
sol_memcpy(&mut self.inner[(pos as usize)..], buf, buf.len());
self.pos += buf.len() as u64;
Ok(buf.len())
}
callensm marked this conversation as resolved.
Show resolved Hide resolved

fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}
5 changes: 3 additions & 2 deletions lang/src/common.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::bpf_writer::BpfWriter;
use crate::error::ErrorCode;
use crate::prelude::error;
use crate::Result;
Expand All @@ -14,8 +15,8 @@ pub fn close<'info>(info: AccountInfo<'info>, sol_destination: AccountInfo<'info
// Mark the account discriminator as closed.
let mut data = info.try_borrow_mut_data()?;
let dst: &mut [u8] = &mut data;
let mut cursor = std::io::Cursor::new(dst);
cursor
let mut writer = BpfWriter::new(dst);
writer
.write_all(&crate::__private::CLOSED_ACCOUNT_DISCRIMINATOR)
.map_err(|_| error!(ErrorCode::AccountDidNotSerialize))
}
1 change: 1 addition & 0 deletions lang/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ use std::io::Write;
mod account_meta;
pub mod accounts;
mod bpf_upgradeable_state;
mod bpf_writer;
mod common;
pub mod context;
mod ctor;
Expand Down