Skip to content

Commit

Permalink
lang: Zero copy deserialization (#202)
Browse files Browse the repository at this point in the history
  • Loading branch information
armaniferrante committed Apr 17, 2021
1 parent 218c2d2 commit b6afb30
Show file tree
Hide file tree
Showing 22 changed files with 977 additions and 79 deletions.
5 changes: 3 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ _examples: &examples
- npm install -g mocha
- npm install -g ts-mocha
- npm install -g typescript
- npm install -g @project-serum/anchor
- cd ts && yarn && yarn build && npm link && cd ../
- npm install -g @project-serum/serum
- npm install -g @project-serum/common
- npm install -g @solana/spl-token
Expand All @@ -28,7 +28,7 @@ _examples: &examples
- export PATH="/home/travis/.local/share/solana/install/active_release/bin:$PATH"
- export NODE_PATH="/home/travis/.nvm/versions/node/v$NODE_VERSION/lib/node_modules/:$NODE_PATH"
- yes | solana-keygen new
- cargo install --git https://github.com/project-serum/anchor anchor-cli --locked
- cargo install --path $TRAVIS_BUILD_DIR/cli anchor-cli --locked

jobs:
include:
Expand Down Expand Up @@ -59,6 +59,7 @@ jobs:
- pushd examples/events && anchor test && popd
- pushd examples/cashiers-check && anchor test && popd
- pushd examples/typescript && yarn && anchor test && popd
- pushd examples/zero-copy && yarn && anchor test && popd
- <<: *examples
name: Runs the examples 2
script:
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ incremented for features.
## Features

* lang: Allows one to specify multiple `with` targets when creating associated acconts ([#197](https://github.com/project-serum/anchor/pull/197)).
* lang, ts: Add array support ([#202](https://github.com/project-serum/anchor/pull/202)).
* lang: Zero copy deserialization for accounts ([#202](https://github.com/project-serum/anchor/pull/202)).

## [0.4.3] - 2021-04-13

Expand Down
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions examples/zero-copy/Anchor.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
cluster = "localnet"
wallet = "~/.config/solana/id.json"
4 changes: 4 additions & 0 deletions examples/zero-copy/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[workspace]
members = [
"programs/*"
]
12 changes: 12 additions & 0 deletions examples/zero-copy/migrations/deploy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Migrations are an early feature. Currently, they're nothing more than this
// single deploy script that's invoked from the CLI, injecting a provider
// configured from the workspace's Anchor.toml.

const anchor = require("@project-serum/anchor");

module.exports = async function (provider) {
// Configure client to use the provider.
anchor.setProvider(provider);

// Add your deploy script here.
}
18 changes: 18 additions & 0 deletions examples/zero-copy/programs/zero-copy/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[package]
name = "zero-copy"
version = "0.1.0"
description = "Created with Anchor"
edition = "2018"

[lib]
crate-type = ["cdylib", "lib"]
name = "zero_copy"

[features]
no-entrypoint = []
no-idl = []
cpi = ["no-entrypoint"]
default = []

[dependencies]
anchor-lang = { path = "../../../../lang" }
2 changes: 2 additions & 0 deletions examples/zero-copy/programs/zero-copy/Xargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[target.bpfel-unknown-unknown.dependencies.std]
features = []
144 changes: 144 additions & 0 deletions examples/zero-copy/programs/zero-copy/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
//! This example demonstrates the use of zero copy deserialization for accounts.
//! The main noticeable benefit one achieves using zero copy is the ability
//! to create accounts larger than the size of the stack or heap, as is
//! demonstrated by the event queue in this example.

use anchor_lang::prelude::*;

#[program]
pub mod zero_copy {
use super::*;

pub fn create_foo(ctx: Context<CreateFoo>) -> ProgramResult {
let foo = &mut ctx.accounts.foo.load_init()?;
foo.authority = *ctx.accounts.authority.key;
foo.set_second_authority(ctx.accounts.authority.key);
Ok(())
}

pub fn update_foo(ctx: Context<UpdateFoo>, data: u64) -> ProgramResult {
let mut foo = ctx.accounts.foo.load_mut()?;
foo.data = data;
Ok(())
}

pub fn update_foo_second(ctx: Context<UpdateFooSecond>, second_data: u64) -> ProgramResult {
let mut foo = ctx.accounts.foo.load_mut()?;
foo.second_data = second_data;
Ok(())
}

pub fn create_bar(ctx: Context<CreateBar>) -> ProgramResult {
let bar = &mut ctx.accounts.bar.load_init()?;
bar.authority = *ctx.accounts.authority.key;
Ok(())
}

pub fn update_bar(ctx: Context<UpdateBar>, data: u64) -> ProgramResult {
let bar = &mut ctx.accounts.bar.load_mut()?;
bar.data = data;
Ok(())
}

pub fn create_large_account(_ctx: Context<CreateLargeAccount>) -> ProgramResult {
Ok(())
}

pub fn update_large_account(
ctx: Context<UpdateLargeAccount>,
idx: u32,
data: u64,
) -> ProgramResult {
let event_q = &mut ctx.accounts.event_q.load_mut()?;
event_q.events[idx as usize] = Event {
data,
from: *ctx.accounts.from.key,
};
Ok(())
}
}

#[derive(Accounts)]
pub struct CreateFoo<'info> {
#[account(init)]
foo: Loader<'info, Foo>,
#[account(signer)]
authority: AccountInfo<'info>,
rent: Sysvar<'info, Rent>,
}

#[derive(Accounts)]
pub struct UpdateFoo<'info> {
#[account(mut, has_one = authority)]
foo: Loader<'info, Foo>,
#[account(signer)]
authority: AccountInfo<'info>,
}

#[derive(Accounts)]
pub struct UpdateFooSecond<'info> {
#[account(mut, "&foo.load()?.get_second_authority() == second_authority.key")]
foo: Loader<'info, Foo>,
#[account(signer)]
second_authority: AccountInfo<'info>,
}

#[derive(Accounts)]
pub struct CreateBar<'info> {
#[account(associated = authority, with = foo)]
bar: Loader<'info, Bar>,
#[account(signer)]
authority: AccountInfo<'info>,
foo: Loader<'info, Foo>,
rent: Sysvar<'info, Rent>,
system_program: AccountInfo<'info>,
}

#[derive(Accounts)]
pub struct UpdateBar<'info> {
#[account(mut, has_one = authority)]
bar: Loader<'info, Bar>,
#[account(signer)]
authority: AccountInfo<'info>,
}

#[derive(Accounts)]
pub struct CreateLargeAccount<'info> {
#[account(init)]
event_q: Loader<'info, EventQ>,
rent: Sysvar<'info, Rent>,
}

#[derive(Accounts)]
pub struct UpdateLargeAccount<'info> {
#[account(mut)]
event_q: Loader<'info, EventQ>,
#[account(signer)]
from: AccountInfo<'info>,
}

#[account(zero_copy)]
pub struct Foo {
pub authority: Pubkey,
pub data: u64,
pub second_data: u64,
#[accessor(Pubkey)] // The `accessor` api will likely be removed.
pub second_authority: [u8; 32],
}

#[associated(zero_copy)]
pub struct Bar {
pub authority: Pubkey,
pub data: u64,
}

#[account(zero_copy)]
pub struct EventQ {
pub events: [Event; 25000],
}

#[zero_copy]
pub struct Event {
pub from: Pubkey,
pub data: u64,
}
Loading

0 comments on commit b6afb30

Please sign in to comment.