Sfoglia il codice sorgente

sdk: Improve comments (#64)

* [wip]: Add new scripts

* [wip]: Use matric strategy

* [wip]: Fix members parsing

* [wip]: Add CI env variables

* [wip]: Remove nothrow

* [wip]: Filter changes

* [wip]: Add audit step

* [wip]: Add semver checks

* [wip]: Refactor publish workflow

* [wip]: Refactor

* [wip]: Fix commands

* Fix formatting

* Remove detect changes step

* Review comments

* Fix lint comments

* Expand crate comment

* Ignore crate comment tests

* Add missing docs

* More missing docs

* Add missing release component

* Pin cargo-release version

* Fix merge

* Review comments
Fernando Otero 9 mesi fa
parent
commit
5f33c92ecd

+ 1 - 1
.github/actions/setup/action.yml

@@ -80,7 +80,7 @@ runs:
     - name: Install 'cargo-release'
       if: ${{ contains(inputs.components, 'release') }}
       shell: bash
-      run: cargo install cargo-release
+      run: cargo install cargo-release@0.25.15
 
     - name: Install 'cargo-semver-checks'
       if: ${{ contains(inputs.components, 'semver-checks') }}

+ 1 - 1
.github/workflows/publish.yml

@@ -61,7 +61,7 @@ jobs:
         with:
           cargo-cache-key: cargo-publish
           toolchain: test
-          components: semver-checks
+          components: release, semver-checks
           solana: true
 
       - name: Build

+ 1 - 1
README.md

@@ -25,7 +25,7 @@
 
 ## Overview
 
-Pinocchio is a zero-dependency library to create Solana programs in Rust. It takes advantage of the way SBF loaders serialize the program input parameters into a byte array that is then passed to the program's entrypoint to define zero-copy types to read the input. Since the communication between a program and SBF loader — either at the first time the program is called or when one program invokes the instructions of another program — is done via a byte array, a program can define its own types. This completely eliminates the dependency on the `solana-program` crate, which in turn mitigates dependency issues by having a crate specifically designed to create on-chain programs.
+Pinocchio is a zero-dependency library to create Solana programs in Rust. It takes advantage of the way SVM loaders serialize the program input parameters into a byte array that is then passed to the program's entrypoint to define zero-copy types to read the input. Since the communication between a program and SVM loader — either at the first time the program is called or when one program invokes the instructions of another program — is done via a byte array, a program can define its own types. This completely eliminates the dependency on the `solana-program` crate, which in turn mitigates dependency issues by having a crate specifically designed to create on-chain programs.
 
 As a result, Pinocchio can be used as a replacement for [`solana-program`](https://crates.io/crates/solana-program) to write on-chain programs, which are optimized in terms of both compute units consumption and binary size.
 

+ 8 - 1
sdk/pinocchio/src/account_info.rs

@@ -10,6 +10,9 @@ use crate::{program_error::ProgramError, pubkey::Pubkey, ProgramResult};
 /// single realloc.
 pub const MAX_PERMITTED_DATA_INCREASE: usize = 1_024 * 10;
 
+/// Returns the account info at the given index.
+///
+/// This macro validates that the index is within the bounds of the accounts.
 #[macro_export]
 macro_rules! get_account_info {
     ( $accounts:ident, $index:expr ) => {{
@@ -465,6 +468,7 @@ pub struct Ref<'a, T: ?Sized> {
 }
 
 impl<'a, T: ?Sized> Ref<'a, T> {
+    /// Maps a reference to a new type.
     #[inline]
     pub fn map<U: ?Sized, F>(orig: Ref<'a, T>, f: F) -> Ref<'a, U>
     where
@@ -481,6 +485,7 @@ impl<'a, T: ?Sized> Ref<'a, T> {
         }
     }
 
+    /// Filters and maps a reference to a new type.
     #[inline]
     pub fn filter_map<U: ?Sized, F>(orig: Ref<'a, T>, f: F) -> Result<Ref<'a, U>, Self>
     where
@@ -534,6 +539,7 @@ pub struct RefMut<'a, T: ?Sized> {
 }
 
 impl<'a, T: ?Sized> RefMut<'a, T> {
+    /// Maps a mutable reference to a new type.
     #[inline]
     pub fn map<U: ?Sized, F>(orig: RefMut<'a, T>, f: F) -> RefMut<'a, U>
     where
@@ -550,6 +556,7 @@ impl<'a, T: ?Sized> RefMut<'a, T> {
         }
     }
 
+    /// Filters and maps a mutable reference to a new type.
     #[inline]
     pub fn filter_map<U: ?Sized, F>(orig: RefMut<'a, T>, f: F) -> Result<RefMut<'a, U>, Self>
     where
@@ -586,8 +593,8 @@ impl<T: ?Sized> core::ops::DerefMut for RefMut<'_, T> {
 }
 
 impl<T: ?Sized> Drop for RefMut<'_, T> {
-    // unset the mutable borrow flag
     fn drop(&mut self) {
+        // unset the mutable borrow flag
         unsafe { *self.state.as_mut() &= self.borrow_mask };
     }
 }

+ 7 - 4
sdk/pinocchio/src/entrypoint/lazy.rs

@@ -1,3 +1,6 @@
+//! Defines the lazy program entrypoint and the context to access the
+//! input buffer.
+
 use crate::{
     account_info::{Account, AccountInfo, MAX_PERMITTED_DATA_INCREASE},
     program_error::ProgramError,
@@ -5,7 +8,7 @@ use crate::{
     BPF_ALIGN_OF_U128, NON_DUP_MARKER,
 };
 
-/// Declare the program entrypoint.
+/// Declare the lazy program entrypoint.
 ///
 /// Use the `lazy_program_entrypoint!` macro instead.
 #[deprecated(
@@ -19,7 +22,7 @@ macro_rules! lazy_entrypoint {
     };
 }
 
-/// Declare the program entrypoint.
+/// Declare the lazy program entrypoint.
 ///
 /// This entrypoint is defined as *lazy* because it does not read the accounts upfront.
 /// Instead, it provides an [`InstructionContext`] to the access input information on demand.
@@ -27,7 +30,7 @@ macro_rules! lazy_entrypoint {
 /// The trade-off is that the program is responsible for managing potential duplicated
 /// accounts and set up a `global allocator` and `panic handler`.
 ///
-/// The usual use-case for a [`lazy_program_entrypoint!`] is small programs with a single
+/// The usual use-case for a [`crate::lazy_program_entrypoint!`] is small programs with a single
 /// instruction. For most use-cases, it is recommended to use the [`crate::program_entrypoint!`]
 /// macro instead.
 ///
@@ -161,7 +164,7 @@ impl InstructionContext {
 
     /// Returns the number of remaining accounts.
     ///
-    /// This value is decremented each time [`next_account`] is called.
+    /// This value is decremented each time [`Self::next_account`] is called.
     #[inline(always)]
     pub fn remaining(&self) -> u64 {
         self.remaining

+ 2 - 2
sdk/pinocchio/src/entrypoint/mod.rs

@@ -39,8 +39,8 @@ pub const SUCCESS: u64 = super::SUCCESS;
 /// provided function to process the program instruction supplied by the runtime, and reporting
 /// its result to the runtime.
 ///
-/// It also sets up a [global allocator] and [panic handler], using the [`default_allocator!`]
-/// and [`default_panic_handler!`] macros.
+/// It also sets up a [global allocator] and [panic handler], using the [`crate::default_allocator!`]
+/// and [`crate::default_panic_handler!`] macros.
 ///
 /// The first argument is the name of a function with this type signature:
 ///

+ 13 - 3
sdk/pinocchio/src/instruction.rs

@@ -110,17 +110,18 @@ impl<'a> From<&'a AccountInfo> for Account<'a> {
 #[repr(C)]
 #[derive(Debug, Clone)]
 pub struct AccountMeta<'a> {
-    // Public key of the account.
+    /// Public key of the account.
     pub pubkey: &'a Pubkey,
 
-    // Indicates whether the account is writable or not.
+    /// Indicates whether the account is writable or not.
     pub is_writable: bool,
 
-    // Indicates whether the account signed the instruction or not.
+    /// Indicates whether the account signed the instruction or not.
     pub is_signer: bool,
 }
 
 impl<'a> AccountMeta<'a> {
+    /// Creates a new `AccountMeta`.
     #[inline(always)]
     pub fn new(pubkey: &'a Pubkey, is_writable: bool, is_signer: bool) -> Self {
         Self {
@@ -130,21 +131,25 @@ impl<'a> AccountMeta<'a> {
         }
     }
 
+    /// Creates a new readonly `AccountMeta`.
     #[inline(always)]
     pub fn readonly(pubkey: &'a Pubkey) -> Self {
         Self::new(pubkey, false, false)
     }
 
+    /// Creates a new writable `AccountMeta`.
     #[inline(always)]
     pub fn writable(pubkey: &'a Pubkey) -> Self {
         Self::new(pubkey, true, false)
     }
 
+    /// Creates a new readonly and signer `AccountMeta`.
     #[inline(always)]
     pub fn readonly_signer(pubkey: &'a Pubkey) -> Self {
         Self::new(pubkey, false, true)
     }
 
+    /// Creates a new writable and signer `AccountMeta`.
     #[inline(always)]
     pub fn writable_signer(pubkey: &'a Pubkey) -> Self {
         Self::new(pubkey, true, true)
@@ -157,6 +162,11 @@ impl<'a> From<&'a AccountInfo> for AccountMeta<'a> {
     }
 }
 
+/// Represents a signer seed.
+///
+/// This struct contains the same information as a `[u8]`, but
+/// has the memory layout as expected by `sol_invoke_signed_c`
+/// syscall.
 #[repr(C)]
 #[derive(Debug, Clone)]
 pub struct Seed<'a> {

+ 216 - 6
sdk/pinocchio/src/lib.rs

@@ -1,12 +1,222 @@
-//! A library to build a Solana program in Rust.
+//! # Pinocchio
 //!
-//! This library is intended to be used by on-chain programs only. It provides
-//! a zero-dependency library to minimise dependencies conflits. For off-chain
-//! programs, use instead the [`solana-sdk`] crate, which re-exports all modules
-//! from [`solana-program`].
+//! Pinocchio is a zero-dependency library to create Solana programs in Rust.
+//! It takes advantage of the way SVM loaders serialize the program input parameters
+//! into a byte array that is then passed to the program's entrypoint to define
+//! zero-copy types to read the input – these types are defined in an efficient way
+//! taking into consideration that they will be used in on-chain programs.
+//!
+//! It is intended to be used by on-chain programs only; for off-chain programs,
+//! use instead the [`solana-sdk`] crate.
 //!
 //! [`solana-sdk`]: https://docs.rs/solana-sdk/latest/solana_sdk/
-//! [`solana-program`]: https://docs.rs/solana-program/latest/solana_program/
+//!
+//! ## Defining the program entrypoint
+//!
+//! A Solana program needs to define an entrypoint, which will be called by the
+//! runtime to begin the program execution. The `entrypoint!` macro emits the common
+//! boilerplate to set up the program entrypoint. The macro will also set up [global
+//! allocator](https://doc.rust-lang.org/stable/core/alloc/trait.GlobalAlloc.html)
+//! and [panic handler](https://doc.rust-lang.org/nomicon/panic-handler.html) using
+//! the [`default_allocator!`] and [`default_panic_handler!`] macros.
+//!
+//! The [`entrypoint!`] is a convenience macro that invokes three other macros to set
+//! all symbols required for a program execution:
+//!
+//! * [`program_entrypoint!`]: declares the program entrypoint
+//! * [`default_allocator!`]: declares the default (bump) global allocator
+//! * [`default_panic_handler!`]: declares the default panic handler
+//!
+//! To use the `entrypoint!` macro, use the following in your entrypoint definition:
+//! ```ignore
+//! use pinocchio::{
+//!   account_info::AccountInfo,
+//!   entrypoint,
+//!   msg,
+//!   ProgramResult,
+//!   pubkey::Pubkey
+//! };
+//!
+//! entrypoint!(process_instruction);
+//!
+//! pub fn process_instruction(
+//!   program_id: &Pubkey,
+//!   accounts: &[AccountInfo],
+//!   instruction_data: &[u8],
+//! ) -> ProgramResult {
+//!   msg!("Hello from my program!");
+//!   Ok(())
+//! }
+//! ```
+//!
+//! The information from the input is parsed into their own entities:
+//!
+//! * `program_id`: the `ID` of the program being called
+//! * `accounts`: the accounts received
+//! * `instruction_data`: data for the instruction
+//!
+//! Pinocchio also offers variations of the program entrypoint
+//! ([`lazy_program_entrypoint`]) and global allocator ([`no_allocator`]). In
+//! order to use these, the program needs to specify the program entrypoint,
+//! global allocator and panic handler individually. The [`entrypoint!`] macro
+//! is equivalent to writing:
+//! ```ignore
+//! program_entrypoint!(process_instruction);
+//! default_allocator!();
+//! default_panic_handler!();
+//! ```
+//! Any of these macros can be replaced by other implementations and Pinocchio
+//! offers a couple of variants for this.
+//!
+//! ### [`lazy_program_entrypoint!`]
+//!
+//! The [`entrypoint!`] macro looks similar to the "standard" one found in
+//! [`solana-program`](https://docs.rs/solana-program-entrypoint/latest/solana_program_entrypoint/macro.entrypoint.html).
+//! It parses the whole input and provides the `program_id`, `accounts` and
+//! `instruction_data` separately. This consumes compute units before the program
+//! begins its execution. In some cases, it is beneficial for a program to have
+//! more control when the input parsing is happening, even whether the parsing
+//! is needed or not &mdash; this is the purpose of the [`lazy_program_entrypoint!`]
+//! macro. This macro only wraps the program input and provides methods to parse
+//! the input on-demand.
+//!
+//! The [`lazy_program_entrypoint`] is suitable for programs that have a single
+//! or very few instructions, since it requires the program to handle the parsing,
+//! which can become complex as the number of instructions increases. For *larger*
+//! programs, the [`program_entrypoint!`] will likely be easier and more efficient
+//! to use.
+//!
+//! To use the [`lazy_program_entrypoint!`] macro, use the following in your
+//! entrypoint definition:
+//! ```ignore
+//! use pinocchio::{
+//!   default_allocator,
+//!   default_panic_handler,
+//!   entrypoint::InstructionContext,
+//!   lazy_program_entrypoint,
+//!   msg,
+//!   ProgramResult
+//! };
+//!
+//! lazy_program_entrypoint!(process_instruction);
+//! default_allocator!();
+//! default_panic_handler!();
+//!
+//! pub fn process_instruction(
+//!   mut context: InstructionContext
+//! ) -> ProgramResult {
+//!     msg!("Hello from my lazy program!");
+//!     Ok(())
+//! }
+//! ```
+//!
+//! The [`InstructionContext`](entrypoint::InstructionContext) provides on-demand
+//! access to the information of the input:
+//!
+//! * [`available()`](entrypoint::InstructionContext::available): number of available
+//!   accounts.
+//! * [`next_account()`](entrypoint::InstructionContext::next_account): parses the
+//!   next available account (can be used as many times as accounts available).
+//! * [`instruction_data()`](entrypoint::InstructionContext::instruction_data): parses
+//!   the intruction data.
+//! * [`program_id()`](entrypoint::InstructionContext::program_id): parses the
+//!   program id.
+//!
+//!
+//! 💡 The [`lazy_program_entrypoint!`] does not set up a global allocator nor a panic
+//! handler. A program should explicitly use one of the provided macros to set them
+//! up or include its own implementation.
+//!
+//! ### [`no_allocator!`]
+//!
+//! When writing programs, it can be useful to make sure the program does not attempt
+//! to make any allocations. For this cases, Pinocchio includes a [`no_allocator!`]
+//! macro that set a global allocator just panics at any attempt to allocate memory.
+//!
+//! To use the [`no_allocator!`] macro, use the following in your entrypoint definition:
+//! ```ignore
+//! use pinocchio::{
+//!   account_info::AccountInfo,
+//!   default_panic_handler,
+//!   msg,
+//!   no_allocator,
+//!   program_entrypoint,
+//!   ProgramResult,
+//!   pubkey::Pubkey
+//! };
+//!
+//! program_entrypoint!(process_instruction);
+//! default_panic_handler!();
+//! no_allocator!();
+//!
+//! pub fn process_instruction(
+//!   program_id: &Pubkey,
+//!   accounts: &[AccountInfo],
+//!   instruction_data: &[u8],
+//! ) -> ProgramResult {
+//!   msg!("Hello from `no_std` program!");
+//!   Ok(())
+//! }
+//! ```
+//!
+//!
+//! 💡 The [`no_allocator!`] macro can also be used in combination with the
+//! [`lazy_program_entrypoint!`].
+//!
+//! ## `std` crate feature
+//!
+//! By default, Pinocchio is a `no_std` crate. This means that it does not use any
+//! code from the standard (`std`) library. While this does not affect how Pinocchio
+//! is used, there is a one particular apparent difference. In a `no_std` environment,
+//! the [`msg!`] macro does not provide any formatting options since the `format!` macro
+//! requires the `std` library. In order to use [`msg!`] with formatting, the `std`
+//! feature should be enable when adding Pinocchio as a dependency:
+//! ```ignore
+//! pinocchio = { version = "0.7.0", features = ["std"] }
+//! ```
+//!
+//! Instead of enabling the `std` feature to be able to format log messages with [`msg!`],
+//! it is recommented to use the [`pinocchio-log`](https://crates.io/crates/pinocchio-log)
+//! crate. This crate provides a lightweight `log!` macro with better compute units
+//! consumption than the standard `format!` macro without requiring the `std` library.
+//!
+//! ## Advanced entrypoint configuration
+//!
+//! The symbols emitted by the entrypoint macros &mdash; program entrypoint, global
+//! allocator and default panic handler &mdash; can only be defined once globally. If
+//! the program crate is also intended to be used as a library, it is common practice
+//! to define a Cargo [feature](https://doc.rust-lang.org/cargo/reference/features.html)
+//! in your program crate to conditionally enable the module that includes the [`entrypoint!`]
+//! macro invocation. The convention is to name the feature `bpf-entrypoint`.
+//!
+//! ```ignore
+//! #[cfg(feature = "bpf-entrypoint")]
+//! mod entrypoint {
+//!   use pinocchio::{
+//!     account_info::AccountInfo,
+//!     entrypoint,
+//!     msg,
+//!     ProgramResult,
+//!     pubkey::Pubkey
+//!   };
+//!
+//!   entrypoint!(process_instruction);
+//!
+//!   pub fn process_instruction(
+//!     program_id: &Pubkey,
+//!     accounts: &[AccountInfo],
+//!     instruction_data: &[u8],
+//!   ) -> ProgramResult {
+//!     msg!("Hello from my program!");
+//!     Ok(())
+//!   }
+//! }
+//! ```
+//!
+//! When building the program binary, you must enable the `bpf-entrypoint` feature:
+//! ```ignore
+//! cargo build-sbf --features bpf-entrypoint
+//! ```
 
 #![no_std]
 

+ 41 - 2
sdk/pinocchio/src/log.rs

@@ -28,13 +28,25 @@
 //! [`RpcClient::get_transaction`]: https://docs.rs/solana-rpc-client/latest/solana_rpc_client/rpc_client/struct.RpcClient.html#method.get_transaction
 //!
 //! While most logging functions are defined in this module, [`Pubkey`]s can
-//! also be efficiently logged with the [`Pubkey::log`] function.
+//! also be efficiently logged with the [`pubkey::log`] function.
 //!
 //! [`Pubkey`]: crate::pubkey::Pubkey
-//! [`Pubkey::log`]: crate::pubkey::Pubkey::log
+//! [`pubkey::log`]: crate::pubkey::log
 
 use crate::{account_info::AccountInfo, pubkey::log};
 
+/// Print a message to the log.
+///
+/// Supports simple strings of type `&str`. The expression will be passed
+/// directly to [`sol_log`]. This is typically used for logging static strings.
+///
+/// # Examples
+///
+/// ```
+/// use pinocchio::msg;
+///
+/// msg!("verifying multisig");
+/// ```
 #[macro_export]
 #[cfg(not(feature = "std"))]
 macro_rules! msg {
@@ -43,6 +55,33 @@ macro_rules! msg {
     };
 }
 
+/// Print a message to the log.
+///
+/// Supports simple strings as well as Rust [format strings][fs]. When passed a
+/// single expression it will be passed directly to [`sol_log`]. The expression
+/// must have type `&str`, and is typically used for logging static strings.
+/// When passed something other than an expression, particularly
+/// a sequence of expressions, the tokens will be passed through the
+/// [`format!`] macro before being logged with `sol_log`.
+///
+/// [fs]: https://doc.rust-lang.org/std/fmt/
+/// [`format!`]: https://doc.rust-lang.org/std/fmt/fn.format.html
+///
+/// Note that Rust's formatting machinery is relatively CPU-intensive
+/// for constrained environments like the Solana VM.
+///
+/// # Examples
+///
+/// ```
+/// use pinocchio::msg;
+///
+/// // The fast form
+/// msg!("verifying multisig");
+///
+/// // With formatting
+/// let err = "not enough signers";
+/// msg!("multisig failed: {}", err);
+/// ```
 #[cfg(feature = "std")]
 #[macro_export]
 macro_rules! msg {

+ 4 - 16
sdk/pinocchio/src/program.rs

@@ -166,9 +166,8 @@ pub fn slice_invoke_signed(
 
 /// Invoke a cross-program instruction but don't enforce Rust's aliasing rules.
 ///
-/// This function does not check that [`Ref`]s within [`Account`]s are properly
-/// borrowable as described in the documentation for that function. Those checks
-/// consume CPU cycles that this function avoids.
+/// This function does not check that [`Account`]s are properly borrowable.
+/// Those checks consume CPU cycles that this function avoids.
 ///
 /// # Safety
 ///
@@ -176,11 +175,6 @@ pub fn slice_invoke_signed(
 /// borrowed within the calling program, and that data is written to by the
 /// callee, then Rust's aliasing rules will be violated and cause undefined
 /// behavior.
-///
-/// # Important
-///
-/// The accounts on the `account_infos` slice must be in the same order as the
-/// `accounts` field of the `instruction`.
 #[inline(always)]
 pub unsafe fn invoke_unchecked(instruction: &Instruction, accounts: &[Account]) {
     invoke_signed_unchecked(instruction, accounts, &[])
@@ -189,9 +183,8 @@ pub unsafe fn invoke_unchecked(instruction: &Instruction, accounts: &[Account])
 /// Invoke a cross-program instruction with signatures but don't enforce Rust's
 /// aliasing rules.
 ///
-/// This function does not check that [`Ref`]s within [`Account`]s are properly
-/// borrowable as described in the documentation for that function. Those checks
-/// consume CPU cycles that this function avoids.
+/// This function does not check that [`Account`]s are properly borrowable.
+/// Those checks consume CPU cycles that this function avoids.
 ///
 /// # Safety
 ///
@@ -199,11 +192,6 @@ pub unsafe fn invoke_unchecked(instruction: &Instruction, accounts: &[Account])
 /// borrowed within the calling program, and that data is written to by the
 /// callee, then Rust's aliasing rules will be violated and cause undefined
 /// behavior.
-///
-/// # Important
-///
-/// The accounts on the `account_infos` slice must be in the same order as the
-/// `accounts` field of the `instruction`.
 pub unsafe fn invoke_signed_unchecked(
     instruction: &Instruction,
     accounts: &[Account],

+ 27 - 1
sdk/pinocchio/src/program_error.rs

@@ -3,7 +3,7 @@
 //! Current implementation is based on the `ProgramError` enum from
 //! the Solana SDK:
 //!
-//! https://github.com/anza-xyz/agave/blob/master/sdk/program/src/program_error.rs
+//! <https://github.com/anza-xyz/solana-sdk/blob/master/program-error/src/lib.rs>
 //!
 //! Considerations:
 //!
@@ -103,31 +103,57 @@ macro_rules! to_builtin {
     };
 }
 
+/// Builtin value for `ProgramError::Custom(0)`.
 pub const CUSTOM_ZERO: u64 = to_builtin!(1);
+/// Builtin value for `ProgramError::InvalidArgument`.
 pub const INVALID_ARGUMENT: u64 = to_builtin!(2);
+/// Builtin value for `ProgramError::InvalidInstructionData`.
 pub const INVALID_INSTRUCTION_DATA: u64 = to_builtin!(3);
+/// Builtin value for `ProgramError::InvalidAccountData`.
 pub const INVALID_ACCOUNT_DATA: u64 = to_builtin!(4);
+/// Builtin value for `ProgramError::AccountDataTooSmall`.
 pub const ACCOUNT_DATA_TOO_SMALL: u64 = to_builtin!(5);
+/// Builtin value for `ProgramError::InsufficientFunds`.
 pub const INSUFFICIENT_FUNDS: u64 = to_builtin!(6);
+/// Builtin value for `ProgramError::IncorrectProgramId`.
 pub const INCORRECT_PROGRAM_ID: u64 = to_builtin!(7);
+/// Builtin value for `ProgramError::MissingRequiredSignature`.
 pub const MISSING_REQUIRED_SIGNATURES: u64 = to_builtin!(8);
+/// Builtin value for `ProgramError::AccountAlreadyInitialized`.
 pub const ACCOUNT_ALREADY_INITIALIZED: u64 = to_builtin!(9);
+/// Builtin value for `ProgramError::UninitializedAccount`.
 pub const UNINITIALIZED_ACCOUNT: u64 = to_builtin!(10);
+/// Builtin value for `ProgramError::NotEnoughAccountKeys`.
 pub const NOT_ENOUGH_ACCOUNT_KEYS: u64 = to_builtin!(11);
+/// Builtin value for `ProgramError::AccountBorrowFailed`.
 pub const ACCOUNT_BORROW_FAILED: u64 = to_builtin!(12);
+/// Builtin value for `ProgramError::MaxSeedLengthExceeded`.
 pub const MAX_SEED_LENGTH_EXCEEDED: u64 = to_builtin!(13);
+/// Builtin value for `ProgramError::InvalidSeeds`.
 pub const INVALID_SEEDS: u64 = to_builtin!(14);
+/// Builtin value for `ProgramError::BorshIoError`.
 pub const BORSH_IO_ERROR: u64 = to_builtin!(15);
+/// Builtin value for `ProgramError::AccountNotRentExempt`.
 pub const ACCOUNT_NOT_RENT_EXEMPT: u64 = to_builtin!(16);
+/// Builtin value for `ProgramError::UnsupportedSysvar`.
 pub const UNSUPPORTED_SYSVAR: u64 = to_builtin!(17);
+/// Builtin value for `ProgramError::IllegalOwner`.
 pub const ILLEGAL_OWNER: u64 = to_builtin!(18);
+/// Builtin value for `ProgramError::MaxAccountsDataAllocationsExceeded`.
 pub const MAX_ACCOUNTS_DATA_ALLOCATIONS_EXCEEDED: u64 = to_builtin!(19);
+/// Builtin value for `ProgramError::InvalidRealloc`.
 pub const INVALID_ACCOUNT_DATA_REALLOC: u64 = to_builtin!(20);
+/// Builtin value for `ProgramError::MaxInstructionTraceLengthExceeded`.
 pub const MAX_INSTRUCTION_TRACE_LENGTH_EXCEEDED: u64 = to_builtin!(21);
+/// Builtin value for `ProgramError::BuiltinProgramsMustConsumeComputeUnits`.
 pub const BUILTIN_PROGRAMS_MUST_CONSUME_COMPUTE_UNITS: u64 = to_builtin!(22);
+/// Builtin value for `ProgramError::InvalidAccountOwner`.
 pub const INVALID_ACCOUNT_OWNER: u64 = to_builtin!(23);
+/// Builtin value for `ProgramError::ArithmeticOverflow`.
 pub const ARITHMETIC_OVERFLOW: u64 = to_builtin!(24);
+/// Builtin value for `ProgramError::Immutable`.
 pub const IMMUTABLE: u64 = to_builtin!(25);
+/// Builtin value for `ProgramError::IncorrectAuthority`.
 pub const INCORRECT_AUTHORITY: u64 = to_builtin!(26);
 
 impl From<u64> for ProgramError {

+ 5 - 5
sdk/pinocchio/src/pubkey.rs

@@ -2,13 +2,13 @@
 
 use crate::program_error::ProgramError;
 
-/// Number of bytes in a pubkey
+/// Number of bytes in a pubkey.
 pub const PUBKEY_BYTES: usize = 32;
 
-/// maximum length of derived `Pubkey` seed
+/// maximum length of derived `Pubkey` seed.
 pub const MAX_SEED_LEN: usize = 32;
 
-/// Maximum number of seeds
+/// Maximum number of seeds.
 pub const MAX_SEEDS: usize = 16;
 
 /// The address of a [Solana account][account].
@@ -16,7 +16,7 @@ pub const MAX_SEEDS: usize = 16;
 /// [account]: https://solana.com/docs/core/accounts
 pub type Pubkey = [u8; PUBKEY_BYTES];
 
-/// Log a `Pubkey` from a program
+/// Log a `Pubkey` from a program.
 #[inline(always)]
 pub fn log(pubkey: &Pubkey) {
     #[cfg(target_os = "solana")]
@@ -75,7 +75,7 @@ pub fn log(pubkey: &Pubkey) {
 /// re-searching for the bump key by using the [`create_program_address`]
 /// function.
 ///
-/// [`create_program_address`]: Pubkey::create_program_address
+/// [`create_program_address`]: crate::pubkey::create_program_address
 ///
 /// **Warning**: Because of the way the seeds are hashed there is a potential
 /// for program address collisions for the same program id.  The seeds are

+ 1 - 0
sdk/pinocchio/src/syscalls.rs

@@ -30,6 +30,7 @@ macro_rules! define_syscall {
 macro_rules! define_syscall {
 	(fn $name:ident($($arg:ident: $typ:ty),*) -> $ret:ty) => {
 		extern "C" {
+            /// Syscall function.
 			pub fn $name($($arg: $typ),*) -> $ret;
 		}
 	};

+ 2 - 2
sdk/pinocchio/src/sysvars/clock.rs

@@ -49,8 +49,8 @@ pub struct Clock {
     pub unix_timestamp: UnixTimestamp,
 }
 
-// At 160 ticks/s, 64 ticks per slot implies that leader rotation and voting will happen
-// every 400 ms. A fast voting cadence ensures faster finality and convergence
+/// At 160 ticks/s, 64 ticks per slot implies that leader rotation and voting will happen
+/// every 400 ms. A fast voting cadence ensures faster finality and convergence
 pub const DEFAULT_TICKS_PER_SLOT: u64 = 64;
 
 /// The default tick rate that the cluster attempts to achieve (160 per second).

+ 4 - 2
sdk/pinocchio/src/sysvars/fees.rs

@@ -38,11 +38,13 @@ pub struct FeeRateGovernor {
     pub burn_percent: u8,
 }
 
+/// Default lamports per signature.
 pub const DEFAULT_TARGET_LAMPORTS_PER_SIGNATURE: u64 = 10_000;
+
+/// Default signatures per slot.
 pub const DEFAULT_TARGET_SIGNATURES_PER_SLOT: u64 = 50 * DEFAULT_MS_PER_SLOT;
 
-// Percentage of tx fees to burn...I think this was changed in the anza update...
-/// 100% of fees now goes to validators...I'll confirm...
+/// Default percentage of fees to burn.
 pub const DEFAULT_BURN_PERCENT: u8 = 50;
 
 impl Default for FeeRateGovernor {