Add programming faq (#12545)
* Add programming faq * feedback and new content * nudge
This commit is contained in:
parent
65cc6a69c8
commit
b51c0f3095
|
@ -0,0 +1,123 @@
|
||||||
|
---
|
||||||
|
title: "Programming FAQ"
|
||||||
|
---
|
||||||
|
|
||||||
|
When writing or interacting with Solana programs, there are common questions or
|
||||||
|
challenges that often come up. Below are resources to help answer these
|
||||||
|
questions. If not addressed here, the Solana
|
||||||
|
[#developers](https://discord.gg/RxeGBH) Discord channel is a great resource.
|
||||||
|
|
||||||
|
## CallDepth
|
||||||
|
|
||||||
|
Cross-program invocations allow programs to invoke other programs directly but
|
||||||
|
the depth is constrained currently to 1.
|
||||||
|
|
||||||
|
## CallDepthExceeded
|
||||||
|
|
||||||
|
Programs are constrained to run quickly, and to facilitate this, the program's
|
||||||
|
call stack is limited to max depth. If this error is encountered, then the
|
||||||
|
program itself or its dependent crate packages have exceeded the max stack
|
||||||
|
depth.
|
||||||
|
|
||||||
|
## Computational constraints
|
||||||
|
|
||||||
|
To prevent a program from abusing computation resources, a cap is enforced
|
||||||
|
during execution. The following operations incur a cost:
|
||||||
|
- Executing BPF instructions
|
||||||
|
- Calling system calls (logging, creating program addresses, ...)
|
||||||
|
- Cross-program invocations incur a base cost and the cost of the program
|
||||||
|
invoked.
|
||||||
|
|
||||||
|
## Failure to compiler due to `rand` incompatibility
|
||||||
|
|
||||||
|
Programs are constrained to run deterministically, so random numbers are not
|
||||||
|
available. Sometimes a program may depend on a crate that depends itself on
|
||||||
|
`rand` even if the program does not use any of the random number functionality.
|
||||||
|
If a program depends on `rand`, the compilation will fail because there is not
|
||||||
|
`get-random` support for Solana. To work around this dependency issue, add the
|
||||||
|
following dependency to the program's `Cargo.toml`:
|
||||||
|
|
||||||
|
```
|
||||||
|
getrandom = { version = "0.1.14", features = ["dummy"] }
|
||||||
|
```
|
||||||
|
|
||||||
|
## Float Rust types
|
||||||
|
|
||||||
|
Programs support a limited subset of Rust's float operations, though they
|
||||||
|
are highly discouraged due to the overhead involved. If a program attempts to
|
||||||
|
use a float operation that is not supported, the runtime will report an
|
||||||
|
unresolved symbol error. Be sure to include integration tests against a local
|
||||||
|
cluster to ensure the operation is supported.
|
||||||
|
|
||||||
|
## Heap size
|
||||||
|
|
||||||
|
Programs have access to a 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.
|
||||||
|
|
||||||
|
## InvalidAccountData
|
||||||
|
|
||||||
|
This program error can happen for a lot of reasons. Usually, it's caused by
|
||||||
|
passing an account to the program that the program is not expecting, either in
|
||||||
|
the wrong position in the instruction or an account not compatible with the
|
||||||
|
instruction being executed.
|
||||||
|
|
||||||
|
An implementation of a program might also cause this error when performing a
|
||||||
|
cross-program instruction and forgetting to provide the account for the program
|
||||||
|
that you are calling.
|
||||||
|
|
||||||
|
## InvalidInstructionData
|
||||||
|
|
||||||
|
This program error can occur while trying to deserialize the instruction, check
|
||||||
|
that the structure passed in matches exactly the instruction. There may be some
|
||||||
|
padding between fields. If the program implements the Rust `Pack` trait then ry
|
||||||
|
packing and unpacking the instruction type `T` to determine the exact encoding
|
||||||
|
the program expects:
|
||||||
|
|
||||||
|
https://github.com/solana-labs/solana/blob/master/sdk/src/program_pack.rs
|
||||||
|
|
||||||
|
|
||||||
|
## MissingRequiredSignature
|
||||||
|
|
||||||
|
Some instructions require the account to be a signer; this error is returned if
|
||||||
|
an account expected to be signed is not.
|
||||||
|
|
||||||
|
An implementation of a program might also cause this error when performing a
|
||||||
|
cross-program invocation that requires a signed program address, but the passed
|
||||||
|
signer seeds passed to `invoke_signed` don't match the signer seeds used to
|
||||||
|
create the program address (`create_program_address`).
|
||||||
|
|
||||||
|
## Rust restrictions
|
||||||
|
|
||||||
|
There are some Rust limitations since programs run in a resource-constrained,
|
||||||
|
single-threaded environment, and must be deterministic:
|
||||||
|
|
||||||
|
- No access to
|
||||||
|
- std::fs
|
||||||
|
- std::net
|
||||||
|
- std::os
|
||||||
|
- std::future
|
||||||
|
- std::net
|
||||||
|
- std::process
|
||||||
|
- std::sync
|
||||||
|
- std::task
|
||||||
|
- std::thread
|
||||||
|
- std::time
|
||||||
|
- Limited access to:
|
||||||
|
- std::os
|
||||||
|
- rand or any crates that depend on it
|
||||||
|
- Bincode is extremely computationally expensive in both cycles and call depth and should be avoided
|
||||||
|
- String formatting should be avoided since it is also computational expensive
|
||||||
|
- No support for `println!`, `print!`, the Solana SDK helpers in `src/log.rs`
|
||||||
|
should be used instead
|
||||||
|
|
||||||
|
## Stack size
|
||||||
|
|
||||||
|
Solana programs compile down to Berkley Packet Filter instructions, which use
|
||||||
|
stack frames instead of a variable stack pointer. Each stack frame is limited
|
||||||
|
to 4KB. If a program violates that stack frame size, the compiler will report
|
||||||
|
the overrun as a warning. 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.
|
Loading…
Reference in New Issue