Skip to content

Commit

Permalink
Contracts: Stabilize APIs (#3384)
Browse files Browse the repository at this point in the history
Remove `#[unstable]` on `call_v2`, `instantiate_v2`,
`lock_delegate_dependency` and `unlock_delegate_dependency`.
See ink! integrations: 
- call_v2: use-ink/ink#2077
- instantiate_v2: <TODO>
- lock/unlock dependency: use-ink/ink#2076
  • Loading branch information
pgherveou committed Feb 20, 2024
1 parent e89d0fc commit d250a6e
Show file tree
Hide file tree
Showing 26 changed files with 137 additions and 140 deletions.
14 changes: 14 additions & 0 deletions prdoc/pr_3384.prdoc
@@ -0,0 +1,14 @@
# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0
# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json

title: "[pallet_contracts] stabilize `call_v2`, `instantiate_v2`, `lock_dependency` and `unlock_dependency`"

doc:
- audience: Runtime Dev
description: |
These APIs are currently unstable and are being stabilized in this PR.
Note: `add_delegate_dependency` and `remove_delegate_dependency` have been renamed to `lock_dependency` and `unlock_dependency` respectively.

crates:
- name: pallet-contracts-uapi
- name: pallet-contracts
8 changes: 5 additions & 3 deletions substrate/frame/contracts/fixtures/contracts/call.rs
Expand Up @@ -35,11 +35,13 @@ pub extern "C" fn call() {
);

// Call the callee
api::call_v1(
api::call_v2(
uapi::CallFlags::empty(),
callee_addr,
0u64, // How much gas to devote for the execution. 0 = all.
&0u64.to_le_bytes(), // value transferred to the contract.
0u64, // How much ref_time to devote for the execution. 0 = all.
0u64, // How much proof_size to devote for the execution. 0 = all.
None, // No deposit limit.
&0u64.to_le_bytes(), // Value transferred to the contract.
callee_input,
None,
)
Expand Down
Expand Up @@ -38,11 +38,13 @@ pub extern "C" fn call() {
);

// Call the callee
let err_code = match api::call_v1(
let err_code = match api::call_v2(
uapi::CallFlags::empty(),
callee_addr,
0u64, // How much gas to devote for the execution. 0 = all.
&100u64.to_le_bytes(), // value transferred to the contract.
0u64, // How much ref_time to devote for the execution. 0 = all.
0u64, // How much proof_size to devote for the execution. 0 = all.
None, // No deposit limit.
&100u64.to_le_bytes(), // Value transferred to the contract.
input,
None,
) {
Expand Down
Expand Up @@ -39,11 +39,13 @@ pub extern "C" fn call() {
api::call_runtime(call).unwrap();

// Call the callee
api::call_v1(
api::call_v2(
uapi::CallFlags::empty(),
callee_addr,
0u64, // How much gas to devote for the execution. 0 = all.
&0u64.to_le_bytes(), // value transferred to the contract.
0u64, // How much ref_time to devote for the execution. 0 = all.
0u64, // How much proof_size to devote for the execution. 0 = all.
None, // No deposit limit.
&0u64.to_le_bytes(), // Value transferred to the contract.
callee_input,
None,
)
Expand Down
Expand Up @@ -38,7 +38,6 @@ pub extern "C" fn call() {
forwarded_input: [u8],
);

#[allow(deprecated)]
api::call_v2(
uapi::CallFlags::empty(),
callee_addr,
Expand Down
10 changes: 1 addition & 9 deletions substrate/frame/contracts/fixtures/contracts/caller_contract.rs
Expand Up @@ -40,7 +40,6 @@ pub extern "C" fn call() {
let reverted_input = [1u8, 34, 51, 68, 85, 102, 119];

// Fail to deploy the contract since it returns a non-zero exit status.
#[allow(deprecated)]
let res = api::instantiate_v2(
code_hash,
0u64, // How much ref_time weight to devote for the execution. 0 = all.
Expand All @@ -55,7 +54,6 @@ pub extern "C" fn call() {
assert!(matches!(res, Err(ReturnErrorCode::CalleeReverted)));

// Fail to deploy the contract due to insufficient ref_time weight.
#[allow(deprecated)]
let res = api::instantiate_v2(
code_hash, 1u64, // too little ref_time weight
0u64, // How much proof_size weight to devote for the execution. 0 = all.
Expand All @@ -65,7 +63,6 @@ pub extern "C" fn call() {
assert!(matches!(res, Err(ReturnErrorCode::CalleeTrapped)));

// Fail to deploy the contract due to insufficient proof_size weight.
#[allow(deprecated)]
let res = api::instantiate_v2(
code_hash, 0u64, // How much ref_time weight to devote for the execution. 0 = all.
1u64, // Too little proof_size weight
Expand All @@ -78,7 +75,6 @@ pub extern "C" fn call() {
let mut callee = [0u8; 32];
let callee = &mut &mut callee[..];

#[allow(deprecated)]
api::instantiate_v2(
code_hash,
0u64, // How much ref_time weight to devote for the execution. 0 = all.
Expand All @@ -94,7 +90,6 @@ pub extern "C" fn call() {
assert_eq!(callee.len(), 32);

// Call the new contract and expect it to return failing exit code.
#[allow(deprecated)]
let res = api::call_v2(
uapi::CallFlags::empty(),
callee,
Expand All @@ -108,11 +103,10 @@ pub extern "C" fn call() {
assert!(matches!(res, Err(ReturnErrorCode::CalleeReverted)));

// Fail to call the contract due to insufficient ref_time weight.
#[allow(deprecated)]
let res = api::call_v2(
uapi::CallFlags::empty(),
callee,
1u64, // too little ref_time weight
1u64, // Too little ref_time weight.
0u64, // How much proof_size weight to devote for the execution. 0 = all.
None, // No deposit limit.
&value,
Expand All @@ -122,7 +116,6 @@ pub extern "C" fn call() {
assert!(matches!(res, Err(ReturnErrorCode::CalleeTrapped)));

// Fail to call the contract due to insufficient proof_size weight.
#[allow(deprecated)]
let res = api::call_v2(
uapi::CallFlags::empty(),
callee,
Expand All @@ -137,7 +130,6 @@ pub extern "C" fn call() {

// Call the contract successfully.
let mut output = [0u8; 4];
#[allow(deprecated)]
api::call_v2(
uapi::CallFlags::empty(),
callee,
Expand Down
Expand Up @@ -50,11 +50,13 @@ pub extern "C" fn call() {
output!(addr, [0u8; 32], api::address,);

// call self
api::call_v1(
api::call_v2(
uapi::CallFlags::ALLOW_REENTRY,
addr,
0u64, // How much gas to devote for the execution. 0 = all.
&0u64.to_le_bytes(), // value transferred to the contract.
0u64, // How much ref_time to devote for the execution. 0 = all.
0u64, // How much proof_size to devote for the execution. 0 = all.
None, // No deposit limit.
&0u64.to_le_bytes(), // Value transferred to the contract.
input,
None,
)
Expand Down
Expand Up @@ -40,14 +40,13 @@ pub extern "C" fn call() {
api::set_storage(buffer, &[1u8; 4]);

// Call the callee
#[allow(deprecated)]
api::call_v2(
uapi::CallFlags::empty(),
callee,
0u64, // How much ref_time weight to devote for the execution. 0 = all.
0u64, // How much proof_size weight to devote for the execution. 0 = all.
Some(deposit_limit),
&0u64.to_le_bytes(), // value transferred to the contract.
&0u64.to_le_bytes(), // Value transferred to the contract.
input,
None,
)
Expand Down
Expand Up @@ -40,7 +40,6 @@ pub extern "C" fn call() {
let mut address = [0u8; 32];
let address = &mut &mut address[..];

#[allow(deprecated)]
api::instantiate_v2(
code_hash,
0u64, // How much ref_time weight to devote for the execution. 0 = all.
Expand Down
Expand Up @@ -34,7 +34,6 @@ pub extern "C" fn deploy() {
let address = &mut &mut address[..];
let salt = [71u8, 17u8];

#[allow(deprecated)]
api::instantiate_v2(
code_hash,
0u64, // How much ref_time weight to devote for the execution. 0 = all.
Expand All @@ -60,7 +59,6 @@ pub extern "C" fn call() {
api::get_storage(&ADDRESS_KEY, callee_addr).unwrap();

// Calling the destination contract with non-empty input data should fail.
#[allow(deprecated)]
let res = api::call_v2(
uapi::CallFlags::empty(),
callee_addr,
Expand All @@ -74,7 +72,6 @@ pub extern "C" fn call() {
assert!(matches!(res, Err(uapi::ReturnErrorCode::CalleeTrapped)));

// Call the destination contract regularly, forcing it to self-destruct.
#[allow(deprecated)]
api::call_v2(
uapi::CallFlags::empty(),
callee_addr,
Expand Down
Expand Up @@ -31,7 +31,6 @@ pub extern "C" fn call() {
input!(buffer, 36, code_hash: [u8; 32],);
let input = &buffer[32..];

#[allow(deprecated)]
let err_code = match api::instantiate_v2(
code_hash,
0u64, // How much ref_time weight to devote for the execution. 0 = all.
Expand Down
Expand Up @@ -15,7 +15,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

//! This contract tests the behavior of adding / removing delegate_dependencies when delegate
//! This contract tests the behavior of locking / unlocking delegate_dependencies when delegate
//! calling into a contract.
#![no_std]
#![no_main]
Expand All @@ -34,15 +34,13 @@ fn load_input(delegate_call: bool) {
);

match action {
// 1 = Add delegate dependency
// 1 = Lock delegate dependency
1 => {
#[allow(deprecated)]
api::add_delegate_dependency(code_hash);
api::lock_delegate_dependency(code_hash);
},
// 2 = Remove delegate dependency
// 2 = Unlock delegate dependency
2 => {
#[allow(deprecated)]
api::remove_delegate_dependency(code_hash);
api::unlock_delegate_dependency(code_hash);
},
// 3 = Terminate
3 => {
Expand Down
Expand Up @@ -42,11 +42,13 @@ pub extern "C" fn call() {
if expected_reentrance_count != 5 {
let count = (expected_reentrance_count + 1).to_le_bytes();

api::call_v1(
api::call_v2(
uapi::CallFlags::ALLOW_REENTRY,
addr,
0u64, // How much gas to devote for the execution. 0 = all.
&0u64.to_le_bytes(), // value transferred to the contract.
0u64, // How much ref_time to devote for the execution. 0 = all.
0u64, // How much proof_size to devote for the execution. 0 = all.
None, // No deposit limit.
&0u64.to_le_bytes(), // Value transferred to the contract.
&count,
None,
)
Expand Down
6 changes: 4 additions & 2 deletions substrate/frame/contracts/fixtures/contracts/self_destruct.rs
Expand Up @@ -37,10 +37,12 @@ pub extern "C" fn call() {

if !input.is_empty() {
output!(addr, [0u8; 32], api::address,);
api::call_v1(
api::call_v2(
uapi::CallFlags::ALLOW_REENTRY,
addr,
0u64, // How much gas to devote for the execution. 0 = all.
0u64, // How much ref_time to devote for the execution. 0 = all.
0u64, // How much proof_size to devote for the execution. 0 = all.
None, // No deposit limit.
&0u64.to_le_bytes(), // Value to transfer.
&[0u8; 0],
None,
Expand Down
12 changes: 6 additions & 6 deletions substrate/frame/contracts/src/benchmarking/mod.rs
Expand Up @@ -895,7 +895,7 @@ benchmarks! {
},
ImportedFunction {
module: "seal0",
name: "add_delegate_dependency",
name: "lock_delegate_dependency",
params: vec![ValueType::I32],
return_type: None,
}
Expand Down Expand Up @@ -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| {
Expand All @@ -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,
}],
Expand All @@ -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| {
Expand All @@ -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
}],
Expand Down
16 changes: 8 additions & 8 deletions substrate/frame/contracts/src/exec.rs
Expand Up @@ -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>;
Expand Down Expand Up @@ -1554,7 +1554,7 @@ where
});
}

fn add_delegate_dependency(
fn lock_delegate_dependency(
&mut self,
code_hash: CodeHash<Self::T>,
) -> Result<(), DispatchError> {
Expand All @@ -1565,22 +1565,22 @@ 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
.charge_deposit(frame.account_id.clone(), StorageDeposit::Charge(deposit));
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
Expand Down

0 comments on commit d250a6e

Please sign in to comment.