Skip to content

Commit

Permalink
[pallet-revive] uapi: allow create1 equivalent calls (#5701)
Browse files Browse the repository at this point in the history
The salt argument should be optional to allow create1 equivalent calls.

---------

Signed-off-by: xermicus <cyrill@parity.io>
  • Loading branch information
xermicus authored Sep 13, 2024
1 parent d66dee3 commit b21da74
Show file tree
Hide file tree
Showing 9 changed files with 98 additions and 12 deletions.
14 changes: 14 additions & 0 deletions prdoc/pr_5701.prdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
title: "[pallet-revive] uapi: allow create1 equivalent calls"

doc:
- audience: Runtime Dev
description: |
The salt argument should be optional to allow create1 equivalent calls.

crates:
- name: pallet-revive
bump: minor
- name: pallet-revive-uapi
bump: major
- name: pallet-revive-fixtures
bump: patch
22 changes: 16 additions & 6 deletions substrate/frame/revive/fixtures/contracts/caller_contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,25 +49,35 @@ pub extern "C" fn call() {
&reverted_input,
None,
None,
&salt,
Some(&salt),
);
assert!(matches!(res, Err(ReturnErrorCode::CalleeReverted)));

// Fail to deploy the contract due to insufficient ref_time weight.
let res = api::instantiate(
code_hash, 1u64, // too little ref_time weight
code_hash,
1u64, // too little ref_time weight
0u64, // How much proof_size weight to devote for the execution. 0 = all.
None, // No deposit limit.
&value, &input, None, None, &salt,
&value,
&input,
None,
None,
Some(&salt),
);
assert!(matches!(res, Err(ReturnErrorCode::CalleeTrapped)));

// Fail to deploy the contract due to insufficient proof_size weight.
let res = api::instantiate(
code_hash, 0u64, // How much ref_time weight to devote for the execution. 0 = all.
code_hash,
0u64, // How much ref_time weight to devote for the execution. 0 = all.
1u64, // Too little proof_size weight
None, // No deposit limit.
&value, &input, None, None, &salt,
&value,
&input,
None,
None,
Some(&salt),
);
assert!(matches!(res, Err(ReturnErrorCode::CalleeTrapped)));

Expand All @@ -83,7 +93,7 @@ pub extern "C" fn call() {
&input,
Some(&mut callee),
None,
&salt,
Some(&salt),
)
.unwrap();

Expand Down
39 changes: 39 additions & 0 deletions substrate/frame/revive/fixtures/contracts/create1_with_value.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// This file is part of Substrate.

// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#![no_std]
#![no_main]

use common::{input, u256_bytes};
use uapi::{HostFn, HostFnImpl as api, ReturnErrorCode};

#[no_mangle]
#[polkavm_derive::polkavm_export]
pub extern "C" fn deploy() {}

#[no_mangle]
#[polkavm_derive::polkavm_export]
pub extern "C" fn call() {
input!(code_hash: &[u8; 32],);

let mut value = [0; 32];
api::value_transferred(&mut value);

// Deploy the contract with no salt (equivalent to create1).
let ret = api::instantiate(code_hash, 0u64, 0u64, None, &value, &[], None, None, None);
assert!(ret.is_ok());
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ pub extern "C" fn call() {
input,
Some(&mut address),
None,
&salt,
Some(&salt),
)
.unwrap();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ pub extern "C" fn deploy() {
&input,
Some(&mut address),
None,
&salt,
Some(&salt),
)
.unwrap();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ pub extern "C" fn call() {
input,
None,
None,
&[0u8; 32], // Salt.
Some(&[0u8; 32]), // Salt.
) {
Ok(_) => 0u32,
Err(code) => code as u32,
Expand Down
22 changes: 22 additions & 0 deletions substrate/frame/revive/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4232,4 +4232,26 @@ mod run_tests {
assert_ok!(builder::call(addr_caller).data(addr_callee.encode()).build());
});
}

#[test]
fn create1_with_value_works() {
let (code, code_hash) = compile_module("create1_with_value").unwrap();
let value = 42;
ExtBuilder::default().existential_deposit(200).build().execute_with(|| {
let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);

// Create the contract: Constructor does nothing.
let Contract { addr, .. } =
builder::bare_instantiate(Code::Upload(code)).build_and_unwrap_contract();

// Call the contract: Deploys itself using create1 and the expected value
assert_ok!(builder::call(addr).value(value).data(code_hash.encode()).build());

// We should see the expected balance at the expected account
let address = crate::address::create1(&addr, 0);
let account_id = <Test as Config>::AddressMapper::to_account_id(&address);
let usable_balance = <Test as Config>::Currency::usable_balance(&account_id);
assert_eq!(usable_balance, value);
});
}
}
2 changes: 1 addition & 1 deletion substrate/frame/revive/uapi/src/host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@ pub trait HostFn: private::Sealed {
input: &[u8],
address: Option<&mut [u8; 20]>,
output: Option<&mut &mut [u8]>,
salt: &[u8; 32],
salt: Option<&[u8; 32]>,
) -> Result;

/// Checks whether a specified address belongs to a contract.
Expand Down
5 changes: 3 additions & 2 deletions substrate/frame/revive/uapi/src/host/riscv32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,14 +198,15 @@ impl HostFn for HostFnImpl {
input: &[u8],
mut address: Option<&mut [u8; 20]>,
mut output: Option<&mut &mut [u8]>,
salt: &[u8; 32],
salt: Option<&[u8; 32]>,
) -> Result {
let address = match address {
Some(ref mut data) => data.as_mut_ptr(),
None => crate::SENTINEL as _,
};
let (output_ptr, mut output_len) = ptr_len_or_sentinel(&mut output);
let deposit_limit_ptr = ptr_or_sentinel(&deposit_limit);
let salt_ptr = ptr_or_sentinel(&salt);
#[repr(packed)]
#[allow(dead_code)]
struct Args {
Expand All @@ -232,7 +233,7 @@ impl HostFn for HostFnImpl {
address,
output: output_ptr,
output_len: &mut output_len as *mut _,
salt: salt.as_ptr(),
salt: salt_ptr,
};

let ret_code = { unsafe { sys::instantiate(&args as *const Args as *const _) } };
Expand Down

0 comments on commit b21da74

Please sign in to comment.