Docs cleanup (#16964)

* Run lint:fix on docs

* Update dependencies

* Run prettier

* Run lint
This commit is contained in:
Justin Starry
2021-04-30 16:20:56 +08:00
committed by GitHub
parent 3d98321b38
commit 545e037e38
53 changed files with 23895 additions and 5418 deletions

View File

@@ -19,7 +19,7 @@ and so this document attempts to clarify and codify the process for new releases
1. In any `PATCH` or `MINOR` release, a feature, API, endpoint, etc. could be marked as deprecated.
2. According to code upgrade difficulty, some features will be remain deprecated for a few release
cycles.
cycles.
3. In a future `MAJOR` release, deprecated features will be removed in an incompatible way.
### Release Cadence
@@ -57,46 +57,55 @@ release channels.
### RPC API
Patch releases:
- Bug fixes
- Security fixes
- Endpoint / feature deprecation
Minor releases:
- New RPC endpoints and features
Major releases:
- Removal of deprecated features
### Rust Crates
* [`solana-sdk`](https://docs.rs/solana-sdk/) - Rust SDK for creating transactions and parsing account state
* [`solana-program`](https://docs.rs/solana-program/) - Rust SDK for writing programs
* [`solana-client`](https://docs.rs/solana-client/) - Rust client for connecting to RPC API
* [`solana-cli-config`](https://docs.rs/solana-cli-config/) - Rust client for managing Solana CLI config files
- [`solana-sdk`](https://docs.rs/solana-sdk/) - Rust SDK for creating transactions and parsing account state
- [`solana-program`](https://docs.rs/solana-program/) - Rust SDK for writing programs
- [`solana-client`](https://docs.rs/solana-client/) - Rust client for connecting to RPC API
- [`solana-cli-config`](https://docs.rs/solana-cli-config/) - Rust client for managing Solana CLI config files
Patch releases:
- Bug fixes
- Security fixes
- Performance improvements
Minor releases:
- New APIs
Major releases
- Removal of deprecated APIs
- Backwards incompatible behavior changes
### CLI Tools
Patch releases:
- Bug and security fixes
- Performance improvements
- Subcommand / argument deprecation
Minor releases:
- New subcommands
Major releases:
- Switch to new RPC API endpoints / configuration introduced in the previous major version.
- Removal of deprecated features
@@ -111,7 +120,7 @@ The release process is as follows:
1. New runtime feature is included in a new release, deactivated by default
2. Once sufficient staked validators upgrade to the new release, the runtime feature switch
is activated manually with an instruction
is activated manually with an instruction
3. The feature takes effect at the beginning of the next epoch
### Infrastructure Changes

View File

@@ -19,17 +19,17 @@ messages.
For information about how to log from a program see the language specific
documentation:
- [Logging from a Rust program](developing-rust.md#logging)
- [Logging from a C program](developing-c.md#logging)
When running a local cluster the logs are written to stdout as long as they are
enabled via the `RUST_LOG` log mask. From the perspective of program
enabled via the `RUST_LOG` log mask. From the perspective of program
development it is helpful to focus on just the runtime and program logs and not
the rest of the cluster logs. To focus in on program specific information the
the rest of the cluster logs. To focus in on program specific information the
following log mask is recommended:
`export
RUST_LOG=solana_runtime::system_instruction_processor=trace,solana_runtime::message_processor=info,solana_bpf_loader=debug,solana_rbpf=debug`
`export RUST_LOG=solana_runtime::system_instruction_processor=trace,solana_runtime::message_processor=info,solana_bpf_loader=debug,solana_rbpf=debug`
Log messages coming directly from the program (not the runtime) will be
displayed in the form:
@@ -39,24 +39,25 @@ displayed in the form:
## Error Handling
The amount of information that can be communicated via a transaction error is
limited but there are many points of possible failures. The following are
limited but there are many points of possible failures. The following are
possible failure points and information about what errors to expect and where to
get more information:
- The BPF loader may fail to parse the program, this should not happen since the
loader has already _finalized_ the program's account data.
- `InstructionError::InvalidAccountData` will be returned as part of the
transaction error.
- The BPF loader may fail to setup the program's execution environment
- `InstructionError::Custom(0x0b9f_0001)` will be returned as part of the
transaction error. "0x0b9f_0001" is the hexadecimal representation of
transaction error. "0x0b9f_0001" is the hexadecimal representation of
[`VirtualMachineCreationFailed`](https://github.com/solana-labs/solana/blob/bc7133d7526a041d1aaee807b80922baa89b6f90/programs/bpf_loader/src/lib.rs#L44).
- The BPF loader may have detected a fatal error during program executions
(things like panics, memory violations, system call errors, etc...)
- `InstructionError::Custom(0x0b9f_0002)` will be returned as part of the
transaction error. "0x0b9f_0002" is the hexadecimal representation of
[`VirtualMachineFailedToRunProgram`](https://github.com/solana-labs/solana/blob/bc7133d7526a041d1aaee807b80922baa89b6f90/programs/bpf_loader/src/lib.rs#L46).
transaction error. "0x0b9f_0002" is the hexadecimal representation of
[`VirtualMachineFailedToRunProgram`](https://github.com/solana-labs/solana/blob/bc7133d7526a041d1aaee807b80922baa89b6f90/programs/bpf_loader/src/lib.rs#L46).
- The program itself may return an error
- `InstructionError::Custom(<user defined value>)` will be returned. The
- `InstructionError::Custom(<user defined value>)` will be returned. The
"user defined value" must not conflict with any of the [builtin runtime
program
errors](https://github.com/solana-labs/solana/blob/bc7133d7526a041d1aaee807b80922baa89b6f90/sdk/program/src/program_error.rs#L87).
@@ -70,13 +71,12 @@ logs](debugging.md#logging).
For example, an access violation involving the stack will look something like
this:
`BPF program 4uQeVj5tqViQh7yWWGStvkEG1Zmhx6uasJtWCJziofM failed: out of bounds
memory store (insn #615), addr 0x200001e38/8 `
`BPF program 4uQeVj5tqViQh7yWWGStvkEG1Zmhx6uasJtWCJziofM failed: out of bounds memory store (insn #615), addr 0x200001e38/8`
## Monitoring Compute Budget Consumption
The program can log the remaining number of compute units it will be allowed
before program execution is halted. Programs can use these logs to wrap
before program execution is halted. Programs can use these logs to wrap
operations they wish to profile.
- [Log the remaining compute units from a Rust
@@ -99,13 +99,13 @@ insight into a program's composition and what it may be doing at runtime.
## Instruction Tracing
During execution the runtime BPF interpreter can be configured to log a trace
message for each BPF instruction executed. This can be very helpful for things
message for each BPF instruction executed. This can be very helpful for things
like pin-pointing the runtime context leading up to a memory access violation.
The trace logs together with the [ELF dump](#elf-dump) can provide a lot of
insight (though the traces produce a lot of information).
To turn on BPF interpreter trace messages in a local cluster configure the
`solana_rbpf` level in `RUST_LOG` to `trace`. For example:
`solana_rbpf` level in `RUST_LOG` to `trace`. For example:
`export RUST_LOG=solana_rbpf=trace`

View File

@@ -11,7 +11,7 @@ clients via a _program ID_. The program ID is an _address_ specified when
deploying and is used to reference the program in subsequent transactions.
Upon a successful deployment the account that holds the program is marked
executable and its account data become permanently immutable. If any changes
executable and its account data become permanently immutable. If any changes
are required to the program (features, patches, etc...) the new program must be
deployed to a new program ID.

View File

@@ -31,11 +31,13 @@ for an example of a C program.
## How to Build
First setup the environment:
- Install the latest Rust stable from https://rustup.rs
- Install the latest Solana command-line tools from
https://docs.solana.com/cli/install-solana-cli-tools
Then build using make:
```bash
make -C <program directory>
```
@@ -46,8 +48,7 @@ Solana uses the [Criterion](https://github.com/Snaipe/Criterion) test framework
and tests are executed each time the program is built [How to
Build](#how-to-build)].
To add tests, create a new file next to your source file named `test_<program
name>.c` and populate it with criterion test cases. For an example see the
To add tests, create a new file next to your source file named `test_<program name>.c` and populate it with criterion test cases. For an example see the
[helloworld C
tests](https://github.com/solana-labs/example-helloworld/blob/master/src/program-c/src/helloworld/test_helloworld.c)
or the [Criterion docs](https://criterion.readthedocs.io/en/master) for
@@ -56,9 +57,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 BPF
calls when invoking a program. Solana supports multiple [versions of the BPF
loader](overview.md#versions) and the entrypoints may vary between them.
Programs must be written for and deployed to the same loader. For more details
Programs must be written for and deployed to the same loader. For more details
see the [overview](overview#loaders).
Currently there are two supported loaders [BPF
@@ -74,7 +75,7 @@ extern uint64_t entrypoint(const uint8_t *input)
```
This entrypoint takes a generic byte array which contains the serialized program
parameters (program id, accounts, instruction data, etc...). To deserialize the
parameters (program id, accounts, instruction data, etc...). To deserialize the
parameters each loader contains its own [helper function](#Serialization).
Refer to [helloworld's use of the
@@ -88,6 +89,7 @@ function](https://github.com/solana-labs/example-helloworld/blob/bc0b25c0ccebeff
Each loader provides a helper function that deserializes the program's input
parameters into C types:
- [BPF Loader
deserialization](https://github.com/solana-labs/solana/blob/d2ee9db2143859fa5dc26b15ee6da9c25cc0429c/sdk/bpf/c/inc/solana_sdk.h#L304)
- [BPF Loader deprecated
@@ -97,8 +99,8 @@ Some programs may want to perform deserialzaiton themselves and they can by
providing their own implementation of the [raw entrypoint](#program-entrypoint).
Take note that the provided deserialization functions retain references back to
the serialized byte array for variables that the program is allowed to modify
(lamports, account data). The reason for this is that upon return the loader
will read those modifications so they may be committed. If a program implements
(lamports, account data). The reason for this is that upon return the loader
will read those modifications so they may be committed. If a program implements
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.
@@ -128,18 +130,18 @@ typedef struct {
'ka' is an ordered array of the accounts referenced by the instruction and
represented as a
[SolAccountInfo](https://github.com/solana-labs/solana/blob/8415c22b593f164020adc7afe782e8041d756ddf/sdk/bpf/c/inc/solana_sdk.h#L173)
structures. An account's place in the array signifies its meaning, for example,
structures. An account's place in the array signifies its meaning, for example,
when transferring lamports an instruction may define the first account as the
source and the second as the destination.
The members of the `SolAccountInfo` structure are read-only except for
`lamports` and `data`. Both may be modified by the program in accordance with
`lamports` and `data`. Both may be modified by the program in accordance with
the [runtime enforcement
policy](developing/programming-model/accounts.md#policy). When an instruction
policy](developing/programming-model/accounts.md#policy). When an instruction
reference the same account multiple times there may be duplicate
`SolAccountInfo` entries in the array but they both point back to the original
input byte array. A program should handle these case delicately to avoid
overlapping read/writes to the same buffer. If a program implements their own
input byte array. A program should handle these case delicately to avoid
overlapping read/writes to the same buffer. If a program implements their own
deserialization function care should be taken to handle duplicate accounts
appropriately.
@@ -154,7 +156,7 @@ processed.
C programs can allocate memory via the system call
[`calloc`](https://github.com/solana-labs/solana/blob/c3d2d2134c93001566e1e56f691582f379b5ae55/sdk/bpf/c/inc/solana_sdk.h#L245)
or implement their own heap on top of the 32KB heap region starting at virtual
address x300000000. The heap region is also used by `calloc` so if a program
address x300000000. The heap region is also used by `calloc` so if a program
implements their own heap it should not also call `calloc`.
## Logging
@@ -162,10 +164,8 @@ implements their own heap it should not also call `calloc`.
The runtime provides two system calls that take data and log it to the program
logs.
- [`sol_log(const
char*)`](https://github.com/solana-labs/solana/blob/d2ee9db2143859fa5dc26b15ee6da9c25cc0429c/sdk/bpf/c/inc/solana_sdk.h#L128)
- [`sol_log_64(uint64_t, uint64_t, uint64_t, uint64_t,
uint64_t)`](https://github.com/solana-labs/solana/blob/d2ee9db2143859fa5dc26b15ee6da9c25cc0429c/sdk/bpf/c/inc/solana_sdk.h#L134)
- [`sol_log(const char*)`](https://github.com/solana-labs/solana/blob/d2ee9db2143859fa5dc26b15ee6da9c25cc0429c/sdk/bpf/c/inc/solana_sdk.h#L128)
- [`sol_log_64(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t)`](https://github.com/solana-labs/solana/blob/d2ee9db2143859fa5dc26b15ee6da9c25cc0429c/sdk/bpf/c/inc/solana_sdk.h#L134)
The [debugging](debugging.md#logging) section has more information about working
with program logs.
@@ -184,9 +184,9 @@ for more information.
## ELF Dump
The BPF shared object internals can be dumped to a text file to gain more
insight into a program's composition and what it may be doing at runtime. The
insight into a program's composition and what it may be doing at runtime. The
dump will contain both the ELF information as well as a list of all the symbols
and the instructions that implement them. Some of the BPF loader's error log
and the instructions that implement them. Some of the BPF loader's error log
messages will reference specific instruction numbers where the error occurred.
These references can be looked up in the ELF dump to identify the offending
instruction and its context.

View File

@@ -17,10 +17,13 @@ layout](https://doc.rust-lang.org/cargo/guide/project-layout.html):
```
But must also include:
```
/Xargo.toml
```
Which must contain:
```
[target.bpfel-unknown-unknown.dependencies.std]
features = []
@@ -30,7 +33,7 @@ Solana Rust programs may depend directly on each other in order to gain access
to instruction helpers when making [cross-program
invocations](developing/../../programming-model/calling-between-programs.md#cross-program-invocations).
When doing so it's important to not pull in the dependent program's entrypoint
symbols because they may conflict with the program's own. To avoid this,
symbols because they may conflict with the program's own. To avoid this,
programs should define an `exclude_entrypoint` feature in `Cargo.toml` and use
to exclude the entrypoint.
@@ -41,6 +44,7 @@ to exclude the entrypoint.
Then when other programs include this program as a dependency, they should do so
using the `exclude_entrypoint` feature.
- [Include without
entrypoint](https://github.com/solana-labs/solana-program-library/blob/a5babd6cbea0d3f29d8c57d2ecbbd2a2bd59c8a9/token-swap/program/Cargo.toml#L19)
@@ -53,19 +57,21 @@ Solana BPF programs have some [restrictions](#restrictions) that may prevent the
inclusion of some crates as dependencies or require special handling.
For example:
- Crates that require the architecture be a subset of the ones supported by the
official toolchain. There is no workaround for this unless that crate is
official toolchain. There is no workaround for this unless that crate is
forked and BPF added to that those architecture checks.
- Crates may depend on `rand` which is not supported in Solana's deterministic
program environment. To include a `rand` dependent crate refer to [Depending
program environment. To include a `rand` dependent crate refer to [Depending
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
included in the program itself. For more information refer to
[Stack](overview.md#stack).
## How to Build
First setup the environment:
- Install the latest Rust stable from https://rustup.rs/
- Install the latest Solana command-line tools from
https://docs.solana.com/cli/install-solana-cli-tools
@@ -92,7 +98,7 @@ exercising program functions directly.
To help facilitate testing in an environment that more closely matches a live
cluster, developers can use the
[`program-test`](https://crates.io/crates/solana-program-test) crate. The
[`program-test`](https://crates.io/crates/solana-program-test) crate. The
`program-test` crate starts up a local instance of the runtime and allows tests
to send multiple transactions while keeping state for the duration of the test.
@@ -104,9 +110,9 @@ 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
calls when invoking a program. Solana supports multiple [versions of the BPF
loader](overview.md#versions) and the entrypoints may vary between them.
Programs must be written for and deployed to the same loader. For more details
Programs must be written for and deployed to the same loader. For more details
see the [overview](overview#loaders).
Currently there are two supported loaders [BPF
@@ -123,12 +129,13 @@ pub unsafe extern "C" fn entrypoint(input: *mut u8) -> u64;
```
This entrypoint takes a generic byte array which contains the serialized program
parameters (program id, accounts, instruction data, etc...). To deserialize the
parameters (program id, accounts, instruction data, etc...). To deserialize the
parameters each loader contains its own wrapper macro that exports the raw
entrypoint, deserializes the parameters, calls a user defined instruction
processing function, and returns the results.
You can find the entrypoint macros here:
- [BPF Loader's entrypoint
macro](https://github.com/solana-labs/solana/blob/7ddf10e602d2ed87a9e3737aa8c32f1db9f909d8/sdk/program/src/entrypoint.rs#L46)
- [BPF Loader deprecated's entrypoint
@@ -149,8 +156,9 @@ as an example of how things fit together.
### Parameter Deserialization
Each loader provides a helper function that deserializes the program's input
parameters into Rust types. The entrypoint macros automatically calls the
parameters into Rust types. The entrypoint macros automatically calls the
deserialization helper:
- [BPF Loader
deserialization](https://github.com/solana-labs/solana/blob/7ddf10e602d2ed87a9e3737aa8c32f1db9f909d8/sdk/program/src/entrypoint.rs#L104)
- [BPF Loader deprecated
@@ -160,8 +168,8 @@ Some programs may want to perform deserialization themselves and they can by
providing their own implementation of the [raw entrypoint](#program-entrypoint).
Take note that the provided deserialization functions retain references back to
the serialized byte array for variables that the program is allowed to modify
(lamports, account data). The reason for this is that upon return the loader
will read those modifications so they may be committed. If a program implements
(lamports, account data). The reason for this is that upon return the loader
will read those modifications so they may be committed. If a program implements
their own deserialization function they need to ensure that any modifications
the program wishes to commit be written back into the input byte array.
@@ -184,19 +192,19 @@ The program id is the public key of the currently executing program.
The accounts is an ordered slice of the accounts referenced by the instruction
and represented as an
[AccountInfo](https://github.com/solana-labs/solana/blob/7ddf10e602d2ed87a9e3737aa8c32f1db9f909d8/sdk/program/src/account_info.rs#L10)
structures. An account's place in the array signifies its meaning, for example,
structures. An account's place in the array signifies its meaning, for example,
when transferring lamports an instruction may define the first account as the
source and the second as the destination.
The members of the `AccountInfo` structure are read-only except for `lamports`
and `data`. Both may be modified by the program in accordance with the [runtime
enforcement policy](developing/programming-model/accounts.md#policy). Both of
and `data`. Both may be modified by the program in accordance with the [runtime
enforcement policy](developing/programming-model/accounts.md#policy). Both of
these members are protected by the Rust `RefCell` construct, so they must be
borrowed to read or write to them. The reason for this is they both point back
borrowed to read or write to them. The reason for this is they both point back
to the original input byte array, but there may be multiple entries in the
accounts slice that point to the same account. Using `RefCell` ensures that the
accounts slice that point to the same account. Using `RefCell` ensures that the
program does not accidentally perform overlapping read/writes to the same
underlying data via multiple `AccountInfo` structures. If a program implements
underlying data via multiple `AccountInfo` structures. If a program implements
their own deserialization function care should be taken to handle duplicate
accounts appropriately.
@@ -242,7 +250,7 @@ single-threaded environment, and must be deterministic:
- No support for `println!`, `print!`, the Solana [logging helpers](#logging)
should be used instead.
- The runtime enforces a limit on the number of instructions a program can
execute during the processing of one instruction. See [computation
execute during the processing of one instruction. See [computation
budget](developing/programming-model/runtime.md#compute-budget) for more
information.
@@ -274,7 +282,7 @@ getrandom = { version = "0.1.14", features = ["dummy"] }
## Logging
Rust's `println!` macro is computationally expensive and not supported. Instead
Rust's `println!` macro is computationally expensive and not supported. Instead
the helper macro
[`msg!`](https://github.com/solana-labs/solana/blob/6705b5a98c076ac08f3991bb8a6f9fcb280bf51e/sdk/program/src/log.rs#L33)
is provided.
@@ -284,12 +292,14 @@ is provided.
```rust
msg!("A string");
```
or
```rust
msg!(0_64, 1_64, 2_64, 3_64, 4_64);
```
Both forms output the results to the program logs. If a program so wishes they
Both forms output the results to the program logs. If a program so wishes they
can emulate `println!` by using `format!`:
```rust
@@ -343,10 +353,10 @@ replace that with something that better suits their needs.
One of the side effects of supporting full panic messages by default is that
programs incur the cost of pulling in more of Rust's `libstd` implementation
into program's shared object. Typical programs will already be pulling in a
into program's shared object. Typical programs will already be pulling in a
fair amount of `libstd` and may not notice much of an increase in the shared
object size. But programs that explicitly attempt to be very small by avoiding
`libstd` may take a significant impact (~25kb). To eliminate that impact,
object size. But programs that explicitly attempt to be very small by avoiding
`libstd` may take a significant impact (~25kb). To eliminate that impact,
programs can provide their own custom panic handler with an empty
implementation.
@@ -372,9 +382,9 @@ for more information.
## ELF Dump
The BPF shared object internals can be dumped to a text file to gain more
insight into a program's composition and what it may be doing at runtime. The
insight into a program's composition and what it may be doing at runtime. The
dump will contain both the ELF information as well as a list of all the symbols
and the instructions that implement them. Some of the BPF loader's error log
and the instructions that implement them. Some of the BPF loader's error log
messages will reference specific instruction numbers where the error occurred.
These references can be looked up in the ELF dump to identify the offending
instruction and its context.

View File

@@ -2,7 +2,6 @@
title: "Examples"
---
## Helloworld
Hello World is a project that demonstrates how to use the Solana Javascript API
@@ -10,9 +9,10 @@ and both Rust and C programs to build, deploy, and interact with programs on the
Solana blockchain.
The project comprises of:
- An on-chain hello world program
- A client that can send a "hello" to an account and get back the number of
times "hello" has been sent
- An on-chain hello world program
- A client that can send a "hello" to an account and get back the number of
times "hello" has been sent
### Build and Run
@@ -26,7 +26,6 @@ $ cd example-helloworld
Next, follow the steps in the git repository's
[README](https://github.com/solana-labs/example-helloworld/blob/master/README.md).
## Break
[Break](https://break.solana.com/) is a React app that gives users a visceral

View File

@@ -78,4 +78,4 @@ See [Rust restrictions](developing-rust.md#restrictions)
## Stack size
See [stack](overview.md#stack)
See [stack](overview.md#stack)

View File

@@ -35,7 +35,7 @@ as follows
- Program input parameters start at 0x400000000
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
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.
@@ -48,14 +48,11 @@ BPF uses stack frames instead of a variable stack pointer. Each stack frame is
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`
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
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
@@ -97,8 +94,8 @@ 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
builtins. Due to be software emulated they consume more compute units than
integer operations. In general, fixed point operations are recommended where
builtins. Due to be 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
@@ -110,7 +107,7 @@ 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
integers equivalents. Fixed point implementations may vary but will also be
less then the float equivalents:
```
@@ -121,7 +118,7 @@ Divide 9 219
## Static Writable Data
Program shared objects do not support writable shared data. Programs are shared
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
@@ -142,7 +139,7 @@ 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
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.
@@ -153,20 +150,21 @@ 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
BPF 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
program account's data and marking the account executable. A client breaks the
BPF 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
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 BPF data is valid
and marks the program account as _executable_. Once the program account is
and marks the program account as _executable_. Once the program account is
marked executable, subsequent transactions may issue instructions for that
program to process.
@@ -180,13 +178,14 @@ For further information see [deploying](deploying.md)
BPF 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
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
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

View File

@@ -14,7 +14,7 @@ Unlike a file, the account includes metadata for the lifetime of the file. That
lifetime is expressed in "tokens", which is a number of fractional native
tokens, called _lamports_. Accounts are held in validator memory and pay
["rent"](#rent) to stay there. Each validator periodically scans all accounts
and collects rent. Any account that drops to zero lamports is purged. Accounts
and collects rent. Any account that drops to zero lamports is purged. Accounts
can also be marked [rent-exempt](#rent-exemption) if they contain a sufficient
number of lamports.
@@ -45,9 +45,9 @@ If an account is marked "executable" in its metadata then it is considered a
program which can be executed by including the account's public key an
instruction's [program id](transactions.md#program-id). Accounts are marked as
executable during a successful program deployment process by the loader that
owns the account. For example, during BPF program deployment, once the loader
owns the account. For example, during BPF program deployment, once the loader
has determined that the BPF bytecode in the account's data is valid, the loader
permanently marks the program account as executable. Once executable, the
permanently marks the program account as executable. Once executable, the
runtime enforces that the account's data (the program) is immutable.
## Creating
@@ -90,23 +90,23 @@ For security purposes, it is recommended that programs check the validity of any
account it reads but does not modify.
The security model enforces that an account's data can only be modified by the
account's `Owner` program. Doing so allows the program to trust that the data
passed to them via accounts they own will be in a known and valid state. The
account's `Owner` program. Doing so allows the program to trust that the data
passed to them via accounts they own will be in a known and valid state. The
runtime enforces this by rejecting any transaction containing a program that
attempts to write to an account it does not own. But, there are also cases
attempts to write to an account it does not own. But, there are also cases
where a program may merely read an account they think they own and assume the
data has only been written by themselves and thus is valid. But anyone can
data has only been written by themselves and thus is valid. But anyone can
issues instructions to a program, and the runtime does not know that those
accounts are expected to be owned by the program. Therefore a malicious user
accounts are expected to be owned by the program. Therefore a malicious user
could create accounts with arbitrary data and then pass these accounts to the
program in the place of a valid account. The arbitrary data could be crafted in
program in the place of a valid account. The arbitrary data could be crafted in
a way that leads to unexpected or harmful program behavior.
To check an account's validity, the program should either check the account's
address against a known value or check that the account is indeed owned
correctly (usually owned by the program itself).
One example is when programs read a sysvar. Unless the program checks the
One example is when programs read a sysvar. Unless the program checks the
address or owner, it's impossible to be sure whether it's a real and valid
sysvar merely by successful deserialization. Accordingly, the Solana SDK [checks
the sysvar's validity during
@@ -169,7 +169,6 @@ For example, an account is created with the initial transfer of 10,000 lamports
and no additional data. Rent is immediately debited from it on creation,
resulting in a balance of 7,561 lamports:
```text
Rent: 2,439 = 19.055441478439427 (rent rate) * 128 bytes (minimum account size) * 1 (epoch)
Account Balance: 7,561 = 10,000 (transfered lamports) - 2,439 (this account's rent fee for an epoch)

View File

@@ -5,8 +5,8 @@ title: Calling Between Programs
## Cross-Program Invocations
The Solana runtime allows programs to call each other via a mechanism called
cross-program invocation. Calling between programs is achieved by one program
invoking an instruction of the other. The invoking program is halted until the
cross-program invocation. Calling between programs is achieved by one program
invoking an instruction of the other. The invoking program is halted until the
invoked program finishes processing the instruction.
For example, a client could create a transaction that modifies two accounts,
@@ -57,7 +57,7 @@ given instruction to the `token` program via the instruction's `program_id`
field.
Note that `invoke` requires the caller to pass all the accounts required by the
instruction being invoked. This means that both the executable account (the
instruction being invoked. This means that both the executable account (the
ones that matches the instruction's program id) and the accounts passed to the
instruction procesor.
@@ -166,17 +166,17 @@ authority elsewhere at its discretion.
A Program address does not lie on the ed25519 curve and therefore has no valid
private key associated with it, and thus generating a signature for it is
impossible. While it has no private key of its own, it can be used by a program
impossible. While it has no private key of its own, it can be used by a program
to issue an instruction that includes the Program address as a signer.
### Hash-based generated program addresses
Program addresses are deterministically derived from a collection of seeds and a
program id using a 256-bit pre-image resistant hash function. Program address
program id using a 256-bit pre-image resistant hash function. Program address
must not lie on the ed25519 curve to ensure there is no associated private key.
During generation an error will be returned if the address is found to lie on
the curve. There is about a 50/50 change of this happening for a given
collection of seeds and program id. If this occurs a different set of seeds or
the curve. There is about a 50/50 change of this happening for a given
collection of seeds and program id. If this occurs a different set of seeds or
a seed bump (additional 8 bit seed) can be used to find a valid program address
off the curve.

View File

@@ -28,6 +28,7 @@ program only performed operations it was permitted to, and that the results
adhere to the runtime policy.
The policy is as follows:
- Only the owner of the account may change owner.
- And only if the account is writable.
- And only if the account is not executable
@@ -45,12 +46,13 @@ The policy is as follows:
## Compute Budget
To prevent a program from abusing computation resources each instruction in a
transaction is given a compute budget. The budget consists of computation units
transaction is given a compute budget. The budget consists of computation units
that are consumed as the program performs various operations and bounds that the
program may not exceed. When the program consumes its entire budget or exceeds
program may not exceed. When the program consumes its entire budget or exceeds
a bound then the runtime halts the program and returns an error.
The following operations incur a compute cost:
- Executing BPF instructions
- Calling system calls
- logging
@@ -59,7 +61,7 @@ The following operations incur a compute cost:
- ...
For cross-program invocations the programs invoked inherit the budget of their
parent. If an invoked program consume the budget or exceeds a bound the entire
parent. If an invoked program consume the budget or exceeds a bound the entire
invocation chain and the parent are halted.
The current [compute
@@ -81,6 +83,7 @@ log_pubkey_units: 100,
```
Then the program
- Could execute 200,000 BPF instructions if it does nothing else
- Could log 2,000 log messages
- Can not exceed 4k of stack usage
@@ -91,28 +94,28 @@ Since the compute budget is consumed incrementally as the program executes the
total budget consumption will be a combination of the various costs of the
operations it performs.
At runtime a program may log how much of the compute budget remains. See
At runtime a program may log how much of the compute budget remains. See
[debugging](developing/on-chain-programs/debugging.md#monitoring-compute-budget-consumption)
for more information.
The budget values are conditional on feature enablement, take a look the compute
budget's
[new](https://github.com/solana-labs/solana/blob/d3a3a7548c857f26ec2cb10e270da72d373020ec/sdk/src/process_instruction.rs#L97)
function to find out how the budget is constructed. An understanding of how
function to find out how the budget is constructed. An understanding of how
[features](runtime.md#features) work and what features are enabled on the
cluster being used are required to determine the current budget's values.
## New Features
As Solana evolves, new features or patches may be introduced that changes the
behavior of the cluster and how programs run. Changes in behavior must be
behavior of the cluster and how programs run. Changes in behavior must be
coordinated between the various nodes of the cluster, if nodes do not coordinate
then these changes can result in a break-down of consensus. Solana supports a
then these changes can result in a break-down of consensus. Solana supports a
mechanism called runtime features to facilitate the smooth adoption of changes.
Runtime features are epoch coordinated events where one or more behavior changes
to the cluster will occur. New changes to Solana that will change behavior are
wrapped with feature gates and disabled by default. The Solana tools are then
to the cluster will occur. New changes to Solana that will change behavior are
wrapped with feature gates and disabled by default. The Solana tools are then
used to activate a feature, which marks it pending, once marked pending the
feature will be activated at the next epoch.
@@ -124,5 +127,5 @@ solana feature status
```
If you encounter problems first ensure that the Solana tools version you are
using match the version returned by `solana cluster-version`. If they do not
using match the version returned by `solana cluster-version`. If they do not
match [install the correct tool suite](cli/install-solana-cli-tools.md).

View File

@@ -134,12 +134,11 @@ which loader should be used to load and execute the program and the data
contains information about how the runtime should execute the program.
In the case of [on-chain BPF programs](developing/on-chain-programs/overview.md),
the owner is the BPF Loader and the account data holds the BPF bytecode. Program
the owner is the BPF Loader and the account data holds the BPF bytecode. Program
accounts are permanently marked as executable by the loader once they are
successfully deployed. The runtime will reject transactions that specify programs
that are not executable.
Unlike on-chain programs, [Native Programs](/developing/runtime-facilities/programs)
are handled differently in that they are built directly into the Solana runtime.
@@ -173,21 +172,21 @@ token account states.
### Multiple instructions in a single transaction
A transaction can contain instructions in any order. This means a malicious
A transaction can contain instructions in any order. This means a malicious
user could craft transactions that may pose instructions in an order that the
program has not been protected against. Programs should be hardened to properly
program has not been protected against. Programs should be hardened to properly
and safely handle any possible instruction sequence.
One not so obvious example is account deinitialization. Some programs may
One not so obvious example is account deinitialization. Some programs may
attempt to deinitialize an account by setting its lamports to zero, with the
assumption that the runtime will delete the account. This assumption may be
assumption that the runtime will delete the account. This assumption may be
valid between transactions, but it is not between instructions or cross-program
invocations. To harden against this, the program should also explicitly zero out the
invocations. To harden against this, the program should also explicitly zero out the
account's data.
An example of where this could be a problem is if a token program, upon
transferring the token out of an account, sets the account's lamports to zero,
assuming it will be deleted by the runtime. If the program does not zero out the
assuming it will be deleted by the runtime. If the program does not zero out the
account's data, a malicious user could trail this instruction with another that
transfers the tokens a second time.
@@ -201,7 +200,6 @@ authorization to permit debiting the account or modifying its data. More
information about how the authorization is communicated to a program can be
found in [Accounts](accounts.md#signers)
## Recent Blockhash
A transaction includes a recent [blockhash](terminology.md#blockhash) to prevent

View File

@@ -88,6 +88,7 @@ struct Secp256k1SignatureOffsets {
```
Pseudo code of the operation:
```
process_instruction() {
for i in 0..count {

View File

@@ -12,7 +12,7 @@ and outlined below.
To include sysvar data in program operations, pass the sysvar account address in
the list of accounts in a transaction. The account can be read in your
instruction processor like any other account. Access to sysvars accounts ßis
always *readonly*.
always _readonly_.
## Clock
@@ -22,6 +22,7 @@ epoch, and estimated wall-clock Unix timestamp. It is updated every slot.
- Address: `SysvarC1ock11111111111111111111111111111111`
- Layout: [Clock](https://docs.rs/solana-program/VERSION_FOR_DOCS_RS/solana_program/clock/struct.Clock.html)
- Fields:
- `slot`: the current slot
- `epoch_start_timestamp`: the Unix timestamp of the first slot in this epoch. In the first slot of an epoch, this timestamp is identical to the `unix_timestamp` (below).
- `epoch`: the current epoch
@@ -48,8 +49,7 @@ epoch, and estimated wall-clock Unix timestamp. It is updated every slot.
The EpochSchedule sysvar contains epoch scheduling constants that are set in
genesis, and enables calculating the number of slots in a given epoch, the epoch
for a given slot, etc. (Note: the epoch schedule is distinct from the [`leader
schedule`](terminology.md#leader-schedule))
for a given slot, etc. (Note: the epoch schedule is distinct from the [`leader schedule`](terminology.md#leader-schedule))
- Address: `SysvarEpochSchedu1e111111111111111111111111`
- Layout: