Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ on:

env:
RUST_BACKTRACE: full
MSRV: 1.79.0
MSRV: 1.80.0

jobs:
tests:
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ authors = ["Aurora Labs <hello@aurora.dev>"]
# 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.79.0"
rust-version = "1.80.0"
description = "Ergonomic plugin system to extend NEAR contracts."
license = "CC0-1.0"
readme = "README.md"
Expand Down
4 changes: 3 additions & 1 deletion near-plugins-derive/src/upgradable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ pub fn derive_upgradable(input: TokenStream) -> TokenStream {
let promise = ::near_sdk::Promise::new(::near_sdk::env::current_account_id())
.deploy_contract(code);
match function_call_args {
None => promise,
None => promise.function_call("up_verify_state".to_owned(), vec![], near_sdk::NearToken::from_yoctonear(0), near_sdk::Gas::from_tgas(2)),
Some(args) => {
// Execute the `DeployContract` and `FunctionCall` actions in a batch
// transaction to make a failure of the function call roll back the code
Expand All @@ -226,6 +226,8 @@ pub fn derive_upgradable(input: TokenStream) -> TokenStream {
}
}

fn up_verify_state(&self) {}

#[#cratename::access_control_any(roles(#(#acl_roles_duration_initializers),*))]
fn up_init_staging_duration(&mut self, staging_duration: ::near_sdk::Duration) {
::near_sdk::require!(self.up_get_duration(__UpgradableStorageKey::StagingDuration).is_none(), "Upgradable: staging duration was already initialized");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[toolchain]
channel = "1.79.0"
channel = "1.80.0"
components = ["clippy", "rustfmt"]
targets = [ "wasm32-unknown-unknown" ]
2 changes: 1 addition & 1 deletion near-plugins-derive/tests/contracts/ownable/rust-toolchain
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[toolchain]
channel = "1.79.0"
channel = "1.80.0"
components = ["clippy", "rustfmt"]
targets = [ "wasm32-unknown-unknown" ]
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[toolchain]
channel = "1.79.0"
channel = "1.80.0"
components = ["clippy", "rustfmt"]
targets = [ "wasm32-unknown-unknown" ]
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[toolchain]
channel = "1.79.0"
channel = "1.80.0"
components = ["clippy", "rustfmt"]
targets = [ "wasm32-unknown-unknown" ]
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[toolchain]
channel = "1.79.0"
channel = "1.80.0"
components = ["clippy", "rustfmt"]
targets = [ "wasm32-unknown-unknown" ]
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[toolchain]
channel = "1.79.0"
channel = "1.80.0"
components = ["clippy", "rustfmt"]
targets = [ "wasm32-unknown-unknown" ]
48 changes: 42 additions & 6 deletions near-plugins-derive/tests/upgradable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,7 @@ async fn test_deploy_code_without_delay() -> anyhow::Result<()> {
let setup = Setup::new(worker.clone(), Some(dao.id().clone()), None).await?;

// Stage some code.
let code = vec![1, 2, 3];
let code = common::repo::compile_project(Path::new(PROJECT_PATH), "upgradable").await?;
let res = setup
.upgradable_contract
.up_stage_code(&dao, code.clone())
Expand All @@ -463,7 +463,7 @@ async fn test_deploy_code_with_hash_success() -> anyhow::Result<()> {
let setup = Setup::new(worker.clone(), Some(dao.id().clone()), None).await?;

// Stage some code.
let code = vec![1, 2, 3];
let code = common::repo::compile_project(Path::new(PROJECT_PATH), "upgradable").await?;
let res = setup
.upgradable_contract
.up_stage_code(&dao, code.clone())
Expand Down Expand Up @@ -491,7 +491,7 @@ async fn test_deploy_code_with_hash_invalid_hash() -> anyhow::Result<()> {
let setup = Setup::new(worker.clone(), Some(dao.id().clone()), None).await?;

// Stage some code.
let code = vec![1, 2, 3];
let code = common::repo::compile_project(Path::new(PROJECT_PATH), "upgradable").await?;
let res = setup
.upgradable_contract
.up_stage_code(&dao, code.clone())
Expand Down Expand Up @@ -647,6 +647,42 @@ async fn test_deploy_code_with_migration_failure_rollback() -> anyhow::Result<()
Ok(())
}

/// Deploys a new version of the contract with missed migration
/// Verifies the failure rolls back the deployment, i.e. the initial
/// code remains active.
#[tokio::test]
async fn test_deploy_code_with_missed_migration() -> anyhow::Result<()> {
let worker = near_workspaces::sandbox().await?;
let dao = worker.dev_create_account().await?;
let setup = Setup::new(worker.clone(), Some(dao.id().clone()), None).await?;

// Compile the other version of the contract and stage its code.
let code = common::repo::compile_project(
Path::new(PROJECT_PATH_STATE_MIGRATION),
"upgradable_state_migration",
)
.await?;
let res = setup
.upgradable_contract
.up_stage_code(&dao, code.clone())
.await?;
assert_success_with_unit_return(res);
setup.assert_staged_code(Some(&code)).await;

// Deploy staged code
let res = setup
.upgradable_contract
.up_deploy_code(&dao, convert_code_to_deploy_hash(&code), None)
.await?;
assert_failure_with(res, "Cannot deserialize the contract state");

// Verify `code` wasn't deployed by calling a function that is defined only in the initial
// contract but not in the contract corresponding to the `code`.
setup.assert_is_set_up(&setup.unauth_account).await;

Ok(())
}

/// Deploys staged code in a batch transaction with two function call actions:
///
/// 1. `up_deploy_code` with a function call to a migration method that fails
Expand Down Expand Up @@ -676,7 +712,7 @@ async fn test_deploy_code_in_batch_transaction_pitfall() -> anyhow::Result<()> {
// Construct the function call actions to be executed in a batch transaction.
// Note that we are attaching a call to `migrate_with_failure`, which will fail.
let fn_call_deploy = near_workspaces::operations::Function::new("up_deploy_code")
.args_json(json!({
.args_json(json!({
"hash": convert_code_to_deploy_hash(&code),
"function_call_args": FunctionCallArgs {
function_name: "migrate_with_failure".to_string(),
Expand Down Expand Up @@ -734,7 +770,7 @@ async fn test_deploy_code_with_delay() -> anyhow::Result<()> {
.await?;

// Stage some code.
let code = vec![1, 2, 3];
let code = common::repo::compile_project(Path::new(PROJECT_PATH), "upgradable").await?;
let res = setup
.upgradable_contract
.up_stage_code(&dao, code.clone())
Expand Down Expand Up @@ -767,7 +803,7 @@ async fn test_deploy_code_with_delay_failure_too_early() -> anyhow::Result<()> {
.await?;

// Stage some code.
let code = vec![1, 2, 3];
let code = common::repo::compile_project(Path::new(PROJECT_PATH), "upgradable").await?;
let res = setup
.upgradable_contract
.up_stage_code(&dao, code.clone())
Expand Down
4 changes: 2 additions & 2 deletions near-plugins/src/access_controllable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ pub trait AccessControllable {
/// }
/// }
/// ```
///
///
/// ```json
/// {
/// "standard":"AccessControllable",
Expand Down Expand Up @@ -356,7 +356,7 @@ pub trait AccessControllable {
///
/// * Get roles with [`Self::acl_get_roles`].
/// * Get (a subset) of permissioned accounts with [`Self::acl_get_super_admins`],
/// [`Self::acl_get_admins`], or [`Self::acl_get_grantees`].
/// [`Self::acl_get_admins`], or [`Self::acl_get_grantees`].
///
/// [gas limit]: https://github.com/near/nearcore/pull/4381
fn acl_get_permissioned_accounts(&self) -> PermissionedAccounts;
Expand Down
3 changes: 3 additions & 0 deletions near-plugins/src/upgradable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,9 @@ pub trait Upgradable {
/// attribute. The example contract (accessible via the `README`) shows how access control roles
/// can be defined and passed on to the `Upgradable` macro.
fn up_apply_update_staging_duration(&mut self);

/// Panic if state is not valid.
fn up_verify_state(&self);
}

#[near(serializers = [json])]
Expand Down