Add section on safety checks (#6)

This commit is contained in:
Tom Linton 2022-02-21 15:00:03 +13:00 committed by GitHub
parent 16fbce6328
commit 73ad095541
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 42 additions and 5 deletions

View File

@ -1,4 +1,5 @@
# The Accounts Struct
The Accounts struct is where you define which accounts your instruction expects and which constraints these accounts should adhere to. You do this via two constructs: Types and constraints.
## Types
@ -46,7 +47,6 @@ Most importantly, the `#[account]` attribute sets the owner of that data to the
#### Using `Account<'a, T>` with non-anchor program accounts
There may be cases where you want your program to interact with a non-Anchor program. You can still get all the benefits of `Account` but you have to write a custom wrapper type instead of using `#[account]`. For instance, Anchor provides wrapper types for the token program accounts so they can be used with `Account`.
```rust,ignore
@ -97,12 +97,14 @@ Check out the [reference for the Account type](https://docs.rs/anchor-lang/lates
Account types can do a lot of work for you but they're not dynamic enough to handle all the security checks a secure program requires.
Add constraints to an account with the following format:
```rust,ignore
#[account(<constraints>)]
pub account: AccountType
```
Some constraints support custom Errors (we will explore errors [later](./errors.md)):
```rust,ignore
#[account(...,<constraint> @ MyError::MyErrorVariant, ...)]
pub account: AccountType
@ -125,3 +127,38 @@ pub struct SetData<'info> {
```
You can find information about all constraints in the reference. We will cover some of the most important ones in the milestone project at the end of the Essentials section.
## Safety checks
Two of the Anchor account types, [AccountInfo](https://docs.rs/anchor-lang/latest/anchor_lang/accounts/account_info/index.html) and [UncheckedAccount](https://docs.rs/anchor-lang/latest/anchor_lang/accounts/unchecked_account/index.html) do not implement any checks on the account being passed. Anchor implements safety checks that encourage additional documentation describing why additional checks are not necesssary.
Attempting to build a program containing the following excerpt with `anchor build`:
```rust,ignore
#[derive(Accounts)]
pub struct Initialize<'info> {
pub potentially_dangerous: UncheckedAccount<'info>
}
```
will result in an error similar to the following:
```
Error:
/anchor/tests/unchecked/programs/unchecked/src/lib.rs:15:8
Struct field "potentially_dangerous" is unsafe, but is not documented.
Please add a `/// SAFETY:` doc comment explaining why no checks through types are necessary.
See https://book.anchor-lang.com/chapter_3/the_accounts_struct.html#safety-checks for more information.
```
To fix this, write a doc comment describing the potential security implications, e.g.:
```rust,ignore
#[derive(Accounts)]
pub struct Initialize<'info> {
/// SAFETY: This is not dangerous because we don't read or write from this account
pub potentially_dangerous: UncheckedAccount<'info>
}
```
Note the doc comment needs to be a [line or block doc comment](https://doc.rust-lang.org/reference/comments.html#doc-comments) (/// or /\*\*) to be interepreted as doc attribute by Rust. Double slash comments (//) are not interpreted as such.