Contracts: Stabilize APIs (#3384)

Remove `#[unstable]` on `call_v2`, `instantiate_v2`,
`lock_delegate_dependency` and `unlock_delegate_dependency`.
See ink! integrations: 
- call_v2: https://github.com/paritytech/ink/pull/2077
- instantiate_v2: <TODO>
- lock/unlock dependency: https://github.com/paritytech/ink/pull/2076
This commit is contained in:
PG Herveou
2024-02-20 15:28:05 +01:00
committed by GitHub
parent e89d0fca35
commit d250a6e427
26 changed files with 137 additions and 140 deletions
@@ -895,7 +895,7 @@ benchmarks! {
},
ImportedFunction {
module: "seal0",
name: "add_delegate_dependency",
name: "lock_delegate_dependency",
params: vec![ValueType::I32],
return_type: None,
}
@@ -2402,7 +2402,7 @@ benchmarks! {
}: call(origin, instance.addr, 0u32.into(), Weight::MAX, None, vec![])
#[pov_mode = Measured]
add_delegate_dependency {
lock_delegate_dependency {
let r in 0 .. T::MaxDelegateDependencies::get();
let code_hashes = (0..r)
.map(|i| {
@@ -2420,7 +2420,7 @@ benchmarks! {
memory: Some(ImportedMemory::max::<T>()),
imported_functions: vec![ImportedFunction {
module: "seal0",
name: "add_delegate_dependency",
name: "lock_delegate_dependency",
params: vec![ValueType::I32],
return_type: None,
}],
@@ -2440,7 +2440,7 @@ benchmarks! {
let origin = RawOrigin::Signed(instance.caller.clone());
}: call(origin, instance.addr, 0u32.into(), Weight::MAX, None, vec![])
remove_delegate_dependency {
unlock_delegate_dependency {
let r in 0 .. T::MaxDelegateDependencies::get();
let code_hashes = (0..r)
.map(|i| {
@@ -2459,12 +2459,12 @@ benchmarks! {
memory: Some(ImportedMemory::max::<T>()),
imported_functions: vec![ImportedFunction {
module: "seal0",
name: "remove_delegate_dependency",
name: "unlock_delegate_dependency",
params: vec![ValueType::I32],
return_type: None,
}, ImportedFunction {
module: "seal0",
name: "add_delegate_dependency",
name: "lock_delegate_dependency",
params: vec![ValueType::I32],
return_type: None
}],
+8 -8
View File
@@ -348,20 +348,20 @@ pub trait Ext: sealing::Sealed {
/// - [`Error::<T>::MaxDelegateDependenciesReached`]
/// - [`Error::<T>::CannotAddSelfAsDelegateDependency`]
/// - [`Error::<T>::DelegateDependencyAlreadyExists`]
fn add_delegate_dependency(
fn lock_delegate_dependency(
&mut self,
code_hash: CodeHash<Self::T>,
) -> Result<(), DispatchError>;
/// Removes a delegate dependency from [`ContractInfo`]'s `delegate_dependencies` field.
///
/// This is the counterpart of [`Self::add_delegate_dependency`]. It decreases the reference
/// count and refunds the deposit that was charged by [`Self::add_delegate_dependency`].
/// This is the counterpart of [`Self::lock_delegate_dependency`]. It decreases the reference
/// count and refunds the deposit that was charged by [`Self::lock_delegate_dependency`].
///
/// # Errors
///
/// - [`Error::<T>::DelegateDependencyNotFound`]
fn remove_delegate_dependency(
fn unlock_delegate_dependency(
&mut self,
code_hash: &CodeHash<Self::T>,
) -> Result<(), DispatchError>;
@@ -1554,7 +1554,7 @@ where
});
}
fn add_delegate_dependency(
fn lock_delegate_dependency(
&mut self,
code_hash: CodeHash<Self::T>,
) -> Result<(), DispatchError> {
@@ -1565,7 +1565,7 @@ where
let code_info = CodeInfoOf::<T>::get(code_hash).ok_or(Error::<T>::CodeNotFound)?;
let deposit = T::CodeHashLockupDepositPercent::get().mul_ceil(code_info.deposit());
info.add_delegate_dependency(code_hash, deposit)?;
info.lock_delegate_dependency(code_hash, deposit)?;
Self::increment_refcount(code_hash)?;
frame
.nested_storage
@@ -1573,14 +1573,14 @@ where
Ok(())
}
fn remove_delegate_dependency(
fn unlock_delegate_dependency(
&mut self,
code_hash: &CodeHash<Self::T>,
) -> Result<(), DispatchError> {
let frame = self.top_frame_mut();
let info = frame.contract_info.get(&frame.account_id);
let deposit = info.remove_delegate_dependency(code_hash)?;
let deposit = info.unlock_delegate_dependency(code_hash)?;
Self::decrement_refcount(*code_hash);
frame
.nested_storage
+2 -2
View File
@@ -325,7 +325,7 @@ pub mod pallet {
type DepositPerItem: Get<BalanceOf<Self>>;
/// The percentage of the storage deposit that should be held for using a code hash.
/// Instantiating a contract, or calling [`chain_extension::Ext::add_delegate_dependency`]
/// Instantiating a contract, or calling [`chain_extension::Ext::lock_delegate_dependency`]
/// protects the code from being removed. In order to prevent abuse these actions are
/// protected with a percentage of the code deposit.
#[pallet::constant]
@@ -347,7 +347,7 @@ pub mod pallet {
type MaxStorageKeyLen: Get<u32>;
/// The maximum number of delegate_dependencies that a contract can lock with
/// [`chain_extension::Ext::add_delegate_dependency`].
/// [`chain_extension::Ext::lock_delegate_dependency`].
#[pallet::constant]
type MaxDelegateDependencies: Get<u32>;
+6 -6
View File
@@ -298,11 +298,11 @@ pub struct HostFnWeights<T: Config> {
/// Weight of calling `instantiation_nonce`.
pub instantiation_nonce: Weight,
/// Weight of calling `add_delegate_dependency`.
pub add_delegate_dependency: Weight,
/// Weight of calling `lock_delegate_dependency`.
pub lock_delegate_dependency: Weight,
/// Weight of calling `remove_delegate_dependency`.
pub remove_delegate_dependency: Weight,
/// Weight of calling `unlock_delegate_dependency`.
pub unlock_delegate_dependency: Weight,
/// The type parameter is used in the default implementation.
#[codec(skip)]
@@ -435,8 +435,8 @@ impl<T: Config> Default for HostFnWeights<T> {
reentrance_count: cost!(seal_reentrance_count),
account_reentrance_count: cost!(seal_account_reentrance_count),
instantiation_nonce: cost!(seal_instantiation_nonce),
add_delegate_dependency: cost!(add_delegate_dependency),
remove_delegate_dependency: cost!(remove_delegate_dependency),
lock_delegate_dependency: cost!(lock_delegate_dependency),
unlock_delegate_dependency: cost!(unlock_delegate_dependency),
_phantom: PhantomData,
}
}
+3 -3
View File
@@ -66,7 +66,7 @@ pub struct ContractInfo<T: Config> {
storage_base_deposit: BalanceOf<T>,
/// Map of code hashes and deposit balances.
///
/// Tracks the code hash and deposit held for adding delegate dependencies. Dependencies added
/// Tracks the code hash and deposit held for locking delegate dependencies. Dependencies added
/// to the map can not be removed from the chain state and can be safely used for delegate
/// calls.
delegate_dependencies: BoundedBTreeMap<CodeHash<T>, BalanceOf<T>, T::MaxDelegateDependencies>,
@@ -233,7 +233,7 @@ impl<T: Config> ContractInfo<T> {
///
/// Returns an error if the maximum number of delegate_dependencies is reached or if
/// the delegate dependency already exists.
pub fn add_delegate_dependency(
pub fn lock_delegate_dependency(
&mut self,
code_hash: CodeHash<T>,
amount: BalanceOf<T>,
@@ -249,7 +249,7 @@ impl<T: Config> ContractInfo<T> {
/// dependency.
///
/// Returns an error if the entry doesn't exist.
pub fn remove_delegate_dependency(
pub fn unlock_delegate_dependency(
&mut self,
code_hash: &CodeHash<T>,
) -> Result<BalanceOf<T>, DispatchError> {
+19 -19
View File
@@ -5406,21 +5406,21 @@ fn delegate_call_indeterministic_code() {
}
#[test]
fn add_remove_delegate_dependency_works() {
fn locking_delegate_dependency_works() {
// set hash lock up deposit to 30%, to test deposit calculation.
CODE_HASH_LOCKUP_DEPOSIT_PERCENT.with(|c| *c.borrow_mut() = Perbill::from_percent(30));
MAX_DELEGATE_DEPENDENCIES.with(|c| *c.borrow_mut() = 1);
let (wasm_caller, self_code_hash) =
compile_module::<Test>("add_remove_delegate_dependency").unwrap();
compile_module::<Test>("locking_delegate_dependency").unwrap();
let (wasm_callee, code_hash) = compile_module::<Test>("dummy").unwrap();
let (wasm_other, other_code_hash) = compile_module::<Test>("call").unwrap();
// Define inputs with various actions to test adding / removing delegate_dependencies.
// Define inputs with various actions to test locking / unlocking delegate_dependencies.
// See the contract for more details.
let noop_input = (0u32, code_hash);
let add_delegate_dependency_input = (1u32, code_hash);
let remove_delegate_dependency_input = (2u32, code_hash);
let lock_delegate_dependency_input = (1u32, code_hash);
let unlock_delegate_dependency_input = (2u32, code_hash);
let terminate_input = (3u32, code_hash);
// Instantiate the caller contract with the given input.
@@ -5457,9 +5457,9 @@ fn add_remove_delegate_dependency_works() {
ExtBuilder::default().existential_deposit(ED).build().execute_with(|| {
let _ = Balances::set_balance(&ALICE, 1_000_000);
// Instantiate with add_delegate_dependency should fail since the code is not yet on chain.
// Instantiate with lock_delegate_dependency should fail since the code is not yet on chain.
assert_err!(
instantiate(&add_delegate_dependency_input).result,
instantiate(&lock_delegate_dependency_input).result,
Error::<Test>::CodeNotFound
);
@@ -5469,7 +5469,7 @@ fn add_remove_delegate_dependency_works() {
.unwrap();
// Instantiate should now work.
let addr_caller = instantiate(&add_delegate_dependency_input).result.unwrap().account_id;
let addr_caller = instantiate(&lock_delegate_dependency_input).result.unwrap().account_id;
// There should be a dependency and a deposit.
let contract = test_utils::get_contract(&addr_caller);
@@ -5490,27 +5490,27 @@ fn add_remove_delegate_dependency_works() {
<Error<Test>>::CodeInUse
);
// Adding an already existing dependency should fail.
// Locking an already existing dependency should fail.
assert_err!(
call(&addr_caller, &add_delegate_dependency_input).result,
call(&addr_caller, &lock_delegate_dependency_input).result,
Error::<Test>::DelegateDependencyAlreadyExists
);
// Adding a dependency to self should fail.
// Locking self should fail.
assert_err!(
call(&addr_caller, &(1u32, self_code_hash)).result,
Error::<Test>::CannotAddSelfAsDelegateDependency
);
// Adding more than the maximum allowed delegate_dependencies should fail.
// Locking more than the maximum allowed delegate_dependencies should fail.
Contracts::bare_upload_code(ALICE, wasm_other, None, Determinism::Enforced).unwrap();
assert_err!(
call(&addr_caller, &(1u32, other_code_hash)).result,
Error::<Test>::MaxDelegateDependenciesReached
);
// Removing dependency should work.
assert_ok!(call(&addr_caller, &remove_delegate_dependency_input).result);
// Unlocking dependency should work.
assert_ok!(call(&addr_caller, &unlock_delegate_dependency_input).result);
// Dependency should be removed, and deposit should be returned.
let contract = test_utils::get_contract(&addr_caller);
@@ -5525,18 +5525,18 @@ fn add_remove_delegate_dependency_works() {
// Removing an unexisting dependency should fail.
assert_err!(
call(&addr_caller, &remove_delegate_dependency_input).result,
call(&addr_caller, &unlock_delegate_dependency_input).result,
Error::<Test>::DelegateDependencyNotFound
);
// Adding a dependency with a storage limit too low should fail.
// Locking a dependency with a storage limit too low should fail.
DEFAULT_DEPOSIT_LIMIT.with(|c| *c.borrow_mut() = dependency_deposit - 1);
assert_err!(
call(&addr_caller, &add_delegate_dependency_input).result,
call(&addr_caller, &lock_delegate_dependency_input).result,
Error::<Test>::StorageDepositLimitExhausted
);
// Since we removed the dependency we should now be able to remove the code.
// Since we unlocked the dependency we should now be able to remove the code.
assert_ok!(Contracts::remove_code(RuntimeOrigin::signed(ALICE), code_hash));
// Calling should fail since the delegated contract is not on chain anymore.
@@ -5545,7 +5545,7 @@ fn add_remove_delegate_dependency_works() {
// Restore initial deposit limit and add the dependency back.
DEFAULT_DEPOSIT_LIMIT.with(|c| *c.borrow_mut() = 10_000_000);
Contracts::bare_upload_code(ALICE, wasm_callee, None, Determinism::Enforced).unwrap();
call(&addr_caller, &add_delegate_dependency_input).result.unwrap();
call(&addr_caller, &lock_delegate_dependency_input).result.unwrap();
// Call terminate should work, and return the deposit.
let balance_before = test_utils::get_balance(&ALICE);
+10 -10
View File
@@ -733,14 +733,14 @@ mod tests {
Ok(())
}
fn decrement_refcount(_code_hash: CodeHash<Self::T>) {}
fn add_delegate_dependency(
fn lock_delegate_dependency(
&mut self,
code: CodeHash<Self::T>,
) -> Result<(), DispatchError> {
self.delegate_dependencies.borrow_mut().insert(code);
Ok(())
}
fn remove_delegate_dependency(
fn unlock_delegate_dependency(
&mut self,
code: &CodeHash<Self::T>,
) -> Result<(), DispatchError> {
@@ -3399,16 +3399,16 @@ mod tests {
}
#[test]
fn add_remove_delegate_dependency() {
const CODE_ADD_REMOVE_DELEGATE_DEPENDENCY: &str = r#"
fn lock_unlock_delegate_dependency() {
const CODE_LOCK_UNLOCK_DELEGATE_DEPENDENCY: &str = r#"
(module
(import "seal0" "add_delegate_dependency" (func $add_delegate_dependency (param i32)))
(import "seal0" "remove_delegate_dependency" (func $remove_delegate_dependency (param i32)))
(import "seal0" "lock_delegate_dependency" (func $lock_delegate_dependency (param i32)))
(import "seal0" "unlock_delegate_dependency" (func $unlock_delegate_dependency (param i32)))
(import "env" "memory" (memory 1 1))
(func (export "call")
(call $add_delegate_dependency (i32.const 0))
(call $add_delegate_dependency (i32.const 32))
(call $remove_delegate_dependency (i32.const 32))
(call $lock_delegate_dependency (i32.const 0))
(call $lock_delegate_dependency (i32.const 32))
(call $unlock_delegate_dependency (i32.const 32))
)
(func (export "deploy"))
@@ -3426,7 +3426,7 @@ mod tests {
)
"#;
let mut mock_ext = MockExt::default();
assert_ok!(execute(&CODE_ADD_REMOVE_DELEGATE_DEPENDENCY, vec![], &mut mock_ext));
assert_ok!(execute(&CODE_LOCK_UNLOCK_DELEGATE_DEPENDENCY, vec![], &mut mock_ext));
let delegate_dependencies: Vec<_> =
mock_ext.delegate_dependencies.into_inner().into_iter().collect();
assert_eq!(delegate_dependencies.len(), 1);
+14 -16
View File
@@ -246,10 +246,10 @@ pub enum RuntimeCosts {
AccountEntranceCount,
/// Weight of calling `instantiation_nonce`
InstantationNonce,
/// Weight of calling `add_delegate_dependency`
AddDelegateDependency,
/// Weight of calling `remove_delegate_dependency`
RemoveDelegateDependency,
/// Weight of calling `lock_delegate_dependency`
LockDelegateDependency,
/// Weight of calling `unlock_delegate_dependency`
UnlockDelegateDependency,
}
impl<T: Config> Token<T> for RuntimeCosts {
@@ -338,8 +338,8 @@ impl<T: Config> Token<T> for RuntimeCosts {
ReentrantCount => s.reentrance_count,
AccountEntranceCount => s.account_reentrance_count,
InstantationNonce => s.instantiation_nonce,
AddDelegateDependency => s.add_delegate_dependency,
RemoveDelegateDependency => s.remove_delegate_dependency,
LockDelegateDependency => s.lock_delegate_dependency,
UnlockDelegateDependency => s.unlock_delegate_dependency,
}
}
}
@@ -1216,7 +1216,6 @@ pub mod env {
/// Make a call to another contract.
/// See [`pallet_contracts_uapi::HostFn::call_v2`].
#[version(2)]
#[unstable]
fn call(
ctx: _,
memory: _,
@@ -1353,7 +1352,6 @@ pub mod env {
/// Instantiate a contract with the specified code hash.
/// See [`pallet_contracts_uapi::HostFn::instantiate_v2`].
#[version(2)]
#[unstable]
fn instantiate(
ctx: _,
memory: _,
@@ -2306,22 +2304,22 @@ pub mod env {
}
/// Adds a new delegate dependency to the contract.
/// See [`pallet_contracts_uapi::HostFn::add_delegate_dependency`].
/// See [`pallet_contracts_uapi::HostFn::lock_delegate_dependency`].
#[unstable]
fn add_delegate_dependency(ctx: _, memory: _, code_hash_ptr: u32) -> Result<(), TrapReason> {
ctx.charge_gas(RuntimeCosts::AddDelegateDependency)?;
fn lock_delegate_dependency(ctx: _, memory: _, code_hash_ptr: u32) -> Result<(), TrapReason> {
ctx.charge_gas(RuntimeCosts::LockDelegateDependency)?;
let code_hash = ctx.read_sandbox_memory_as(memory, code_hash_ptr)?;
ctx.ext.add_delegate_dependency(code_hash)?;
ctx.ext.lock_delegate_dependency(code_hash)?;
Ok(())
}
/// Removes the delegate dependency from the contract.
/// see [`pallet_contracts_uapi::HostFn::remove_delegate_dependency`].
/// see [`pallet_contracts_uapi::HostFn::unlock_delegate_dependency`].
#[unstable]
fn remove_delegate_dependency(ctx: _, memory: _, code_hash_ptr: u32) -> Result<(), TrapReason> {
ctx.charge_gas(RuntimeCosts::RemoveDelegateDependency)?;
fn unlock_delegate_dependency(ctx: _, memory: _, code_hash_ptr: u32) -> Result<(), TrapReason> {
ctx.charge_gas(RuntimeCosts::UnlockDelegateDependency)?;
let code_hash = ctx.read_sandbox_memory_as(memory, code_hash_ptr)?;
ctx.ext.remove_delegate_dependency(&code_hash)?;
ctx.ext.unlock_delegate_dependency(&code_hash)?;
Ok(())
}
}
+6 -6
View File
@@ -124,8 +124,8 @@ pub trait WeightInfo {
fn seal_ecdsa_recover(r: u32, ) -> Weight;
fn seal_ecdsa_to_eth_address(r: u32, ) -> Weight;
fn seal_set_code_hash(r: u32, ) -> Weight;
fn add_delegate_dependency(r: u32, ) -> Weight;
fn remove_delegate_dependency(r: u32, ) -> Weight;
fn lock_delegate_dependency(r: u32, ) -> Weight;
fn unlock_delegate_dependency(r: u32, ) -> Weight;
fn seal_reentrance_count(r: u32, ) -> Weight;
fn seal_account_reentrance_count(r: u32, ) -> Weight;
fn seal_instantiation_nonce(r: u32, ) -> Weight;
@@ -1891,7 +1891,7 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
/// Storage: `System::EventTopics` (r:2 w:2)
/// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// The range of component `r` is `[0, 32]`.
fn add_delegate_dependency(r: u32, ) -> Weight {
fn lock_delegate_dependency(r: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `928 + r * (131 ±0)`
// Estimated: `6878 + r * (2606 ±0)`
@@ -1920,7 +1920,7 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
/// Storage: `System::EventTopics` (r:2 w:2)
/// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// The range of component `r` is `[0, 32]`.
fn remove_delegate_dependency(r: u32, ) -> Weight {
fn unlock_delegate_dependency(r: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `969 + r * (183 ±0)`
// Estimated: `129453 + r * (2568 ±0)`
@@ -3787,7 +3787,7 @@ impl WeightInfo for () {
/// Storage: `System::EventTopics` (r:2 w:2)
/// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// The range of component `r` is `[0, 32]`.
fn add_delegate_dependency(r: u32, ) -> Weight {
fn lock_delegate_dependency(r: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `928 + r * (131 ±0)`
// Estimated: `6878 + r * (2606 ±0)`
@@ -3816,7 +3816,7 @@ impl WeightInfo for () {
/// Storage: `System::EventTopics` (r:2 w:2)
/// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// The range of component `r` is `[0, 32]`.
fn remove_delegate_dependency(r: u32, ) -> Weight {
fn unlock_delegate_dependency(r: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `969 + r * (183 ±0)`
// Estimated: `129453 + r * (2568 ±0)`