From ea9ffcbfd0b3413a36143694339d058014041919 Mon Sep 17 00:00:00 2001 From: Dorin Marian Iancu Date: Mon, 17 Jun 2024 10:36:04 +0300 Subject: [PATCH 1/2] best practices update --- .../best-practices/best-practices-basics.md | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/docs/developers/best-practices/best-practices-basics.md b/docs/developers/best-practices/best-practices-basics.md index 57aed7184..850b19002 100644 --- a/docs/developers/best-practices/best-practices-basics.md +++ b/docs/developers/best-practices/best-practices-basics.md @@ -16,3 +16,27 @@ We'll start with something simple: code arrangement. It's best to separate your This ensures that it's much easier to find what you're looking for, and it's also much easier for everyone else who's working on that smart contract. Additionally, it's also best to split endpoints by their level of access. Some endpoints might be owner-only, some might be usable only by a select few addresses from a whitelist, and some can be called by anyone. The recommended order is the one from the list above, but order is not important as long as you clearly separate your code. Even better if you split those into modules. + +## Module Size + +Each module should have a maximum of 200-300 lines. If you ever need more than that, consider splitting. Makes it much easier to find what you're looking for. + +## Function Size + +Each function should be 30-50 lines. Any more than that and it's really hard to navigate the file. + +## Code Placement + +The lib.rs file should contain only the init and upgrade functions most of the time. Sometimes it's tempting to bundle a bunch of unrelated functions there, but don't. You'll end up with a lib.rs file of 500 lines. + +## Module Placement + +Each module can be placed in its own folder along with other related modules. Sure, splitting the code is nice, but having to navigate through 20 files, all at the level of lib.rs, doesn't help at all. This makes it even easier to search for specific features. + +## Error Messages + +If you have the same error message in multiple places, it's better to declare a static with the message and use that instead of copy-pasting the message. If you have the same condition too, consider having a separate `require_X` function. + +## Small PRs + +Unless you're mass-upgrading everything, in which case you really have no other choice, it's much better to keep your PRs focused on one specific task. Also much easier for reviewers to spot issues instead of simply giving you a green and moving on. From 6af37d88bf928d96c4002b101e39af65445e2cfa Mon Sep 17 00:00:00 2001 From: Dorin Marian Iancu Date: Mon, 17 Jun 2024 11:07:16 +0300 Subject: [PATCH 2/2] fixes --- .../best-practices/best-practices-basics.md | 25 ++++++++++++++++--- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/docs/developers/best-practices/best-practices-basics.md b/docs/developers/best-practices/best-practices-basics.md index 850b19002..a19592f1e 100644 --- a/docs/developers/best-practices/best-practices-basics.md +++ b/docs/developers/best-practices/best-practices-basics.md @@ -23,20 +23,37 @@ Each module should have a maximum of 200-300 lines. If you ever need more than t ## Function Size -Each function should be 30-50 lines. Any more than that and it's really hard to navigate the file. +Each function should be ~30 lines. Any more than that and it's really hard to navigate the file. ## Code Placement -The lib.rs file should contain only the init and upgrade functions most of the time. Sometimes it's tempting to bundle a bunch of unrelated functions there, but don't. You'll end up with a lib.rs file of 500 lines. +The `lib.rs` file should contain only the `init` and `upgrade` functions most of the time. Sometimes it's tempting to bundle a bunch of unrelated functions there, but don't. You'll end up with an unreasonably large `lib.rs` file. ## Module Placement -Each module can be placed in its own folder along with other related modules. Sure, splitting the code is nice, but having to navigate through 20 files, all at the level of lib.rs, doesn't help at all. This makes it even easier to search for specific features. +Each module can be placed in its own folder along with other related modules. Sure, splitting the code is nice, but having to navigate through a large number of files, all at the level of `lib.rs`, might be cumbersome. This makes it even easier to search for specific features. ## Error Messages If you have the same error message in multiple places, it's better to declare a static with the message and use that instead of copy-pasting the message. If you have the same condition too, consider having a separate `require_X` function. +Example: +``` +pub static TOO_MANY_ARGS_ERR_MSG: &[u8] = b"Too many arguments"; + +#[endpoint(myEndpoint)] +fn my_endpoint(&self, args: MultiValueEncoded) { + require!(args.len() < 10, TOO_MANY_ARGS_ERR_MSG); +} +``` + +or: +``` +fn require_less_than_max_args(&self, args: &MultiValueEncoded) { + require!(args.len() < 10, "Too many arguments"); +} +``` + ## Small PRs -Unless you're mass-upgrading everything, in which case you really have no other choice, it's much better to keep your PRs focused on one specific task. Also much easier for reviewers to spot issues instead of simply giving you a green and moving on. +Unless you're mass-upgrading everything, in which case you really have no other choice, it's much better to keep your PRs focused on one specific task. Also much easier for reviewers to spot issues.