From 5918d6f09d507561f55639ee826956559b3b7b71 Mon Sep 17 00:00:00 2001 From: Nick Frostbutter <75431177+nickfrosty@users.noreply.github.com> Date: Wed, 21 Dec 2022 23:27:10 -0500 Subject: [PATCH] [docs] updating the "writing programs" section (#29197) * docs: added limitations page * fix: updated deprecated cargo test-bpf * docs: moved content off of overview * fix: added compute budget description * fix: updated compute buddget * fix: rearranged sections * fix: update code snippet * docs: overview page and links --- docs/sidebars.js | 5 + .../on-chain-programs/developing-c.md | 7 +- .../on-chain-programs/developing-rust.md | 12 +- docs/src/developing/on-chain-programs/faq.md | 171 ++++++++++++-- .../on-chain-programs/limitations.md | 72 ++++++ .../developing/on-chain-programs/overview.md | 222 +++--------------- docs/src/getstarted/rust.md | 2 +- docs/src/terminology.md | 4 +- 8 files changed, 276 insertions(+), 219 deletions(-) create mode 100644 docs/src/developing/on-chain-programs/limitations.md diff --git a/docs/sidebars.js b/docs/sidebars.js index 7ef24a0f7..9f439dcde 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -240,6 +240,11 @@ module.exports = { id: "developing/on-chain-programs/examples", label: "Program Examples", }, + { + type: "doc", + id: "developing/on-chain-programs/limitations", + label: "Limitations", + }, { type: "doc", id: "developing/on-chain-programs/faq", diff --git a/docs/src/developing/on-chain-programs/developing-c.md b/docs/src/developing/on-chain-programs/developing-c.md index db3ef04bd..3c9096773 100644 --- a/docs/src/developing/on-chain-programs/developing-c.md +++ b/docs/src/developing/on-chain-programs/developing-c.md @@ -56,10 +56,9 @@ information on how to write a test case. ## Program Entrypoint Programs export a known entrypoint symbol which the Solana runtime looks up and -calls when invoking a program. Solana supports multiple [versions of the SBF -loader](overview.md#versions) and the entrypoints may vary between them. +calls when invoking a program. Solana supports multiple versions of the SBF loader and the entrypoints may vary between them. Programs must be written for and deployed to the same loader. For more details -see the [overview](overview#loaders). +see the [FAQ section on Loaders](./faq.md#loaders). Currently there are two supported loaders [SBF Loader](https://github.com/solana-labs/solana/blob/7ddf10e602d2ed87a9e3737aa8c32f1db9f909d8/sdk/program/src/bpf_loader.rs#L17) @@ -104,7 +103,7 @@ their own deserialization function they need to ensure that any modifications the program wishes to commit must be written back into the input byte array. Details on how the loader serializes the program inputs can be found in the -[Input Parameter Serialization](overview.md#input-parameter-serialization) docs. +[Input Parameter Serialization](./faq.md#input-parameter-serialization) docs. ## Data Types diff --git a/docs/src/developing/on-chain-programs/developing-rust.md b/docs/src/developing/on-chain-programs/developing-rust.md index 537a089ce..ba8e9b332 100644 --- a/docs/src/developing/on-chain-programs/developing-rust.md +++ b/docs/src/developing/on-chain-programs/developing-rust.md @@ -52,7 +52,7 @@ For example: on Rand](#depending-on-rand). - Crates may overflow the stack even if the stack overflowing code isn't included in the program itself. For more information refer to - [Stack](overview.md#stack). + [Stack](./faq.md#stack). ## How to Build @@ -95,10 +95,10 @@ program. ## Program Entrypoint Programs export a known entrypoint symbol which the Solana runtime looks up and -calls when invoking a program. Solana supports multiple [versions of the BPF -loader](overview.md#versions) and the entrypoints may vary between them. +calls when invoking a program. Solana supports multiple versions of the BPF +loader and the entrypoints may vary between them. Programs must be written for and deployed to the same loader. For more details -see the [overview](overview#loaders). +see the [FAQ section on Loaders](./faq.md#loaders). Currently there are two supported loaders [BPF Loader](https://github.com/solana-labs/solana/blob/d9b0fc0e3eec67dfe4a97d9298b15969b2804fab/sdk/program/src/bpf_loader.rs#L17) @@ -159,7 +159,7 @@ their own deserialization function they need to ensure that any modifications the program wishes to commit be written back into the input byte array. Details on how the loader serializes the program inputs can be found in the -[Input Parameter Serialization](overview.md#input-parameter-serialization) docs. +[Input Parameter Serialization](./faq.md#input-parameter-serialization) docs. ### Data Types @@ -211,7 +211,7 @@ On-chain Rust programs support most of Rust's libstd, libcore, and liballoc, as well as many 3rd party crates. There are some limitations since these programs run in a resource-constrained, -single-threaded environment, and must be deterministic: +single-threaded environment, as well as being deterministic: - No access to - `rand` diff --git a/docs/src/developing/on-chain-programs/faq.md b/docs/src/developing/on-chain-programs/faq.md index 61d2515a5..e5e0aec3f 100644 --- a/docs/src/developing/on-chain-programs/faq.md +++ b/docs/src/developing/on-chain-programs/faq.md @@ -8,32 +8,36 @@ questions. If not addressed here, ask on [StackOverflow](https://stackoverflow.com/questions/tagged/solana) with the `solana` tag or check out the Solana [#developer-support](https://discord.gg/RxeGBH) -## `CallDepth` error +## Limitations -This error means that that cross-program invocation exceeded the allowed -invocation call depth. +Developing programs on the Solana blockchain have some inherent limitation associated with them. Below is a list of common limitation that you may run into. -See [cross-program invocation Call -Depth](developing/programming-model/calling-between-programs.md#call-depth) +See [Limitations of developing programs](./limitations.md) for more details -## `CallDepthExceeded` error +## Berkeley Packet Filter (BPF) -This error means the SBF stack depth was exceeded. +Solana on-chain programs are compiled via the [LLVM compiler infrastructure](https://llvm.org/) to an [Executable and Linkable Format (ELF)](https://en.wikipedia.org/wiki/Executable_and_Linkable_Format) containing +a variation of the [Berkeley Packet Filter (BPF)](https://en.wikipedia.org/wiki/Berkeley_Packet_Filter) bytecode. -See [call depth](overview.md#call-depth) +Because Solana uses the LLVM compiler infrastructure, a program may be written in any programming language that can target the LLVM's BPF backend. -## Computational constraints +BPF provides an efficient [instruction set](https://github.com/iovisor/bpf-docs/blob/master/eBPF.md) that can be executed in an interpreted virtual machine or as efficient just-in-time compiled native instructions. -See [computational -constraints](developing/programming-model/runtime.md#compute-budget) +## Memory map -## Float Rust types +The virtual address memory map used by Solana SBF programs is fixed and laid out +as follows -See [float support](overview.md#float-support) +- Program code starts at 0x100000000 +- Stack data starts at 0x200000000 +- Heap data starts at 0x300000000 +- Program input parameters start at 0x400000000 -## Heap size - -See [heap](overview.md#heap) +The above virtual addresses are start addresses but programs are given access to +a subset of the memory map. The program will panic if it attempts to read or +write to a virtual address that it was not granted access to, and an +`AccessViolation` error will be returned that contains the address and size of +the attempted violation. ## InvalidAccountData @@ -75,6 +79,137 @@ See [Rust Project Dependencies](developing-rust.md#project-dependencies) See [Rust restrictions](developing-rust.md#restrictions) -## Stack size +## Stack -See [stack](overview.md#stack) +SBF uses stack frames instead of a variable stack pointer. Each stack frame is +4KB in size. + +If a program violates that stack frame size, the compiler will report the +overrun as a warning. + +For example: + +``` +Error: Function _ZN16curve25519_dalek7edwards21EdwardsBasepointTable6create17h178b3d2411f7f082E Stack offset of -30728 exceeded max offset of -4096 by 26632 bytes, please minimize large stack variables +``` + +The message identifies which symbol is exceeding its stack frame, but the name +might be mangled if it is a Rust or C++ symbol. + +> To demangle a Rust symbol use [rustfilt](https://github.com/luser/rustfilt). + +The above warning came from a Rust program, so the demangled symbol name is: + +```bash +rustfilt _ZN16curve25519_dalek7edwards21EdwardsBasepointTable6create17h178b3d2411f7f082E +curve25519_dalek::edwards::EdwardsBasepointTable::create +``` + +To demangle a C++ symbol use `c++filt` from binutils. + +The reason a warning is reported rather than an error is because some dependent +crates may include functionality that violates the stack frame restrictions even +if the program doesn't use that functionality. If the program violates the stack +size at runtime, an `AccessViolation` error will be reported. + +SBF stack frames occupy a virtual address range starting at `0x200000000`. + +## Heap size + +Programs have access to a runtime heap either directly in C or via the Rust +`alloc` APIs. To facilitate fast allocations, a simple 32KB bump heap is +utilized. The heap does not support `free` or `realloc` so use it wisely. + +Internally, programs have access to the 32KB memory region starting at virtual +address 0x300000000 and may implement a custom heap based on the program's +specific needs. + +- [Rust program heap usage](developing-rust.md#heap) +- [C program heap usage](developing-c.md#heap) + +## Loaders + +Programs are deployed with and executed by runtime loaders, currently there are +two supported loaders [BPF +Loader](https://github.com/solana-labs/solana/blob/7ddf10e602d2ed87a9e3737aa8c32f1db9f909d8/sdk/program/src/bpf_loader.rs#L17) +and [BPF loader +deprecated](https://github.com/solana-labs/solana/blob/7ddf10e602d2ed87a9e3737aa8c32f1db9f909d8/sdk/program/src/bpf_loader_deprecated.rs#L14) + +Loaders may support different application binary interfaces so developers must +write their programs for and deploy them to the same loader. If a program +written for one loader is deployed to a different one the result is usually a +`AccessViolation` error due to mismatched deserialization of the program's input +parameters. + +For all practical purposes program should always be written to target the latest +BPF loader and the latest loader is the default for the command-line interface +and the javascript APIs. + +For language specific information about implementing a program for a particular +loader see: + +- [Rust program entrypoints](developing-rust.md#program-entrypoint) +- [C program entrypoints](developing-c.md#program-entrypoint) + +### Deployment + +SBF program deployment is the process of uploading a BPF shared object into a +program account's data and marking the account executable. A client breaks the +SBF shared object into smaller pieces and sends them as the instruction data of +[`Write`](https://github.com/solana-labs/solana/blob/bc7133d7526a041d1aaee807b80922baa89b6f90/sdk/program/src/loader_instruction.rs#L13) +instructions to the loader where loader writes that data into the program's +account data. Once all the pieces are received the client sends a +[`Finalize`](https://github.com/solana-labs/solana/blob/bc7133d7526a041d1aaee807b80922baa89b6f90/sdk/program/src/loader_instruction.rs#L30) +instruction to the loader, the loader then validates that the SBF data is valid +and marks the program account as _executable_. Once the program account is +marked executable, subsequent transactions may issue instructions for that +program to process. + +When an instruction is directed at an executable SBF program the loader +configures the program's execution environment, serializes the program's input +parameters, calls the program's entrypoint, and reports any errors encountered. + +For further information see [deploying](deploying.md) + +### Input Parameter Serialization + +SBF loaders serialize the program input parameters into a byte array that is +then passed to the program's entrypoint, where the program is responsible for +deserializing it on-chain. One of the changes between the deprecated loader and +the current loader is that the input parameters are serialized in a way that +results in various parameters falling on aligned offsets within the aligned byte +array. This allows deserialization implementations to directly reference the +byte array and provide aligned pointers to the program. + +For language specific information about serialization see: + +- [Rust program parameter + deserialization](developing-rust.md#parameter-deserialization) +- [C program parameter + deserialization](developing-c.md#parameter-deserialization) + +The latest loader serializes the program input parameters as follows (all +encoding is little endian): + +- 8 bytes unsigned number of accounts +- For each account + - 1 byte indicating if this is a duplicate account, if not a duplicate then + the value is 0xff, otherwise the value is the index of the account it is a + duplicate of. + - If duplicate: 7 bytes of padding + - If not duplicate: + - 1 byte boolean, true if account is a signer + - 1 byte boolean, true if account is writable + - 1 byte boolean, true if account is executable + - 4 bytes of padding + - 32 bytes of the account public key + - 32 bytes of the account's owner public key + - 8 bytes unsigned number of lamports owned by the account + - 8 bytes unsigned number of bytes of account data + - x bytes of account data + - 10k bytes of padding, used for realloc + - enough padding to align the offset to 8 bytes. + - 8 bytes rent epoch +- 8 bytes of unsigned number of instruction data +- x bytes of instruction data +- 32 bytes of the program id diff --git a/docs/src/developing/on-chain-programs/limitations.md b/docs/src/developing/on-chain-programs/limitations.md new file mode 100644 index 000000000..f5c5e1742 --- /dev/null +++ b/docs/src/developing/on-chain-programs/limitations.md @@ -0,0 +1,72 @@ +--- +title: "Limitations" +--- + +Developing programs on the Solana blockchain have some inherent limitation associated with them. Below is a list of common limitation that you may run into. + +## Rust libraries + +Since Rust based on-chain programs must run be deterministic while running in a resource-constrained, single-threaded environment, they have some limitations on various libraries. + +See [Developing with Rust - Restrictions](./developing-rust.md#restrictions) for a detailed breakdown these restrictions and limitations. + +## Compute budget + +To prevent abuse of the blockchain's computational resources, each transaction is allocated a [compute budget](./../../terminology.md#compute-budget). Exceeding this compute budget will result in the transaction failing. + +See [computational constraints](../programming-model/runtime.md#compute-budget) in the Runtime for more specific details. + +## Call stack depth - `CallDepthExceeded` error + +Solana programs are constrained to run quickly, and to facilitate this, the program's call stack is limited to a max depth of **64 frames**. + +When a program exceeds the allowed call stack depth limit, it will receive the `CallDepthExceeded` error. + +## CPI call depth - `CallDepth` error + +Cross-program invocations allow programs to invoke other programs directly, but the depth is constrained currently to `4`. + +When a program exceeds the allowed [cross-program invocation call depth](../programming-model/calling-between-programs.md#call-depth), it will receive a `CallDepth` error + +## Float Rust types support + +Programs support a limited subset of Rust's float operations. If a program +attempts to use a float operation that is not supported, the runtime will report +an unresolved symbol error. + +Float operations are performed via software libraries, specifically LLVM's float +built-ins. Due to the software emulated, they consume more compute units than +integer operations. In general, fixed point operations are recommended where +possible. + +The Solana Program Library math tests will report the performance of some math +operations: https://github.com/solana-labs/solana-program-library/tree/master/libraries/math + +To run the test: sync the repo and run: + +```sh +cargo test-sbf -- --nocapture --test-threads=1 +``` + +Recent results show the float operations take more instructions compared to +integers equivalents. Fixed point implementations may vary but will also be +less than the float equivalents: + +``` + u64 f32 +Multiply 8 176 +Divide 9 219 +``` + +## Static writable data + +Program shared objects do not support writable shared data. Programs are shared +between multiple parallel executions using the same shared read-only code and +data. This means that developers should not include any static writable or +global variables in programs. In the future a copy-on-write mechanism could be +added to support writable data. + +## Signed division + +The SBF instruction set does not support +[signed division](https://www.kernel.org/doc/html/latest/bpf/bpf_design_QA.Html#q-why-there-is-no-bpf-sdiv-for-signed-divide-operation). Adding a signed division instruction is a consideration. diff --git a/docs/src/developing/on-chain-programs/overview.md b/docs/src/developing/on-chain-programs/overview.md index ea2cf2fe3..d87b6e5ff 100644 --- a/docs/src/developing/on-chain-programs/overview.md +++ b/docs/src/developing/on-chain-programs/overview.md @@ -1,218 +1,64 @@ --- -title: "Overview" +title: "Overview of Writing Programs" +sidebar_label: "Overview" --- -Developers can write and deploy their own programs to the Solana blockchain. +Developers can write and deploy their own programs to the Solana blockchain. While developing these "on-chain" programs can seem cumbersome, the entire process can be broadly summarized into a few key steps. -The [Helloworld example](examples.md#helloworld) is a good starting place to see -how a program is written, built, deployed, and interacted with on-chain. +## Solana Development Lifecycle -## Berkeley Packet Filter (BPF) +1. Setup your development environment +2. Write your program +3. Compile the program +4. Generate the program's public address +5. Deploy the program -Solana on-chain programs are compiled via the [LLVM compiler -infrastructure](https://llvm.org/) to an [Executable and Linkable Format -(ELF)](https://en.wikipedia.org/wiki/Executable_and_Linkable_Format) containing -a variation of the [Berkeley Packet Filter -(BPF)](https://en.wikipedia.org/wiki/Berkeley_Packet_Filter) bytecode. +### 1. Setup your development environment -Because Solana uses the LLVM compiler infrastructure, a program may be written -in any programming language that can target the LLVM's BPF backend. Solana -currently supports writing programs in Rust and C/C++. +The most robust way of getting started with Solana development, is [installing the Solana CLI](./../../cli/install-solana-cli-tools.md) tools on your local computer. This will allow you to have the most powerful development environment. -BPF provides an efficient [instruction -set](https://github.com/iovisor/bpf-docs/blob/master/eBPF.md) that can be -executed in an interpreted virtual machine or as efficient just-in-time compiled -native instructions. +Some developers may also opt for using [Solana Playground](https://beta.solpg.io/), a browser based IDE. It will let you write, build, and deploy on-chain programs. All from your browser. No installation needed. -## Memory map +### 2. Write your program -The virtual address memory map used by Solana SBF programs is fixed and laid out -as follows +Writing Solana programs is most commonly done so using the Rust language. These Rust programs are effectively the same as creating a traditional [Rust library](https://doc.rust-lang.org/rust-by-example/crates/lib.html). -- Program code starts at 0x100000000 -- Stack data starts at 0x200000000 -- Heap data starts at 0x300000000 -- Program input parameters start at 0x400000000 +> You can read more about other [supported languages](#support-languages) below. -The above virtual addresses are start addresses but programs are given access to -a subset of the memory map. The program will panic if it attempts to read or -write to a virtual address that it was not granted access to, and an -`AccessViolation` error will be returned that contains the address and size of -the attempted violation. +### 3. Compile the program -## Stack +Once the program is written, it must be complied down to [Berkley Packet Filter](./faq.md#berkeley-packet-filter-bpf) byte-code that will then be deployed to the blockchain. -SBF uses stack frames instead of a variable stack pointer. Each stack frame is -4KB in size. +### 4. Generate the program's public address -If a program violates that stack frame size, the compiler will report the -overrun as a warning. +Using the [Solana CLI](./../../cli/install-solana-cli-tools.md), the developer will generate a new unique [Keypair](./../../terminology.md#keypair) for the new program. The public address (aka [Pubkey](./../../terminology.md#public-key-pubkey)) from this Keypair will be used on-chain as the program's public address (aka [`programId`](./../../terminology.md#program-id)). -For example: `Error: Function _ZN16curve25519_dalek7edwards21EdwardsBasepointTable6create17h178b3d2411f7f082E Stack offset of -30728 exceeded max offset of -4096 by 26632 bytes, please minimize large stack variables` +### 5. Deploying the program -The message identifies which symbol is exceeding its stack frame but the name -might be mangled if it is a Rust or C++ symbol. To demangle a Rust symbol use -[rustfilt](https://github.com/luser/rustfilt). The above warning came from a -Rust program, so the demangled symbol name is: +Then again using the CLI, the compiled program can be deployed to the selected blockchain cluster by creating many transactions containing the program's byte-code. Due to the transaction memory size limitations, each transaction effectively sends small chunks of the program to the blockchain in a rapid-fire manner. -```bash -$ rustfilt _ZN16curve25519_dalek7edwards21EdwardsBasepointTable6create17h178b3d2411f7f082E -curve25519_dalek::edwards::EdwardsBasepointTable::create -``` +Once the entire program has been sent to the blockchain, a final transaction is sent to write all of the buffered byte-code to the program's data account. This either mark the new program as [`executable`](./../programming-model/accounts.md#executable), or complete the process to upgrade an existing program (if it already existed). -To demangle a C++ symbol use `c++filt` from binutils. +## Support languages -The reason a warning is reported rather than an error is because some dependent -crates may include functionality that violates the stack frame restrictions even -if the program doesn't use that functionality. If the program violates the stack -size at runtime, an `AccessViolation` error will be reported. +Solana programs are typically written in the [Rust language](./developing-rust.md), but [C/C++](./developing-c.md) are also supported. -SBF stack frames occupy a virtual address range starting at 0x200000000. +There are also various community driven efforts to enable writing on-chain programs using other languages, including: -## Call Depth +- Python via [Seahorse](https://seahorse-lang.org/) (that acts as a wrapper the Rust based Anchor framework) -Programs are constrained to run quickly, and to facilitate this, the program's -call stack is limited to a max depth of 64 frames. +## Example programs -## Heap +The [Hello world example](examples.md#helloworld) is a good starting place to see how a program is written, built, deployed, and interacted with on-chain. -Programs have access to a runtime heap either directly in C or via the Rust -`alloc` APIs. To facilitate fast allocations, a simple 32KB bump heap is -utilized. The heap does not support `free` or `realloc` so use it wisely. +You can also explore the [Program Examples](./examples.md) for other examples of on-chain programs. -Internally, programs have access to the 32KB memory region starting at virtual -address 0x300000000 and may implement a custom heap based on the program's -specific needs. +## Limitations -- [Rust program heap usage](developing-rust.md#heap) -- [C program heap usage](developing-c.md#heap) +As you dive deeper into program development, it is important to understand some of the important limitations associated with on-chain programs. -## Float Support +Read more details on the [Limitations](./limitations.md) page -Programs support a limited subset of Rust's float operations, if a program -attempts to use a float operation that is not supported, the runtime will report -an unresolved symbol error. +## Frequently asked questions -Float operations are performed via software libraries, specifically LLVM's float -builtins. Due to the software emulated they consume more compute units than -integer operations. In general, fixed point operations are recommended where -possible. - -The Solana Program Library math tests will report the performance of some math -operations: -https://github.com/solana-labs/solana-program-library/tree/master/libraries/math - -To run the test, sync the repo, and run: - -`$ cargo test-bpf -- --nocapture --test-threads=1` - -Recent results show the float operations take more instructions compared to -integers equivalents. Fixed point implementations may vary but will also be -less than the float equivalents: - -``` - u64 f32 -Multipy 8 176 -Divide 9 219 -``` - -## Static Writable Data - -Program shared objects do not support writable shared data. Programs are shared -between multiple parallel executions using the same shared read-only code and -data. This means that developers should not include any static writable or -global variables in programs. In the future a copy-on-write mechanism could be -added to support writable data. - -## Signed division - -The SBF instruction set does not support [signed -division](https://www.kernel.org/doc/html/latest/bpf/bpf_design_QA.html#q-why-there-is-no-bpf-sdiv-for-signed-divide-operation). -Adding a signed division instruction is a consideration. - -## Loaders - -Programs are deployed with and executed by runtime loaders, currently there are -two supported loaders [BPF -Loader](https://github.com/solana-labs/solana/blob/7ddf10e602d2ed87a9e3737aa8c32f1db9f909d8/sdk/program/src/bpf_loader.rs#L17) -and [BPF loader -deprecated](https://github.com/solana-labs/solana/blob/7ddf10e602d2ed87a9e3737aa8c32f1db9f909d8/sdk/program/src/bpf_loader_deprecated.rs#L14) - -Loaders may support different application binary interfaces so developers must -write their programs for and deploy them to the same loader. If a program -written for one loader is deployed to a different one the result is usually a -`AccessViolation` error due to mismatched deserialization of the program's input -parameters. - -For all practical purposes program should always be written to target the latest -BPF loader and the latest loader is the default for the command-line interface -and the javascript APIs. - -For language specific information about implementing a program for a particular -loader see: - -- [Rust program entrypoints](developing-rust.md#program-entrypoint) -- [C program entrypoints](developing-c.md#program-entrypoint) - -### Deployment - -SBF program deployment is the process of uploading a BPF shared object into a -program account's data and marking the account executable. A client breaks the -SBF shared object into smaller pieces and sends them as the instruction data of -[`Write`](https://github.com/solana-labs/solana/blob/bc7133d7526a041d1aaee807b80922baa89b6f90/sdk/program/src/loader_instruction.rs#L13) -instructions to the loader where loader writes that data into the program's -account data. Once all the pieces are received the client sends a -[`Finalize`](https://github.com/solana-labs/solana/blob/bc7133d7526a041d1aaee807b80922baa89b6f90/sdk/program/src/loader_instruction.rs#L30) -instruction to the loader, the loader then validates that the SBF data is valid -and marks the program account as _executable_. Once the program account is -marked executable, subsequent transactions may issue instructions for that -program to process. - -When an instruction is directed at an executable SBF program the loader -configures the program's execution environment, serializes the program's input -parameters, calls the program's entrypoint, and reports any errors encountered. - -For further information see [deploying](deploying.md) - -### Input Parameter Serialization - -SBF loaders serialize the program input parameters into a byte array that is -then passed to the program's entrypoint, where the program is responsible for -deserializing it on-chain. One of the changes between the deprecated loader and -the current loader is that the input parameters are serialized in a way that -results in various parameters falling on aligned offsets within the aligned byte -array. This allows deserialization implementations to directly reference the -byte array and provide aligned pointers to the program. - -For language specific information about serialization see: - -- [Rust program parameter - deserialization](developing-rust.md#parameter-deserialization) -- [C program parameter - deserialization](developing-c.md#parameter-deserialization) - -The latest loader serializes the program input parameters as follows (all -encoding is little endian): - -- 8 bytes unsigned number of accounts -- For each account - - 1 byte indicating if this is a duplicate account, if not a duplicate then - the value is 0xff, otherwise the value is the index of the account it is a - duplicate of. - - If duplicate: 7 bytes of padding - - If not duplicate: - - 1 byte boolean, true if account is a signer - - 1 byte boolean, true if account is writable - - 1 byte boolean, true if account is executable - - 4 bytes of padding - - 32 bytes of the account public key - - 32 bytes of the account's owner public key - - 8 bytes unsigned number of lamports owned by the account - - 8 bytes unsigned number of bytes of account data - - x bytes of account data - - 10k bytes of padding, used for realloc - - enough padding to align the offset to 8 bytes. - - 8 bytes rent epoch -- 8 bytes of unsigned number of instruction data -- x bytes of instruction data -- 32 bytes of the program id +Discover many of the [frequently asked questions](./faq.md) other developers have about writing/understanding Solana programs. diff --git a/docs/src/getstarted/rust.md b/docs/src/getstarted/rust.md index 167580a97..a9956c56c 100644 --- a/docs/src/getstarted/rust.md +++ b/docs/src/getstarted/rust.md @@ -43,7 +43,7 @@ solana config set --url localhost ## Create a new Rust library with Cargo -Solana programs written in Rust are _libraries_ which are compiled to [BPF bytecode](../developing/on-chain-programs/overview#berkeley-packet-filter-bpf) and saved in the `.so` format. +Solana programs written in Rust are _libraries_ which are compiled to [BPF bytecode](../developing/on-chain-programs/faq.md#berkeley-packet-filter-bpf) and saved in the `.so` format. Initialize a new Rust library named `hello_world` via the Cargo command line: diff --git a/docs/src/terminology.md b/docs/src/terminology.md index bf12e6734..f72c56900 100644 --- a/docs/src/terminology.md +++ b/docs/src/terminology.md @@ -48,7 +48,7 @@ The [validator](#validator) that produces the genesis (first) [block](#block) of ## BPF loader -The Solana program that owns and loads [BPF](developing/on-chain-programs/overview#berkeley-packet-filter-bpf) smart contract programs, allowing the program to interface with the runtime. +The Solana program that owns and loads [BPF](developing/on-chain-programs/faq#berkeley-packet-filter-bpf) smart contract programs, allowing the program to interface with the runtime. ## client @@ -259,7 +259,7 @@ See also [rent exempt](#rent-exempt) below. Learn more about rent here: [What is ## rent exempt -Accounts that maintain more than 2 years with of rent payments in their account are considered "*rent exempt*" and will not incur the [collection of rent](../src/developing/intro/rent.md#collecting-rent). +Accounts that maintain more than 2 years with of rent payments in their account are considered "_rent exempt_" and will not incur the [collection of rent](../src/developing/intro/rent.md#collecting-rent). ## root