You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The module exposes `transfer{:rs}`, `create_account{:rs}`, `allocate{:rs}`, `assign{:rs}`, `*_with_seed{:rs}` variants for each, and the nonce-account family. The `with_seed{:rs}` variants are useful when a base address is owned by another program and the resulting account address is derived deterministically.
44
+
The module exposes typed wrappers for the System Program instructions:
45
+
46
+
| Wrappers | Use for |
47
+
| --- | --- |
48
+
|`transfer{:rs}`, `create_account{:rs}`, `allocate{:rs}`, `assign{:rs}`| Ordinary signed account creation and lamport movement. |
49
+
|`*_with_seed{:rs}` variants of each | Cases where the base address is owned by another program and the resulting account address is derived deterministically. |
50
+
| The nonce-account family | Nonce account creation, withdrawal, authorization, and advance. |
That missing `Deref{:rs}` is intentional. It prevents accidental use with checked pinocchio CPI builders that would re-borrow the same account views.
154
160
155
-
`CpiContext::invoke(data){:rs}` uses pinocchio's `invoke_signed_unchecked{:rs}`. Anchor keeps that path safe for ordinary typed CPI by making CPI account structs hold `CpiHandle<'a>{:rs}` values that borrow the typed account wrappers for the duration of the call. Rust rejects concurrent typed mutable access, while pinocchio's account borrow state still catches stale raw-borrow cases after the CPI.
161
+
`CpiContext::invoke(data){:rs}` uses pinocchio's `invoke_signed_unchecked{:rs}`. The path stays safe for ordinary typed CPI because CPI account structs hold `CpiHandle<'a>{:rs}` values that borrow the typed account wrappers for the duration of the call.
162
+
163
+
Two layers catch aliasing:
164
+
165
+
- Rust rejects concurrent typed mutable access at compile time.
166
+
- pinocchio's account borrow state catches stale raw-borrow cases after the CPI returns.
Copy file name to clipboardExpand all lines: docs-v2/src/content/docs/v2/programs/account-types.mdx
+3-1Lines changed: 3 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -94,7 +94,9 @@ The nested fields are flattened into the outer account list. `Nested<T>{:rs}` do
94
94
95
95
`Signer{:rs}`, `Program<T>{:rs}`, `SystemAccount{:rs}`, `UncheckedAccount{:rs}`, and `Sysvar<T>{:rs}` keep ordinary Anchor code readable. `UncheckedAccount{:rs}` performs no validation, so pair it with explicit constraints or handler checks before trusting it.
96
96
97
-
`Sysvar<T>{:rs}` accepts the pinocchio sysvar types whose payload can be read directly into a typed value: `Clock{:rs}`, `Rent{:rs}`, and `Instructions{:rs}`. `SlotHashes{:rs}` deliberately does not implement `SysvarId{:rs}`, so `Sysvar<SlotHashes>{:rs}` fails to compile with a missing-trait diagnostic. Programs that need slot-hash data should call the partial-read syscall directly through pinocchio.
97
+
`Sysvar<T>{:rs}` accepts the pinocchio sysvar types whose payload can be read directly into a typed value. The supported types are `Clock{:rs}`, `Rent{:rs}`, and `Instructions{:rs}`.
98
+
99
+
`SlotHashes{:rs}` deliberately does not implement `SysvarId{:rs}`, so `Sysvar<SlotHashes>{:rs}` fails to compile with a missing-trait diagnostic. Programs that need slot-hash data should call the partial-read syscall directly through pinocchio.
-`update{:rs}` runs inside an `update(...){:rs}` constraint clause
94
94
-`exit{:rs}` always runs during the account exit phase
95
95
96
-
Once the impl is in scope, a constraint marker named `my_namespace::key{:rs}` becomes available as `#[account(my_namespace::key = value)]{:rs}` on any account field. The `anchor-spl-v2` crate is built on top of this pattern, using it to implement `token::*{:rs}` and `mint::*{:rs}` as a downstream crate rather than baking them into the core derive. Its `associated_token{:rs}` module currently exposes associated token address derivation helpers.
96
+
Once the impl is in scope, a constraint marker named `my_namespace::key{:rs}` becomes available as `#[account(my_namespace::key = value)]{:rs}` on any account field.
97
+
98
+
The `anchor-spl-v2` crate is built on this pattern. It implements `token::*{:rs}` and `mint::*{:rs}` as a downstream crate rather than baking them into the core derive. Its `associated_token{:rs}` module currently exposes associated token address derivation helpers.
Copy file name to clipboardExpand all lines: docs-v2/src/content/docs/v2/programs/pod-types.mdx
+18-3Lines changed: 18 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -11,7 +11,11 @@ To make `T: Pod{:rs}` easy to satisfy, Anchor ships a small set of alignment-1 w
11
11
12
12
## Integer wrappers
13
13
14
-
`PodU16{:rs}`, `PodU32{:rs}`, `PodU64{:rs}`, `PodU128{:rs}`, and the signed counterparts (`PodI16{:rs}`, `PodI32{:rs}`, `PodI64{:rs}`, `PodI128{:rs}`) store an integer as `[u8; N]{:rs}` with native little-endian encoding. Alignment 1 means no padding around the field, so wide integer fields sit flush against neighbors in a `#[repr(C)]{:rs}` struct. `PodU8{:rs}` and `PodI8{:rs}` are re-exported as type aliases for native `u8{:rs}` and `i8{:rs}` because the primitive types are already alignment 1 and need no wrapper:
14
+
The unsigned wrappers are `PodU16{:rs}`, `PodU32{:rs}`, `PodU64{:rs}`, and `PodU128{:rs}`. The signed wrappers are `PodI16{:rs}`, `PodI32{:rs}`, `PodI64{:rs}`, and `PodI128{:rs}`. Each stores an integer as `[u8; N]{:rs}` with native little-endian encoding.
15
+
16
+
Alignment 1 means no padding around the field, so wide integer fields sit flush against their neighbors in a `#[repr(C)]{:rs}` struct.
17
+
18
+
`PodU8{:rs}` and `PodI8{:rs}` are type aliases for native `u8{:rs}` and `i8{:rs}`. The primitives are already alignment 1, so no wrapper is needed:
15
19
16
20
```rust title="lib.rs" showLineNumbers=false
17
21
#[account]
@@ -48,7 +52,9 @@ pub struct Listing {
48
52
49
53
## `PodVec<T, MAX>{:rs}`
50
54
51
-
`PodVec<T, MAX>{:rs}` is a fixed-capacity vector with a `u16{:rs}` length prefix, stored inline in the account rather than behind a heap pointer. The on-disk layout is `[len:u16][T; MAX]{:rs}` with no padding, since `T{:rs}` must itself be alignment-1 for the surrounding `#[account]{:rs}` struct to be `Pod{:rs}`. `MAX{:rs}` is baked into the type so the compiler knows the exact size at every site:
55
+
`PodVec<T, MAX>{:rs}` is a fixed-capacity vector with a `u16{:rs}` length prefix, stored inline in the account rather than behind a heap pointer. The on-disk layout is `[len:u16][T; MAX]{:rs}` with no padding.
56
+
57
+
`T{:rs}` must itself be alignment-1 so the surrounding `#[account]{:rs}` struct can be `Pod{:rs}`. `MAX{:rs}` is baked into the type so the compiler knows the exact size at every call site:
52
58
53
59
```rust title="lib.rs" showLineNumbers=false
54
60
#[account]
@@ -61,7 +67,16 @@ pub struct MultisigConfig {
61
67
}
62
68
```
63
69
64
-
Mutators come in panicking and fallible pairs. `.push{:rs}`, `.extend_from_slice{:rs}`, and `.set_from_slice{:rs}` panic on overflow. `.try_push{:rs}` and `.try_extend_from_slice{:rs}` return `Result<(), CapacityError>{:rs}`. Indexing accessors (`.as_slice{:rs}`, `.iter{:rs}`, `.get{:rs}`, `.pop{:rs}`, and friends) panic when the stored length prefix exceeds `MAX{:rs}`, which can happen on a `PodVec{:rs}` cast from attacker-controlled bytes. Pair them with `.try_as_slice{:rs}`, `.try_get{:rs}`, `.try_pop{:rs}`, or call `.validate(){:rs}` once at load time. Length-only helpers (`.len{:rs}`, `.is_empty{:rs}`, `.capacity{:rs}`, `.clear{:rs}`, `.truncate{:rs}`) never index into `data{:rs}` and are always safe.
70
+
Methods fall into four groups:
71
+
72
+
| Group | Methods | Behavior |
73
+
| --- | --- | --- |
74
+
| Panicking mutators |`.push{:rs}`, `.extend_from_slice{:rs}`, `.set_from_slice{:rs}`| Panic on overflow. |
| Indexing accessors |`.as_slice{:rs}`, `.iter{:rs}`, `.get{:rs}`, `.pop{:rs}`| Panic when the stored length prefix exceeds `MAX{:rs}`. Pair with `.try_as_slice{:rs}`, `.try_get{:rs}`, `.try_pop{:rs}`. |
77
+
| Length-only helpers |`.len{:rs}`, `.is_empty{:rs}`, `.capacity{:rs}`, `.clear{:rs}`, `.truncate{:rs}`| Never index into `data{:rs}`. Always safe. |
78
+
79
+
The indexing-accessor panic can fire when a `PodVec{:rs}` is cast from attacker-controlled bytes whose length prefix exceeds `MAX{:rs}`. Either use the fallible variants at the call site or call `.validate(){:rs}` once at load time to reject bad bytes up front.
65
80
66
81
Reach for `PodVec{:rs}` when the upper bound is small and known ahead of time. For genuinely open-ended data, use `BorshAccount<T>{:rs}` with a regular `Vec<T>{:rs}` instead.
Copy file name to clipboardExpand all lines: docs-v2/src/content/docs/v2/reference/cli.mdx
+9-3Lines changed: 9 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -240,17 +240,21 @@ Use on-chain IDLs carefully while this version is alpha because IDL shapes may c
240
240
241
241
The `codama` subcommand converts an Anchor IDL to a Codama IDL tree and renders client libraries through the `@codama/cli` toolchain. It is the path for generating cross-language clients from a single program description.
`convert{:bash}` translates an Anchor IDL JSON file into a Codama IDL JSON tree rooted at a `rootNode`. The conversion runs in-process and mirrors the reference TypeScript implementation in `@codama/nodes-from-anchor`, so the output is stable against the JavaScript toolchain.
`generate{:bash}` runs the same conversion in-process and then hands the result to `@codama/cli` (run via `npx --yes codama` by default) to render clients in one or more languages. Each language is written under `<path>/<language>/{:dir}` and uses the matching `@codama/renderers-*` package:
257
+
`generate{:bash}` runs the same conversion in-process, then hands the result to `@codama/cli` (run via `npx --yes codama` by default) to render clients in one or more languages. Each language is written under `<path>/<language>/{:dir}` and uses the matching `@codama/renderers-*` package:
|`<dim>-l</dim> <dim><language></dim>`| Languages to generate. Repeat or comma-separate: `<dim>-l</dim> <dim>js,go</dim> <dim>-l</dim> <dim>rust</dim>`. |
267
271
|`<dim>-p</dim> <dim><path></dim>`| Base output directory. Default: `clients{:dir}`. |
268
272
|`<dim>-o</dim> <dim><file></dim>`| (Convert only) Write Codama IDL JSON to a file instead of stdout. |
269
273
270
-
`generate{:bash}` shells out to `npx{:bash}`, so the host needs a Node.js toolchain on `PATH`. The Codama IDL is versioned independently from the Anchor IDL, so the rendered clients depend on the `@codama/nodes` version stamped into `rootNode.version`.
274
+
<Calloutvariant="note"title="Operational notes">
275
+
`generate{:bash}` shells out to `npx{:bash}`, so the host needs a Node.js toolchain on `PATH`. The Codama IDL is versioned independently from the Anchor IDL, so rendered clients depend on the `@codama/nodes` version stamped into `rootNode.version`.
Copy file name to clipboardExpand all lines: docs-v2/src/content/docs/v2/reference/feature-flags.mdx
+41-11Lines changed: 41 additions & 11 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -17,7 +17,11 @@ description: 'Reference for the `alloc{:toml}`, `guardrails{:toml}`, `account-re
17
17
18
18
## `alloc{:toml}` (default)
19
19
20
-
The `alloc{:toml}` feature enables `extern crate alloc{:rs}` and re-exports the `alloc{:rs}` crate under `anchor_lang_v2::__alloc{:rs}` so generated macro code can reach `Vec{:rs}`, `String{:rs}`, and other heap-allocated types without forcing each user crate to import them. Disabling the feature is only sensible for embedded targets that have no heap, and the ergonomic cost is significant. Most realistic user code that touches `Vec{:rs}` or `String{:rs}` will not compile with `alloc{:toml}` turned off.
20
+
The `alloc{:toml}` feature enables `extern crate alloc{:rs}` and re-exports the `alloc{:rs}` crate under `anchor_lang_v2::__alloc{:rs}`. Generated macro code reaches `Vec{:rs}`, `String{:rs}`, and other heap-allocated types through that re-export, so user crates do not have to import `alloc{:rs}` themselves.
21
+
22
+
<Calloutvariant="note"title="When to disable">
23
+
Only embedded targets without a heap have a reason to turn `alloc{:toml}` off. The ergonomic cost is significant. Most realistic user code that touches `Vec{:rs}` or `String{:rs}` will not compile without it.
24
+
</Callout>
21
25
22
26
## `guardrails{:toml}` (default)
23
27
@@ -27,16 +31,20 @@ The `guardrails{:toml}` feature enables a small set of runtime checks that catch
27
31
-`is_writable{:rs}` enforcement in data-account `load_mut{:rs}` paths returns an error when the account is not marked `mut{:rs}`
28
32
- executable checks on `Program<T>{:rs}` reject non-program accounts before CPI
29
33
30
-
Disabling the feature drops those guardrail-only emits, which saves roughly 300 bytes of binary and 1 to 2 CU per account. Only turn it off in production after the program has been thoroughly tested, since the runtime safety net is what catches accidental misuse during development:
34
+
Disabling the feature drops those guardrail-only emits, which saves roughly 300 bytes of binary and 1 to 2 CU per account:
The runtime safety net is what catches accidental misuse during development. Only turn `guardrails{:toml}` off in production after the program has been thoroughly tested.
43
+
</Callout>
44
+
37
45
## `account-resize{:toml}` (default)
38
46
39
-
The `account-resize{:toml}` feature enables `realloc_account{:rs}`along with the pinocchio entrypoint hook that writes `data_len{:rs}` into `RuntimeAccount.padding{:rs}` for every non-duplicate account, which is what allows`AccountView::resize(){:rs}` to enforce the `MAX_PERMITTED_DATA_INCREASE{:rs}` cap.
47
+
The `account-resize{:toml}` feature enables `realloc_account{:rs}`and adds a pinocchio entrypoint hook. The hook writes `data_len{:rs}` into `RuntimeAccount.padding{:rs}` for every non-duplicate account, which is what lets`AccountView::resize(){:rs}` enforce the `MAX_PERMITTED_DATA_INCREASE{:rs}` cap.
40
48
41
49
Disabling the feature saves roughly 300 bytes of binary and 2 CU per account, but only when the program never calls `realloc_account{:rs}` in the first place.
42
50
@@ -46,23 +54,43 @@ Disabling the feature saves roughly 300 bytes of binary and 2 CU per account, bu
46
54
47
55
## `const-rent{:toml}` (off)
48
56
49
-
The `const-rent{:toml}` feature folds `rent_exempt_lamports{:rs}` to a compile-time constant by combining pinocchio's `DEFAULT_LAMPORTS_PER_BYTE{:rs}` and `ACCOUNT_STORAGE_OVERHEAD{:rs}`, which lets `create_account{:rs}`skip the `Rent::get(){:rs}` sysvar call entirely.
57
+
The `const-rent{:toml}` feature folds `rent_exempt_lamports{:rs}` to a compile-time constant by combining pinocchio's `DEFAULT_LAMPORTS_PER_BYTE{:rs}` and `ACCOUNT_STORAGE_OVERHEAD{:rs}`. With the constant in place, `create_account{:rs}`skips the `Rent::get(){:rs}` sysvar call entirely. The savings come out to roughly 90 CU per `create_account{:rs}` CPI.
50
58
51
-
The savings come out to roughly 90 CU per `create_account{:rs}` CPI. The trade-off is that if Solana changes the rent formula in the future (for example, through a SIMD like SIMD-0194), programs built with `const-rent{:toml}` will compute stale values until they are rebuilt. The feature is off by default precisely so programs pick up runtime formula changes transparently.
If Solana changes the rent formula in the future (for example, through a SIMD like SIMD-0194), programs built with `const-rent{:toml}` will compute stale values until they are rebuilt. The feature is off by default so programs pick up runtime formula changes transparently.
61
+
</Callout>
52
62
53
-
Reach for `const-rent{:toml}` when the 90 CU per `create_account{:rs}` matters more than rent-formula drift safety, and when the program is built and re-deployed often enough that refreshing the constant is part of the normal release cycle.
63
+
<Calloutvariant="tip"title="When to enable">
64
+
Reach for `const-rent{:toml}` when 90 CU per `create_account{:rs}` matters more than rent-formula drift safety, and when the program is rebuilt and redeployed often enough that refreshing the constant is part of the normal release cycle.
65
+
</Callout>
54
66
55
67
## `compat{:toml}` (off)
56
68
57
-
The `compat{:toml}` feature exposes a small set of v1-shaped helpers for programs in the middle of porting. The most useful one is `debug!(msg){:rs}`, a logging macro shaped like `msg!{:rs}` that accepts any Rust format string (including `{:?}{:rs}`, `{:x}{:rs}`, and dynamic width specifiers) by routing through `alloc::format!{:rs}`. The feature also re-exports the v1 `error!{:rs}`, `err!{:rs}`, and `pubkey!{:rs}` macros, the `Pubkey{:rs}` type alias, and the `AccountViewCompat{:rs}` extension trait so existing call sites compile without rewrites.
69
+
The `compat{:toml}` feature exposes a small set of v1-shaped helpers for programs in the middle of porting. The most useful is `debug!(msg){:rs}`, a logging macro shaped like `msg!{:rs}` that accepts any Rust format string by routing through `alloc::format!{:rs}`. That covers `{:?}{:rs}`, `{:x}{:rs}`, and dynamic width specifiers, none of which native `msg!{:rs}` supports.
70
+
71
+
The remaining helpers re-expose v1 names so existing call sites compile without rewrites:
58
72
59
-
The trade-off is cost. `debug!{:rs}` is meaningfully more expensive than the native `msg!{:rs}` because of the heap allocation and fmt-trait dispatch, so the feature is off by default to keep production binaries from accidentally shipping the heavier path.
`debug!{:rs}` is meaningfully more expensive than the native `msg!{:rs}` because of the heap allocation and fmt-trait dispatch. The feature is off by default to keep production binaries from accidentally shipping the heavier path.
81
+
</Callout>
60
82
61
83
## `event-cpi{:toml}` (off)
62
84
63
-
The `event-cpi{:toml}` feature wires the self-CPI event emit pattern through Anchor's derives. When enabled it adds the `#[event_cpi]{:rs}` accounts attribute and the `emit_cpi!{:rs}` macro, and the `#[program]{:rs}` dispatcher reserves an 8-byte tag at the top of instruction data so emitted events can be recovered from instruction history by indexers that cannot read transaction logs.
85
+
The `event-cpi{:toml}` feature wires the self-CPI event emit pattern through Anchor's derives. When enabled, it adds the `#[event_cpi]{:rs}` accounts attribute and the `emit_cpi!{:rs}` macro.
86
+
87
+
The `#[program]{:rs}` dispatcher then reserves an 8-byte tag at the top of instruction data. Indexers that cannot read transaction logs can recover emitted events from instruction history through that tag.
64
88
65
-
The feature is off by default so the dispatcher does not pay the tag check on programs that do not use event CPIs. See [Events](/docs/v2/programs/events/) for the call shape.
89
+
<Calloutvariant="note"title="Why off by default">
90
+
The dispatcher would pay the 8-byte tag check on every instruction. Programs that do not use event CPIs avoid that cost by keeping `event-cpi{:toml}` off.
91
+
</Callout>
92
+
93
+
See [Events](/docs/v2/programs/events/) for the call shape.
66
94
67
95
## `testing{:toml}` (off)
68
96
@@ -72,7 +100,9 @@ The `testing{:toml}` feature exposes the `anchor_lang_v2::testing{:rs}` module,
0 commit comments