add space reference (#50)
This commit is contained in:
parent
4744a13768
commit
c032d12e35
|
@ -29,8 +29,9 @@
|
|||
|
||||
---
|
||||
|
||||
- [Anchor Tooling](./chapter_5/anchor_tooling.md)
|
||||
- [Anchor References](./chapter_5/anchor_references.md)
|
||||
- [Space Reference](./chapter_5/space.md)
|
||||
- [CLI Reference](./chapter_5/cli.md)
|
||||
- [AVM Reference](./chapter_5/avm.md)
|
||||
- [Anchor.toml Reference](./chapter_5/anchor-toml_reference.md)
|
||||
- [Reference Links](./reference_links.md)
|
||||
- [Code References](./chapter_5/reference_links.md)
|
||||
|
|
|
@ -247,7 +247,9 @@ Let us briefly explain how we arrived at the `Game::MAXIMUM_SIZE`. Anchor uses t
|
|||
- the `board` has a length of (`9 * (1 + 1)`). We know the board has 9 tiles (-> `9`) of type `Option` which borsh serializes with 1 byte (set to `1` for Some and `0` for None) plus the size of whatever's in the `Option`. In this case, it's a simple enum with types that don't hold more types so the maximum size of the enum is also just `1` (for its discriminant). In total that means we get `9 (tiles) * (1 (Option) + 1(Sign discriminant))`.
|
||||
- `state` is also an enum so we need `1` byte for the discriminant. We have to init the account with the maximum size and the maximum size of an enum is the size of its biggest variant. In this case that's the `winner` variant which holds a Pubkey. A Pubkey is `32` bytes long so the size of `state` is `1 (discriminant) + 32 (winner pubkey)` (`MAXIMUM_SIZE` is a [`const`](https://doc.rust-lang.org/std/keyword.const.html) variable so specifying it in terms of a sum of the sizes of `Game`'s members' fields does not incur any runtime cost).
|
||||
|
||||
In addition to the game's size, we have to add another 8 to the space. This is space for the internal discriminator which anchor sets automatically. In short, the discriminator is how anchor can differentiate between different accounts of the same program.
|
||||
In addition to the game's size, we have to add another 8 to the space. This is space for the internal discriminator which anchor sets automatically. In short, the discriminator is how anchor can differentiate between different accounts of the same program. For more information, check out the Anchor space reference.
|
||||
|
||||
> [Anchor Space Reference](./../chapter_5/space.md)
|
||||
|
||||
> (What about using `mem::size_of<Game>()`? This almost works but not quite. The issue is that borsh will always serialize an option as 1 byte for the variant identifier and then additional x bytes for the content if it's Some. Rust uses null-pointer optimization to make Option's variant identifier 0 bytes when it can, so an option is sometimes just as big as its contents. This is the case with `Sign`. This means the `MAXIMUM_SIZE` could also be expressed as `mem::size_of<Game>() + 9`.)
|
||||
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
# Anchor References
|
||||
Is exactly what it says on the tin.
|
|
@ -1,2 +0,0 @@
|
|||
# Anchor Tooling
|
||||
This chapter explores Anchor's tooling.
|
|
@ -1,4 +1,4 @@
|
|||
# Reference Links
|
||||
# Code References
|
||||
|
||||
- [Accounts Reference](https://docs.rs/anchor-lang/latest/anchor_lang/accounts/index.html)
|
||||
- [Constraints Reference](https://docs.rs/anchor-lang/latest/anchor_lang/derive.Accounts.html)
|
|
@ -0,0 +1,50 @@
|
|||
# Space Reference
|
||||
|
||||
This reference tells you how much space you should allocate for an account.
|
||||
|
||||
| Types | Space in bytes | Details/Example
|
||||
| --------------- | -------------------- | -----------
|
||||
| bool | 1 | would only require 1 bit but still uses 1 byte
|
||||
| u8/i8 | 1 |
|
||||
| u16/i16 | 2 |
|
||||
| u32/i32 | 4 |
|
||||
| u64/i64 | 8 |
|
||||
| u128/i128 | 16 |
|
||||
| [T;amount] | space(T) * amount | e.g. space([u16;32]) = 2 * 32 = 64
|
||||
| Pubkey | 32 |
|
||||
| Vec\<T> | 4 + (space(T) * amount) | Account size is fixed so account should be initialized with sufficient space from the beginning
|
||||
| String | 4 + length of string in bytes | Account size is fixed so account should be initialized with sufficient space from the beginning
|
||||
| Option<T> | 1 + (space(T)) |
|
||||
| Enum | 1 + Largest Variant Size | e.g. Enum { A, B { val: u8 }, C { val: u16 } } -> 1 + space(u16) = 3
|
||||
| f32 | 4 | serialization will fail for NaN
|
||||
| f64 | 8 | serialization will fail for NaN
|
||||
|
||||
# Example
|
||||
```rust,ignore
|
||||
#[account]
|
||||
pub struct MyData {
|
||||
pub val: u16,
|
||||
pub state: GameState,
|
||||
pub players: Vec<Pubkey> // we want to support up to 10 players
|
||||
}
|
||||
|
||||
impl MyData {
|
||||
pub const MAX_SIZE: usize = 2 + (1 + 32) + (4 + 10 * 32);
|
||||
}
|
||||
|
||||
#[derive(AnchorSerialize, AnchorDeserialize, Clone, PartialEq, Eq)]
|
||||
pub enum GameState {
|
||||
Active,
|
||||
Tie,
|
||||
Won { winner: Pubkey },
|
||||
}
|
||||
|
||||
#[derive(Accounts)]
|
||||
pub struct InitializeMyData<'info> {
|
||||
// Note that we have to add 8 to the space for the internal anchor
|
||||
#[account(init, payer = signer, space = 8 + MyData::MAX_SIZE)]
|
||||
pub acc: Account<'info, MyData>,
|
||||
pub signer: Signer<'info>,
|
||||
pub system_program: Program<'info, System>
|
||||
}
|
||||
```
|
Loading…
Reference in New Issue