Skip to content

Commit

Permalink
[pallet-revive] refactor uapi with better types (#5555)
Browse files Browse the repository at this point in the history
start using better type for address, code_hash, and salt in runtime and
the uapi crate

fix #5575
  • Loading branch information
pgherveou authored Sep 5, 2024
1 parent d5346e7 commit cf330cc
Show file tree
Hide file tree
Showing 35 changed files with 211 additions and 201 deletions.
15 changes: 15 additions & 0 deletions prdoc/pr_5555.prdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
title: Make salt optional

doc:
- audience: Runtime Dev
description: |
Remove address_len and salt_len from uapi as both are now fixed size

crates:
- name: pallet-revive
bump: patch
- name: pallet-revive-uapi
bump: patch
- name: pallet-revive-fixtures
bump: patch

1 change: 1 addition & 0 deletions substrate/frame/revive/fixtures/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ mod build {
fn post_process(input_path: &Path, output_path: &Path) -> Result<()> {
let mut config = polkavm_linker::Config::default();
config.set_strip(true);
config.set_optimize(false);
let orig =
fs::read(input_path).with_context(|| format!("Failed to read {:?}", input_path))?;
let linked = polkavm_linker::program_from_elf(config, orig.as_ref())
Expand Down
2 changes: 1 addition & 1 deletion substrate/frame/revive/fixtures/contracts/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pub extern "C" fn deploy() {}
pub extern "C" fn call() {
input!(
callee_input: [u8; 4],
callee_addr: [u8; 20],
callee_addr: &[u8; 20],
);

// Call the callee
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pub extern "C" fn deploy() {}
pub extern "C" fn call() {
input!(
100,
callee_addr: [u8; 20],
callee_addr: &[u8; 20],
input: [u8],
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pub extern "C" fn call() {
input!(
512,
callee_input: [u8; 4],
callee_addr: [u8; 20],
callee_addr: &[u8; 20],
call: [u8],
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pub extern "C" fn deploy() {}
pub extern "C" fn call() {
input!(
256,
callee_addr: [u8; 20],
callee_addr: &[u8; 20],
flags: u32,
value: u64,
forwarded_input: [u8],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pub extern "C" fn deploy() {}
pub extern "C" fn call() {
input!(
256,
callee_addr: [u8; 20],
callee_addr: &[u8; 20],
ref_time: u64,
proof_size: u64,
forwarded_input: [u8],
Expand Down
14 changes: 6 additions & 8 deletions substrate/frame/revive/fixtures/contracts/caller_contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub extern "C" fn deploy() {}
#[no_mangle]
#[polkavm_derive::polkavm_export]
pub extern "C" fn call() {
input!(code_hash: [u8; 32],);
input!(code_hash: &[u8; 32],);

// The value to transfer on instantiation and calls. Chosen to be greater than existential
// deposit.
Expand Down Expand Up @@ -73,7 +73,6 @@ pub extern "C" fn call() {

// Deploy the contract successfully.
let mut callee = [0u8; 20];
let callee = &mut &mut callee[..];

api::instantiate(
code_hash,
Expand All @@ -82,17 +81,16 @@ pub extern "C" fn call() {
None, // No deposit limit.
&value,
&input,
Some(callee),
Some(&mut callee),
None,
&salt,
)
.unwrap();
assert_eq!(callee.len(), 20);

// Call the new contract and expect it to return failing exit code.
let res = api::call(
uapi::CallFlags::empty(),
callee,
&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.
None, // No deposit limit.
Expand All @@ -105,7 +103,7 @@ pub extern "C" fn call() {
// Fail to call the contract due to insufficient ref_time weight.
let res = api::call(
uapi::CallFlags::empty(),
callee,
&callee,
1u64, // Too little ref_time weight.
0u64, // How much proof_size weight to devote for the execution. 0 = all.
None, // No deposit limit.
Expand All @@ -118,7 +116,7 @@ pub extern "C" fn call() {
// Fail to call the contract due to insufficient proof_size weight.
let res = api::call(
uapi::CallFlags::empty(),
callee,
&callee,
0u64, // How much ref_time weight to devote for the execution. 0 = all.
1u64, // too little proof_size weight
None, // No deposit limit.
Expand All @@ -132,7 +130,7 @@ pub extern "C" fn call() {
let mut output = [0u8; 4];
api::call(
uapi::CallFlags::empty(),
callee,
&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.
None, // No deposit limit.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
#![no_std]
#![no_main]

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

#[no_mangle]
Expand All @@ -47,12 +47,13 @@ pub extern "C" fn call() {
input[8] = 1u8;

// Read the contract address.
output!(addr, [0u8; 32], api::address,);
let mut addr = [0u8; 20];
api::address(&mut addr);

// call self
api::call(
uapi::CallFlags::ALLOW_REENTRY,
addr,
&addr,
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.
Expand Down
12 changes: 12 additions & 0 deletions substrate/frame/revive/fixtures/contracts/common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,23 @@ macro_rules! input {
input!(@inner $input, $cursor + $n, $($rest)*);
};

// Match an array reference of the given size.
// e.g input!(var1: &[u8; 32], );
(@inner $input:expr, $cursor:expr, $var:ident: &[u8; $n:expr], $($rest:tt)*) => {
let $var: &[u8; $n] = &$input[$cursor..$cursor+$n].try_into().unwrap();
input!(@inner $input, $cursor + $n, $($rest)*);
};

// Size of a u8 slice.
(@size $size:expr, $var:ident: [u8; $n:expr], $($rest:tt)*) => {
input!(@size $size + $n, $($rest)*)
};

// Size of an array reference.
(@size $size:expr, $var:ident: &[u8; $n:expr], $($rest:tt)*) => {
input!(@size $size + $n, $($rest)*)
};

// Entry point, with the buffer and it's size specified first.
// e.g input!(buffer, 512, var1: u32, var2: [u8], );
($buffer:ident, $size:expr, $($rest:tt)*) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pub extern "C" fn call() {
input!(
buffer,
input: [u8; 4],
callee: [u8; 20],
callee: &[u8; 20],
deposit_limit: [u8; 8],
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,13 @@ pub extern "C" fn deploy() {}
pub extern "C" fn call() {
input!(
input: [u8; 4],
code_hash: [u8; 32],
code_hash: &[u8; 32],
deposit_limit: [u8; 8],
);

let value = 10_000u64.to_le_bytes();
let salt = [0u8; 32];
let mut address = [0u8; 20];
let address = &mut &mut address[..];

api::instantiate(
code_hash,
Expand All @@ -47,12 +46,12 @@ pub extern "C" fn call() {
Some(deposit_limit),
&value,
input,
Some(address),
Some(&mut address),
None,
&salt,
)
.unwrap();

// Return the deployed contract address.
api::return_value(uapi::ReturnFlags::empty(), address);
api::return_value(uapi::ReturnFlags::empty(), &address);
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ pub extern "C" fn call() {
buffer,
len: u32,
input: [u8; 4],
callee: [u8; 20],
callee: &[u8; 20],
);

let rounds = len as usize / BUFFER.len();
Expand Down
2 changes: 1 addition & 1 deletion substrate/frame/revive/fixtures/contracts/delegate_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub extern "C" fn deploy() {}
#[no_mangle]
#[polkavm_derive::polkavm_export]
pub extern "C" fn call() {
input!(code_hash: [u8; 32],);
input!(code_hash: &[u8; 32],);

let mut key = [0u8; 32];
key[0] = 1u8;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ pub extern "C" fn call() {
assert_eq!(value_transferred, 1337);

// Assert that ALICE is the caller of the contract.
output!(caller, [0u8; 20], api::caller,);
assert_eq!(&caller[..], &[1u8; 20]);
let mut caller = [0u8; 20];
api::caller(&mut caller);
assert_eq!(caller, [1u8; 20]);
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub extern "C" fn deploy() {}
#[no_mangle]
#[polkavm_derive::polkavm_export]
pub extern "C" fn call() {
input!(code_hash: [u8; 32],);
input!(code_hash: &[u8; 32],);

// Delegate call into passed code hash.
let input = [0u8; 0];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,10 @@ const VALUE: [u8; 8] = [0, 0, 1u8, 0, 0, 0, 0, 0];
#[no_mangle]
#[polkavm_derive::polkavm_export]
pub extern "C" fn deploy() {
input!(code_hash: [u8; 32],);
input!(code_hash: &[u8; 32],);

let input = [0u8; 0];
let mut address = [0u8; 20];
let address = &mut &mut address[..];
let salt = [47u8; 32];

api::instantiate(
Expand All @@ -41,27 +40,28 @@ pub extern "C" fn deploy() {
None, // No deposit limit.
&VALUE,
&input,
Some(address),
Some(&mut address),
None,
&salt,
)
.unwrap();

// Return the deployed contract address.
api::set_storage(StorageFlags::empty(), &ADDRESS_KEY, address);
api::set_storage(StorageFlags::empty(), &ADDRESS_KEY, &address);
}

#[no_mangle]
#[polkavm_derive::polkavm_export]
pub extern "C" fn call() {
let mut callee_addr = [0u8; 20];
let callee_addr = &mut &mut callee_addr[..];
api::get_storage(StorageFlags::empty(), &ADDRESS_KEY, callee_addr).unwrap();
let callee = &mut &mut callee_addr[..];
api::get_storage(StorageFlags::empty(), &ADDRESS_KEY, callee).unwrap();
assert!(callee.len() == 20);

// Calling the destination contract with non-empty input data should fail.
let res = api::call(
uapi::CallFlags::empty(),
callee_addr,
&callee_addr,
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.
None, // No deposit limit.
Expand All @@ -74,7 +74,7 @@ pub extern "C" fn call() {
// Call the destination contract regularly, forcing it to self-destruct.
api::call(
uapi::CallFlags::empty(),
callee_addr,
&callee_addr,
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.
None, // No deposit limit.
Expand Down
2 changes: 1 addition & 1 deletion substrate/frame/revive/fixtures/contracts/drain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,6 @@ pub extern "C" fn call() {

// Try to self-destruct by sending more balance to the 0 address.
// The call will fail because a contract transfer has a keep alive requirement.
let res = api::transfer(&[0u8; 32], &balance.to_le_bytes());
let res = api::transfer(&[0u8; 20], &balance.to_le_bytes());
assert!(matches!(res, Err(uapi::ReturnErrorCode::TransferFailed)));
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub extern "C" fn deploy() {}
#[no_mangle]
#[polkavm_derive::polkavm_export]
pub extern "C" fn call() {
input!(buffer, 36, code_hash: [u8; 32],);
input!(buffer, 36, code_hash: &[u8; 32],);
let input = &buffer[32..];

let err_code = match api::instantiate(
Expand All @@ -41,7 +41,7 @@ pub extern "C" fn call() {
input,
None,
None,
&[0u8; 0], // Empty salt.
&[0u8; 32], // Salt.
) {
Ok(_) => 0u32,
Err(code) => code as u32,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const ETH_ALICE: [u8; 20] = [1u8; 20];
fn load_input(delegate_call: bool) {
input!(
action: u32,
code_hash: [u8; 32],
code_hash: &[u8; 32],
);

match action {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pub extern "C" fn deploy() {}
pub extern "C" fn call() {
input!(
256,
callee_addr: [u8; 20],
callee_addr: &[u8; 20],
callee_input: [u8],
);

Expand Down
7 changes: 4 additions & 3 deletions substrate/frame/revive/fixtures/contracts/recurse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
#![no_std]
#![no_main]

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

#[no_mangle]
Expand All @@ -33,15 +33,16 @@ pub extern "C" fn call() {
input!(calls_left: u32, );

// own address
output!(addr, [0u8; 32], api::address,);
let mut addr = [0u8; 20];
api::address(&mut addr);

if calls_left == 0 {
return
}

api::call(
uapi::CallFlags::ALLOW_REENTRY,
addr,
&addr,
0u64, // How much ref_time to devote for the execution. 0 = all.
0u64, // How much deposit_limit to devote for the execution. 0 = all.
None, // No deposit limit.
Expand Down
Loading

0 comments on commit cf330cc

Please sign in to comment.