Skip to content

Commit

Permalink
feat: bump near-sdk to 5.1.0 (#134)
Browse files Browse the repository at this point in the history
* feat: bump near-sdk to 5.1.0

* fix: access_controllable

* fix(tests): borsh usage

* fix: use LookupMap where iteration isn't needed

* chore: make clippy happy

* Update test.yml

* fix: do not gitignore Cargo.lock

* chore: bump msrv

* chore: bump rust in contracts for tests

* chore: decrease gas

* fix: rm Cargo.lock from lib crates

* fix: bring UnorderedMap back

* fix: use #[near] instead of #[near_bindgen]

* fix: bump version in separate PR

* fix(tests): gas consumption is slightly bigger now

* fix: #[allow(deprecated)] on UnorderedMap/UnorderedSet

* fix: #[allow(depreated)] attributes syntax

* docs: comment on deprecated collections from near_sdk::store

* fix: use FQDNs for #[derive(...)] in macros

* fix: use FQDNs everywhere in quote!{...}

---------

Co-authored-by: Oleksandr Anyshchenko <[email protected]>
  • Loading branch information
mitinarseny and aleksuss authored May 29, 2024
1 parent a852ce8 commit 12d3fee
Show file tree
Hide file tree
Showing 33 changed files with 156 additions and 195 deletions.
14 changes: 4 additions & 10 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,13 @@ jobs:
- name: Install toolchain
uses: actions-rs/toolchain@v1
with:
toolchain: 1.69.0 # MSRV
toolchain: 1.74.0 # MSRV
override: true
target: wasm32-unknown-unknown

- uses: Swatinem/rust-cache@v1
with:
key: rust-version-1.69.0-msrv-2

- name: downgrade some dev-dependencies for msrv, see https://github.com/near/near-workspaces-rs/issues/336
run: ./scripts/fix_dependencies.sh
key: rust-version-1.74.0-msrv-2

- name: add wasm32-unknown-unknown
run: rustup target add wasm32-unknown-unknown
Expand All @@ -44,16 +41,13 @@ jobs:
- name: Install toolchain
uses: actions-rs/toolchain@v1
with:
toolchain: 1.69.0 # MSRV
toolchain: 1.74.0 # MSRV
override: true
components: rustfmt, clippy

- uses: Swatinem/rust-cache@v1
with:
key: rust-version-1.69.0-msrv-2

- name: downgrade some dev-dependencies for msrv, see https://github.com/near/near-workspaces-rs/issues/336
run: ./scripts/fix_dependencies.sh
key: rust-version-1.74.0-msrv-2

- name: cargo fmt
run: cargo fmt --all -- --check
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/target
Cargo.lock
**/Cargo.lock
near-plugins-derive/tests/contracts/*/target

# Ignore IDE data
Expand Down
17 changes: 5 additions & 12 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
[workspace]
members = [
"near-plugins",
"near-plugins-derive"
]
members = ["near-plugins", "near-plugins-derive"]
exclude = ["target", "examples"]
resolver = "2"

[workspace.metadata.workspaces]
version = "0.15.0"
Expand All @@ -15,7 +13,7 @@ authors = ["Aurora Labs <[email protected]>"]
# An update of the MSRV requires updating:
# - `rust-toolchain` files in `near-plugins-derive/tests/contracts/**`
# - the toolchain installed in CI via the `toolchain` parameter of `actions-rs/toolchain@v1`
rust-version = "1.69.0"
rust-version = "1.74.0"
description = "Ergonomic plugin system to extend NEAR contracts."
license = "CC0-1.0"
readme = "README.md"
Expand All @@ -25,21 +23,16 @@ keywords = ["near", "smart contract", "plugin"]

[workspace.dependencies]
bitflags = "1.3"
near-sdk = "4.1.1"
near-sdk = "5.1.0"
near-plugins = { path = "near-plugins" }
near-plugins-derive = { path = "near-plugins-derive" }
serde = "1"
anyhow = "1.0"
tokio = { version = "1", features = ["full"] }
near-workspaces = "0.9"
near-workspaces = "0.10"
toml = "0.5"
darling = "0.13.1"
proc-macro2 = "1.0"
quote = "1.0.9"
syn = { version = "1.0.69", features = ["full"] }
proc-macro-crate = "0.1.5"

# Required to build tests with near-sdk v4.1.1, see #128.
# TODO(#125): Remove after upgrading to near-sdk v5.
[patch.crates-io]
parity-secp256k1 = {git = "https://github.com/paritytech/rust-secp256k1", tag = "parity-secp256k1-v0.7.0"}
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# NEAR Smart Contracts Plugins

Implementation of common patterns used for NEAR smart contracts. Macros provided by default assumes the contract is
using near-sdk-rs and `#[near_bindgen]` macro.
using near-sdk-rs and `#[near]` macro.

## Plugins

Expand Down Expand Up @@ -71,7 +71,7 @@ Tests should verify that once the macros provided by this crate are expanded, th
## Traits and their implementations

Traits doesn't contain any implementation, even though some interfaces are self-contained enough to have it.
It is this way since `near_bindgen` macro from near-sdk-rs will only expose as public methods those that are implemented
It is this way since `near` macro from near-sdk-rs will only expose as public methods those that are implemented
during the trait implementation for the contract.

In the documentation all comments under Default Implementation makes remarks about the current implementation derived
Expand Down
2 changes: 1 addition & 1 deletion near-plugins-derive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ proc-macro-crate.workspace = true
[dev-dependencies]
anyhow.workspace = true
near-plugins.workspace = true
near-sdk.workspace = true
near-sdk = { workspace = true, features = ["unit-testing"] }
tokio.workspace = true
near-workspaces.workspace = true
toml.workspace = true
9 changes: 7 additions & 2 deletions near-plugins-derive/src/access_control_role.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ pub fn derive_access_control_role(input: TokenStream) -> TokenStream {
.unwrap_or_else(|| ::near_sdk::env::panic_str("Too many enum variants to be represented by bitflags"))
}

impl AccessControlRole for #ident {
impl #cratename::AccessControlRole for #ident {
fn acl_role_variants() -> Vec<&'static str> {
vec![
#(#variant_names,)*
Expand Down Expand Up @@ -196,7 +196,12 @@ pub fn derive_access_control_role(input: TokenStream) -> TokenStream {

#cratename::bitflags::bitflags! {
/// Encodes permissions for roles and admins.
#[derive(BorshDeserialize, BorshSerialize, Default)]
#[derive(
Default,
::near_sdk::borsh::BorshDeserialize,
::near_sdk::borsh::BorshSerialize,
)]
#[borsh(crate = "near_sdk::borsh")]
struct #bitflags_type_ident: u128 {
#(
const #bitflags_idents = 1u128 << #bitflags_idxs;
Expand Down
43 changes: 28 additions & 15 deletions near-plugins-derive/src/access_controllable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,9 @@ pub fn access_controllable(attrs: TokenStream, item: TokenStream) -> TokenStream
let storage_prefix = macro_args
.storage_prefix
.unwrap_or_else(|| DEFAULT_STORAGE_PREFIX.to_string());
assert!(
macro_args.role_type.len() == 1,
assert_eq!(
macro_args.role_type.len(),
1,
"role_type should be exactly one path"
);
let role_type = &macro_args.role_type[0];
Expand All @@ -49,13 +50,22 @@ pub fn access_controllable(attrs: TokenStream, item: TokenStream) -> TokenStream
#input

#[derive(::near_sdk::borsh::BorshDeserialize, ::near_sdk::borsh::BorshSerialize)]
#[borsh(crate = "near_sdk::borsh")]
/// NOTE: Despite `near_sdk::store::UnorderedMap` and `near_sdk::store::UnorderedSet`
/// have been deprecated, it still makes sense to use them here as we might still
/// need to iterate over the keys.
/// The impact on gas consumption compared to `near_sdk::store::LookupMap` is negligible
/// as it lazily loads list of keys to iterate over internally. Compiled size of a
/// contract is not affected that much as well.
struct #acl_type {
/// Stores permissions per account.
#[allow(deprecated)]
permissions: ::near_sdk::store::UnorderedMap<
::near_sdk::AccountId,
#bitflags_type,
>,
/// Stores the set of accounts that bear a permission.
#[allow(deprecated)]
bearers: ::near_sdk::store::UnorderedMap<
#bitflags_type,
::near_sdk::store::UnorderedSet<::near_sdk::AccountId>,
Expand All @@ -64,11 +74,13 @@ pub fn access_controllable(attrs: TokenStream, item: TokenStream) -> TokenStream

impl Default for #acl_type {
fn default() -> Self {
let base_prefix = <#ident as AccessControllable>::acl_storage_prefix();
let base_prefix = <#ident as #cratename::AccessControllable>::acl_storage_prefix();
Self {
permissions: ::near_sdk::store::UnorderedMap::new(
#[allow(deprecated)]
permissions: ::near_sdk::store::UnorderedMap::new(
__acl_storage_prefix(base_prefix, __AclStorageKey::Permissions),
),
#[allow(deprecated)]
bearers: ::near_sdk::store::UnorderedMap::new(
__acl_storage_prefix(base_prefix, __AclStorageKey::Bearers),
),
Expand All @@ -80,6 +92,7 @@ pub fn access_controllable(attrs: TokenStream, item: TokenStream) -> TokenStream
/// instead it should be prepended to the storage prefix specified by
/// the user.
#[derive(::near_sdk::borsh::BorshSerialize)]
#[borsh(crate = "near_sdk::borsh")]
enum __AclStorageKey {
Permissions,
Bearers,
Expand All @@ -89,21 +102,20 @@ pub fn access_controllable(attrs: TokenStream, item: TokenStream) -> TokenStream

/// Generates a prefix by concatenating the input parameters.
fn __acl_storage_prefix(base: &[u8], specifier: __AclStorageKey) -> Vec<u8> {
let specifier = specifier
.try_to_vec()
let specifier = near_sdk::borsh::to_vec(&specifier)
.unwrap_or_else(|_| ::near_sdk::env::panic_str("Storage key should be serializable"));
[base, specifier.as_slice()].concat()
}

impl #ident {
fn acl_get_storage(&self) -> Option<#acl_type> {
let base_prefix = <#ident as AccessControllable>::acl_storage_prefix();
let base_prefix = <#ident as #cratename::AccessControllable>::acl_storage_prefix();
near_sdk::env::storage_read(&__acl_storage_prefix(
base_prefix,
__AclStorageKey::AclStorage,
))
.map(|acl_storage_bytes| {
#acl_type::try_from_slice(&acl_storage_bytes)
::near_sdk::borsh::BorshDeserialize::try_from_slice(&acl_storage_bytes)
.unwrap_or_else(|_| near_sdk::env::panic_str("ACL: invalid acl storage format"))
})
}
Expand All @@ -113,19 +125,20 @@ pub fn access_controllable(attrs: TokenStream, item: TokenStream) -> TokenStream
}

fn acl_init_storage_unchecked(&mut self) -> #acl_type {
let base_prefix = <#ident as AccessControllable>::acl_storage_prefix();
let base_prefix = <#ident as #cratename::AccessControllable>::acl_storage_prefix();
let acl_storage: #acl_type = Default::default();
near_sdk::env::storage_write(
&__acl_storage_prefix(base_prefix, __AclStorageKey::AclStorage),
&acl_storage.try_to_vec().unwrap(),
&near_sdk::borsh::to_vec(&acl_storage).unwrap(),
);
acl_storage
}
}

impl #acl_type {
#[allow(deprecated)]
fn new_bearers_set(permission: #bitflags_type) -> ::near_sdk::store::UnorderedSet<::near_sdk::AccountId> {
let base_prefix = <#ident as AccessControllable>::acl_storage_prefix();
let base_prefix = <#ident as #cratename::AccessControllable>::acl_storage_prefix();
let specifier = __AclStorageKey::BearersSet { permission };
::near_sdk::store::UnorderedSet::new(__acl_storage_prefix(base_prefix, specifier))
}
Expand Down Expand Up @@ -566,13 +579,13 @@ pub fn access_controllable(attrs: TokenStream, item: TokenStream) -> TokenStream
};
}

// Note that `#[near-bindgen]` exposes non-public functions in trait
// Note that `#[near]` exposes non-public functions in trait
// implementations. This is [documented] behavior. Therefore some
// functions are made `#[private]` despite _not_ being public.
//
// [documented]: https://docs.near.org/sdk/rust/contract-interface/public-methods#exposing-trait-implementations
#[near_bindgen]
impl AccessControllable for #ident {
// [documented]: https://docs.near.org/sdk/rust/contract-structure/near-bindgen
#[near]
impl #cratename::AccessControllable for #ident {
fn acl_storage_prefix() -> &'static [u8] {
(#storage_prefix).as_bytes()
}
Expand Down
6 changes: 3 additions & 3 deletions near-plugins-derive/src/ownable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ pub fn derive_ownable(input: TokenStream) -> TokenStream {
.unwrap_or_else(|| "__OWNER__".to_string());

let output = quote! {
#[near_bindgen]
impl Ownable for #ident {
#[near]
impl #cratename::Ownable for #ident {
fn owner_storage_key(&self) -> &'static [u8] {
(#owner_storage_key).as_bytes()
}
Expand Down Expand Up @@ -66,7 +66,7 @@ pub fn derive_ownable(input: TokenStream) -> TokenStream {
match owner.as_ref() {
Some(owner) => ::near_sdk::env::storage_write(
&self.owner_storage_key(),
owner.as_ref().as_bytes(),
owner.as_bytes(),
),
None => ::near_sdk::env::storage_remove(&self.owner_storage_key()),
};
Expand Down
10 changes: 4 additions & 6 deletions near-plugins-derive/src/pausable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ pub fn derive_pausable(input: TokenStream) -> TokenStream {
);

let output = quote! {
#[near_bindgen]
impl Pausable for #ident {
#[near]
impl #cratename::Pausable for #ident {
fn pa_storage_key(&self) -> &'static [u8] {
(#paused_storage_key).as_bytes()
}
Expand Down Expand Up @@ -65,8 +65,7 @@ pub fn derive_pausable(input: TokenStream) -> TokenStream {

::near_sdk::env::storage_write(
self.pa_storage_key().as_ref(),
paused_keys
.try_to_vec()
::near_sdk::borsh::to_vec(&paused_keys)
.unwrap_or_else(|_| ::near_sdk::env::panic_str("Pausable: Unexpected error serializing keys"))
.as_ref(),
);
Expand Down Expand Up @@ -96,8 +95,7 @@ pub fn derive_pausable(input: TokenStream) -> TokenStream {
} else {
::near_sdk::env::storage_write(
self.pa_storage_key().as_ref(),
paused_keys
.try_to_vec()
::near_sdk::borsh::to_vec(&paused_keys)
.unwrap_or_else(|_| ::near_sdk::env::panic_str("Pausable: Unexpected error serializing keys"))
.as_ref(),
);
Expand Down
Loading

0 comments on commit 12d3fee

Please sign in to comment.