From 0675a45f19829449009145ce82dee9ee9cac9061 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 26 Jan 2024 11:20:12 +0000 Subject: [PATCH 01/26] *WIP* add `delegate_dependency` env api calls --- crates/env/src/api.rs | 20 ++++++++++++ crates/env/src/backend.rs | 29 +++++++++++++++++ crates/env/src/engine/off_chain/impls.rs | 14 +++++++++ crates/env/src/engine/on_chain/impls.rs | 18 +++++++++++ crates/ink/src/env_access.rs | 10 ++++++ .../upgradeable-contracts/delegator/lib.rs | 31 +++++++++++++++---- 6 files changed, 116 insertions(+), 6 deletions(-) diff --git a/crates/env/src/api.rs b/crates/env/src/api.rs index 61682408185..56e9ac7c905 100644 --- a/crates/env/src/api.rs +++ b/crates/env/src/api.rs @@ -787,3 +787,23 @@ where TypedEnvBackend::call_runtime::(instance, call) }) } + +/// todo: add_delegate_dependency docs +pub fn add_delegate_dependency(code_hash: &E::Hash) -> Result<()> +where + E: Environment, +{ + ::on_instance(|instance| { + instance.add_delegate_dependency::(code_hash) + }) +} + +/// todo: remove_delegate_dependency docs +pub fn remove_delegate_dependency(code_hash: &E::Hash) -> Result<()> +where + E: Environment, +{ + ::on_instance(|instance| { + instance.remove_delegate_dependency::(code_hash) + }) +} diff --git a/crates/env/src/backend.rs b/crates/env/src/backend.rs index d5da075d807..81f1fbf1fa9 100644 --- a/crates/env/src/backend.rs +++ b/crates/env/src/backend.rs @@ -399,4 +399,33 @@ pub trait TypedEnvBackend: EnvBackend { where E: Environment, Call: scale::Encode; + + /// Adds a new delegate dependency to the contract. + /// + /// This guarantees that the code of the dependency cannot be removed without first + /// calling [`remove_delegate_dependency`]. It charges a fraction of the code + /// deposit. + /// + /// # Errors + /// + /// - If the supplied `code_hash` cannot be found on-chain. + /// - If the `code_hash` is the same as the calling contract. + /// - If the maximum number of delegate_dependencies is reached + /// - If the delegate dependency already exists. + fn add_delegate_dependency(&mut self, code_hash: &E::Hash) -> Result<()> + where + E: Environment; + + /// Removes the delegate dependency from the contract. + /// + /// This removes the lock and refunds the deposit from the call to + /// [`add_delegate_dependency`]. The code of the dependency can be removed if the + /// reference count for the code hash is now zero. + /// + /// # Errors + /// + /// - If the delegate dependency does not exist. + fn remove_delegate_dependency(&mut self, code_hash: &E::Hash) -> Result<()> + where + E: Environment; } diff --git a/crates/env/src/engine/off_chain/impls.rs b/crates/env/src/engine/off_chain/impls.rs index df1a3321028..938c2e9aaa6 100644 --- a/crates/env/src/engine/off_chain/impls.rs +++ b/crates/env/src/engine/off_chain/impls.rs @@ -547,4 +547,18 @@ impl TypedEnvBackend for EnvInstance { { unimplemented!("off-chain environment does not support `call_runtime`") } + + fn add_delegate_dependency(&mut self, _code_hash: &E::Hash) -> Result<()> + where + E: Environment, + { + unimplemented!("off-chain environment does not support delegate dependencies") + } + + fn remove_delegate_dependency(&mut self, _code_hash: &E::Hash) -> Result<()> + where + E: Environment, + { + unimplemented!("off-chain environment does not support delegate dependencies") + } } diff --git a/crates/env/src/engine/on_chain/impls.rs b/crates/env/src/engine/on_chain/impls.rs index b1c39c37794..d5ec2c464a1 100644 --- a/crates/env/src/engine/on_chain/impls.rs +++ b/crates/env/src/engine/on_chain/impls.rs @@ -612,4 +612,22 @@ impl TypedEnvBackend for EnvInstance { let enc_call = scope.take_encoded(call); ext::call_runtime(enc_call).map_err(Into::into) } + + fn add_delegate_dependency(&mut self, code_hash: &E::Hash) -> Result<()> + where + E: Environment, + { + let mut scope = self.scoped_buffer(); + let enc_code_hash = scope.take_encoded(code_hash); + ext::add_delegate_dependency(enc_code_hash).map_err(Into::into) + } + + fn remove_delegate_dependency(&mut self, code_hash: &E::Hash) -> Result<()> + where + E: Environment, + { + let mut scope = self.scoped_buffer(); + let enc_code_hash = scope.take_encoded(code_hash); + ext::remove_delegate_dependency(enc_code_hash).map_err(Into::into) + } } diff --git a/crates/ink/src/env_access.rs b/crates/ink/src/env_access.rs index a7a705882d8..df7b7724987 100644 --- a/crates/ink/src/env_access.rs +++ b/crates/ink/src/env_access.rs @@ -1112,4 +1112,14 @@ where pub fn call_runtime(self, call: &Call) -> Result<()> { ink_env::call_runtime::(call) } + + /// todo: add_delegate_dependency docs + pub fn add_delegate_dependency(self, code_hash: &E::Hash) -> Result<()> { + ink_env::add_delegate_dependency::(code_hash) + } + + /// todo: remove_delegate_dependency docs + pub fn remove_delegate_dependency(self, code_hash: &E::Hash) -> Result<()> { + ink_env::remove_delegate_dependency::(code_hash) + } } diff --git a/integration-tests/upgradeable-contracts/delegator/lib.rs b/integration-tests/upgradeable-contracts/delegator/lib.rs index b6d95c3a1ca..7d24c2ad5c0 100644 --- a/integration-tests/upgradeable-contracts/delegator/lib.rs +++ b/integration-tests/upgradeable-contracts/delegator/lib.rs @@ -2,11 +2,6 @@ #[ink::contract] pub mod delegator { - use ink::{ - env::CallFlags, - storage::Mapping, - }; - use ink::{ env::{ call::{ @@ -14,15 +9,24 @@ pub mod delegator { ExecutionInput, Selector, }, + CallFlags, DefaultEnvironment, }, - storage::traits::ManualKey, + prelude::{ + format, + string::String, + }, + storage::{ + traits::ManualKey, + Mapping, + }, }; #[ink(storage)] pub struct Delegator { addresses: Mapping>, counter: i32, + delegate_to: Option, } impl Delegator { @@ -33,6 +37,7 @@ pub mod delegator { Self { addresses: v, counter: init_value, + delegate_to: None, } } @@ -42,6 +47,20 @@ pub mod delegator { Self::new(Default::default()) } + #[ink(message)] + pub fn update_delegate(&mut self, hash: Hash) -> Result<(), String> { + if let Some(old_hash) = self.delegate_to { + self.env() + .remove_delegate_dependency(&old_hash) + .map_err(|e| format!("remove_delegate_dependency failed: {:?}", e))?; + } + self.env() + .add_delegate_dependency(&hash) + .map_err(|e| format!("remove_delegate_dependency failed: {:?}", e))?; + self.delegate_to = Some(hash); + Ok(()) + } + /// Increment the current value using delegate call. #[ink(message)] pub fn inc_delegate(&mut self, hash: Hash) { From a4bb790d9424072ae0b31d71dcf3b24554ae0df5 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 8 Feb 2024 12:46:59 +0000 Subject: [PATCH 02/26] Updated return types and moved docs --- crates/env/src/api.rs | 27 ++++++++++++++++--- crates/env/src/backend.rs | 23 +++++----------- crates/env/src/engine/off_chain/impls.rs | 4 +-- crates/env/src/engine/on_chain/impls.rs | 8 +++--- crates/ink/src/env_access.rs | 4 +-- .../upgradeable-contracts/delegator/lib.rs | 11 +++----- 6 files changed, 40 insertions(+), 37 deletions(-) diff --git a/crates/env/src/api.rs b/crates/env/src/api.rs index 56e9ac7c905..dc7b5dc3249 100644 --- a/crates/env/src/api.rs +++ b/crates/env/src/api.rs @@ -788,8 +788,19 @@ where }) } -/// todo: add_delegate_dependency docs -pub fn add_delegate_dependency(code_hash: &E::Hash) -> Result<()> +/// Adds a new delegate dependency to the contract. +/// +/// This guarantees that the code of the dependency cannot be removed without first +/// calling [`remove_delegate_dependency`]. It charges a fraction of the code +/// deposit. +/// +/// # Errors +/// +/// - If the supplied `code_hash` cannot be found on-chain. +/// - If the `code_hash` is the same as the calling contract. +/// - If the maximum number of delegate_dependencies is reached +/// - If the delegate dependency already exists. +pub fn add_delegate_dependency(code_hash: &E::Hash) where E: Environment, { @@ -798,8 +809,16 @@ where }) } -/// todo: remove_delegate_dependency docs -pub fn remove_delegate_dependency(code_hash: &E::Hash) -> Result<()> +/// Removes the delegate dependency from the contract. +/// +/// This removes the lock and refunds the deposit from the call to +/// [`add_delegate_dependency`]. The code of the dependency can be removed if the +/// reference count for the code hash is now zero. +/// +/// # Errors +/// +/// - If the delegate dependency does not exist. +pub fn remove_delegate_dependency(code_hash: &E::Hash) where E: Environment, { diff --git a/crates/env/src/backend.rs b/crates/env/src/backend.rs index 81f1fbf1fa9..fed68f7a89a 100644 --- a/crates/env/src/backend.rs +++ b/crates/env/src/backend.rs @@ -402,30 +402,19 @@ pub trait TypedEnvBackend: EnvBackend { /// Adds a new delegate dependency to the contract. /// - /// This guarantees that the code of the dependency cannot be removed without first - /// calling [`remove_delegate_dependency`]. It charges a fraction of the code - /// deposit. - /// - /// # Errors + /// # Note /// - /// - If the supplied `code_hash` cannot be found on-chain. - /// - If the `code_hash` is the same as the calling contract. - /// - If the maximum number of delegate_dependencies is reached - /// - If the delegate dependency already exists. - fn add_delegate_dependency(&mut self, code_hash: &E::Hash) -> Result<()> + /// For more details visit: [`remove_delegate_dependency`][`crate::remove_delegate_dependency`] + fn add_delegate_dependency(&mut self, code_hash: &E::Hash) where E: Environment; /// Removes the delegate dependency from the contract. /// - /// This removes the lock and refunds the deposit from the call to - /// [`add_delegate_dependency`]. The code of the dependency can be removed if the - /// reference count for the code hash is now zero. - /// - /// # Errors + /// # Note /// - /// - If the delegate dependency does not exist. - fn remove_delegate_dependency(&mut self, code_hash: &E::Hash) -> Result<()> + /// For more details visit: [`remove_delegate_dependency`][`crate::remove_delegate_dependency`] + fn remove_delegate_dependency(&mut self, code_hash: &E::Hash) where E: Environment; } diff --git a/crates/env/src/engine/off_chain/impls.rs b/crates/env/src/engine/off_chain/impls.rs index 938c2e9aaa6..45cd20beae7 100644 --- a/crates/env/src/engine/off_chain/impls.rs +++ b/crates/env/src/engine/off_chain/impls.rs @@ -548,14 +548,14 @@ impl TypedEnvBackend for EnvInstance { unimplemented!("off-chain environment does not support `call_runtime`") } - fn add_delegate_dependency(&mut self, _code_hash: &E::Hash) -> Result<()> + fn add_delegate_dependency(&mut self, _code_hash: &E::Hash) where E: Environment, { unimplemented!("off-chain environment does not support delegate dependencies") } - fn remove_delegate_dependency(&mut self, _code_hash: &E::Hash) -> Result<()> + fn remove_delegate_dependency(&mut self, _code_hash: &E::Hash) where E: Environment, { diff --git a/crates/env/src/engine/on_chain/impls.rs b/crates/env/src/engine/on_chain/impls.rs index d5ec2c464a1..9de291b8fb4 100644 --- a/crates/env/src/engine/on_chain/impls.rs +++ b/crates/env/src/engine/on_chain/impls.rs @@ -613,21 +613,21 @@ impl TypedEnvBackend for EnvInstance { ext::call_runtime(enc_call).map_err(Into::into) } - fn add_delegate_dependency(&mut self, code_hash: &E::Hash) -> Result<()> + fn add_delegate_dependency(&mut self, code_hash: &E::Hash) where E: Environment, { let mut scope = self.scoped_buffer(); let enc_code_hash = scope.take_encoded(code_hash); - ext::add_delegate_dependency(enc_code_hash).map_err(Into::into) + ext::add_delegate_dependency(enc_code_hash) } - fn remove_delegate_dependency(&mut self, code_hash: &E::Hash) -> Result<()> + fn remove_delegate_dependency(&mut self, code_hash: &E::Hash) where E: Environment, { let mut scope = self.scoped_buffer(); let enc_code_hash = scope.take_encoded(code_hash); - ext::remove_delegate_dependency(enc_code_hash).map_err(Into::into) + ext::remove_delegate_dependency(enc_code_hash) } } diff --git a/crates/ink/src/env_access.rs b/crates/ink/src/env_access.rs index df7b7724987..b468b47cc9f 100644 --- a/crates/ink/src/env_access.rs +++ b/crates/ink/src/env_access.rs @@ -1114,12 +1114,12 @@ where } /// todo: add_delegate_dependency docs - pub fn add_delegate_dependency(self, code_hash: &E::Hash) -> Result<()> { + pub fn add_delegate_dependency(self, code_hash: &E::Hash) { ink_env::add_delegate_dependency::(code_hash) } /// todo: remove_delegate_dependency docs - pub fn remove_delegate_dependency(self, code_hash: &E::Hash) -> Result<()> { + pub fn remove_delegate_dependency(self, code_hash: &E::Hash) { ink_env::remove_delegate_dependency::(code_hash) } } diff --git a/integration-tests/upgradeable-contracts/delegator/lib.rs b/integration-tests/upgradeable-contracts/delegator/lib.rs index 0db71bd9a21..fa8885602aa 100644 --- a/integration-tests/upgradeable-contracts/delegator/lib.rs +++ b/integration-tests/upgradeable-contracts/delegator/lib.rs @@ -48,17 +48,12 @@ pub mod delegator { } #[ink(message)] - pub fn update_delegate(&mut self, hash: Hash) -> Result<(), String> { + pub fn update_delegate(&mut self, hash: Hash) { if let Some(old_hash) = self.delegate_to { - self.env() - .remove_delegate_dependency(&old_hash) - .map_err(|e| format!("remove_delegate_dependency failed: {:?}", e))?; + self.env().remove_delegate_dependency(&old_hash) } - self.env() - .add_delegate_dependency(&hash) - .map_err(|e| format!("remove_delegate_dependency failed: {:?}", e))?; + self.env().add_delegate_dependency(&hash); self.delegate_to = Some(hash); - Ok(()) } /// Increment the current value using delegate call. From c0084ddd7048e37ce9e429bdff93f69c60c33dec Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 9 Feb 2024 09:20:54 +0000 Subject: [PATCH 03/26] unused imports --- integration-tests/upgradeable-contracts/delegator/lib.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/integration-tests/upgradeable-contracts/delegator/lib.rs b/integration-tests/upgradeable-contracts/delegator/lib.rs index fa8885602aa..cef38e2cea8 100644 --- a/integration-tests/upgradeable-contracts/delegator/lib.rs +++ b/integration-tests/upgradeable-contracts/delegator/lib.rs @@ -12,10 +12,6 @@ pub mod delegator { CallFlags, DefaultEnvironment, }, - prelude::{ - format, - string::String, - }, storage::{ traits::ManualKey, Mapping, From 9fc6820f49088ea575d85e92ee08bfd249f974d9 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 9 Feb 2024 09:24:58 +0000 Subject: [PATCH 04/26] Lazy delegate to --- integration-tests/upgradeable-contracts/delegator/lib.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/integration-tests/upgradeable-contracts/delegator/lib.rs b/integration-tests/upgradeable-contracts/delegator/lib.rs index cef38e2cea8..e4a941b1224 100644 --- a/integration-tests/upgradeable-contracts/delegator/lib.rs +++ b/integration-tests/upgradeable-contracts/delegator/lib.rs @@ -15,6 +15,7 @@ pub mod delegator { storage::{ traits::ManualKey, Mapping, + Lazy, }, }; @@ -22,7 +23,7 @@ pub mod delegator { pub struct Delegator { addresses: Mapping>, counter: i32, - delegate_to: Option, + delegate_to: Lazy, } impl Delegator { @@ -33,7 +34,7 @@ pub mod delegator { Self { addresses: v, counter: init_value, - delegate_to: None, + delegate_to: Lazy::new(), } } @@ -45,11 +46,11 @@ pub mod delegator { #[ink(message)] pub fn update_delegate(&mut self, hash: Hash) { - if let Some(old_hash) = self.delegate_to { + if let Some(old_hash) = self.delegate_to.get() { self.env().remove_delegate_dependency(&old_hash) } self.env().add_delegate_dependency(&hash); - self.delegate_to = Some(hash); + self.delegate_to.set(&hash); } /// Increment the current value using delegate call. From 5086e0a60033cff74f0fd240e4810f45239a6257 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 9 Feb 2024 09:29:32 +0000 Subject: [PATCH 05/26] Allow deprecated --- crates/env/src/engine/on_chain/impls.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/env/src/engine/on_chain/impls.rs b/crates/env/src/engine/on_chain/impls.rs index b5ed1d8db94..6bb2a088169 100644 --- a/crates/env/src/engine/on_chain/impls.rs +++ b/crates/env/src/engine/on_chain/impls.rs @@ -667,6 +667,7 @@ impl TypedEnvBackend for EnvInstance { { let mut scope = self.scoped_buffer(); let enc_code_hash = scope.take_encoded(code_hash); + #[allow(deprecated)] ext::add_delegate_dependency(enc_code_hash) } @@ -676,6 +677,7 @@ impl TypedEnvBackend for EnvInstance { { let mut scope = self.scoped_buffer(); let enc_code_hash = scope.take_encoded(code_hash); + #[allow(deprecated)] ext::remove_delegate_dependency(enc_code_hash) } } From 6e358da72238f8be2bc9d0d47b95a25555d69e55 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 9 Feb 2024 10:31:28 +0000 Subject: [PATCH 06/26] Initialise delegate_to hash in constructor --- .../upgradeable-contracts/delegator/lib.rs | 68 +++++++++++-------- 1 file changed, 38 insertions(+), 30 deletions(-) diff --git a/integration-tests/upgradeable-contracts/delegator/lib.rs b/integration-tests/upgradeable-contracts/delegator/lib.rs index e4a941b1224..a0e90d9918f 100644 --- a/integration-tests/upgradeable-contracts/delegator/lib.rs +++ b/integration-tests/upgradeable-contracts/delegator/lib.rs @@ -29,21 +29,25 @@ pub mod delegator { impl Delegator { /// Creates a new delegator smart contract initialized with the given value. #[ink(constructor)] - pub fn new(init_value: i32) -> Self { + pub fn new(init_value: i32, hash: Hash) -> Self { let v = Mapping::new(); + + // Initialize the hash of the contract to delegate to. + // Adds a delegate dependency, ensuring that the delegated to code cannot be removed. + let mut delegate_to = Lazy::new(); + delegate_to.set(&hash); + Self::env().add_delegate_dependency(&hash); + Self { addresses: v, counter: init_value, - delegate_to: Lazy::new(), + delegate_to, } } - /// Creates a new contract with default values. - #[ink(constructor)] - pub fn new_default() -> Self { - Self::new(Default::default()) - } - + /// Update the hash of the contract to delegate to. + /// - Removes the old delegate dependency, releasing the deposit and allowing old delegated to code to be removed. + /// - Adds a new delegate dependency, ensuring that the new delegated to code cannot be removed. #[ink(message)] pub fn update_delegate(&mut self, hash: Hash) { if let Some(old_hash) = self.delegate_to.get() { @@ -55,10 +59,10 @@ pub mod delegator { /// Increment the current value using delegate call. #[ink(message)] - pub fn inc_delegate(&mut self, hash: Hash) { + pub fn inc_delegate(&mut self) { let selector = ink::selector_bytes!("inc"); let _ = build_call::() - .delegate(hash) + .delegate(self.delegate_to()) // We specify `CallFlags::TAIL_CALL` to use the delegatee last memory frame // as the end of the execution cycle. // So any mutations to `Packed` types, made by delegatee, @@ -77,10 +81,10 @@ pub mod delegator { /// Note that we don't need `CallFlags::TAIL_CALL` flag /// because `Mapping` updates the storage instantly on-demand. #[ink(message)] - pub fn add_entry_delegate(&mut self, hash: Hash) { + pub fn add_entry_delegate(&mut self) { let selector = ink::selector_bytes!("append_address_value"); let _ = build_call::() - .delegate(hash) + .delegate(self.delegate_to()) .exec_input(ExecutionInput::new(Selector::new(selector))) .returns::<()>() .try_invoke(); @@ -97,6 +101,10 @@ pub mod delegator { pub fn get_value(&self, address: AccountId) -> (AccountId, Option) { (self.env().caller(), self.addresses.get(address)) } + + fn delegate_to(&self) -> Hash { + self.delegate_to.get().expect("delegate_to always has a value") + } } #[cfg(all(test, feature = "e2e-tests"))] @@ -118,14 +126,6 @@ pub mod delegator { .create_and_fund_account(&ink_e2e::alice(), 10_000_000_000_000) .await; - let mut constructor = DelegatorRef::new_default(); - let contract = client - .instantiate("delegator", &origin, &mut constructor) - .submit() - .await - .expect("instantiate failed"); - let mut call_builder = contract.call_builder::(); - let code_hash = client .upload("delegatee", &origin) .submit() @@ -133,8 +133,16 @@ pub mod delegator { .expect("upload `delegatee` failed") .code_hash; + let mut constructor = DelegatorRef::new(0, code_hash); + let contract = client + .instantiate("delegator", &origin, &mut constructor) + .submit() + .await + .expect("instantiate failed"); + let mut call_builder = contract.call_builder::(); + // when - let call_delegate = call_builder.inc_delegate(code_hash); + let call_delegate = call_builder.inc_delegate(); let result = client.call(&origin, &call_delegate).submit().await; assert!(result.is_ok(), "delegate call failed."); @@ -170,8 +178,15 @@ pub mod delegator { .create_and_fund_account(&ink_e2e::alice(), 10_000_000_000_000) .await; + let code_hash = client + .upload("delegatee", &origin) + .submit() + .await + .expect("upload `delegatee` failed") + .code_hash; + // given - let mut constructor = DelegatorRef::new(10); + let mut constructor = DelegatorRef::new(10, code_hash); let contract = client .instantiate("delegator", &origin, &mut constructor) .submit() @@ -179,15 +194,8 @@ pub mod delegator { .expect("instantiate failed"); let mut call_builder = contract.call_builder::(); - let code_hash = client - .upload("delegatee", &origin) - .submit() - .await - .expect("upload `delegatee` failed") - .code_hash; - // when - let call_delegate = call_builder.add_entry_delegate(code_hash); + let call_delegate = call_builder.add_entry_delegate(); let result = client.call(&origin, &call_delegate).submit().await; assert!(result.is_ok(), "delegate call failed."); From b5bede657433d6346153f7b65f0ed6d8a7a676c3 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 9 Feb 2024 15:02:22 +0000 Subject: [PATCH 07/26] Test example, adding `remove_code` extrinsic to e2e --- crates/e2e/src/backend.rs | 32 ++++++++- crates/e2e/src/backend_calls.rs | 31 +++++++++ crates/e2e/src/error.rs | 3 + crates/e2e/src/subxt_client.rs | 33 +++++++-- crates/e2e/src/xts.rs | 26 +++++++ crates/env/src/backend.rs | 6 +- .../delegator/.gitignore | 9 --- .../delegator/Cargo.toml | 1 + .../delegator/delegatee/.gitignore | 9 --- .../delegator/delegatee2/Cargo.toml | 20 ++++++ .../delegator/delegatee2/lib.rs | 37 ++++++++++ .../upgradeable-contracts/delegator/lib.rs | 69 +++++++++++++++++-- 12 files changed, 245 insertions(+), 31 deletions(-) delete mode 100644 integration-tests/upgradeable-contracts/delegator/.gitignore delete mode 100644 integration-tests/upgradeable-contracts/delegator/delegatee/.gitignore create mode 100644 integration-tests/upgradeable-contracts/delegator/delegatee2/Cargo.toml create mode 100644 integration-tests/upgradeable-contracts/delegator/delegatee2/lib.rs diff --git a/crates/e2e/src/backend.rs b/crates/e2e/src/backend.rs index b3de9755104..86df3fbe258 100644 --- a/crates/e2e/src/backend.rs +++ b/crates/e2e/src/backend.rs @@ -16,6 +16,7 @@ use super::Keypair; use crate::{ backend_calls::{ InstantiateBuilder, + RemoveCodeBuilder, UploadBuilder, }, builders::CreateBuilderPartial, @@ -159,6 +160,28 @@ pub trait ContractsBackend { UploadBuilder::new(self, contract_name, caller) } + /// Start building an upload call. + /// # Example + /// + /// ```ignore + /// let contract = client + /// .remove(&ink_e2e::alice(), code_hash) + /// // Submit the call for on-chain execution. + /// .submit() + /// .await + /// .expect("upload failed"); + /// ``` + fn remove_code<'a>( + &'a mut self, + caller: &'a Keypair, + code_hash: E::Hash, + ) -> RemoveCodeBuilder + where + Self: Sized + BuilderClient, + { + RemoveCodeBuilder::new(self, caller, code_hash) + } + /// Start building a call using a builder pattern. /// /// # Example @@ -193,7 +216,7 @@ pub trait ContractsBackend { #[async_trait] pub trait BuilderClient: ContractsBackend { - /// Executes a bare `call` for the contract at `account_id`. This function does + /// Executes a bare `call` for the contract at `account_id`. This function does not /// perform a dry-run, and user is expected to provide the gas limit. /// /// Use it when you want to have a more precise control over submitting extrinsic. @@ -239,6 +262,13 @@ pub trait BuilderClient: ContractsBackend { storage_deposit_limit: Option, ) -> Result, Self::Error>; + /// Removes the code of the contract at `code_hash`. + async fn bare_remove_code( + &mut self, + caller: &Keypair, + code_hash: E::Hash, + ) -> Result; + /// Bare instantiate call. This function does not perform a dry-run, /// and user is expected to provide the gas limit. /// diff --git a/crates/e2e/src/backend_calls.rs b/crates/e2e/src/backend_calls.rs index 8fea6449d2a..d83cb987c2d 100644 --- a/crates/e2e/src/backend_calls.rs +++ b/crates/e2e/src/backend_calls.rs @@ -403,3 +403,34 @@ where .await } } + +/// Allows to build an end-to-end upload call using a builder pattern. +pub struct RemoveCodeBuilder<'a, E, B> +where + E: Environment, + B: BuilderClient, +{ + client: &'a mut B, + caller: &'a Keypair, + code_hash: E::Hash, +} + +impl<'a, E, B> RemoveCodeBuilder<'a, E, B> +where + E: Environment, + B: BuilderClient, +{ + /// Initialize a remove code builder with essential values. + pub fn new(client: &'a mut B, caller: &'a Keypair, code_hash: E::Hash) -> Self { + Self { + client, + caller, + code_hash, + } + } + + /// Execute the upload. + pub async fn submit(&mut self) -> Result { + B::bare_remove_code(self.client, self.caller, self.code_hash).await + } +} diff --git a/crates/e2e/src/error.rs b/crates/e2e/src/error.rs index 7554a033192..f59f500e18f 100644 --- a/crates/e2e/src/error.rs +++ b/crates/e2e/src/error.rs @@ -44,6 +44,9 @@ pub enum Error { /// The `call` extrinsic failed. #[error("Call extrinsic error: {0}")] CallExtrinsic(DispatchError), + /// The `call` extrinsic failed. + #[error("Remove code extrinsic error: {0}")] + RemoveCodeExtrinsic(DispatchError), /// Error fetching account balance. #[error("Fetching account Balance error: {0}")] Balance(String), diff --git a/crates/e2e/src/subxt_client.rs b/crates/e2e/src/subxt_client.rs index f887ae0bfc3..0aa92826ff0 100644 --- a/crates/e2e/src/subxt_client.rs +++ b/crates/e2e/src/subxt_client.rs @@ -468,7 +468,7 @@ where E::AccountId: Debug + Send + Sync, E::Balance: Clone + Debug + Send + Sync + From + scale::HasCompact + serde::Serialize, - E::Hash: Debug + Send + scale::Encode, + E::Hash: Debug + Send + Sync + scale::Encode, { async fn bare_instantiate( &mut self, @@ -536,6 +536,30 @@ where Ok(ret) } + async fn bare_remove_code( + &mut self, + caller: &Keypair, + code_hash: E::Hash, + ) -> Result { + let tx_events = self.api.remove_code(caller, code_hash).await; + + for evt in tx_events.iter() { + let evt = evt.unwrap_or_else(|err| { + panic!("unable to unwrap event: {err:?}"); + }); + + if is_extrinsic_failed_event(&evt) { + let metadata = self.api.client.metadata(); + let dispatch_error = + DispatchError::decode_from(evt.field_bytes(), metadata) + .map_err(|e| Error::Decoding(e.to_string()))?; + return Err(Error::RemoveCodeExtrinsic(dispatch_error)) + } + } + + Ok(tx_events) + } + async fn bare_call( &mut self, caller: &Keypair, @@ -571,7 +595,7 @@ where if is_extrinsic_failed_event(&evt) { let metadata = self.api.client.metadata(); let dispatch_error = - subxt::error::DispatchError::decode_from(evt.field_bytes(), metadata) + DispatchError::decode_from(evt.field_bytes(), metadata) .map_err(|e| Error::Decoding(e.to_string()))?; log_error(&format!("extrinsic for call failed: {dispatch_error}")); return Err(Error::CallExtrinsic(dispatch_error)) @@ -660,13 +684,14 @@ where C::Address: From, C::Signature: From, C::Address: Send + Sync, - <::ExtrinsicParams as subxt::config::ExtrinsicParams>::OtherParams: Default + Send + Sync, + <::ExtrinsicParams as ExtrinsicParams>::OtherParams: + Default + Send + Sync, E: Environment, E::AccountId: Debug + Send + Sync, E::Balance: Clone + Debug + Send + Sync + From + scale::HasCompact + serde::Serialize, - E::Hash: Debug + Send + scale::Encode, + E::Hash: Debug + Send + Sync + scale::Encode, { } diff --git a/crates/e2e/src/xts.rs b/crates/e2e/src/xts.rs index 568f26aadf6..f0c73619f2a 100644 --- a/crates/e2e/src/xts.rs +++ b/crates/e2e/src/xts.rs @@ -144,6 +144,13 @@ pub enum Determinism { Relaxed, } +/// A raw call to `pallet-contracts`'s `remove_code`. +#[derive(Debug, scale::Encode, scale::Decode, scale_encode::EncodeAsType)] +#[encode_as_type(trait_bounds = "", crate_path = "subxt::ext::scale_encode")] +pub struct RemoveCode { + code_hash: E::Hash, +} + /// A raw call to `pallet-contracts`'s `upload`. #[derive(Debug, scale::Encode, scale::Decode, scale_encode::EncodeAsType)] #[encode_as_type(trait_bounds = "", crate_path = "subxt::ext::scale_encode")] @@ -471,6 +478,25 @@ where self.submit_extrinsic(&call, signer).await } + /// Submits an extrinsic to remove the code at the given hash. + /// + /// Returns when the transaction is included in a block. The return value + /// contains all events that are associated with this transaction. + pub async fn remove_code( + &self, + signer: &Keypair, + code_hash: E::Hash, + ) -> ExtrinsicEvents { + let call = subxt::tx::Payload::new( + "Contracts", + "remove_code", + RemoveCode:: { code_hash }, + ) + .unvalidated(); + + self.submit_extrinsic(&call, signer).await + } + /// Dry runs a call of the contract at `contract` with the given parameters. pub async fn call_dry_run( &self, diff --git a/crates/env/src/backend.rs b/crates/env/src/backend.rs index 1f70156f90e..30ca092652c 100644 --- a/crates/env/src/backend.rs +++ b/crates/env/src/backend.rs @@ -423,7 +423,8 @@ pub trait TypedEnvBackend: EnvBackend { /// /// # Note /// - /// For more details visit: [`remove_delegate_dependency`][`crate::remove_delegate_dependency`] + /// For more details visit: + /// [`remove_delegate_dependency`][`crate::remove_delegate_dependency`] fn add_delegate_dependency(&mut self, code_hash: &E::Hash) where E: Environment; @@ -432,7 +433,8 @@ pub trait TypedEnvBackend: EnvBackend { /// /// # Note /// - /// For more details visit: [`remove_delegate_dependency`][`crate::remove_delegate_dependency`] + /// For more details visit: + /// [`remove_delegate_dependency`][`crate::remove_delegate_dependency`] fn remove_delegate_dependency(&mut self, code_hash: &E::Hash) where E: Environment; diff --git a/integration-tests/upgradeable-contracts/delegator/.gitignore b/integration-tests/upgradeable-contracts/delegator/.gitignore deleted file mode 100644 index bf910de10af..00000000000 --- a/integration-tests/upgradeable-contracts/delegator/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -# Ignore build artifacts from the local tests sub-crate. -/target/ - -# Ignore backup files creates by cargo fmt. -**/*.rs.bk - -# Remove Cargo.lock when creating an executable, leave it for libraries -# More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock -Cargo.lock \ No newline at end of file diff --git a/integration-tests/upgradeable-contracts/delegator/Cargo.toml b/integration-tests/upgradeable-contracts/delegator/Cargo.toml index ffcc3283363..9bafce1d72e 100644 --- a/integration-tests/upgradeable-contracts/delegator/Cargo.toml +++ b/integration-tests/upgradeable-contracts/delegator/Cargo.toml @@ -8,6 +8,7 @@ publish = false [dependencies] ink = { path = "../../../crates/ink", default-features = false } delegatee = { path = "delegatee", default-features = false, features = ["ink-as-dependency"] } +delegatee2 = { path = "delegatee2", default-features = false, features = ["ink-as-dependency"] } [dev-dependencies] ink_e2e = { path = "../../../crates/e2e" } diff --git a/integration-tests/upgradeable-contracts/delegator/delegatee/.gitignore b/integration-tests/upgradeable-contracts/delegator/delegatee/.gitignore deleted file mode 100644 index bf910de10af..00000000000 --- a/integration-tests/upgradeable-contracts/delegator/delegatee/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -# Ignore build artifacts from the local tests sub-crate. -/target/ - -# Ignore backup files creates by cargo fmt. -**/*.rs.bk - -# Remove Cargo.lock when creating an executable, leave it for libraries -# More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock -Cargo.lock \ No newline at end of file diff --git a/integration-tests/upgradeable-contracts/delegator/delegatee2/Cargo.toml b/integration-tests/upgradeable-contracts/delegator/delegatee2/Cargo.toml new file mode 100644 index 00000000000..651b045a6c9 --- /dev/null +++ b/integration-tests/upgradeable-contracts/delegator/delegatee2/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "delegatee2" +version = "5.0.0-rc" +authors = ["Parity Technologies "] +edition = "2021" +publish = false + +[dependencies] +ink = { path = "../../../../crates/ink", default-features = false } + +[lib] +path = "lib.rs" + +[features] +default = ["std"] +std = [ + "ink/std", +] +ink-as-dependency = [] +e2e-tests = [] diff --git a/integration-tests/upgradeable-contracts/delegator/delegatee2/lib.rs b/integration-tests/upgradeable-contracts/delegator/delegatee2/lib.rs new file mode 100644 index 00000000000..447db46e00f --- /dev/null +++ b/integration-tests/upgradeable-contracts/delegator/delegatee2/lib.rs @@ -0,0 +1,37 @@ +#![cfg_attr(not(feature = "std"), no_std, no_main)] + +#[ink::contract] +pub mod delegatee2 { + use ink::storage::{ + traits::ManualKey, + Mapping, + }; + #[ink(storage)] + pub struct Delegatee2 { + addresses: Mapping>, + counter: i32, + } + + impl Delegatee2 { + #[allow(clippy::new_without_default)] + #[ink(constructor)] + pub fn new() -> Self { + unreachable!( + "Constructors are not called when upgrading using `set_code_hash`." + ) + } + + /// Increments the current value. + #[ink(message)] + pub fn inc(&mut self) { + self.counter = self.counter.checked_add(3).unwrap(); + } + + /// Adds current value of counter to the `addresses` + #[ink(message)] + pub fn append_address_value(&mut self) { + let caller = self.env().caller(); + self.addresses.insert(caller, &self.counter); + } + } +} diff --git a/integration-tests/upgradeable-contracts/delegator/lib.rs b/integration-tests/upgradeable-contracts/delegator/lib.rs index a0e90d9918f..4f508050add 100644 --- a/integration-tests/upgradeable-contracts/delegator/lib.rs +++ b/integration-tests/upgradeable-contracts/delegator/lib.rs @@ -14,8 +14,8 @@ pub mod delegator { }, storage::{ traits::ManualKey, - Mapping, Lazy, + Mapping, }, }; @@ -33,7 +33,8 @@ pub mod delegator { let v = Mapping::new(); // Initialize the hash of the contract to delegate to. - // Adds a delegate dependency, ensuring that the delegated to code cannot be removed. + // Adds a delegate dependency, ensuring that the delegated to code cannot be + // removed. let mut delegate_to = Lazy::new(); delegate_to.set(&hash); Self::env().add_delegate_dependency(&hash); @@ -46,10 +47,12 @@ pub mod delegator { } /// Update the hash of the contract to delegate to. - /// - Removes the old delegate dependency, releasing the deposit and allowing old delegated to code to be removed. - /// - Adds a new delegate dependency, ensuring that the new delegated to code cannot be removed. + /// - Removes the old delegate dependency, releasing the deposit and allowing old + /// delegated to code to be removed. + /// - Adds a new delegate dependency, ensuring that the new delegated to code + /// cannot be removed. #[ink(message)] - pub fn update_delegate(&mut self, hash: Hash) { + pub fn update_delegate_to(&mut self, hash: Hash) { if let Some(old_hash) = self.delegate_to.get() { self.env().remove_delegate_dependency(&old_hash) } @@ -103,7 +106,9 @@ pub mod delegator { } fn delegate_to(&self) -> Hash { - self.delegate_to.get().expect("delegate_to always has a value") + self.delegate_to + .get() + .expect("delegate_to always has a value") } } @@ -223,5 +228,57 @@ pub mod delegator { Ok(()) } + + #[ink_e2e::test] + async fn update_delegate( + mut client: Client, + ) -> E2EResult<()> { + // given + let origin = client + .create_and_fund_account(&ink_e2e::alice(), 10_000_000_000_000) + .await; + + let code_hash = client + .upload("delegatee", &origin) + .submit() + .await + .expect("upload `delegatee` failed") + .code_hash; + + let code_hash2 = client + .upload("delegatee2", &origin) + .submit() + .await + .expect("upload `delegatee2` failed") + .code_hash; + + let mut constructor = DelegatorRef::new(10, code_hash); + let contract = client + .instantiate("delegator", &origin, &mut constructor) + .submit() + .await + .expect("instantiate failed"); + let mut call_builder = contract.call_builder::(); + + // when + let call_delegate = call_builder.update_delegate_to(code_hash2); + let result = client.call(&origin, &call_delegate).submit().await; + assert!(result.is_ok(), "update_delegate_to failed."); + + // then + + // remove the original delegatee code. + // should succeed because the delegate dependency has been removed. + let original_code_removed = + client.remove_code(&origin, code_hash).submit().await; + assert!(original_code_removed.is_ok()); + + // attempt to remove the new delegatee code. + // should fail because of the delegate dependency. + let new_code_removed = client.remove_code(&origin, code_hash2).submit().await; + assert!(new_code_removed.is_err()); + + Ok(()) + } } } From d864abb743bf77a35929737aa36ad10d51082a88 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 9 Feb 2024 15:13:28 +0000 Subject: [PATCH 08/26] Docs --- crates/env/src/api.rs | 2 +- crates/ink/src/env_access.rs | 57 ++++++++++++++++++++++++++++++++++-- 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/crates/env/src/api.rs b/crates/env/src/api.rs index 5c1e6eb407f..bffc442b067 100644 --- a/crates/env/src/api.rs +++ b/crates/env/src/api.rs @@ -834,7 +834,7 @@ where /// /// - If the supplied `code_hash` cannot be found on-chain. /// - If the `code_hash` is the same as the calling contract. -/// - If the maximum number of delegate_dependencies is reached +/// - If the maximum number of delegate dependencies is reached /// - If the delegate dependency already exists. pub fn add_delegate_dependency(code_hash: &E::Hash) where diff --git a/crates/ink/src/env_access.rs b/crates/ink/src/env_access.rs index 8265f2d2d7c..b0eaaed3d92 100644 --- a/crates/ink/src/env_access.rs +++ b/crates/ink/src/env_access.rs @@ -1184,12 +1184,65 @@ where ink_env::call_runtime::(call) } - /// todo: add_delegate_dependency docs + /// Adds a new delegate dependency for the given `code_hash` to prevent it from being + /// deleted. + /// + /// # Example + /// + /// ``` + /// # #[ink::contract] + /// # pub mod my_contract { + /// # #[ink(storage)] + /// # pub struct MyContract { } + /// # + /// # impl MyContract { + /// # #[ink(constructor)] + /// # pub fn new() -> Self { + /// # Self {} + /// # } + /// # + /// #[ink(message)] + /// pub fn add_delegate_dependency(&mut self, code_hash: Hash) { + /// self.env().add_delegate_dependency(&code_hash) + /// } + /// # } + /// # } + /// ``` + /// + /// # Note + /// + /// For more details visit: [`ink_env::add_delegate_dependency`] pub fn add_delegate_dependency(self, code_hash: &E::Hash) { ink_env::add_delegate_dependency::(code_hash) } - /// todo: remove_delegate_dependency docs + /// Removes the delegate dependency from this contract for the given `code_hash`. + /// + /// # Example + /// + /// ``` + /// # #[ink::contract] + /// # pub mod my_contract { + /// # #[ink(storage)] + /// # pub struct MyContract { } + /// # + /// # impl MyContract { + /// # #[ink(constructor)] + /// # pub fn new() -> Self { + /// # Self {} + /// # } + /// # + /// #[ink(message)] + /// pub fn remove_delegate_dependency(&mut self, code_hash: Hash) { + /// self.env().remove_delegate_dependency(&code_hash) + /// } + /// # } + /// # } + /// ``` + /// + /// # Note + /// + /// For more details visit: [`ink_env::remove_delegate_dependency`] pub fn remove_delegate_dependency(self, code_hash: &E::Hash) { ink_env::remove_delegate_dependency::(code_hash) } From 60b76629bb870e42e30d9d155b83d82e769b0c80 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 9 Feb 2024 15:16:53 +0000 Subject: [PATCH 09/26] CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ce2d2283b6a..6a7f1294eab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [Linter] Publish the linting crates on crates.io - [#2060](https://github.com/paritytech/ink/pull/2060) - [E2E] Added `create_call_builder` for testing existing contracts - [#2075](https://github.com/paritytech/ink/pull/2075) - `call_v2` cross-contract calls with additional limit parameters - [#2077](https://github.com/paritytech/ink/pull/2077) +- `delegate_dependency` api calls - [#2076](https://github.com/paritytech/ink/pull/2076) ### Changed - `Mapping`: Reflect all possible failure cases in comments ‒ [#2079](https://github.com/paritytech/ink/pull/2079) From e9282840dce0d0586b307d855199a4ba7d6dea1e Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 9 Feb 2024 15:31:12 +0000 Subject: [PATCH 10/26] drink unimplemented --- crates/e2e/src/drink_client.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/crates/e2e/src/drink_client.rs b/crates/e2e/src/drink_client.rs index 0f2ed54a166..1670d68dd3a 100644 --- a/crates/e2e/src/drink_client.rs +++ b/crates/e2e/src/drink_client.rs @@ -340,6 +340,14 @@ where }) } + async fn bare_remove_code( + &mut self, + _caller: &Keypair, + _code_hash: E::Hash, + ) -> Result { + unimplemented!("drink! sandbox does not yet support remove_code") + } + async fn bare_call( &mut self, caller: &Keypair, From 82fcc91fe2fc1b4d9dd274fe501588410a9c27fc Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 9 Feb 2024 15:32:15 +0000 Subject: [PATCH 11/26] Send it --- crates/e2e/src/drink_client.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/e2e/src/drink_client.rs b/crates/e2e/src/drink_client.rs index 1670d68dd3a..4370164a8d4 100644 --- a/crates/e2e/src/drink_client.rs +++ b/crates/e2e/src/drink_client.rs @@ -208,7 +208,7 @@ where #[async_trait] impl< AccountId: Clone + Send + Sync + From<[u8; 32]> + AsRef<[u8; 32]>, - Hash: Copy + From<[u8; 32]>, + Hash: Copy + Send + From<[u8; 32]>, Runtime: RuntimeT + pallet_balances::Config + pallet_contracts::Config, E: Environment< AccountId = AccountId, @@ -427,7 +427,7 @@ where impl< AccountId: Clone + Send + Sync + From<[u8; 32]> + AsRef<[u8; 32]>, - Hash: Copy + From<[u8; 32]>, + Hash: Copy + Send + From<[u8; 32]>, Runtime: RuntimeT + pallet_balances::Config + pallet_contracts::Config, E: Environment< AccountId = AccountId, From e1f7a9f017ac6664527faa8acde269fc6334f479 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 9 Feb 2024 16:06:01 +0000 Subject: [PATCH 12/26] Fix comment --- crates/e2e/src/backend.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/e2e/src/backend.rs b/crates/e2e/src/backend.rs index 86df3fbe258..133cfd880db 100644 --- a/crates/e2e/src/backend.rs +++ b/crates/e2e/src/backend.rs @@ -160,12 +160,12 @@ pub trait ContractsBackend { UploadBuilder::new(self, contract_name, caller) } - /// Start building an upload call. + /// Start building a remove code call. /// # Example /// /// ```ignore /// let contract = client - /// .remove(&ink_e2e::alice(), code_hash) + /// .remove_code(&ink_e2e::alice(), code_hash) /// // Submit the call for on-chain execution. /// .submit() /// .await From be62c509f05473f5dffa12f115701552e5afe486 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 9 Feb 2024 16:07:05 +0000 Subject: [PATCH 13/26] Fix comment --- crates/e2e/src/backend_calls.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/e2e/src/backend_calls.rs b/crates/e2e/src/backend_calls.rs index d83cb987c2d..c6a5e59fd4f 100644 --- a/crates/e2e/src/backend_calls.rs +++ b/crates/e2e/src/backend_calls.rs @@ -404,7 +404,7 @@ where } } -/// Allows to build an end-to-end upload call using a builder pattern. +/// Allows to build an end-to-end remove code call using a builder pattern. pub struct RemoveCodeBuilder<'a, E, B> where E: Environment, From 56a3bbf35049c2c82bd13f405fa7a5f65b1706db Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 9 Feb 2024 16:07:33 +0000 Subject: [PATCH 14/26] Fix comment --- crates/e2e/src/backend_calls.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/e2e/src/backend_calls.rs b/crates/e2e/src/backend_calls.rs index c6a5e59fd4f..fde84be4440 100644 --- a/crates/e2e/src/backend_calls.rs +++ b/crates/e2e/src/backend_calls.rs @@ -429,7 +429,7 @@ where } } - /// Execute the upload. + /// Submit the remove code extrinsic. pub async fn submit(&mut self) -> Result { B::bare_remove_code(self.client, self.caller, self.code_hash).await } From 8b21039fb47778fcdcbd3655da9459811631156e Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 9 Feb 2024 16:08:01 +0000 Subject: [PATCH 15/26] Fix comment --- crates/e2e/src/error.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/e2e/src/error.rs b/crates/e2e/src/error.rs index f59f500e18f..b122ceeed7c 100644 --- a/crates/e2e/src/error.rs +++ b/crates/e2e/src/error.rs @@ -44,7 +44,7 @@ pub enum Error { /// The `call` extrinsic failed. #[error("Call extrinsic error: {0}")] CallExtrinsic(DispatchError), - /// The `call` extrinsic failed. + /// The `remove_code` extrinsic failed. #[error("Remove code extrinsic error: {0}")] RemoveCodeExtrinsic(DispatchError), /// Error fetching account balance. From c72676d62b5f380c73613efceb031d553464d132 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 9 Feb 2024 16:08:49 +0000 Subject: [PATCH 16/26] Fix comment --- crates/env/src/backend.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/env/src/backend.rs b/crates/env/src/backend.rs index 30ca092652c..93ef744edd5 100644 --- a/crates/env/src/backend.rs +++ b/crates/env/src/backend.rs @@ -424,7 +424,7 @@ pub trait TypedEnvBackend: EnvBackend { /// # Note /// /// For more details visit: - /// [`remove_delegate_dependency`][`crate::remove_delegate_dependency`] + /// [`add_delegate_dependency`][`crate::add_delegate_dependency`] fn add_delegate_dependency(&mut self, code_hash: &E::Hash) where E: Environment; From 785db390f0651ea8eadcda8328cf20d74e6ceb2d Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Wed, 21 Feb 2024 17:50:20 +0000 Subject: [PATCH 17/26] Update integration-tests/upgradeable-contracts/delegator/delegatee2/Cargo.toml Co-authored-by: Gherman --- .../upgradeable-contracts/delegator/delegatee2/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration-tests/upgradeable-contracts/delegator/delegatee2/Cargo.toml b/integration-tests/upgradeable-contracts/delegator/delegatee2/Cargo.toml index 651b045a6c9..3a0a91ca0a8 100644 --- a/integration-tests/upgradeable-contracts/delegator/delegatee2/Cargo.toml +++ b/integration-tests/upgradeable-contracts/delegator/delegatee2/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "delegatee2" -version = "5.0.0-rc" +version = "5.0.0-rc.1" authors = ["Parity Technologies "] edition = "2021" publish = false From 82d720e720d78badd1c2433016a46bd872ac4f8f Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Wed, 21 Feb 2024 17:51:36 +0000 Subject: [PATCH 18/26] Update crates/e2e/src/backend.rs Co-authored-by: Gherman --- crates/e2e/src/backend.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/e2e/src/backend.rs b/crates/e2e/src/backend.rs index 133cfd880db..3666626a439 100644 --- a/crates/e2e/src/backend.rs +++ b/crates/e2e/src/backend.rs @@ -169,7 +169,7 @@ pub trait ContractsBackend { /// // Submit the call for on-chain execution. /// .submit() /// .await - /// .expect("upload failed"); + /// .expect("remove failed"); /// ``` fn remove_code<'a>( &'a mut self, From 22b01d080e5cd617abd1915d36f150aa96e307ba Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 22 Feb 2024 09:42:31 +0000 Subject: [PATCH 19/26] update to `lock/unlock` host fns --- Cargo.lock | 55 ++++++++++++++++--- Cargo.toml | 2 +- crates/env/src/api.rs | 16 +++--- crates/env/src/backend.rs | 12 ++-- crates/env/src/engine/off_chain/impls.rs | 4 +- crates/env/src/engine/on_chain/impls.rs | 10 ++-- crates/ink/src/env_access.rs | 26 ++++----- .../upgradeable-contracts/delegator/lib.rs | 14 ++--- 8 files changed, 88 insertions(+), 51 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4f6c6e8ad19..b082abd9b74 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2626,7 +2626,6 @@ name = "ink" version = "5.0.0-rc.1" dependencies = [ "derive_more", - "ink-pallet-contracts-uapi", "ink_env 5.0.0-rc.1", "ink_ir", "ink_macro", @@ -2634,6 +2633,7 @@ dependencies = [ "ink_prelude 5.0.0-rc.1", "ink_primitives 5.0.0-rc.1", "ink_storage", + "pallet-contracts-uapi-next", "parity-scale-codec", "scale-info", "trybuild", @@ -2647,7 +2647,7 @@ checksum = "dd3e608f5410d03e529145875eb736305e0d7cae4b989faf54f932eff31bc048" dependencies = [ "bitflags 1.3.2", "paste", - "polkavm-derive", + "polkavm-derive 0.4.0", ] [[package]] @@ -2743,8 +2743,8 @@ version = "5.0.0-rc.1" dependencies = [ "blake2", "derive_more", - "ink-pallet-contracts-uapi", "ink_primitives 5.0.0-rc.1", + "pallet-contracts-uapi-next", "parity-scale-codec", "secp256k1", "sha2 0.10.8", @@ -2776,13 +2776,13 @@ dependencies = [ "const_env", "derive_more", "ink", - "ink-pallet-contracts-uapi", "ink_allocator 5.0.0-rc.1", "ink_engine 5.0.0-rc.1", "ink_prelude 5.0.0-rc.1", "ink_primitives 5.0.0-rc.1", "ink_storage_traits 5.0.0-rc.1", "num-traits", + "pallet-contracts-uapi-next", "parity-scale-codec", "paste", "rlibc", @@ -2946,13 +2946,13 @@ dependencies = [ "cfg-if", "derive_more", "ink", - "ink-pallet-contracts-uapi", "ink_env 5.0.0-rc.1", "ink_metadata 5.0.0-rc.1", "ink_prelude 5.0.0-rc.1", "ink_primitives 5.0.0-rc.1", "ink_storage_traits 5.0.0-rc.1", "itertools 0.12.1", + "pallet-contracts-uapi-next", "parity-scale-codec", "quickcheck", "quickcheck_macros", @@ -3860,10 +3860,21 @@ dependencies = [ "bitflags 1.3.2", "parity-scale-codec", "paste", - "polkavm-derive", + "polkavm-derive 0.4.0", "scale-info", ] +[[package]] +name = "pallet-contracts-uapi-next" +version = "6.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e941fe56abf3b3d127c80d0a82989323f240ad81e6222421a56f1a3142db1e16" +dependencies = [ + "bitflags 1.3.2", + "paste", + "polkavm-derive 0.5.0", +] + [[package]] name = "pallet-timestamp" version = "27.0.0" @@ -4090,13 +4101,29 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fecd2caacfc4a7ee34243758dd7348859e6dec73f5e5df059890f5742ee46f0e" +[[package]] +name = "polkavm-common" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b4e215c80fe876147f3d58158d5dfeae7dabdd6047e175af77095b78d0035c" + [[package]] name = "polkavm-derive" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db65a500d4adf574893c726ae365e37e4fbb7f2cbd403f6eaa1b665457456adc" dependencies = [ - "polkavm-derive-impl", + "polkavm-derive-impl 0.4.0", + "syn 2.0.48", +] + +[[package]] +name = "polkavm-derive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6380dbe1fb03ecc74ad55d841cfc75480222d153ba69ddcb00977866cbdabdb8" +dependencies = [ + "polkavm-derive-impl 0.5.0", "syn 2.0.48", ] @@ -4106,7 +4133,19 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c99f4e7a9ff434ef9c885b874c99d824c3a5693bf5e3e8569bb1d2245a8c1b7f" dependencies = [ - "polkavm-common", + "polkavm-common 0.4.0", + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "polkavm-derive-impl" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc8211b3365bbafb2fb32057d68b0e1ca55d079f5cf6f9da9b98079b94b3987d" +dependencies = [ + "polkavm-common 0.5.0", "proc-macro2", "quote", "syn 2.0.48", diff --git a/Cargo.toml b/Cargo.toml index 7631cb6dfbc..c6bc9097495 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -84,7 +84,7 @@ const_env = { version = "0.1"} # Substrate dependencies pallet-contracts = { version = "27.0.0", default-features = false } -pallet-contracts-uapi = { package = "ink-pallet-contracts-uapi", version = "=6.0.0", default-features = false } +pallet-contracts-uapi = { package = "pallet-contracts-uapi-next", version = "=6.0.1", default-features = false } sp-core = { version = "28.0.0", default-features = false } sp-keyring = { version = "31.0.0", default-features = false } sp-runtime = { version = "31.0.1", default-features = false } diff --git a/crates/env/src/api.rs b/crates/env/src/api.rs index bffc442b067..ce094ee3095 100644 --- a/crates/env/src/api.rs +++ b/crates/env/src/api.rs @@ -824,10 +824,10 @@ where }) } -/// Adds a new delegate dependency to the contract. +/// Adds a new delegate dependency lock to the contract. /// /// This guarantees that the code of the dependency cannot be removed without first -/// calling [`remove_delegate_dependency`]. It charges a fraction of the code +/// calling [`unlock_delegate_dependency`]. It charges a fraction of the code /// deposit. /// /// # Errors @@ -836,29 +836,29 @@ where /// - If the `code_hash` is the same as the calling contract. /// - If the maximum number of delegate dependencies is reached /// - If the delegate dependency already exists. -pub fn add_delegate_dependency(code_hash: &E::Hash) +pub fn lock_delegate_dependency(code_hash: &E::Hash) where E: Environment, { ::on_instance(|instance| { - instance.add_delegate_dependency::(code_hash) + instance.lock_delegate_dependency::(code_hash) }) } -/// Removes the delegate dependency from the contract. +/// Unlocks the delegate dependency from the contract. /// /// This removes the lock and refunds the deposit from the call to -/// [`add_delegate_dependency`]. The code of the dependency can be removed if the +/// [`lock_delegate_dependency`]. The code of the dependency can be removed if the /// reference count for the code hash is now zero. /// /// # Errors /// /// - If the delegate dependency does not exist. -pub fn remove_delegate_dependency(code_hash: &E::Hash) +pub fn unlock_delegate_dependency(code_hash: &E::Hash) where E: Environment, { ::on_instance(|instance| { - instance.remove_delegate_dependency::(code_hash) + instance.unlock_delegate_dependency::(code_hash) }) } diff --git a/crates/env/src/backend.rs b/crates/env/src/backend.rs index 93ef744edd5..e6888523d37 100644 --- a/crates/env/src/backend.rs +++ b/crates/env/src/backend.rs @@ -419,23 +419,23 @@ pub trait TypedEnvBackend: EnvBackend { E: Environment, Call: scale::Encode; - /// Adds a new delegate dependency to the contract. + /// Adds a new delegate dependency lock to the contract. /// /// # Note /// /// For more details visit: - /// [`add_delegate_dependency`][`crate::add_delegate_dependency`] - fn add_delegate_dependency(&mut self, code_hash: &E::Hash) + /// [`lock_delegate_dependency`][`crate::lock_delegate_dependency`] + fn lock_delegate_dependency(&mut self, code_hash: &E::Hash) where E: Environment; - /// Removes the delegate dependency from the contract. + /// Unlocks the delegate dependency from the contract. /// /// # Note /// /// For more details visit: - /// [`remove_delegate_dependency`][`crate::remove_delegate_dependency`] - fn remove_delegate_dependency(&mut self, code_hash: &E::Hash) + /// [`unlock_delegate_dependency`][`crate::unlock_delegate_dependency`] + fn unlock_delegate_dependency(&mut self, code_hash: &E::Hash) where E: Environment; } diff --git a/crates/env/src/engine/off_chain/impls.rs b/crates/env/src/engine/off_chain/impls.rs index e19cbbf41a0..92321ae6e9f 100644 --- a/crates/env/src/engine/off_chain/impls.rs +++ b/crates/env/src/engine/off_chain/impls.rs @@ -561,14 +561,14 @@ impl TypedEnvBackend for EnvInstance { unimplemented!("off-chain environment does not support `call_runtime`") } - fn add_delegate_dependency(&mut self, _code_hash: &E::Hash) + fn lock_delegate_dependency(&mut self, _code_hash: &E::Hash) where E: Environment, { unimplemented!("off-chain environment does not support delegate dependencies") } - fn remove_delegate_dependency(&mut self, _code_hash: &E::Hash) + fn unlock_delegate_dependency(&mut self, _code_hash: &E::Hash) where E: Environment, { diff --git a/crates/env/src/engine/on_chain/impls.rs b/crates/env/src/engine/on_chain/impls.rs index 6bb2a088169..da4bc2628a8 100644 --- a/crates/env/src/engine/on_chain/impls.rs +++ b/crates/env/src/engine/on_chain/impls.rs @@ -661,23 +661,21 @@ impl TypedEnvBackend for EnvInstance { ext::call_runtime(enc_call).map_err(Into::into) } - fn add_delegate_dependency(&mut self, code_hash: &E::Hash) + fn lock_delegate_dependency(&mut self, code_hash: &E::Hash) where E: Environment, { let mut scope = self.scoped_buffer(); let enc_code_hash = scope.take_encoded(code_hash); - #[allow(deprecated)] - ext::add_delegate_dependency(enc_code_hash) + ext::lock_delegate_dependency(enc_code_hash) } - fn remove_delegate_dependency(&mut self, code_hash: &E::Hash) + fn unlock_delegate_dependency(&mut self, code_hash: &E::Hash) where E: Environment, { let mut scope = self.scoped_buffer(); let enc_code_hash = scope.take_encoded(code_hash); - #[allow(deprecated)] - ext::remove_delegate_dependency(enc_code_hash) + ext::unlock_delegate_dependency(enc_code_hash) } } diff --git a/crates/ink/src/env_access.rs b/crates/ink/src/env_access.rs index b0eaaed3d92..a19f9ed7b8b 100644 --- a/crates/ink/src/env_access.rs +++ b/crates/ink/src/env_access.rs @@ -1184,8 +1184,8 @@ where ink_env::call_runtime::(call) } - /// Adds a new delegate dependency for the given `code_hash` to prevent it from being - /// deleted. + /// Adds a new delegate dependency lock for the given `code_hash` to prevent it from + /// being deleted. /// /// # Example /// @@ -1202,8 +1202,8 @@ where /// # } /// # /// #[ink(message)] - /// pub fn add_delegate_dependency(&mut self, code_hash: Hash) { - /// self.env().add_delegate_dependency(&code_hash) + /// pub fn lock_delegate_dependency(&mut self, code_hash: Hash) { + /// self.env().lock_delegate_dependency(&code_hash) /// } /// # } /// # } @@ -1211,12 +1211,12 @@ where /// /// # Note /// - /// For more details visit: [`ink_env::add_delegate_dependency`] - pub fn add_delegate_dependency(self, code_hash: &E::Hash) { - ink_env::add_delegate_dependency::(code_hash) + /// For more details visit: [`ink_env::lock_delegate_dependency`] + pub fn lock_delegate_dependency(self, code_hash: &E::Hash) { + ink_env::lock_delegate_dependency::(code_hash) } - /// Removes the delegate dependency from this contract for the given `code_hash`. + /// Removes the delegate dependency lock from this contract for the given `code_hash`. /// /// # Example /// @@ -1233,8 +1233,8 @@ where /// # } /// # /// #[ink(message)] - /// pub fn remove_delegate_dependency(&mut self, code_hash: Hash) { - /// self.env().remove_delegate_dependency(&code_hash) + /// pub fn unlock_delegate_dependency(&mut self, code_hash: Hash) { + /// self.env().unlock_delegate_dependency(&code_hash) /// } /// # } /// # } @@ -1242,8 +1242,8 @@ where /// /// # Note /// - /// For more details visit: [`ink_env::remove_delegate_dependency`] - pub fn remove_delegate_dependency(self, code_hash: &E::Hash) { - ink_env::remove_delegate_dependency::(code_hash) + /// For more details visit: [`ink_env::unlock_delegate_dependency`] + pub fn unlock_delegate_dependency(self, code_hash: &E::Hash) { + ink_env::unlock_delegate_dependency::(code_hash) } } diff --git a/integration-tests/upgradeable-contracts/delegator/lib.rs b/integration-tests/upgradeable-contracts/delegator/lib.rs index 4f508050add..1969378d7d3 100644 --- a/integration-tests/upgradeable-contracts/delegator/lib.rs +++ b/integration-tests/upgradeable-contracts/delegator/lib.rs @@ -33,11 +33,11 @@ pub mod delegator { let v = Mapping::new(); // Initialize the hash of the contract to delegate to. - // Adds a delegate dependency, ensuring that the delegated to code cannot be - // removed. + // Adds a delegate dependency lock, ensuring that the delegated to code cannot + // be removed. let mut delegate_to = Lazy::new(); delegate_to.set(&hash); - Self::env().add_delegate_dependency(&hash); + Self::env().lock_delegate_dependency(&hash); Self { addresses: v, @@ -47,16 +47,16 @@ pub mod delegator { } /// Update the hash of the contract to delegate to. - /// - Removes the old delegate dependency, releasing the deposit and allowing old + /// - Unlocks the old delegate dependency, releasing the deposit and allowing old /// delegated to code to be removed. - /// - Adds a new delegate dependency, ensuring that the new delegated to code + /// - Adds a new delegate dependency lock, ensuring that the new delegated to code /// cannot be removed. #[ink(message)] pub fn update_delegate_to(&mut self, hash: Hash) { if let Some(old_hash) = self.delegate_to.get() { - self.env().remove_delegate_dependency(&old_hash) + self.env().unlock_delegate_dependency(&old_hash) } - self.env().add_delegate_dependency(&hash); + self.env().lock_delegate_dependency(&hash); self.delegate_to.set(&hash); } From f0c99e822b81fd4c6de3c39971b5171760842e7b Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 22 Feb 2024 09:49:15 +0000 Subject: [PATCH 20/26] #[allow(deprecated)] for _v1 calls --- crates/env/src/engine/on_chain/impls.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/env/src/engine/on_chain/impls.rs b/crates/env/src/engine/on_chain/impls.rs index da4bc2628a8..10f5af7d155 100644 --- a/crates/env/src/engine/on_chain/impls.rs +++ b/crates/env/src/engine/on_chain/impls.rs @@ -447,6 +447,7 @@ impl TypedEnvBackend for EnvInstance { }; let output = &mut scope.take_rest(); let flags = params.call_flags(); + #[allow(deprecated)] let call_result = ext::call_v1( *flags, enc_callee, @@ -570,6 +571,7 @@ impl TypedEnvBackend for EnvInstance { let salt = params.salt_bytes().as_ref(); let out_return_value = &mut scoped.take_rest(); + #[allow(deprecated)] let instantiate_result = ext::instantiate_v1( enc_code_hash, gas_limit, From 4d975b8824cf715ae54ff370fa7033932f2ad096 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 22 Feb 2024 10:18:58 +0000 Subject: [PATCH 21/26] Add link to lock up deposit --- crates/env/src/api.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/env/src/api.rs b/crates/env/src/api.rs index ce094ee3095..6afbec3e0b9 100644 --- a/crates/env/src/api.rs +++ b/crates/env/src/api.rs @@ -828,7 +828,7 @@ where /// /// This guarantees that the code of the dependency cannot be removed without first /// calling [`unlock_delegate_dependency`]. It charges a fraction of the code -/// deposit. +/// deposit, see [`pallet_contracts::Config::CodeHashLockupDepositPercent`](https://docs.rs/pallet-contracts/latest/pallet_contracts/pallet/trait.Config.html#associatedtype.CodeHashLockupDepositPercent) for details. /// /// # Errors /// From 430a831b1e4084e154744910f36a9f40516699fe Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 22 Feb 2024 10:19:14 +0000 Subject: [PATCH 22/26] doc comment as per review --- integration-tests/upgradeable-contracts/delegator/lib.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/integration-tests/upgradeable-contracts/delegator/lib.rs b/integration-tests/upgradeable-contracts/delegator/lib.rs index 1969378d7d3..75b43bb04ea 100644 --- a/integration-tests/upgradeable-contracts/delegator/lib.rs +++ b/integration-tests/upgradeable-contracts/delegator/lib.rs @@ -27,7 +27,11 @@ pub mod delegator { } impl Delegator { - /// Creates a new delegator smart contract initialized with the given value. + /// Creates a new delegator smart contract with an initial value, and the hash of + /// the contract code to delegate to. + /// + /// Additionally, this code hash will be locked to prevent its deletion, since + /// this contract depends on it. #[ink(constructor)] pub fn new(init_value: i32, hash: Hash) -> Self { let v = Mapping::new(); From eb36349983ca0bf733ded0a4cfff61eaa20a99f2 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 23 Feb 2024 17:12:58 +0000 Subject: [PATCH 23/26] Update crates/e2e/src/backend.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Michael Müller --- crates/e2e/src/backend.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/e2e/src/backend.rs b/crates/e2e/src/backend.rs index 3666626a439..6efac2ab4be 100644 --- a/crates/e2e/src/backend.rs +++ b/crates/e2e/src/backend.rs @@ -217,7 +217,7 @@ pub trait ContractsBackend { #[async_trait] pub trait BuilderClient: ContractsBackend { /// Executes a bare `call` for the contract at `account_id`. This function does not - /// perform a dry-run, and user is expected to provide the gas limit. + /// perform a dry-run, and the user is expected to provide the gas limit. /// /// Use it when you want to have a more precise control over submitting extrinsic. /// From c5581dca1a527321135fc8a91e5b5ccf6a1f0024 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 23 Feb 2024 17:13:11 +0000 Subject: [PATCH 24/26] Update crates/e2e/src/backend.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Michael Müller --- crates/e2e/src/backend.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/e2e/src/backend.rs b/crates/e2e/src/backend.rs index 6efac2ab4be..2f9b395dddb 100644 --- a/crates/e2e/src/backend.rs +++ b/crates/e2e/src/backend.rs @@ -161,6 +161,7 @@ pub trait ContractsBackend { } /// Start building a remove code call. + /// /// # Example /// /// ```ignore From e9b39c9352dde168d855ce43d57daa2d190d4a89 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 23 Feb 2024 17:13:21 +0000 Subject: [PATCH 25/26] Update crates/env/src/api.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Michael Müller --- crates/env/src/api.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/env/src/api.rs b/crates/env/src/api.rs index 6afbec3e0b9..a532f593c8b 100644 --- a/crates/env/src/api.rs +++ b/crates/env/src/api.rs @@ -834,7 +834,7 @@ where /// /// - If the supplied `code_hash` cannot be found on-chain. /// - If the `code_hash` is the same as the calling contract. -/// - If the maximum number of delegate dependencies is reached +/// - If the maximum number of delegate dependencies is reached. /// - If the delegate dependency already exists. pub fn lock_delegate_dependency(code_hash: &E::Hash) where From d20cd52aa18cee5ad14e471d9068871cf390d521 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 23 Feb 2024 17:14:28 +0000 Subject: [PATCH 26/26] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Michael Müller --- crates/env/src/backend.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/env/src/backend.rs b/crates/env/src/backend.rs index e6888523d37..55af65dc965 100644 --- a/crates/env/src/backend.rs +++ b/crates/env/src/backend.rs @@ -434,7 +434,7 @@ pub trait TypedEnvBackend: EnvBackend { /// # Note /// /// For more details visit: - /// [`unlock_delegate_dependency`][`crate::unlock_delegate_dependency`] + /// [`unlock_delegate_dependency`][`crate::unlock_delegate_dependency`]. fn unlock_delegate_dependency(&mut self, code_hash: &E::Hash) where E: Environment;