Skip to content

Commit 9a93202

Browse files
Merge pull request #1201 from dfinity/jessiemongeon1-patch-32
add: Deploy to ICP Ninja + Standardize README
2 parents 7a305ac + b82e189 commit 9a93202

File tree

1 file changed

+22
-36
lines changed

1 file changed

+22
-36
lines changed

rust/guards/README.md

Lines changed: 22 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
# Guards and async code
22

3-
## Summary
4-
53
This example canister shows some advanced behavior between guards and asynchronous code. This example is meant for Rust
64
canister developers that are already familiar
7-
with [asynchronous code](https://internetcomputer.org/docs/current/developer-docs/smart-contracts/advanced-features/async-code/)
5+
with [asynchronous code](https://internetcomputer.org/docs/references/async-code)
86
and the security best-practices related
9-
to [inter-canister calls and rollbacks](https://internetcomputer.org/docs/current/developer-docs/security/rust-canister-development-security-best-practices#inter-canister-calls-and-rollbacks).
7+
to [inter-canister calls and rollbacks](https://internetcomputer.org/docs/building-apps/security/inter-canister-calls#inter-canister-calls-and-rollbacks).
108

119
## Guard to maintain invariants
1210

@@ -17,7 +15,7 @@ requests by contacting a ledger canister, where crucially double minting should
1715

1816
One tricky part in this scenario is that an item can therefore only be marked as processed after the asynchronous code
1917
has completed, meaning in the callback. As mentioned in
20-
the [security best-practices](https://internetcomputer.org/docs/current/developer-docs/security/rust-canister-development-security-best-practices#securely-handle-traps-in-callbacks),
18+
the [security best-practices](https://internetcomputer.org/docs/building-apps/security/inter-canister-calls#securely-handle-traps-in-callbacks),
2119
it's not always feasible to guarantee that the callback will not trap, which in that case would break the invariant due
2220
to the state being rolled back.
2321

@@ -27,42 +25,35 @@ another message than the callback, which is the case for true asynchronous code
2725
etc.). It's in particular not enough to `await` a function that's declared to be `async`, since if the future can polled
2826
until completion directly, everything will be executed in a single message.
2927

30-
## Automated integration tests
28+
## Deploying from ICP Ninja
3129

32-
To run the integration tests under `tests/` install [PocketIC server](https://github.com/dfinity/pocketic) and then run:
30+
[![](https://icp.ninja/assets/open.svg)](https://icp.ninja/editor?g=https://github.com/dfinity/examples/tree/master/rust/counter)
3331

34-
```shell
35-
cargo build --target wasm32-unknown-unknown --release && cargo test
36-
```
32+
## Build and deploy from the command-line
3733

38-
## Manual testing with `dfx`
34+
### 1. [Download and install the IC SDK.](https://internetcomputer.org/docs/building-apps/getting-started/install)
3935

40-
### Setup
36+
### 2. Download your project from ICP Ninja using the 'Download files' button on the upper left corner, or [clone the GitHub examples repository.](https://github.com/dfinity/examples/)
4137

42-
Start `dfx`:
38+
### 3. Navigate into the project's directory.
4339

44-
```shell
45-
dfx start --background
46-
```
47-
48-
Deploy the canister:
40+
### 4. Deploy the project to your local environment:
4941

50-
```shell
51-
dfx deploy
42+
```
43+
dfx start --background --clean && dfx deploy
5244
```
5345

54-
You should now be able to query the canister, e.g., to check if an item is processed:
46+
## Automated integration tests
47+
48+
To run the integration tests under `tests/` install [PocketIC server](https://github.com/dfinity/pocketic) and then run:
5549

5650
```shell
57-
dfx canister call guards is_item_processed 'mint'
51+
cargo build --target wasm32-unknown-unknown --release && cargo test
5852
```
5953

60-
This should return `(null)` since the canister currently has an empty state.
61-
6254
### Test
6355

64-
As an example, we show how the behavior tested in `should_process_single_item_and_mark_it_as_processed` can be tested
65-
manually.
56+
Below tests the behavior in `should_process_single_item_and_mark_it_as_processed` manually.
6657

6758
Set the item `"mint"` to be processed:
6859

@@ -76,27 +67,22 @@ As a sanity check, ensure that the item is not yet processed:
7667
dfx canister call guards is_item_processed 'mint'
7768
```
7869

79-
should return `(opt false)`.
70+
This should return `(opt false)`.
8071

8172
Process the item by calling the *panicking* callback:
8273

8374
```shell
8475
dfx canister call guards process_single_item_with_panicking_callback '("mint", variant { TrueAsyncCall })'
8576
```
8677

87-
Since the queried endpoint panics on purpose, expect some error message similar to:
88-
89-
```text
90-
2024-05-29 11:54:39.817800 UTC: [Canister bkyz2-fmaaa-aaaaa-qaaaq-cai] Panicked at 'panicking callback!', src/lib.rs:47:5
91-
Error: Failed update call.
92-
Caused by: Failed update call.
93-
The replica returned a rejection error: reject code CanisterError, reject message Canister bkyz2-fmaaa-aaaaa-qaaaq-cai trapped explicitly: Panicked at 'panicking callback!', src/lib.rs:47:5, error code None
94-
```
95-
9678
Ensure that the guard was executed to ensure that the item is marked as processed despite the previous panic:
9779

9880
```shell
9981
dfx canister call guards is_item_processed 'mint'
10082
```
10183

10284
This should return `(opt true)`.
85+
86+
## Security considerations and best practices
87+
88+
If you base your application on this example, it is recommended that you familiarize yourself with and adhere to the [security best practices](https://internetcomputer.org/docs/building-apps/security/overview) for developing on ICP. This example may not implement all the best practices.

0 commit comments

Comments
 (0)