|
1 | | -//! # Pinocchio |
| 1 | +//! # A library to create Solana programs in Rust |
2 | 2 | //! |
3 | | -//! Pinocchio is a "no-external" dependencies library to create Solana programs |
4 | | -//! in Rust, which means that the only dependencies are from the Solana SDK. This |
5 | | -//! reduces the chance of dependency conflicts when compiling the program. |
6 | | -//! |
7 | | -//! It takes advantage of the way SVM loaders serialize the program input |
8 | | -//! parameters into a byte array that is then passed to the program's entrypoint |
9 | | -//! to use zero-copy types to read the input - these types are defined in an efficient |
10 | | -//! way taking into consideration that they will be used in on-chain programs. |
11 | | -//! |
12 | | -//! It is intended to be used by on-chain programs only; for off-chain programs, |
13 | | -//! use instead [`solana-sdk`] crates. |
14 | | -//! |
15 | | -//! [`solana-sdk`]: https://docs.rs/solana-sdk/latest/solana_sdk/ |
| 3 | +//! Pinocchio is a *no-external* dependencies library to create Solana programs |
| 4 | +//! in Rust. The only dependencies are types from the Solana SDK specifically |
| 5 | +//! designed for on-chain programs. This mitigates dependency issues and offers |
| 6 | +//! an efficient zero-copy library to write programs, optimized in terms of both |
| 7 | +//! compute units consumption and binary size. |
16 | 8 | //! |
17 | 9 | //! ## Defining the program entrypoint |
18 | 10 | //! |
|
23 | 15 | //! and [panic handler](https://doc.rust-lang.org/nomicon/panic-handler.html) using |
24 | 16 | //! the [`default_allocator!`] and [`default_panic_handler!`] macros. |
25 | 17 | //! |
26 | | -//! The [`entrypoint!`] is a convenience macro that invokes three other macros to set |
27 | | -//! all symbols required for a program execution: |
| 18 | +//! The [`entrypoint!`](https://docs.rs/pinocchio/latest/pinocchio/macro.entrypoint.html) |
| 19 | +//! is a convenience macro that invokes three other macros to set all components |
| 20 | +//! required for a program execution: |
28 | 21 | //! |
29 | 22 | //! * [`program_entrypoint!`]: declares the program entrypoint |
30 | 23 | //! * [`default_allocator!`]: declares the default (bump) global allocator |
31 | 24 | //! * [`default_panic_handler!`]: declares the default panic handler |
32 | 25 | //! |
| 26 | +//! When all dependencies are `no_std`, you should use [`nostd_panic_handler!`](https://docs.rs/pinocchio/latest/pinocchio/macro.nostd_panic_handler.html) |
| 27 | +//! instead of `default_panic_handler!` to declare a rust runtime panic handler. |
| 28 | +//! There's no need to do this when any dependency is `std` since rust compiler will |
| 29 | +//! emit a panic handler. |
| 30 | +//! |
33 | 31 | //! To use the `entrypoint!` macro, use the following in your entrypoint definition: |
34 | 32 | //! ```ignore |
35 | 33 | //! use pinocchio::{ |
36 | | -//! AccountView, |
| 34 | +//! account::AccountView, |
37 | 35 | //! Address, |
38 | 36 | //! entrypoint, |
39 | 37 | //! ProgramResult |
|
56 | 54 | //! * `accounts`: the accounts received |
57 | 55 | //! * `instruction_data`: data for the instruction |
58 | 56 | //! |
59 | | -//! Pinocchio also offers variations of the program entrypoint |
60 | | -//! ([`lazy_program_entrypoint`]) and global allocator ([`no_allocator`]). In |
61 | | -//! order to use these, the program needs to specify the program entrypoint, |
62 | | -//! global allocator and panic handler individually. The [`entrypoint!`] macro |
63 | | -//! is equivalent to writing: |
| 57 | +//! `pinocchio` also offers variations of the program entrypoint (`lazy_program_entrypoint`) |
| 58 | +//! and global allocator (`no_allocator`). In order to use these, the program needs to |
| 59 | +//! specify the program entrypoint, global allocator and panic handler individually. The |
| 60 | +//! `entrypoint!` macro is equivalent to writing: |
64 | 61 | //! ```ignore |
65 | 62 | //! program_entrypoint!(process_instruction); |
66 | 63 | //! default_allocator!(); |
67 | 64 | //! default_panic_handler!(); |
68 | 65 | //! ``` |
69 | | -//! Any of these macros can be replaced by other implementations and Pinocchio |
70 | | -//! offers a couple of variants for this. |
| 66 | +//! Any of these macros can be replaced by alternative implementations. |
71 | 67 | //! |
72 | 68 | //! ### [`lazy_program_entrypoint!`] |
73 | 69 | //! |
|
160 | 156 | //! 💡 The [`no_allocator!`] macro can also be used in combination with the |
161 | 157 | //! [`lazy_program_entrypoint!`]. |
162 | 158 | //! |
163 | | -//! ## `std` crate feature |
| 159 | +//! Since the `no_allocator!` macro does not allocate memory, the `32kb` memory region |
| 160 | +//! reserved for the heap remains unused. To take advantage of this, the `no_allocator!` |
| 161 | +//! macro emits an `allocate_unchecked` helper function that allows you to manually |
| 162 | +//! reserve memory for a type at compile time. |
| 163 | +//! ```ignore |
| 164 | +//! /// static allocation: |
| 165 | +//! /// - 0 is the offset when the type will be allocated |
| 166 | +//! /// - `allocate_unchecked` returns a mutable reference to the allocated type |
| 167 | +//! let lamports = allocate_unchecked::<u64>(0); |
| 168 | +//! *lamports = 1_000_000_000; |
| 169 | +//! ``` |
| 170 | +//! |
| 171 | +//! Note that it is the developer's responsibility to ensure that types do not overlap |
| 172 | +//! in memory - the `offset + <size of type>` of different types must not overlap. |
| 173 | +//! |
| 174 | +//! ## Crate features |
| 175 | +//! |
| 176 | +//! ### `alloc` |
| 177 | +//! |
| 178 | +//! The `alloc` feature is enabled by default and it uses the [`alloc`](https://doc.rust-lang.org/alloc/) |
| 179 | +//! crate. This provides access to dynamic memory allocation in combination with the |
| 180 | +//! [`default_allocator!`], e.g., required to use `String` and `Vec` in a program. |
| 181 | +//! Helpers that need to allocate memory, such as fetching [`crate::sysvars::slot_hashes::SlotHashes::fetch`] |
| 182 | +//! sysvar data, are also available. |
| 183 | +//! |
| 184 | +//! When no allocation is needed or desired, the feature can be disabled: |
| 185 | +//! |
| 186 | +//! ```ignore |
| 187 | +//! pinocchio = { version = "0.10.0", default-features = false } |
| 188 | +//! ``` |
| 189 | +//! |
| 190 | +//! ### `cpi` |
| 191 | +//! |
| 192 | +//! The `cpi` feature enables the cross-program invocation helpers, as well as types |
| 193 | +//! to define instructions and signer information. |
164 | 194 | //! |
165 | | -//! By default, Pinocchio is a `no_std` crate. This means that it does not use any |
166 | | -//! code from the standard (`std`) library. While this does not affect how Pinocchio |
167 | | -//! is used, there is a one particular apparent difference. Helpers that need to |
168 | | -//! allocate memory, such as fetching `SlotHashes` sysvar, are not available. To |
169 | | -//! enable these helpers, the `alloc` feature must be enabled when adding Pinocchio |
170 | | -//! as a dependency: |
171 | 195 | //! ```ignore |
172 | | -//! pinocchio = { version = "0.10.0", features = ["alloc"] } |
| 196 | +//! pinocchio = { version = "0.10.0", features = ["cpi"] } |
173 | 197 | //! ``` |
174 | 198 | //! |
175 | 199 | //! ## Advanced entrypoint configuration |
|
185 | 209 | //! #[cfg(feature = "bpf-entrypoint")] |
186 | 210 | //! mod entrypoint { |
187 | 211 | //! use pinocchio::{ |
188 | | -//! AccountView, |
| 212 | +//! account::AccountView, |
189 | 213 | //! Address, |
190 | 214 | //! entrypoint, |
191 | 215 | //! ProgramResult |
|
0 commit comments