Skip to content

Commit

Permalink
lang/docs: Context and CpiContext docs (#1247)
Browse files Browse the repository at this point in the history
  • Loading branch information
paul-schaaf authored Jan 6, 2022
1 parent e026e9e commit bb20eee
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 1 deletion.
2 changes: 1 addition & 1 deletion .github/actions/setup/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ description: "Setup"
runs:
using: "composite"
steps:
- run: sudo apt-get install -y pkg-config build-essential libudev-dev
- run: sudo apt-get update && sudo apt-get install -y pkg-config build-essential libudev-dev
shell: bash
- run: echo "ANCHOR_VERSION=$(cat ./VERSION)" >> $GITHUB_ENV
shell: bash
Expand Down
115 changes: 115 additions & 0 deletions lang/src/context.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,26 @@
//! Data structures that are used to provide non-argument inputs to program endpoints
use crate::{Accounts, ToAccountInfos, ToAccountMetas};
use solana_program::account_info::AccountInfo;
use solana_program::instruction::AccountMeta;
use solana_program::pubkey::Pubkey;
use std::fmt;

/// Provides non-argument inputs to the program.
///
/// # Example
/// ```ignore
/// pub fn set_data(ctx: Context<SetData>, age: u64, other_data: u32) -> ProgramResult {
/// // Set account data like this
/// (*ctx.accounts.my_account).age = age;
/// (*ctx.accounts.my_account).other_data = other_data;
/// // or like this
/// let my_account = &mut ctx.account.my_account;
/// my_account.age = age;
/// my_account.other_data = other_data;
/// Ok(())
/// }
/// ```
pub struct Context<'a, 'b, 'c, 'info, T> {
/// Currently executing program id.
pub program_id: &'a Pubkey,
Expand Down Expand Up @@ -40,6 +56,104 @@ impl<'a, 'b, 'c, 'info, T: Accounts<'info>> Context<'a, 'b, 'c, 'info, T> {
}

/// Context specifying non-argument inputs for cross-program-invocations.
///
/// # Example with and without PDA signature
/// ```ignore
/// // Callee Program
///
/// use anchor_lang::prelude::*;
///
/// declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS");
///
/// #[program]
/// pub mod callee {
/// use super::*;
/// pub fn init(ctx: Context<Init>) -> ProgramResult {
/// (*ctx.accounts.data).authority = ctx.accounts.authority.key();
/// Ok(())
/// }
///
/// pub fn set_data(ctx: Context<SetData>, data: u64) -> ProgramResult {
/// (*ctx.accounts.data_acc).data = data;
/// Ok(())
/// }
/// }
///
/// #[account]
/// #[derive(Default)]
/// pub struct Data {
/// data: u64,
/// authority: Pubkey,
/// }
///
/// #[derive(Accounts)]
/// pub struct Init<'info> {
/// #[account(init, payer = payer)]
/// pub data: Account<'info, Data>,
/// pub payer: Signer<'info>,
/// pub authority: UncheckedAccount<'info>,
/// pub system_program: Program<'info, System>
/// }
///
/// #[derive(Accounts)]
/// pub struct SetData<'info> {
/// #[account(mut, has_one = authority)]
/// pub data_acc: Account<'info, Data>,
/// pub authority: Signer<'info>,
/// }
///
/// // Caller Program
///
/// use anchor_lang::prelude::*;
/// use callee::{self, program::Callee};
///
/// declare_id!("Sxg7dBh5VLT8S1o6BqncZCPq9nhHHukjfVd6ohQJeAk");
///
/// #[program]
/// pub mod caller {
/// use super::*;
/// pub fn do_cpi(ctx: Context<DoCpi>, data: u64) -> ProgramResult {
/// let callee_id = ctx.accounts.callee.to_account_info();
/// let callee_accounts = callee::cpi::accounts::SetData {
/// data_acc: ctx.accounts.data_acc.to_account_info(),
/// authority: ctx.accounts.callee_authority.to_account_info(),
/// };
/// let cpi_ctx = CpiContext::new(callee_id, callee_accounts);
/// callee::cpi::set_data(cpi_ctx, data)
/// }
///
/// pub fn do_cpi_with_pda_authority(ctx: Context<DoCpiWithPDAAuthority>, bump: u8, data: u64) -> ProgramResult {
/// let seeds = &[&[b"example_seed", bytemuck::bytes_of(&bump)][..]];
/// let callee_id = ctx.accounts.callee.to_account_info();
/// let callee_accounts = callee::cpi::accounts::SetData {
/// data_acc: ctx.accounts.data_acc.to_account_info(),
/// authority: ctx.accounts.callee_authority.to_account_info(),
/// };
/// let cpi_ctx = CpiContext::new_with_signer(callee_id, callee_accounts, seeds);
/// callee::cpi::set_data(cpi_ctx, data)
/// }
/// }
///
/// // We can use "UncheckedAccount"s here because
/// // the callee program does the checks.
/// // We use "mut" so the autogenerated clients know
/// // that this account should be mutable.
/// #[derive(Accounts)]
/// pub struct DoCpi<'info> {
/// #[account(mut)]
/// pub data_acc: UncheckedAccount<'info>,
/// pub callee_authority: UncheckedAccount<'info>,
/// pub callee: Program<'info, Callee>,
/// }
///
/// #[derive(Accounts)]
/// pub struct DoCpiWithPDAAuthority<'info> {
/// #[account(mut)]
/// pub data_acc: UncheckedAccount<'info>,
/// pub callee_authority: UncheckedAccount<'info>,
/// pub callee: Program<'info, Callee>,
/// }
/// ```
pub struct CpiContext<'a, 'b, 'c, 'info, T>
where
T: ToAccountMetas + ToAccountInfos<'info>,
Expand Down Expand Up @@ -122,6 +236,7 @@ impl<'info, T: ToAccountInfos<'info> + ToAccountMetas> ToAccountMetas

/// Context specifying non-argument inputs for cross-program-invocations
/// targeted at program state instructions.
#[doc(hidden)]
#[deprecated]
pub struct CpiStateContext<'a, 'b, 'c, 'info, T: Accounts<'info>> {
state: AccountInfo<'info>,
Expand Down

0 comments on commit bb20eee

Please sign in to comment.