mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-06 03:18:01 +00:00
Contracts: Translate .wat fixtures to rust (#2654)
- Translate all pallet-contracts fixtures from `wat` to Rust files. - Fix read_sandbox_memory_as to not use MaxEncodedLen as this could break if used with types with a non-fixed encoded len. --------- Co-authored-by: alvicsam <alvicsam@gmail.com> Co-authored-by: Alexander Samusev <41779041+alvicsam@users.noreply.github.com> Co-authored-by: Alexander Theißen <alex.theissen@me.com> Co-authored-by: command-bot <>
This commit is contained in:
@@ -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.
|
||||
|
||||
//! This fixture tests if account_reentrance_count works as expected.
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use common::input;
|
||||
use uapi::{HostFn, HostFnImpl as api};
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn deploy() {}
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn call() {
|
||||
input!(callee: [u8; 32],);
|
||||
|
||||
#[allow(deprecated)]
|
||||
let reentrance_count = api::account_reentrance_count(callee);
|
||||
|
||||
// Return the reentrance count.
|
||||
api::return_value(uapi::ReturnFlags::empty(), &reentrance_count.to_le_bytes());
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
// 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.
|
||||
|
||||
//! This contract tests the behavior of adding / removing delegate_dependencies when delegate
|
||||
//! calling into a contract.
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use common::input;
|
||||
use uapi::{HostFn, HostFnImpl as api};
|
||||
|
||||
const ALICE: [u8; 32] = [1u8; 32];
|
||||
|
||||
/// Load input data and perform the action specified by the input.
|
||||
/// If `delegate_call` is true, then delegate call into the contract.
|
||||
fn load_input(delegate_call: bool) {
|
||||
input!(
|
||||
action: u32,
|
||||
code_hash: [u8; 32],
|
||||
);
|
||||
|
||||
match action {
|
||||
// 1 = Add delegate dependency
|
||||
1 => {
|
||||
#[allow(deprecated)]
|
||||
api::add_delegate_dependency(code_hash);
|
||||
},
|
||||
// 2 = Remove delegate dependency
|
||||
2 => {
|
||||
#[allow(deprecated)]
|
||||
api::remove_delegate_dependency(code_hash);
|
||||
},
|
||||
// 3 = Terminate
|
||||
3 => {
|
||||
api::terminate_v1(&ALICE);
|
||||
},
|
||||
// Everything else is a noop
|
||||
_ => {},
|
||||
}
|
||||
|
||||
if delegate_call {
|
||||
api::delegate_call(uapi::CallFlags::empty(), code_hash, &[], None).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn deploy() {
|
||||
load_input(false);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn call() {
|
||||
load_input(true);
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
// 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::output;
|
||||
use uapi::{HostFn, HostFnImpl as api};
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn deploy() {}
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn call() {
|
||||
// Initialize buffer with 1s so that we can check that it is overwritten.
|
||||
output!(balance, [1u8; 8], api::balance,);
|
||||
|
||||
// Assert that the balance is 0.
|
||||
assert_eq!(&[0u8; 8], balance);
|
||||
}
|
||||
@@ -19,8 +19,8 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
extern crate common;
|
||||
use uapi::{CallFlags, HostFn, HostFnImpl as api};
|
||||
use common::input;
|
||||
use uapi::{HostFn, HostFnImpl as api};
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
@@ -29,21 +29,18 @@ pub extern "C" fn deploy() {}
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn call() {
|
||||
let mut buffer = [0u8; 40];
|
||||
let callee_input = 0..4;
|
||||
let callee_addr = 4..36;
|
||||
let value = 36..40;
|
||||
|
||||
// Read the input data.
|
||||
api::input(&mut &mut buffer[..]);
|
||||
input!(
|
||||
callee_input: [u8; 4],
|
||||
callee_addr: [u8; 32],
|
||||
);
|
||||
|
||||
// Call the callee
|
||||
api::call_v1(
|
||||
CallFlags::empty(),
|
||||
&buffer[callee_addr],
|
||||
0u64, // How much gas to devote for the execution. 0 = all.
|
||||
&buffer[value],
|
||||
&buffer[callee_input],
|
||||
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.
|
||||
callee_input,
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
// 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.
|
||||
|
||||
//! This calls the supplied dest and transfers 100 balance during this call and copies
|
||||
//! the return code of this call to the output buffer.
|
||||
//! It also forwards its input to the callee.
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use common::input;
|
||||
use uapi::{HostFn, HostFnImpl as api};
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn deploy() {}
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn call() {
|
||||
input!(
|
||||
100,
|
||||
callee_addr: [u8; 32],
|
||||
input: [u8],
|
||||
);
|
||||
|
||||
// Call the callee
|
||||
let err_code = match api::call_v1(
|
||||
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.
|
||||
input,
|
||||
None,
|
||||
) {
|
||||
Ok(_) => 0u32,
|
||||
Err(code) => code as u32,
|
||||
};
|
||||
|
||||
api::return_value(uapi::ReturnFlags::empty(), &err_code.to_le_bytes());
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
// 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.
|
||||
|
||||
//! This passes its input to `call_runtime` and returns the return value to its caller.
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use common::input;
|
||||
use uapi::{HostFn, HostFnImpl as api};
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn deploy() {}
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn call() {
|
||||
// Fixture calls should fit into 100 bytes.
|
||||
input!(100, call: [u8], );
|
||||
|
||||
// Use the call passed as input to call the runtime.
|
||||
let err_code = match api::call_runtime(call) {
|
||||
Ok(_) => 0u32,
|
||||
Err(code) => code as u32,
|
||||
};
|
||||
|
||||
api::return_value(uapi::ReturnFlags::empty(), &err_code.to_le_bytes());
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
// 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;
|
||||
use uapi::{HostFn, HostFnImpl as api};
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn deploy() {}
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn call() {
|
||||
input!(
|
||||
512,
|
||||
callee_input: [u8; 4],
|
||||
callee_addr: [u8; 32],
|
||||
call: [u8],
|
||||
);
|
||||
|
||||
// Use the call passed as input to call the runtime.
|
||||
api::call_runtime(call).unwrap();
|
||||
|
||||
// Call the callee
|
||||
api::call_v1(
|
||||
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.
|
||||
callee_input,
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
// 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.
|
||||
|
||||
//! This fixture calls the account_id with the 2D Weight limit.
|
||||
//! It returns the result of the call as output data.
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use common::input;
|
||||
use uapi::{HostFn, HostFnImpl as api};
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn deploy() {}
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn call() {
|
||||
input!(
|
||||
callee_addr: [u8; 32],
|
||||
ref_time: u64,
|
||||
proof_size: u64,
|
||||
);
|
||||
|
||||
#[allow(deprecated)]
|
||||
api::call_v2(
|
||||
uapi::CallFlags::empty(),
|
||||
callee_addr,
|
||||
ref_time,
|
||||
proof_size,
|
||||
None, // No deposit limit.
|
||||
&0u64.to_le_bytes(), // value transferred to the contract.
|
||||
&[0u8; 0], // input data.
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
// 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;
|
||||
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],);
|
||||
|
||||
// The value to transfer on instantiation and calls. Chosen to be greater than existential
|
||||
// deposit.
|
||||
let value = 32768u64.to_le_bytes();
|
||||
let salt = [0u8; 0];
|
||||
|
||||
// Callee will use the first 4 bytes of the input to return an exit status.
|
||||
let input = [0u8, 1, 34, 51, 68, 85, 102, 119];
|
||||
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.
|
||||
0u64, // How much proof_size weight to devote for the execution. 0 = all.
|
||||
None, // No deposit limit.
|
||||
&value,
|
||||
&reverted_input,
|
||||
None,
|
||||
None,
|
||||
&salt,
|
||||
);
|
||||
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.
|
||||
None, // No deposit limit.
|
||||
&value, &input, None, None, &salt,
|
||||
);
|
||||
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
|
||||
None, // No deposit limit.
|
||||
&value, &input, None, None, &salt,
|
||||
);
|
||||
assert!(matches!(res, Err(ReturnErrorCode::CalleeTrapped)));
|
||||
|
||||
// Deploy the contract successfully.
|
||||
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.
|
||||
0u64, // How much proof_size weight to devote for the execution. 0 = all.
|
||||
None, // No deposit limit.
|
||||
&value,
|
||||
&input,
|
||||
Some(callee),
|
||||
None,
|
||||
&salt,
|
||||
)
|
||||
.unwrap();
|
||||
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,
|
||||
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.
|
||||
&value,
|
||||
&reverted_input,
|
||||
None,
|
||||
);
|
||||
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
|
||||
0u64, // How much proof_size weight to devote for the execution. 0 = all.
|
||||
None, // No deposit limit.
|
||||
&value,
|
||||
&input,
|
||||
None,
|
||||
);
|
||||
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,
|
||||
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,
|
||||
);
|
||||
assert!(matches!(res, Err(ReturnErrorCode::CalleeTrapped)));
|
||||
|
||||
// Call the contract successfully.
|
||||
let mut output = [0u8; 4];
|
||||
#[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.
|
||||
None, // No deposit limit.
|
||||
&value,
|
||||
&input,
|
||||
Some(&mut &mut output[..]),
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(&output, &input[4..])
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
// 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.
|
||||
|
||||
//! Call chain extension by passing through input and output of this contract.
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use common::input;
|
||||
use uapi::{HostFn, HostFnImpl as api};
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn deploy() {}
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn call() {
|
||||
input!(input, 8, func_id: u32,);
|
||||
|
||||
// the chain extension passes through the input and returns it as output
|
||||
let mut output_buffer = [0u8; 32];
|
||||
let output = &mut &mut output_buffer[0..input.len()];
|
||||
|
||||
let ret_id = api::call_chain_extension(func_id, input, Some(output));
|
||||
assert_eq!(ret_id, func_id);
|
||||
|
||||
api::return_value(uapi::ReturnFlags::empty(), output);
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
// 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.
|
||||
|
||||
//! Call chain extension two times with the specified func_ids
|
||||
//! It then calls itself once
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use common::{input, output};
|
||||
use uapi::{HostFn, HostFnImpl as api};
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn deploy() {}
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn call() {
|
||||
input!(
|
||||
input,
|
||||
func_id1: u32,
|
||||
func_id2: u32,
|
||||
stop_recurse: u8,
|
||||
);
|
||||
|
||||
api::call_chain_extension(func_id1, input, None);
|
||||
api::call_chain_extension(func_id2, input, None);
|
||||
|
||||
if stop_recurse == 0 {
|
||||
// Setup next call
|
||||
input[0..4].copy_from_slice(&((3 << 16) | 2u32).to_le_bytes());
|
||||
input[4..8].copy_from_slice(&((3 << 16) | 3u32).to_le_bytes());
|
||||
input[8] = 1u8;
|
||||
|
||||
// Read the contract address.
|
||||
output!(addr, [0u8; 32], api::address,);
|
||||
|
||||
// call self
|
||||
api::call_v1(
|
||||
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.
|
||||
input,
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
@@ -6,3 +6,6 @@ authors.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
description = "Common utilities for pallet-contracts-fixtures."
|
||||
|
||||
[dependencies]
|
||||
uapi = { package = 'pallet-contracts-uapi', path = "../../../uapi", default-features = false }
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#![no_std]
|
||||
#![cfg(any(target_arch = "wasm32", target_arch = "riscv32"))]
|
||||
|
||||
pub use uapi::{HostFn, HostFnImpl as api};
|
||||
|
||||
#[panic_handler]
|
||||
fn panic(_info: &core::panic::PanicInfo) -> ! {
|
||||
@@ -29,3 +30,122 @@ fn panic(_info: &core::panic::PanicInfo) -> ! {
|
||||
core::hint::unreachable_unchecked();
|
||||
}
|
||||
}
|
||||
|
||||
/// Utility macro to read input passed to a contract.
|
||||
///
|
||||
/// Example:
|
||||
///
|
||||
/// ```
|
||||
/// input$!(
|
||||
/// var1: u32, // [0, 4) var1 decoded as u32
|
||||
/// var2: [u8; 32], // [4, 36) var2 decoded as a [u8] slice
|
||||
/// var3: u8, // [36, 37) var3 decoded as a u8
|
||||
/// );
|
||||
///
|
||||
/// // Input and size can be specified as well:
|
||||
/// input$!(
|
||||
/// input, // input buffer (optional)
|
||||
/// 512, // input size (optional)
|
||||
/// var4: u32, // [0, 4) var4 decoded as u32
|
||||
/// var5: [u8], // [4, ..) var5 decoded as a [u8] slice
|
||||
/// );
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! input {
|
||||
(@inner $input:expr, $cursor:expr,) => {};
|
||||
(@size $size:expr, ) => { $size };
|
||||
|
||||
// Match a u8 variable.
|
||||
// e.g input!(var1: u8, );
|
||||
(@inner $input:expr, $cursor:expr, $var:ident: u8, $($rest:tt)*) => {
|
||||
let $var = $input[$cursor];
|
||||
input!(@inner $input, $cursor + 1, $($rest)*);
|
||||
};
|
||||
|
||||
// Size of u8 variable.
|
||||
(@size $size:expr, $var:ident: u8, $($rest:tt)*) => {
|
||||
input!(@size $size + 1, $($rest)*)
|
||||
};
|
||||
|
||||
// Match a u64 variable.
|
||||
// e.g input!(var1: u64, );
|
||||
(@inner $input:expr, $cursor:expr, $var:ident: u64, $($rest:tt)*) => {
|
||||
let $var = u64::from_le_bytes($input[$cursor..$cursor + 8].try_into().unwrap());
|
||||
input!(@inner $input, $cursor + 8, $($rest)*);
|
||||
};
|
||||
|
||||
// Size of u64 variable.
|
||||
(@size $size:expr, $var:ident: u64, $($rest:tt)*) => {
|
||||
input!(@size $size + 8, $($rest)*)
|
||||
};
|
||||
|
||||
// Match a u32 variable.
|
||||
// e.g input!(var1: u32, );
|
||||
(@inner $input:expr, $cursor:expr, $var:ident: u32, $($rest:tt)*) => {
|
||||
let $var = u32::from_le_bytes($input[$cursor..$cursor + 4].try_into().unwrap());
|
||||
input!(@inner $input, $cursor + 4, $($rest)*);
|
||||
};
|
||||
|
||||
// Size of u32 variable.
|
||||
(@size $size:expr, $var:ident: u32, $($rest:tt)*) => {
|
||||
input!(@size $size + 4, $($rest)*)
|
||||
};
|
||||
|
||||
// Match a u8 slice with the remaining bytes.
|
||||
// e.g input!(512, var1: [u8; 32], var2: [u8], );
|
||||
(@inner $input:expr, $cursor:expr, $var:ident: [u8],) => {
|
||||
let $var = &$input[$cursor..];
|
||||
};
|
||||
|
||||
// Match a u8 slice of the given size.
|
||||
// e.g input!(var1: [u8; 32], );
|
||||
(@inner $input:expr, $cursor:expr, $var:ident: [u8; $n:expr], $($rest:tt)*) => {
|
||||
let $var = &$input[$cursor..$cursor+$n];
|
||||
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)*)
|
||||
};
|
||||
|
||||
// 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)*) => {
|
||||
let mut $buffer = [0u8; $size];
|
||||
let $buffer = &mut &mut $buffer[..];
|
||||
$crate::api::input($buffer);
|
||||
input!(@inner $buffer, 0, $($rest)*);
|
||||
};
|
||||
|
||||
// Entry point, with the name of the buffer specified and size of the input buffer computed.
|
||||
// e.g input!(buffer, var1: u32, var2: u64, );
|
||||
($buffer: ident, $($rest:tt)*) => {
|
||||
input!($buffer, input!(@size 0, $($rest)*), $($rest)*);
|
||||
};
|
||||
|
||||
// Entry point, with the size of the input buffer computed.
|
||||
// e.g input!(var1: u32, var2: u64, );
|
||||
($($rest:tt)*) => {
|
||||
input!(buffer, $($rest)*);
|
||||
};
|
||||
}
|
||||
|
||||
/// Utility macro to invoke a host function that expect a `output: &mut &mut [u8]` as last argument.
|
||||
///
|
||||
/// Example:
|
||||
/// ```
|
||||
/// // call `api::caller` and store the output in `caller`
|
||||
/// output!(caller, [0u8; 32], api::caller,);
|
||||
///
|
||||
/// // call `api::get_storage` and store the output in `address`
|
||||
/// output!(address, [0u8; 32], api::get_storage, &[1u8; 32]);
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! output {
|
||||
($output: ident, $buffer: expr, $host_fn:path, $($arg:expr),*) => {
|
||||
let mut $output = $buffer;
|
||||
let $output = &mut &mut $output[..];
|
||||
$host_fn($($arg,)* $output);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
// 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.
|
||||
|
||||
//! This calls another contract as passed as its account id. It also creates some storage.
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use common::input;
|
||||
use uapi::{HostFn, HostFnImpl as api};
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn deploy() {}
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn call() {
|
||||
input!(
|
||||
buffer,
|
||||
input: [u8; 4],
|
||||
callee: [u8; 32],
|
||||
deposit_limit: [u8; 8],
|
||||
);
|
||||
|
||||
// create 4 byte of storage before calling
|
||||
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.
|
||||
input,
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// create 8 byte of storage after calling
|
||||
// item of 12 bytes because we override 4 bytes
|
||||
api::set_storage(buffer, &[1u8; 12]);
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
// 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.
|
||||
|
||||
//! This instantiates another contract and passes some input to its constructor.
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use common::input;
|
||||
use uapi::{HostFn, HostFnImpl as api};
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn deploy() {}
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn call() {
|
||||
input!(
|
||||
input: [u8; 4],
|
||||
code_hash: [u8; 32],
|
||||
deposit_limit: [u8; 8],
|
||||
);
|
||||
|
||||
let value = 10_000u64.to_le_bytes();
|
||||
let salt = [0u8; 0];
|
||||
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.
|
||||
0u64, // How much proof_size weight to devote for the execution. 0 = all.
|
||||
Some(deposit_limit),
|
||||
&value,
|
||||
input,
|
||||
Some(address),
|
||||
None,
|
||||
&salt,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// Return the deployed contract address.
|
||||
api::return_value(uapi::ReturnFlags::empty(), address);
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
// 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;
|
||||
use uapi::{HostFn, HostFnImpl as api};
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn deploy() {}
|
||||
|
||||
/// Called by the tests.
|
||||
///
|
||||
/// The `call` function expects data in a certain format in the input buffer.
|
||||
///
|
||||
/// 1. The first byte encodes an identifier for the crypto hash function under test. (*)
|
||||
/// 2. The rest encodes the input data that is directly fed into the crypto hash function chosen in
|
||||
/// 1.
|
||||
///
|
||||
/// The `deploy` function then computes the chosen crypto hash function
|
||||
/// given the input and puts the result into the output buffer.
|
||||
/// After contract execution the test driver then asserts that the returned
|
||||
/// values are equal to the expected bytes for the input and chosen hash
|
||||
/// function.
|
||||
///
|
||||
/// (*) The possible value for the crypto hash identifiers can be found below:
|
||||
///
|
||||
/// | value | Algorithm | Bit Width |
|
||||
/// |-------|-----------|-----------|
|
||||
/// | 0 | SHA2 | 256 |
|
||||
/// | 1 | KECCAK | 256 |
|
||||
/// | 2 | BLAKE2 | 256 |
|
||||
/// | 3 | BLAKE2 | 128 |
|
||||
/// ---------------------------------
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn call() {
|
||||
input!(
|
||||
256,
|
||||
chosen_hash_fn: u8,
|
||||
input: [u8],
|
||||
);
|
||||
|
||||
match chosen_hash_fn {
|
||||
1 => {
|
||||
let mut output = [0u8; 32];
|
||||
api::hash_sha2_256(input, &mut output);
|
||||
api::return_value(uapi::ReturnFlags::empty(), &output);
|
||||
},
|
||||
2 => {
|
||||
let mut output = [0u8; 32];
|
||||
api::hash_keccak_256(input, &mut output);
|
||||
api::return_value(uapi::ReturnFlags::empty(), &output);
|
||||
},
|
||||
3 => {
|
||||
let mut output = [0u8; 32];
|
||||
api::hash_blake2_256(input, &mut output);
|
||||
api::return_value(uapi::ReturnFlags::empty(), &output);
|
||||
},
|
||||
4 => {
|
||||
let mut output = [0u8; 16];
|
||||
api::hash_blake2_128(input, &mut output);
|
||||
api::return_value(uapi::ReturnFlags::empty(), &output);
|
||||
},
|
||||
_ => panic!("unknown crypto hash function identifier"),
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// 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.
|
||||
|
||||
//! Emit a debug message with an invalid utf-8 code.
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
extern crate common;
|
||||
use uapi::{HostFn, HostFnImpl as api};
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn deploy() {}
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn call() {
|
||||
api::debug_message(b"\xFC").unwrap();
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// 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.
|
||||
|
||||
//! Emit a "Hello World!" debug message but assume that logging is disabled.
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
extern crate common;
|
||||
use uapi::{HostFn, HostFnImpl as api};
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn deploy() {}
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn call() {
|
||||
api::debug_message(b"Hello World!").unwrap();
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// 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.
|
||||
|
||||
//! Emit a "Hello World!" debug message.
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
extern crate common;
|
||||
use uapi::{HostFn, HostFnImpl as api};
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn deploy() {}
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn call() {
|
||||
api::debug_message(b"Hello World!").unwrap();
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
// 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;
|
||||
use uapi::{HostFn, HostFnImpl as api};
|
||||
|
||||
#[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 key = [0u8; 32];
|
||||
key[0] = 1u8;
|
||||
|
||||
let mut value = [0u8; 32];
|
||||
let value = &mut &mut value[..];
|
||||
value[0] = 2u8;
|
||||
|
||||
api::set_storage(&key, value);
|
||||
api::get_storage(&key, value).unwrap();
|
||||
assert!(value[0] == 2u8);
|
||||
|
||||
let input = [0u8; 0];
|
||||
api::delegate_call(uapi::CallFlags::empty(), code_hash, &input, None).unwrap();
|
||||
|
||||
api::get_storage(&[1u8], value).unwrap();
|
||||
assert!(value[0] == 1u8);
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
// 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::output;
|
||||
use uapi::{HostFn, HostFnImpl as api};
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn deploy() {}
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn call() {
|
||||
let mut key = [0u8; 32];
|
||||
key[0] = 1u8;
|
||||
|
||||
// Place a value in storage.
|
||||
let mut value = [0u8; 32];
|
||||
let value = &mut &mut value[..];
|
||||
value[0] = 1u8;
|
||||
api::set_storage(&key, value);
|
||||
|
||||
// Assert that `value_transferred` is equal to the value
|
||||
// passed to the `caller` contract: 1337.
|
||||
output!(value_transferred, [0u8; 8], api::value_transferred,);
|
||||
let value_transferred = u64::from_le_bytes(value_transferred[..].try_into().unwrap());
|
||||
assert_eq!(value_transferred, 1337);
|
||||
|
||||
// Assert that ALICE is the caller of the contract.
|
||||
output!(caller, [0u8; 32], api::caller,);
|
||||
assert_eq!(&caller[..], &[1u8; 32]);
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
// 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;
|
||||
use uapi::{HostFn, HostFnImpl as api};
|
||||
|
||||
#[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],);
|
||||
|
||||
// Delegate call into passed code hash.
|
||||
let input = [0u8; 0];
|
||||
api::delegate_call(uapi::CallFlags::empty(), code_hash, &input, None).unwrap();
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
// 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;
|
||||
use uapi::{HostFn, HostFnImpl as api};
|
||||
|
||||
const ADDRESS_KEY: [u8; 32] = [0u8; 32];
|
||||
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],);
|
||||
|
||||
let input = [0u8; 0];
|
||||
let mut address = [0u8; 32];
|
||||
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.
|
||||
0u64, // How much proof_size weight to devote for the execution. 0 = all.
|
||||
None, // No deposit limit.
|
||||
&VALUE,
|
||||
&input,
|
||||
Some(address),
|
||||
None,
|
||||
&salt,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// Return the deployed contract address.
|
||||
api::set_storage(&ADDRESS_KEY, address);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn call() {
|
||||
let mut callee_addr = [0u8; 32];
|
||||
let callee_addr = &mut &mut callee_addr[..];
|
||||
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,
|
||||
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.
|
||||
&VALUE,
|
||||
&[0u8; 1],
|
||||
None,
|
||||
);
|
||||
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,
|
||||
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.
|
||||
&VALUE,
|
||||
&[0u8; 0],
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
// 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::output;
|
||||
use uapi::{HostFn, HostFnImpl as api};
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn deploy() {}
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn call() {
|
||||
output!(balance, [0u8; 8], api::balance,);
|
||||
let balance = u64::from_le_bytes(balance[..].try_into().unwrap());
|
||||
|
||||
output!(minimum_balance, [0u8; 8], api::minimum_balance,);
|
||||
let minimum_balance = u64::from_le_bytes(minimum_balance[..].try_into().unwrap());
|
||||
|
||||
// Make the transferred value exceed the balance by adding the minimum balance.
|
||||
let balance = balance + minimum_balance;
|
||||
|
||||
// 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());
|
||||
assert!(matches!(res, Err(uapi::ReturnErrorCode::TransferFailed)));
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
// 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;
|
||||
use uapi::{HostFn, HostFnImpl as api};
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn deploy() {}
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn call() {
|
||||
input!(
|
||||
signature: [u8; 65],
|
||||
hash: [u8; 32],
|
||||
);
|
||||
|
||||
let mut output = [0u8; 33];
|
||||
api::ecdsa_recover(
|
||||
&signature[..].try_into().unwrap(),
|
||||
&hash[..].try_into().unwrap(),
|
||||
&mut output,
|
||||
)
|
||||
.unwrap();
|
||||
api::return_value(uapi::ReturnFlags::empty(), &output);
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
// 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]
|
||||
|
||||
extern crate common;
|
||||
use uapi::{HostFn, HostFnImpl as api};
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn deploy() {
|
||||
let buffer = [1u8, 2, 3, 4];
|
||||
api::deposit_event(&[0u8; 0], &buffer);
|
||||
api::return_value(uapi::ReturnFlags::empty(), &buffer);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn call() {
|
||||
unreachable!()
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
// 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;
|
||||
use uapi::{HostFn, HostFnImpl as api};
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn deploy() {}
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn call() {
|
||||
input!(len: u32,);
|
||||
|
||||
let buffer = [0u8; 16 * 1024 + 1];
|
||||
let data = &buffer[..len as usize];
|
||||
|
||||
api::deposit_event(&[0u8; 0], data);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
// 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]
|
||||
|
||||
extern crate common;
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn deploy() {}
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn call() {}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn add(a: f32, b: f32) -> f32 {
|
||||
a + b
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
// 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;
|
||||
use uapi::{HostFn, HostFnImpl as api};
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn deploy() {}
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
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.
|
||||
0u64, /* How much proof_size weight to devote for the execution. 0 =
|
||||
* all. */
|
||||
None, // No deposit limit.
|
||||
&10_000u64.to_le_bytes(), // Value to transfer.
|
||||
input,
|
||||
None,
|
||||
None,
|
||||
&[0u8; 0], // Empty salt.
|
||||
) {
|
||||
Ok(_) => 0u32,
|
||||
Err(code) => code as u32,
|
||||
};
|
||||
|
||||
// Exit with success and take transfer return code to the output buffer.
|
||||
api::return_value(uapi::ReturnFlags::empty(), &err_code.to_le_bytes());
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
// 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.
|
||||
//! Valid module but missing the call function
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
extern crate common;
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn deploy() {}
|
||||
@@ -0,0 +1,43 @@
|
||||
// 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.
|
||||
|
||||
//! Does two stores to two seperate storage items
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use common::input;
|
||||
use uapi::{HostFn, HostFnImpl as api};
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn deploy() {}
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn call() {
|
||||
input!(
|
||||
size1: u32,
|
||||
size2: u32,
|
||||
);
|
||||
|
||||
let buffer = [0u8; 16 * 1024];
|
||||
|
||||
// Place a values in storage sizes are specified in the input buffer.
|
||||
// We don't care about the contents of the storage item.
|
||||
api::set_storage(&[1u8; 32], &buffer[0..size1 as _]);
|
||||
api::set_storage(&[2u8; 32], &buffer[0..size2 as _]);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// 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]
|
||||
|
||||
extern crate common;
|
||||
use uapi::{HostFn, HostFnImpl as api};
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn deploy() {}
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn call() {
|
||||
api::return_value(uapi::ReturnFlags::empty(), &2u32.to_le_bytes());
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
// 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;
|
||||
use uapi::{HostFn, HostFnImpl as api};
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn deploy() {
|
||||
ok_trap_revert();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn call() {
|
||||
ok_trap_revert();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
fn ok_trap_revert() {
|
||||
input!(buffer, 4,);
|
||||
match buffer.first().unwrap_or(&0) {
|
||||
1 => api::return_value(uapi::ReturnFlags::REVERT, &[0u8; 0]),
|
||||
2 => panic!(),
|
||||
_ => {},
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
// 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.
|
||||
|
||||
// This fixture tests if account_reentrance_count works as expected.
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use common::{input, output};
|
||||
use uapi::{HostFn, HostFnImpl as api};
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn deploy() {}
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn call() {
|
||||
input!(expected_reentrance_count: u32,);
|
||||
|
||||
// Read the contract address.
|
||||
output!(addr, [0u8; 32], api::address,);
|
||||
|
||||
#[allow(deprecated)]
|
||||
let reentrance_count = api::reentrance_count();
|
||||
assert_eq!(reentrance_count, expected_reentrance_count);
|
||||
|
||||
// Re-enter 5 times in a row and assert that the reentrant counter works as expected.
|
||||
if expected_reentrance_count != 5 {
|
||||
let count = (expected_reentrance_count + 1).to_le_bytes();
|
||||
|
||||
api::call_v1(
|
||||
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.
|
||||
&count,
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
// 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.
|
||||
|
||||
// This fixture tests if account_reentrance_count works as expected.
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use common::input;
|
||||
use uapi::{HostFn, HostFnImpl as api};
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn deploy() {}
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn call() {
|
||||
input!(
|
||||
input,
|
||||
code_hash: [u8; 32],
|
||||
call_stack_height: u32,
|
||||
);
|
||||
|
||||
let call_stack_height = call_stack_height + 1;
|
||||
|
||||
#[allow(deprecated)]
|
||||
let reentrance_count = api::reentrance_count();
|
||||
|
||||
// Reentrance count stays 0.
|
||||
assert_eq!(reentrance_count, 0);
|
||||
|
||||
// Re-enter 5 times in a row and assert that the reentrant counter works as expected.
|
||||
if call_stack_height != 5 {
|
||||
let mut input = [0u8; 36];
|
||||
input[0..32].copy_from_slice(code_hash);
|
||||
input[32..36].copy_from_slice(&call_stack_height.to_le_bytes());
|
||||
api::delegate_call(uapi::CallFlags::empty(), code_hash, &input, None).unwrap();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
// 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;
|
||||
use uapi::{HostFn, HostFnImpl as api};
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn deploy() {
|
||||
call();
|
||||
}
|
||||
|
||||
/// Reads the first byte as the exit status and copy all but the first 4 bytes of the input as
|
||||
/// output data.
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn call() {
|
||||
input!(
|
||||
input, 128,
|
||||
exit_status: [u8; 4],
|
||||
output: [u8],
|
||||
);
|
||||
|
||||
let exit_status = uapi::ReturnFlags::from_bits(exit_status[0] as u32).unwrap();
|
||||
api::return_value(exit_status, output);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// 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]
|
||||
|
||||
extern crate common;
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn deploy() {}
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn call() {
|
||||
#[allow(clippy::empty_loop)]
|
||||
loop {}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
// 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, output};
|
||||
use uapi::{HostFn, HostFnImpl as api};
|
||||
|
||||
const DJANGO: [u8; 32] = [4u8; 32];
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn deploy() {}
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn call() {
|
||||
// If the input data is not empty, then recursively call self with empty input data.
|
||||
// This should trap instead of self-destructing since a contract cannot be removed, while it's
|
||||
// in the execution stack. If the recursive call traps, then trap here as well.
|
||||
input!(input, 4,);
|
||||
|
||||
if !input.is_empty() {
|
||||
output!(addr, [0u8; 32], api::address,);
|
||||
api::call_v1(
|
||||
uapi::CallFlags::ALLOW_REENTRY,
|
||||
addr,
|
||||
0u64, // How much gas to devote for the execution. 0 = all.
|
||||
&0u64.to_le_bytes(), // Value to transfer.
|
||||
&[0u8; 0],
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
} else {
|
||||
// Try to terminate and give balance to django.
|
||||
api::terminate_v1(&DJANGO);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// 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]
|
||||
|
||||
extern crate common;
|
||||
use uapi::{HostFn, HostFnImpl as api};
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn deploy() {
|
||||
api::terminate_v1(&[0u8; 32]);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn call() {}
|
||||
@@ -0,0 +1,37 @@
|
||||
// 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;
|
||||
use uapi::{HostFn, HostFnImpl as api};
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn deploy() {}
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn call() {
|
||||
input!(addr: [u8; 32],);
|
||||
api::set_code_hash(addr).unwrap();
|
||||
|
||||
// we return 1 after setting new code_hash
|
||||
// next `call` will NOT return this value, because contract code has been changed
|
||||
api::return_value(uapi::ReturnFlags::empty(), &1u32.to_le_bytes());
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// 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]
|
||||
|
||||
extern crate common;
|
||||
use uapi::{HostFn, HostFnImpl as api};
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn deploy() {}
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn call() {
|
||||
api::set_storage(&[0u8; 32], &[0u8; 4]);
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
// 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;
|
||||
use uapi::{HostFn, HostFnImpl as api};
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn deploy() {}
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn call() {
|
||||
input!(
|
||||
signature: [u8; 64],
|
||||
pub_key: [u8; 32],
|
||||
msg: [u8; 11],
|
||||
);
|
||||
|
||||
let exit_status = match api::sr25519_verify(
|
||||
&signature.try_into().unwrap(),
|
||||
msg,
|
||||
&pub_key.try_into().unwrap(),
|
||||
) {
|
||||
Ok(_) => 0u32,
|
||||
Err(code) => code as u32,
|
||||
};
|
||||
|
||||
// Exit with success and take transfer return code to the output buffer.
|
||||
api::return_value(uapi::ReturnFlags::empty(), &exit_status.to_le_bytes());
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
// 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;
|
||||
use uapi::{HostFn, HostFnImpl as api};
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn deploy() {}
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn call() {
|
||||
input!(len: u32, );
|
||||
|
||||
let mut buffer = [0u8; 16 * 1024 + 1];
|
||||
let data = &buffer[..len as usize];
|
||||
|
||||
// Place a garbage value in storage, the size of which is specified by the call input.
|
||||
let mut key = [0u8; 32];
|
||||
key[0] = 1;
|
||||
|
||||
api::set_storage(&key, data);
|
||||
|
||||
let data = &mut &mut buffer[..];
|
||||
api::get_storage(&key, data).unwrap();
|
||||
assert_eq!(data.len(), len as usize);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
// 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;
|
||||
use uapi::{HostFn, HostFnImpl as api};
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn deploy() {}
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn call() {
|
||||
input!(len: u32, );
|
||||
|
||||
let buffer = [0u8; 16 * 1024 + 1];
|
||||
let data = &buffer[..len as usize];
|
||||
|
||||
// Place a garbage value in storage, the size of which is specified by the call input.
|
||||
let mut key = [0u8; 32];
|
||||
key[0] = 1;
|
||||
|
||||
api::set_storage(&key, data);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
// 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;
|
||||
use uapi::{HostFn, HostFnImpl as api};
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn deploy() {
|
||||
input!(len: u32, );
|
||||
|
||||
let buffer = [0u8; 16 * 1024 + 1];
|
||||
let data = &buffer[..len as usize];
|
||||
|
||||
// place a garbage value in storage, the size of which is specified by the call input.
|
||||
let mut key = [0u8; 32];
|
||||
key[0] = 1;
|
||||
|
||||
api::set_storage(&key, data);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn call() {}
|
||||
@@ -0,0 +1,38 @@
|
||||
// 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]
|
||||
|
||||
extern crate common;
|
||||
use uapi::{HostFn, HostFnImpl as api};
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn deploy() {}
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn call() {
|
||||
let ret_code = match api::transfer(&[0u8; 32], &100u64.to_le_bytes()) {
|
||||
Ok(_) => 0u32,
|
||||
Err(code) => code as u32,
|
||||
};
|
||||
|
||||
// Exit with success and take transfer return code to the output buffer.
|
||||
api::return_value(uapi::ReturnFlags::empty(), &ret_code.to_le_bytes());
|
||||
}
|
||||
@@ -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;
|
||||
use uapi::{HostFn, HostFnImpl as api};
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn deploy() {}
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn call() {
|
||||
input!(512, msg: [u8],);
|
||||
|
||||
let mut outcome = [0u8; 512];
|
||||
let outcome = &mut &mut outcome[..];
|
||||
|
||||
#[allow(deprecated)]
|
||||
api::xcm_execute(msg, outcome).unwrap();
|
||||
api::return_value(uapi::ReturnFlags::empty(), outcome);
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
// 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;
|
||||
use uapi::{HostFn, HostFnImpl as api};
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn deploy() {}
|
||||
|
||||
#[no_mangle]
|
||||
#[polkavm_derive::polkavm_export]
|
||||
pub extern "C" fn call() {
|
||||
input!(
|
||||
512,
|
||||
dest: [u8; 3],
|
||||
msg: [u8],
|
||||
);
|
||||
|
||||
let mut message_id = [0u8; 32];
|
||||
|
||||
#[allow(deprecated)]
|
||||
api::xcm_send(dest, msg, &mut message_id).unwrap();
|
||||
api::return_value(uapi::ReturnFlags::empty(), &message_id);
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
;; This fixture tests if account_reentrance_count works as expected
|
||||
;; testing it with 2 different addresses
|
||||
(module
|
||||
(import "seal0" "seal_input" (func $seal_input (param i32 i32)))
|
||||
(import "seal0" "seal_caller" (func $seal_caller (param i32 i32)))
|
||||
(import "seal0" "seal_return" (func $seal_return (param i32 i32 i32)))
|
||||
(import "seal0" "account_reentrance_count" (func $account_reentrance_count (param i32) (result i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
;; [0, 32) buffer where input is copied
|
||||
;; [32, 36) size of the input buffer
|
||||
(data (i32.const 32) "\20")
|
||||
|
||||
(func $assert (param i32)
|
||||
(block $ok
|
||||
(br_if $ok
|
||||
(local.get 0)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "call")
|
||||
;; Reading "callee" input address
|
||||
(call $seal_input (i32.const 0) (i32.const 32))
|
||||
|
||||
(i32.store
|
||||
(i32.const 36)
|
||||
(call $account_reentrance_count (i32.const 0))
|
||||
)
|
||||
|
||||
(call $seal_return (i32.const 0) (i32.const 36) (i32.const 4))
|
||||
)
|
||||
|
||||
(func (export "deploy"))
|
||||
|
||||
)
|
||||
@@ -1,111 +0,0 @@
|
||||
;; This contract tests the behavior of adding / removing delegate_dependencies when delegate calling into a contract.
|
||||
(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" "input" (func $input (param i32 i32)))
|
||||
(import "seal1" "terminate" (func $terminate (param i32)))
|
||||
(import "seal0" "delegate_call" (func $delegate_call (param i32 i32 i32 i32 i32 i32) (result i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
;; [100, 132) Address of Alice
|
||||
(data (i32.const 100)
|
||||
"\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01"
|
||||
"\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01"
|
||||
)
|
||||
|
||||
(func $assert (param i32)
|
||||
(block $ok
|
||||
(br_if $ok
|
||||
(local.get 0)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
|
||||
;; This function loads input data and performs the action specified.
|
||||
;; The first 4 bytes of the input specify the action to perform.
|
||||
;; The next 32 bytes specify the code hash to use when calling add_delegate_dependency or remove_delegate_dependency.
|
||||
;; Actions are:
|
||||
;; 1: call add_delegate_dependency
|
||||
;; 2: call remove_delegate_dependency.
|
||||
;; 3: call terminate.
|
||||
;; Any other value is a no-op.
|
||||
(func $load_input
|
||||
(local $action i32)
|
||||
(local $code_hash_ptr i32)
|
||||
|
||||
;; Store available input size at offset 0.
|
||||
(i32.store (i32.const 0) (i32.const 512))
|
||||
|
||||
;; Read input data.
|
||||
(call $input (i32.const 4) (i32.const 0))
|
||||
|
||||
;; Input data layout.
|
||||
;; [0..4) - size of the call
|
||||
;; [4..8) - action to perform
|
||||
;; [8..42) - code hash of the callee
|
||||
(local.set $action (i32.load (i32.const 4)))
|
||||
(local.set $code_hash_ptr (i32.const 8))
|
||||
|
||||
;; Assert input size == 36 (4 for action + 32 for code_hash).
|
||||
(call $assert
|
||||
(i32.eq
|
||||
(i32.load (i32.const 0))
|
||||
(i32.const 36)
|
||||
)
|
||||
)
|
||||
|
||||
;; Call add_delegate_dependency when action == 1.
|
||||
(if (i32.eq (local.get $action) (i32.const 1))
|
||||
(then
|
||||
(call $add_delegate_dependency (local.get $code_hash_ptr))
|
||||
)
|
||||
(else)
|
||||
)
|
||||
|
||||
;; Call remove_delegate_dependency when action == 2.
|
||||
(if (i32.eq (local.get $action) (i32.const 2))
|
||||
(then
|
||||
(call $remove_delegate_dependency
|
||||
(local.get $code_hash_ptr)
|
||||
)
|
||||
)
|
||||
(else)
|
||||
)
|
||||
|
||||
;; Call terminate when action == 3.
|
||||
(if (i32.eq (local.get $action) (i32.const 3))
|
||||
(then
|
||||
(call $terminate
|
||||
(i32.const 100) ;; Pointer to beneficiary address
|
||||
)
|
||||
(unreachable) ;; terminate never returns
|
||||
)
|
||||
(else)
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "deploy")
|
||||
(call $load_input)
|
||||
)
|
||||
|
||||
(func (export "call")
|
||||
(call $load_input)
|
||||
|
||||
;; Delegate call into passed code hash.
|
||||
(call $assert
|
||||
(i32.eq
|
||||
(call $delegate_call
|
||||
(i32.const 0) ;; Set no call flags.
|
||||
(i32.const 8) ;; Pointer to "callee" code_hash.
|
||||
(i32.const 0) ;; Input is ignored.
|
||||
(i32.const 0) ;; Length of the input.
|
||||
(i32.const 4294967295) ;; u32 max sentinel value: do not copy output.
|
||||
(i32.const 0) ;; Length is ignored in this case.
|
||||
)
|
||||
(i32.const 0)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
)
|
||||
@@ -1,42 +0,0 @@
|
||||
(module
|
||||
(import "seal0" "seal_balance" (func $seal_balance (param i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
;; [0, 8) reserved for $seal_balance output
|
||||
|
||||
;; [8, 16) length of the buffer for $seal_balance
|
||||
(data (i32.const 8) "\08")
|
||||
|
||||
;; [16, inf) zero initialized
|
||||
|
||||
(func $assert (param i32)
|
||||
(block $ok
|
||||
(br_if $ok
|
||||
(local.get 0)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "deploy"))
|
||||
|
||||
(func (export "call")
|
||||
(call $seal_balance (i32.const 0) (i32.const 8))
|
||||
|
||||
;; Balance should be encoded as a u64.
|
||||
(call $assert
|
||||
(i32.eq
|
||||
(i32.load (i32.const 8))
|
||||
(i32.const 8)
|
||||
)
|
||||
)
|
||||
|
||||
;; Assert the free balance to be zero.
|
||||
(call $assert
|
||||
(i64.eq
|
||||
(i64.load (i32.const 0))
|
||||
(i64.const 0)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -1,42 +0,0 @@
|
||||
;; This calls the supplied dest and transfers 100 balance during this call and copies
|
||||
;; the return code of this call to the output buffer.
|
||||
;; It also forwards its input to the callee.
|
||||
(module
|
||||
(import "seal0" "seal_input" (func $seal_input (param i32 i32)))
|
||||
(import "seal0" "seal_call" (func $seal_call (param i32 i32 i64 i32 i32 i32 i32 i32 i32) (result i32)))
|
||||
(import "seal0" "seal_return" (func $seal_return (param i32 i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
;; [0, 8) 100 balance
|
||||
(data (i32.const 0) "\64\00\00\00\00\00\00\00")
|
||||
|
||||
;; [8, 12) here we store the return code of the transfer
|
||||
|
||||
;; [12, 16) size of the input data
|
||||
(data (i32.const 12) "\24")
|
||||
|
||||
;; [16, inf) here we store the input data
|
||||
;; 32 byte dest + 4 byte forward
|
||||
|
||||
(func (export "deploy"))
|
||||
|
||||
(func (export "call")
|
||||
(call $seal_input (i32.const 16) (i32.const 12))
|
||||
(i32.store
|
||||
(i32.const 8)
|
||||
(call $seal_call
|
||||
(i32.const 16) ;; Pointer to "callee" address.
|
||||
(i32.const 32) ;; Length of "callee" address.
|
||||
(i64.const 0) ;; How much gas to devote for the execution. 0 = all.
|
||||
(i32.const 0) ;; Pointer to the buffer with value to transfer
|
||||
(i32.const 8) ;; Length of the buffer with value to transfer.
|
||||
(i32.const 48) ;; Pointer to input data buffer address
|
||||
(i32.const 4) ;; Length of input data buffer
|
||||
(i32.const 0xffffffff) ;; u32 max sentinel value: do not copy output
|
||||
(i32.const 0) ;; Ptr to output buffer len
|
||||
)
|
||||
)
|
||||
;; exit with success and take transfer return code to the output buffer
|
||||
(call $seal_return (i32.const 0) (i32.const 8) (i32.const 4))
|
||||
)
|
||||
)
|
||||
@@ -1,33 +0,0 @@
|
||||
;; This passes its input to `seal_call_runtime` and returns the return value to its caller.
|
||||
(module
|
||||
(import "seal0" "call_runtime" (func $call_runtime (param i32 i32) (result i32)))
|
||||
(import "seal0" "seal_input" (func $seal_input (param i32 i32)))
|
||||
(import "seal0" "seal_return" (func $seal_return (param i32 i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
;; 0x1000 = 4k in little endian
|
||||
;; size of input buffer
|
||||
(data (i32.const 0) "\00\10")
|
||||
|
||||
(func (export "call")
|
||||
;; Receive the encoded call
|
||||
(call $seal_input
|
||||
(i32.const 4) ;; Pointer to the input buffer
|
||||
(i32.const 0) ;; Size of the length buffer
|
||||
)
|
||||
;; Just use the call passed as input and store result to memory
|
||||
(i32.store (i32.const 0)
|
||||
(call $call_runtime
|
||||
(i32.const 4) ;; Pointer where the call is stored
|
||||
(i32.load (i32.const 0)) ;; Size of the call
|
||||
)
|
||||
)
|
||||
(call $seal_return
|
||||
(i32.const 0) ;; flags
|
||||
(i32.const 0) ;; returned value
|
||||
(i32.const 4) ;; length of returned value
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "deploy"))
|
||||
)
|
||||
@@ -1,56 +0,0 @@
|
||||
(module
|
||||
(import "seal0" "call_runtime" (func $call_runtime (param i32 i32) (result i32)))
|
||||
(import "seal1" "seal_call" (func $seal_call (param i32 i32 i64 i32 i32 i32 i32 i32) (result i32)))
|
||||
(import "seal0" "seal_input" (func $seal_input (param i32 i32)))
|
||||
(import "seal0" "seal_return" (func $seal_return (param i32 i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
(func $assert (param i32)
|
||||
(block $ok
|
||||
(br_if $ok (local.get 0))
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "call")
|
||||
;; Store available input size at offset 0.
|
||||
(i32.store (i32.const 0) (i32.const 512))
|
||||
|
||||
;; read input data
|
||||
(call $seal_input (i32.const 4) (i32.const 0))
|
||||
|
||||
;; Input data layout.
|
||||
;; [0..4) - size of the call
|
||||
;; [4..8) - how many bytes to add to storage
|
||||
;; [8..40) - address of the callee
|
||||
;; [40..n) - encoded runtime call
|
||||
|
||||
;; Invoke call_runtime with the encoded call passed to this contract.
|
||||
(call $assert (i32.eqz
|
||||
(call $call_runtime
|
||||
(i32.const 40) ;; Pointer where the call is stored
|
||||
(i32.sub
|
||||
(i32.load (i32.const 0)) ;; Size of the call
|
||||
(i32.const 36) ;; Subtract size of the subcall-related part: 4 bytes for storage length to add + 32 bytes of the callee address
|
||||
)
|
||||
)
|
||||
))
|
||||
|
||||
;; call passed contract
|
||||
(call $assert (i32.eqz
|
||||
(call $seal_call
|
||||
(i32.const 0) ;; No flags
|
||||
(i32.const 8) ;; Pointer to "callee" address.
|
||||
(i64.const 0) ;; How much gas to devote for the execution. 0 = all.
|
||||
(i32.const 512) ;; Pointer to the buffer with value to transfer
|
||||
(i32.const 4) ;; Pointer to input data buffer address
|
||||
(i32.const 4) ;; Length of input data buffer
|
||||
(i32.const 4294967295) ;; u32 max value is the sentinel value: do not copy output
|
||||
(i32.const 0) ;; Length is ignored in this case
|
||||
)
|
||||
))
|
||||
)
|
||||
|
||||
(func (export "deploy"))
|
||||
)
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
;; This expects [account_id, ref_time, proof_size] as input and calls the account_id with the supplied 2D Weight limit.
|
||||
;; It returns the result of the call as output data.
|
||||
(module
|
||||
(import "seal0" "seal_input" (func $seal_input (param i32 i32)))
|
||||
(import "seal2" "call" (func $seal_call (param i32 i32 i64 i64 i32 i32 i32 i32 i32 i32) (result i32)))
|
||||
(import "seal0" "seal_return" (func $seal_return (param i32 i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
;; 0x1000 = 4k in little endian
|
||||
;; size of input buffer
|
||||
(data (i32.const 0) "\00\10")
|
||||
|
||||
(func (export "deploy"))
|
||||
|
||||
(func (export "call")
|
||||
;; Receive the encoded account_id, ref_time, proof_size
|
||||
(call $seal_input
|
||||
(i32.const 4) ;; Pointer to the input buffer
|
||||
(i32.const 0) ;; Pointer to the length of the input buffer
|
||||
)
|
||||
(i32.store
|
||||
(i32.const 0)
|
||||
(call $seal_call
|
||||
(i32.const 0) ;; Set no flag.
|
||||
(i32.const 4) ;; Pointer to "callee" address.
|
||||
(i64.load (i32.const 36)) ;; How much ref_time to devote for the execution.
|
||||
(i64.load (i32.const 44)) ;; How much proof_size to devote for the execution.
|
||||
(i32.const 0xffffffff) ;; u32 max sentinel value: pass no deposit limit.
|
||||
(i32.const 0) ;; Pointer to the buffer with value to transfer
|
||||
(i32.const 0) ;; Pointer to input data buffer address
|
||||
(i32.const 0) ;; Length of input data buffer
|
||||
(i32.const 0xffffffff) ;; u32 max sentinel value: do not copy output
|
||||
(i32.const 0) ;; Length is ignored in this case
|
||||
)
|
||||
)
|
||||
(call $seal_return (i32.const 0) (i32.const 0) (i32.const 4))
|
||||
)
|
||||
)
|
||||
@@ -1,286 +0,0 @@
|
||||
(module
|
||||
(import "seal0" "seal_input" (func $seal_input (param i32 i32)))
|
||||
(import "seal0" "seal_balance" (func $seal_balance (param i32 i32)))
|
||||
(import "seal2" "call" (func $seal_call (param i32 i32 i64 i64 i32 i32 i32 i32 i32 i32) (result i32)))
|
||||
(import "seal2" "instantiate" (func $seal_instantiate
|
||||
(param i32 i64 i64 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32) (result i32)
|
||||
))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
(func $assert (param i32)
|
||||
(block $ok
|
||||
(br_if $ok
|
||||
(local.get 0)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "deploy"))
|
||||
|
||||
(func (export "call")
|
||||
(local $sp i32)
|
||||
(local $exit_code i32)
|
||||
|
||||
;; Length of the buffer
|
||||
(i32.store (i32.const 20) (i32.const 32))
|
||||
|
||||
;; Copy input to this contracts memory
|
||||
(call $seal_input (i32.const 24) (i32.const 20))
|
||||
|
||||
;; Input data is the code hash of the contract to be deployed.
|
||||
(call $assert
|
||||
(i32.eq
|
||||
(i32.load (i32.const 20))
|
||||
(i32.const 32)
|
||||
)
|
||||
)
|
||||
|
||||
;; Read current balance into local variable.
|
||||
(local.set $sp (i32.const 1024))
|
||||
|
||||
;; Fail to deploy the contract since it returns a non-zero exit status.
|
||||
(local.set $exit_code
|
||||
(call $seal_instantiate
|
||||
(i32.const 24) ;; Pointer to the code hash.
|
||||
(i64.const 0) ;; How much ref_time weight to devote for the execution. 0 = all.
|
||||
(i64.const 0) ;; How much proof_size weight to devote for the execution. 0 = all.
|
||||
(i32.const 0xffffffff) ;; u32 max sentinel value: pass no deposit limit.
|
||||
(i32.const 0) ;; Pointer to the buffer with value to transfer
|
||||
(i32.const 9) ;; Pointer to input data buffer address
|
||||
(i32.const 7) ;; Length of input data buffer
|
||||
(i32.const 4294967295) ;; u32 max sentinel value: do not copy address
|
||||
(i32.const 0) ;; Length is ignored in this case
|
||||
(i32.const 4294967295) ;; u32 max sentinel value: do not copy output
|
||||
(i32.const 0) ;; Length is ignored in this case
|
||||
(i32.const 0) ;; salt_ptr
|
||||
(i32.const 0) ;; salt_le
|
||||
)
|
||||
)
|
||||
|
||||
;; Check non-zero exit status.
|
||||
(call $assert
|
||||
(i32.eq (local.get $exit_code) (i32.const 2)) ;; ReturnCode::CalleeReverted
|
||||
)
|
||||
|
||||
;; Fail to deploy the contract due to insufficient ref_time weight.
|
||||
(local.set $exit_code
|
||||
(call $seal_instantiate
|
||||
(i32.const 24) ;; Pointer to the code hash.
|
||||
(i64.const 1) ;; Supply too little ref_time weight
|
||||
(i64.const 0) ;; How much proof_size weight to devote for the execution. 0 = all.
|
||||
(i32.const 0xffffffff) ;; u32 max sentinel value: pass no deposit limit.
|
||||
(i32.const 0) ;; Pointer to the buffer with value to transfer
|
||||
(i32.const 8) ;; Pointer to input data buffer address
|
||||
(i32.const 8) ;; Length of input data buffer
|
||||
(i32.const 4294967295) ;; u32 max sentinel value: do not copy address
|
||||
(i32.const 0) ;; Length is ignored in this case
|
||||
(i32.const 4294967295) ;; u32 max sentinel value: do not copy output
|
||||
(i32.const 0) ;; Length is ignored in this case
|
||||
(i32.const 0) ;; salt_ptr
|
||||
(i32.const 0) ;; salt_le
|
||||
|
||||
)
|
||||
)
|
||||
|
||||
;; Check for special trap exit status.
|
||||
(call $assert
|
||||
(i32.eq (local.get $exit_code) (i32.const 1)) ;; ReturnCode::CalleeTrapped
|
||||
)
|
||||
|
||||
;; Fail to deploy the contract due to insufficient ref_time weight.
|
||||
(local.set $exit_code
|
||||
(call $seal_instantiate
|
||||
(i32.const 24) ;; Pointer to the code hash.
|
||||
(i64.const 0) ;; How much ref_time weight to devote for the execution. 0 = all.
|
||||
(i64.const 1) ;; Supply too little proof_size weight
|
||||
(i32.const 0xffffffff) ;; u32 max sentinel value: pass no deposit limit.
|
||||
(i32.const 0) ;; Pointer to the buffer with value to transfer
|
||||
(i32.const 8) ;; Pointer to input data buffer address
|
||||
(i32.const 8) ;; Length of input data buffer
|
||||
(i32.const 4294967295) ;; u32 max sentinel value: do not copy address
|
||||
(i32.const 0) ;; Length is ignored in this case
|
||||
(i32.const 4294967295) ;; u32 max sentinel value: do not copy output
|
||||
(i32.const 0) ;; Length is ignored in this case
|
||||
(i32.const 0) ;; salt_ptr
|
||||
(i32.const 0) ;; salt_le
|
||||
|
||||
)
|
||||
)
|
||||
|
||||
;; Check for special trap exit status.
|
||||
(call $assert
|
||||
(i32.eq (local.get $exit_code) (i32.const 1)) ;; ReturnCode::CalleeTrapped
|
||||
)
|
||||
|
||||
;; Length of the output buffer
|
||||
(i32.store
|
||||
(i32.sub (local.get $sp) (i32.const 4))
|
||||
(i32.const 256)
|
||||
)
|
||||
|
||||
;; Deploy the contract successfully.
|
||||
(local.set $exit_code
|
||||
(call $seal_instantiate
|
||||
(i32.const 24) ;; Pointer to the code hash.
|
||||
(i64.const 0) ;; How much ref_time weight to devote for the execution. 0 = all.
|
||||
(i64.const 0) ;; How much proof_size weight to devote for the execution. 0 = all.
|
||||
(i32.const 0xffffffff) ;; u32 max sentinel value: pass no deposit limit.
|
||||
(i32.const 0) ;; Pointer to the buffer with value to transfer
|
||||
(i32.const 8) ;; Pointer to input data buffer address
|
||||
(i32.const 8) ;; Length of input data buffer
|
||||
(i32.const 16) ;; Pointer to the address output buffer
|
||||
(i32.sub (local.get $sp) (i32.const 4)) ;; Pointer to the address buffer length
|
||||
(i32.const 4294967295) ;; u32 max sentinel value: do not copy output
|
||||
(i32.const 0) ;; Length is ignored in this case
|
||||
(i32.const 0) ;; salt_ptr
|
||||
(i32.const 0) ;; salt_le
|
||||
|
||||
)
|
||||
)
|
||||
|
||||
;; Check for success exit status.
|
||||
(call $assert
|
||||
(i32.eq (local.get $exit_code) (i32.const 0)) ;; ReturnCode::Success
|
||||
)
|
||||
|
||||
;; Check that address has the expected length
|
||||
(call $assert
|
||||
(i32.eq (i32.load (i32.sub (local.get $sp) (i32.const 4))) (i32.const 32))
|
||||
)
|
||||
|
||||
;; Zero out destination buffer of output
|
||||
(i32.store
|
||||
(i32.sub (local.get $sp) (i32.const 4))
|
||||
(i32.const 0)
|
||||
)
|
||||
|
||||
;; Length of the output buffer
|
||||
(i32.store
|
||||
(i32.sub (local.get $sp) (i32.const 8))
|
||||
(i32.const 4)
|
||||
)
|
||||
|
||||
;; Call the new contract and expect it to return failing exit code.
|
||||
(local.set $exit_code
|
||||
(call $seal_call
|
||||
(i32.const 0) ;; Set no flag
|
||||
(i32.const 16) ;; Pointer to "callee" address.
|
||||
(i64.const 0) ;; How much ref_time weight to devote for the execution. 0 = all.
|
||||
(i64.const 0) ;; How much proof_size weight to devote for the execution. 0 = all.
|
||||
(i32.const 0xffffffff) ;; u32 max sentinel value: pass no deposit limit.
|
||||
(i32.const 0) ;; Pointer to the buffer with value to transfer
|
||||
(i32.const 9) ;; Pointer to input data buffer address
|
||||
(i32.const 7) ;; Length of input data buffer
|
||||
(i32.sub (local.get $sp) (i32.const 4)) ;; Ptr to output buffer
|
||||
(i32.sub (local.get $sp) (i32.const 8)) ;; Ptr to output buffer len
|
||||
)
|
||||
)
|
||||
|
||||
;; Check non-zero exit status.
|
||||
(call $assert
|
||||
(i32.eq (local.get $exit_code) (i32.const 2)) ;; ReturnCode::CalleeReverted
|
||||
)
|
||||
|
||||
;; Check that output buffer contains the expected return data.
|
||||
(call $assert
|
||||
(i32.eq (i32.load (i32.sub (local.get $sp) (i32.const 8))) (i32.const 3))
|
||||
)
|
||||
(call $assert
|
||||
(i32.eq
|
||||
(i32.load (i32.sub (local.get $sp) (i32.const 4)))
|
||||
(i32.const 0x00776655)
|
||||
)
|
||||
)
|
||||
|
||||
;; Fail to call the contract due to insufficient ref_time weight.
|
||||
(local.set $exit_code
|
||||
(call $seal_call
|
||||
(i32.const 0) ;; Set no flag
|
||||
(i32.const 16) ;; Pointer to "callee" address.
|
||||
(i64.const 1) ;; Supply too little ref_time weight
|
||||
(i64.const 0) ;; How much proof_size weight to devote for the execution. 0 = all.
|
||||
(i32.const 0xffffffff) ;; u32 max sentinel value: pass no deposit limit.
|
||||
(i32.const 0) ;; Pointer to the buffer with value to transfer
|
||||
(i32.const 8) ;; Pointer to input data buffer address
|
||||
(i32.const 8) ;; Length of input data buffer
|
||||
(i32.const 4294967295) ;; u32 max sentinel value: do not copy output
|
||||
(i32.const 0) ;; Length is ignored in this cas
|
||||
)
|
||||
)
|
||||
|
||||
;; Check for special trap exit status.
|
||||
(call $assert
|
||||
(i32.eq (local.get $exit_code) (i32.const 1)) ;; ReturnCode::CalleeTrapped
|
||||
)
|
||||
|
||||
;; Fail to call the contract due to insufficient proof_size weight.
|
||||
(local.set $exit_code
|
||||
(call $seal_call
|
||||
(i32.const 0) ;; Set no flag
|
||||
(i32.const 16) ;; Pointer to "callee" address.
|
||||
(i64.const 0) ;; How much ref_time weight to devote for the execution. 0 = all.
|
||||
(i64.const 1) ;; Supply too little proof_size weight
|
||||
(i32.const 0xffffffff) ;; u32 max sentinel value: pass no deposit limit.
|
||||
(i32.const 0) ;; Pointer to the buffer with value to transfer
|
||||
(i32.const 8) ;; Pointer to input data buffer address
|
||||
(i32.const 8) ;; Length of input data buffer
|
||||
(i32.const 4294967295) ;; u32 max sentinel value: do not copy output
|
||||
(i32.const 0) ;; Length is ignored in this cas
|
||||
)
|
||||
)
|
||||
|
||||
;; Check for special trap exit status.
|
||||
(call $assert
|
||||
(i32.eq (local.get $exit_code) (i32.const 1)) ;; ReturnCode::CalleeTrapped
|
||||
)
|
||||
|
||||
;; Zero out destination buffer of output
|
||||
(i32.store
|
||||
(i32.sub (local.get $sp) (i32.const 4))
|
||||
(i32.const 0)
|
||||
)
|
||||
|
||||
;; Length of the output buffer
|
||||
(i32.store
|
||||
(i32.sub (local.get $sp) (i32.const 8))
|
||||
(i32.const 4)
|
||||
)
|
||||
|
||||
;; Call the contract successfully.
|
||||
(local.set $exit_code
|
||||
(call $seal_call
|
||||
(i32.const 0) ;; Set no flag
|
||||
(i32.const 16) ;; Pointer to "callee" address.
|
||||
(i64.const 0) ;; How much ref_time weight to devote for the execution. 0 = all.
|
||||
(i64.const 0) ;; How much proof_size weight to devote for the execution. 0 = all.
|
||||
(i32.const 0xffffffff) ;; u32 max sentinel value: pass no deposit limit.
|
||||
(i32.const 0) ;; Pointer to the buffer with value to transfer
|
||||
(i32.const 8) ;; Pointer to input data buffer address
|
||||
(i32.const 8) ;; Length of input data buffer
|
||||
(i32.sub (local.get $sp) (i32.const 4)) ;; Ptr to output buffer
|
||||
(i32.sub (local.get $sp) (i32.const 8)) ;; Ptr to output buffer len
|
||||
)
|
||||
)
|
||||
|
||||
;; Check for success exit status.
|
||||
(call $assert
|
||||
(i32.eq (local.get $exit_code) (i32.const 0)) ;; ReturnCode::Success
|
||||
)
|
||||
|
||||
;; Check that the output buffer contains the expected return data.
|
||||
(call $assert
|
||||
(i32.eq (i32.load (i32.sub (local.get $sp) (i32.const 8))) (i32.const 4))
|
||||
)
|
||||
(call $assert
|
||||
(i32.eq
|
||||
(i32.load (i32.sub (local.get $sp) (i32.const 4)))
|
||||
(i32.const 0x77665544)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
(data (i32.const 0) "\00\80") ;; The value to transfer on instantiation and calls.
|
||||
;; Chosen to be greater than existential deposit.
|
||||
(data (i32.const 8) "\00\01\22\33\44\55\66\77") ;; The input data to instantiations and calls.
|
||||
)
|
||||
@@ -1,46 +0,0 @@
|
||||
;; Call chain extension by passing through input and output of this contract
|
||||
(module
|
||||
(import "seal0" "call_chain_extension"
|
||||
(func $call_chain_extension (param i32 i32 i32 i32 i32) (result i32))
|
||||
)
|
||||
(import "seal0" "seal_input" (func $seal_input (param i32 i32)))
|
||||
(import "seal0" "seal_return" (func $seal_return (param i32 i32 i32)))
|
||||
(import "env" "memory" (memory 16 16))
|
||||
|
||||
(func $assert (param i32)
|
||||
(block $ok
|
||||
(br_if $ok (local.get 0))
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
|
||||
;; [0, 4) len of input output
|
||||
(data (i32.const 0) "\08")
|
||||
|
||||
;; [4, 12) buffer for input
|
||||
|
||||
;; [12, 48) len of output buffer
|
||||
(data (i32.const 12) "\20")
|
||||
|
||||
;; [16, inf) buffer for output
|
||||
|
||||
(func (export "deploy"))
|
||||
|
||||
(func (export "call")
|
||||
(call $seal_input (i32.const 4) (i32.const 0))
|
||||
|
||||
;; the chain extension passes through the input and returns it as output
|
||||
(call $call_chain_extension
|
||||
(i32.load (i32.const 4)) ;; id
|
||||
(i32.const 4) ;; input_ptr
|
||||
(i32.load (i32.const 0)) ;; input_len
|
||||
(i32.const 16) ;; output_ptr
|
||||
(i32.const 12) ;; output_len_ptr
|
||||
)
|
||||
|
||||
;; the chain extension passes through the id
|
||||
(call $assert (i32.eq (i32.load (i32.const 4))))
|
||||
|
||||
(call $seal_return (i32.const 0) (i32.const 16) (i32.load (i32.const 12)))
|
||||
)
|
||||
)
|
||||
@@ -1,85 +0,0 @@
|
||||
;; Call chain extension two times with the specified func_ids
|
||||
;; It then calls itself once
|
||||
(module
|
||||
(import "seal0" "seal_call_chain_extension"
|
||||
(func $seal_call_chain_extension (param i32 i32 i32 i32 i32) (result i32))
|
||||
)
|
||||
(import "seal0" "seal_input" (func $seal_input (param i32 i32)))
|
||||
(import "seal0" "seal_address" (func $seal_address (param i32 i32)))
|
||||
(import "seal1" "seal_call" (func $seal_call (param i32 i32 i64 i32 i32 i32 i32 i32) (result i32)))
|
||||
(import "env" "memory" (memory 16 16))
|
||||
|
||||
(func $assert (param i32)
|
||||
(block $ok
|
||||
(br_if $ok (local.get 0))
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
|
||||
;; [0, 4) len of input buffer: 8 byte (func_ids) + 1byte (stop_recurse)
|
||||
(data (i32.const 0) "\09")
|
||||
|
||||
;; [4, 16) buffer for input
|
||||
|
||||
;; [16, 48] buffer for self address
|
||||
|
||||
;; [48, 52] len of self address buffer
|
||||
(data (i32.const 48) "\20")
|
||||
|
||||
(func (export "deploy"))
|
||||
|
||||
(func (export "call")
|
||||
;; input: (func_id1: i32, func_id2: i32, stop_recurse: i8)
|
||||
(call $seal_input (i32.const 4) (i32.const 0))
|
||||
|
||||
(call $seal_call_chain_extension
|
||||
(i32.load (i32.const 4)) ;; id
|
||||
(i32.const 0) ;; input_ptr
|
||||
(i32.const 0) ;; input_len
|
||||
(i32.const 0xffffffff) ;; u32 max sentinel value: do not copy output
|
||||
(i32.const 0) ;; output_len_ptr
|
||||
)
|
||||
drop
|
||||
|
||||
(call $seal_call_chain_extension
|
||||
(i32.load (i32.const 8)) ;; _id
|
||||
(i32.const 0) ;; input_ptr
|
||||
(i32.const 0) ;; input_len
|
||||
(i32.const 0xffffffff) ;; u32 max sentinel value: do not copy output
|
||||
(i32.const 0) ;; output_len_ptr
|
||||
)
|
||||
drop
|
||||
|
||||
(if (i32.eqz (i32.load8_u (i32.const 12)))
|
||||
(then
|
||||
;; stop recursion
|
||||
(i32.store8 (i32.const 12) (i32.const 1))
|
||||
|
||||
;; load own address into buffer
|
||||
(call $seal_address (i32.const 16) (i32.const 48))
|
||||
|
||||
;; call function 2 + 3 of chainext 3 next time
|
||||
;; (3 << 16) | 2
|
||||
;; (3 << 16) | 3
|
||||
(i32.store (i32.const 4) (i32.const 196610))
|
||||
(i32.store (i32.const 8) (i32.const 196611))
|
||||
|
||||
;; call self
|
||||
(call $seal_call
|
||||
(i32.const 8) ;; Set ALLOW_REENTRY
|
||||
(i32.const 16) ;; Pointer to "callee" address.
|
||||
(i64.const 0) ;; How much gas to devote for the execution. 0 = all.
|
||||
(i32.const 512) ;; Pointer to the buffer with value to transfer
|
||||
(i32.const 4) ;; Pointer to input data buffer address
|
||||
(i32.load (i32.const 0)) ;; Length of input data buffer
|
||||
(i32.const 4294967295) ;; u32 max value is the sentinel value: do not copy output
|
||||
(i32.const 0) ;; Length is ignored in this case
|
||||
)
|
||||
|
||||
;; check that call succeeded of call
|
||||
(call $assert (i32.eqz))
|
||||
)
|
||||
(else)
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -1,60 +0,0 @@
|
||||
;; This calls another contract as passed as its account id. It also creates some storage.
|
||||
(module
|
||||
(import "seal0" "seal_input" (func $seal_input (param i32 i32)))
|
||||
(import "seal0" "seal_set_storage" (func $seal_set_storage (param i32 i32 i32)))
|
||||
(import "seal2" "call" (func $seal_call (param i32 i32 i64 i64 i32 i32 i32 i32 i32 i32) (result i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
(func $assert (param i32)
|
||||
(block $ok
|
||||
(br_if $ok
|
||||
(local.get 0)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "deploy"))
|
||||
|
||||
(func (export "call")
|
||||
;; store length of input buffer
|
||||
(i32.store (i32.const 0) (i32.const 512))
|
||||
|
||||
;; copy input at address 4:
|
||||
;; first 4 bytes for the size of the storage to be created in callee
|
||||
;; next 32 bytes are for the callee address
|
||||
;; next bytes for the encoded deposit limit
|
||||
(call $seal_input (i32.const 4) (i32.const 0))
|
||||
|
||||
;; create 4 byte of storage before calling
|
||||
(call $seal_set_storage
|
||||
(i32.const 0) ;; Pointer to storage key
|
||||
(i32.const 0) ;; Pointer to value
|
||||
(i32.const 4) ;; Size of value
|
||||
)
|
||||
|
||||
;; call passed contract
|
||||
(call $assert (i32.eqz
|
||||
(call $seal_call
|
||||
(i32.const 0) ;; No flags
|
||||
(i32.const 8) ;; Pointer to "callee" address
|
||||
(i64.const 0) ;; How much ref_time to devote for the execution. 0 = all
|
||||
(i64.const 0) ;; How much proof_limit to devote for the execution. 0 = all
|
||||
(i32.const 40) ;; Pointer to the storage deposit limit
|
||||
(i32.const 512) ;; Pointer to the buffer with value to transfer
|
||||
(i32.const 4) ;; Pointer to input data buffer address
|
||||
(i32.const 4) ;; Length of input data buffer
|
||||
(i32.const 4294967295) ;; u32 max value is the sentinel value: do not copy output
|
||||
(i32.const 0) ;; Length is ignored in this case
|
||||
)
|
||||
))
|
||||
|
||||
;; create 8 byte of storage after calling
|
||||
;; item of 12 bytes because we override 4 bytes
|
||||
(call $seal_set_storage
|
||||
(i32.const 0) ;; Pointer to storage key
|
||||
(i32.const 0) ;; Pointer to value
|
||||
(i32.const 12) ;; Size of value
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -1,66 +0,0 @@
|
||||
;; This instantiates another contract and passes some input to its constructor.
|
||||
(module
|
||||
(import "seal0" "seal_input" (func $seal_input (param i32 i32)))
|
||||
(import "seal0" "seal_set_storage" (func $seal_set_storage (param i32 i32 i32)))
|
||||
(import "seal2" "instantiate" (func $seal_instantiate
|
||||
(param i32 i64 i64 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32) (result i32)
|
||||
))
|
||||
(import "seal0" "seal_return" (func $seal_return (param i32 i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
;; [0, 8) send 10_000 balance
|
||||
(data (i32.const 48) "\10\27\00\00\00\00\00\00")
|
||||
|
||||
(func $assert (param i32)
|
||||
(block $ok
|
||||
(br_if $ok
|
||||
(local.get 0)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "deploy"))
|
||||
|
||||
(func (export "call")
|
||||
;; store length of input buffer
|
||||
(i32.store (i32.const 0) (i32.const 512))
|
||||
;; store length of contract address
|
||||
(i32.store (i32.const 84) (i32.const 32))
|
||||
|
||||
;; copy input at address 4
|
||||
(call $seal_input (i32.const 4) (i32.const 0))
|
||||
|
||||
;; memory layout is:
|
||||
;; [0,4): size of input buffer
|
||||
;; [4,8): size of the storage to be created in callee
|
||||
;; [8,40): the code hash of the contract to instantiate
|
||||
;; [40,48): for the encoded deposit limit
|
||||
;; [48,52): value to transfer
|
||||
;; [52,84): address of the deployed contract
|
||||
;; [84,88): len of the address
|
||||
|
||||
;; instantiate a contract
|
||||
(call $assert (i32.eqz
|
||||
;; (i32.store
|
||||
;; (i32.const 64)
|
||||
(call $seal_instantiate
|
||||
(i32.const 8) ;; Pointer to the code hash.
|
||||
(i64.const 0) ;; How much ref_time weight to devote for the execution. 0 = all.
|
||||
(i64.const 0) ;; How much proof_size weight to devote for the execution. 0 = all.
|
||||
(i32.const 40) ;; Pointer to the storage deposit limit
|
||||
(i32.const 48) ;; Pointer to the buffer with value to transfer
|
||||
(i32.const 4) ;; Pointer to input data buffer address
|
||||
(i32.const 4) ;; Length of input data buffer
|
||||
(i32.const 52) ;; Pointer to where to copy address
|
||||
(i32.const 84) ;; Pointer to address len ptr
|
||||
(i32.const 0xffffffff) ;; u32 max sentinel value: do not copy output
|
||||
(i32.const 0) ;; Length is ignored in this case
|
||||
(i32.const 0) ;; salt_ptr
|
||||
(i32.const 0) ;; salt_len
|
||||
)
|
||||
))
|
||||
;; return the deployed contract address
|
||||
(call $seal_return (i32.const 0) (i32.const 52) (i32.const 32))
|
||||
)
|
||||
)
|
||||
@@ -1,83 +0,0 @@
|
||||
(module
|
||||
(import "seal0" "seal_input" (func $seal_input (param i32 i32)))
|
||||
(import "seal0" "seal_return" (func $seal_return (param i32 i32 i32)))
|
||||
|
||||
(import "seal0" "seal_hash_sha2_256" (func $seal_hash_sha2_256 (param i32 i32 i32)))
|
||||
(import "seal0" "seal_hash_keccak_256" (func $seal_hash_keccak_256 (param i32 i32 i32)))
|
||||
(import "seal0" "seal_hash_blake2_256" (func $seal_hash_blake2_256 (param i32 i32 i32)))
|
||||
(import "seal0" "seal_hash_blake2_128" (func $seal_hash_blake2_128 (param i32 i32 i32)))
|
||||
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
(type $hash_fn_sig (func (param i32 i32 i32)))
|
||||
(table 8 funcref)
|
||||
(elem (i32.const 1)
|
||||
$seal_hash_sha2_256
|
||||
$seal_hash_keccak_256
|
||||
$seal_hash_blake2_256
|
||||
$seal_hash_blake2_128
|
||||
)
|
||||
(data (i32.const 1) "20202010201008") ;; Output sizes of the hashes in order in hex.
|
||||
|
||||
;; Not in use by the tests besides instantiating the contract.
|
||||
(func (export "deploy"))
|
||||
|
||||
;; Called by the tests.
|
||||
;;
|
||||
;; The `call` function expects data in a certain format in the input buffer.
|
||||
;;
|
||||
;; 1. The first byte encodes an identifier for the crypto hash function
|
||||
;; under test. (*)
|
||||
;; 2. The rest encodes the input data that is directly fed into the
|
||||
;; crypto hash function chosen in 1.
|
||||
;;
|
||||
;; The `deploy` function then computes the chosen crypto hash function
|
||||
;; given the input and puts the result into the output buffer.
|
||||
;; After contract execution the test driver then asserts that the returned
|
||||
;; values are equal to the expected bytes for the input and chosen hash
|
||||
;; function.
|
||||
;;
|
||||
;; (*) The possible value for the crypto hash identifiers can be found below:
|
||||
;;
|
||||
;; | value | Algorithm | Bit Width |
|
||||
;; |-------|-----------|-----------|
|
||||
;; | 0 | SHA2 | 256 |
|
||||
;; | 1 | KECCAK | 256 |
|
||||
;; | 2 | BLAKE2 | 256 |
|
||||
;; | 3 | BLAKE2 | 128 |
|
||||
;; ---------------------------------
|
||||
(func (export "call")
|
||||
(local $chosen_hash_fn i32)
|
||||
(local $input_len_ptr i32)
|
||||
(local $input_ptr i32)
|
||||
(local $input_len i32)
|
||||
(local $output_ptr i32)
|
||||
(local $output_len i32)
|
||||
(local.set $input_len_ptr (i32.const 256))
|
||||
(local.set $input_ptr (i32.const 10))
|
||||
(i32.store (local.get $input_len_ptr) (i32.const 246))
|
||||
(call $seal_input (local.get $input_ptr) (local.get $input_len_ptr))
|
||||
(local.set $chosen_hash_fn (i32.load8_u (local.get $input_ptr)))
|
||||
(if (i32.gt_u (local.get $chosen_hash_fn) (i32.const 7))
|
||||
(then
|
||||
;; We check that the chosen hash fn identifier is within bounds: [0,7]
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
(local.set $input_ptr (i32.add (local.get $input_ptr) (i32.const 1)))
|
||||
(local.set $input_len (i32.sub (i32.load (local.get $input_len_ptr)) (i32.const 1)))
|
||||
(local.set $output_len (i32.load8_u (local.get $chosen_hash_fn)))
|
||||
(call_indirect (type $hash_fn_sig)
|
||||
(local.get $input_ptr)
|
||||
(local.get $input_len)
|
||||
(local.get $input_ptr)
|
||||
(local.get $chosen_hash_fn) ;; Which crypto hash function to execute.
|
||||
)
|
||||
(call $seal_return
|
||||
(i32.const 0)
|
||||
(local.get $input_ptr) ;; Linear memory location of the output buffer.
|
||||
(local.get $output_len) ;; Number of output buffer bytes.
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
@@ -1,28 +0,0 @@
|
||||
;; Emit a debug message with an invalid utf-8 code
|
||||
(module
|
||||
(import "seal0" "seal_debug_message" (func $seal_debug_message (param i32 i32) (result i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
(data (i32.const 0) "\fc")
|
||||
|
||||
(func $assert_eq (param i32 i32)
|
||||
(block $ok
|
||||
(br_if $ok
|
||||
(i32.eq (local.get 0) (local.get 1))
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "call")
|
||||
(call $assert_eq
|
||||
(call $seal_debug_message
|
||||
(i32.const 0) ;; Pointer to the text buffer
|
||||
(i32.const 12) ;; The size of the buffer
|
||||
)
|
||||
(i32.const 0) ;; Success return code
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "deploy"))
|
||||
)
|
||||
@@ -1,28 +0,0 @@
|
||||
;; Emit a "Hello World!" debug message but assume that logging is disabled.
|
||||
(module
|
||||
(import "seal0" "seal_debug_message" (func $seal_debug_message (param i32 i32) (result i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
(data (i32.const 0) "Hello World!")
|
||||
|
||||
(func $assert_eq (param i32 i32)
|
||||
(block $ok
|
||||
(br_if $ok
|
||||
(i32.eq (local.get 0) (local.get 1))
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "call")
|
||||
(call $assert_eq
|
||||
(call $seal_debug_message
|
||||
(i32.const 0) ;; Pointer to the text buffer
|
||||
(i32.const 12) ;; The size of the buffer
|
||||
)
|
||||
(i32.const 0) ;; Success return code
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "deploy"))
|
||||
)
|
||||
@@ -1,28 +0,0 @@
|
||||
;; Emit a "Hello World!" debug message
|
||||
(module
|
||||
(import "seal0" "seal_debug_message" (func $seal_debug_message (param i32 i32) (result i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
(data (i32.const 0) "Hello World!")
|
||||
|
||||
(func $assert_eq (param i32 i32)
|
||||
(block $ok
|
||||
(br_if $ok
|
||||
(i32.eq (local.get 0) (local.get 1))
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "call")
|
||||
(call $assert_eq
|
||||
(call $seal_debug_message
|
||||
(i32.const 0) ;; Pointer to the text buffer
|
||||
(i32.const 12) ;; The size of the buffer
|
||||
)
|
||||
(i32.const 0) ;; success return code
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "deploy"))
|
||||
)
|
||||
@@ -1,111 +0,0 @@
|
||||
(module
|
||||
(import "seal0" "seal_input" (func $seal_input (param i32 i32)))
|
||||
(import "seal0" "seal_get_storage" (func $seal_get_storage (param i32 i32 i32) (result i32)))
|
||||
(import "seal0" "seal_set_storage" (func $seal_set_storage (param i32 i32 i32)))
|
||||
(import "seal0" "seal_delegate_call" (func $seal_delegate_call (param i32 i32 i32 i32 i32 i32) (result i32)))
|
||||
(import "env" "memory" (memory 3 3))
|
||||
|
||||
;; [0, 32) storage key
|
||||
(data (i32.const 0) "\01")
|
||||
|
||||
;; [32, 64) storage key
|
||||
(data (i32.const 32) "\02")
|
||||
|
||||
;; [64, 96) buffer where input is copied
|
||||
|
||||
;; [96, 100) size of the input buffer
|
||||
(data (i32.const 96) "\20")
|
||||
|
||||
;; [100, 104) size of buffer for seal_get_storage
|
||||
(data (i32.const 100) "\20")
|
||||
|
||||
;; [104, 136) seal_get_storage buffer
|
||||
|
||||
(func $assert (param i32)
|
||||
(block $ok
|
||||
(br_if $ok
|
||||
(local.get 0)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "call")
|
||||
(local $exit_code i32)
|
||||
|
||||
;; Reading "callee" code_hash
|
||||
(call $seal_input (i32.const 64) (i32.const 96))
|
||||
|
||||
;; assert input size == 32
|
||||
(call $assert
|
||||
(i32.eq
|
||||
(i32.load (i32.const 96))
|
||||
(i32.const 32)
|
||||
)
|
||||
)
|
||||
|
||||
;; place a value in storage, the size of which is specified by the call input.
|
||||
(call $seal_set_storage
|
||||
(i32.const 0) ;; Pointer to storage key
|
||||
(i32.const 32) ;; Pointer to initial value
|
||||
(i32.load (i32.const 100)) ;; Size of value
|
||||
)
|
||||
|
||||
(call $assert
|
||||
(i32.eq
|
||||
(call $seal_get_storage
|
||||
(i32.const 0) ;; Pointer to storage key
|
||||
(i32.const 104) ;; buffer where to copy result
|
||||
(i32.const 100) ;; pointer to size of buffer
|
||||
)
|
||||
(i32.const 0) ;; ReturnCode::Success
|
||||
)
|
||||
)
|
||||
|
||||
(call $assert
|
||||
(i32.eq
|
||||
(i32.load (i32.const 104)) ;; value received from storage
|
||||
(i32.load (i32.const 32)) ;; initial value
|
||||
)
|
||||
)
|
||||
|
||||
;; Call deployed library contract code.
|
||||
(local.set $exit_code
|
||||
(call $seal_delegate_call
|
||||
(i32.const 0) ;; Set no call flags
|
||||
(i32.const 64) ;; Pointer to "callee" code_hash.
|
||||
(i32.const 0) ;; Input is ignored
|
||||
(i32.const 0) ;; Length of the input
|
||||
(i32.const 4294967295) ;; u32 max sentinel value: do not copy output
|
||||
(i32.const 0) ;; Length is ignored in this case
|
||||
)
|
||||
)
|
||||
|
||||
;; Check for success exit status.
|
||||
(call $assert
|
||||
(i32.eq (local.get $exit_code) (i32.const 0)) ;; ReturnCode::Success
|
||||
)
|
||||
|
||||
(call $assert
|
||||
(i32.eq
|
||||
(call $seal_get_storage
|
||||
(i32.const 0) ;; Pointer to storage key
|
||||
(i32.const 104) ;; buffer where to copy result
|
||||
(i32.const 100) ;; pointer to size of buffer
|
||||
)
|
||||
(i32.const 0) ;; ReturnCode::Success
|
||||
)
|
||||
)
|
||||
|
||||
;; Make sure that 'callee' code changed the value
|
||||
(call $assert
|
||||
(i32.eq
|
||||
(i32.load (i32.const 104))
|
||||
(i32.const 1)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "deploy"))
|
||||
|
||||
)
|
||||
@@ -1,79 +0,0 @@
|
||||
(module
|
||||
(import "seal0" "seal_set_storage" (func $seal_set_storage (param i32 i32 i32)))
|
||||
(import "seal0" "seal_caller" (func $seal_caller (param i32 i32)))
|
||||
(import "seal0" "seal_value_transferred" (func $seal_value_transferred (param i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
;; [0, 32) storage key
|
||||
(data (i32.const 0) "\01")
|
||||
|
||||
;; [32, 64) buffer for transferred value
|
||||
|
||||
;; [64, 96) size of the buffer for transferred value
|
||||
(data (i32.const 64) "\20")
|
||||
|
||||
;; [96, 128) buffer for the caller
|
||||
|
||||
;; [128, 160) size of the buffer for caller
|
||||
(data (i32.const 128) "\20")
|
||||
|
||||
(func $assert (param i32)
|
||||
(block $ok
|
||||
(br_if $ok
|
||||
(local.get 0)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "call")
|
||||
;; place a value in storage
|
||||
(call $seal_set_storage
|
||||
(i32.const 0) ;; Pointer to storage key
|
||||
(i32.const 0) ;; Pointer to value
|
||||
(i32.const 32) ;; Size of value
|
||||
)
|
||||
|
||||
;; This stores the value transferred in the buffer
|
||||
(call $seal_value_transferred (i32.const 32) (i32.const 64))
|
||||
|
||||
;; assert len == 8
|
||||
(call $assert
|
||||
(i32.eq
|
||||
(i32.load (i32.const 64))
|
||||
(i32.const 8)
|
||||
)
|
||||
)
|
||||
|
||||
;; assert that contents of the buffer is equal to the value
|
||||
;; passed to the `caller` contract: 1337
|
||||
(call $assert
|
||||
(i64.eq
|
||||
(i64.load (i32.const 32))
|
||||
(i64.const 1337)
|
||||
)
|
||||
)
|
||||
|
||||
;; fill the buffer with the caller.
|
||||
(call $seal_caller (i32.const 96) (i32.const 128))
|
||||
|
||||
;; assert len == 32
|
||||
(call $assert
|
||||
(i32.eq
|
||||
(i32.load (i32.const 128))
|
||||
(i32.const 32)
|
||||
)
|
||||
)
|
||||
|
||||
;; assert that the first 64 byte are the beginning of "ALICE",
|
||||
;; who is the caller of the `caller` contract
|
||||
(call $assert
|
||||
(i64.eq
|
||||
(i64.load (i32.const 96))
|
||||
(i64.const 0x0101010101010101)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "deploy"))
|
||||
)
|
||||
@@ -1,50 +0,0 @@
|
||||
;; Just delegate call into the passed code hash and assert success.
|
||||
(module
|
||||
(import "seal0" "seal_input" (func $seal_input (param i32 i32)))
|
||||
(import "seal0" "seal_delegate_call" (func $seal_delegate_call (param i32 i32 i32 i32 i32 i32) (result i32)))
|
||||
(import "env" "memory" (memory 3 3))
|
||||
|
||||
;; [0, 32) buffer where input is copied
|
||||
|
||||
;; [32, 36) size of the input buffer
|
||||
(data (i32.const 32) "\20")
|
||||
|
||||
(func $assert (param i32)
|
||||
(block $ok
|
||||
(br_if $ok
|
||||
(local.get 0)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "call")
|
||||
;; Reading "callee" code_hash
|
||||
(call $seal_input (i32.const 0) (i32.const 32))
|
||||
|
||||
;; assert input size == 32
|
||||
(call $assert
|
||||
(i32.eq
|
||||
(i32.load (i32.const 32))
|
||||
(i32.const 32)
|
||||
)
|
||||
)
|
||||
|
||||
;; Delegate call into passed code hash
|
||||
(call $assert
|
||||
(i32.eq
|
||||
(call $seal_delegate_call
|
||||
(i32.const 0) ;; Set no call flags
|
||||
(i32.const 0) ;; Pointer to "callee" code_hash.
|
||||
(i32.const 0) ;; Input is ignored
|
||||
(i32.const 0) ;; Length of the input
|
||||
(i32.const 4294967295) ;; u32 max sentinel value: do not copy output
|
||||
(i32.const 0) ;; Length is ignored in this case
|
||||
)
|
||||
(i32.const 0)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "deploy"))
|
||||
)
|
||||
@@ -1,161 +0,0 @@
|
||||
(module
|
||||
(import "seal0" "seal_input" (func $seal_input (param i32 i32)))
|
||||
(import "seal0" "seal_get_storage" (func $seal_get_storage (param i32 i32 i32) (result i32)))
|
||||
(import "seal0" "seal_set_storage" (func $seal_set_storage (param i32 i32 i32)))
|
||||
(import "seal0" "seal_call" (func $seal_call (param i32 i32 i64 i32 i32 i32 i32 i32 i32) (result i32)))
|
||||
(import "seal0" "seal_transfer" (func $seal_transfer (param i32 i32 i32 i32) (result i32)))
|
||||
(import "seal0" "seal_instantiate" (func $seal_instantiate
|
||||
(param i32 i32 i64 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32) (result i32)
|
||||
))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
;; [0, 8) value to send when creating contract.
|
||||
(data (i32.const 0) "\00\00\01")
|
||||
|
||||
;; [8, 16) Value to send when calling contract.
|
||||
|
||||
;; [16, 48) The key to store the contract address under.
|
||||
|
||||
;; [48, 80) Buffer where to store the input to the contract
|
||||
|
||||
;; [88, 96) Size of the buffer
|
||||
(data (i32.const 88) "\FF")
|
||||
|
||||
;; [96, 100) Size of the input buffer
|
||||
(data (i32.const 96) "\20")
|
||||
|
||||
;; [100, 132) Buffer where to store the address of the instantiated contract
|
||||
|
||||
;; [132, 134) Salt
|
||||
(data (i32.const 132) "\47\11")
|
||||
|
||||
|
||||
(func $assert (param i32)
|
||||
(block $ok
|
||||
(br_if $ok
|
||||
(local.get 0)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "deploy")
|
||||
;; Input data is the code hash of the contract to be deployed.
|
||||
(call $seal_input (i32.const 48) (i32.const 96))
|
||||
(call $assert
|
||||
(i32.eq
|
||||
(i32.load (i32.const 96))
|
||||
(i32.const 32)
|
||||
)
|
||||
)
|
||||
|
||||
;; Deploy the contract with the provided code hash.
|
||||
(call $assert
|
||||
(i32.eq
|
||||
(call $seal_instantiate
|
||||
(i32.const 48) ;; Pointer to the code hash.
|
||||
(i32.const 32) ;; Length of the code hash.
|
||||
(i64.const 0) ;; How much gas to devote for the execution. 0 = all.
|
||||
(i32.const 0) ;; Pointer to the buffer with value to transfer
|
||||
(i32.const 8) ;; Length of the buffer with value to transfer.
|
||||
(i32.const 0) ;; Pointer to input data buffer address
|
||||
(i32.const 0) ;; Length of input data buffer
|
||||
(i32.const 100) ;; Buffer where to store address of new contract
|
||||
(i32.const 88) ;; Pointer to the length of the buffer
|
||||
(i32.const 4294967295) ;; u32 max sentinel value: do not copy output
|
||||
(i32.const 0) ;; Length is ignored in this case
|
||||
(i32.const 132) ;; salt_ptr
|
||||
(i32.const 2) ;; salt_len
|
||||
)
|
||||
(i32.const 0)
|
||||
)
|
||||
)
|
||||
|
||||
;; Check that address has expected length
|
||||
(call $assert
|
||||
(i32.eq
|
||||
(i32.load (i32.const 88))
|
||||
(i32.const 32)
|
||||
)
|
||||
)
|
||||
|
||||
;; Store the return address.
|
||||
(call $seal_set_storage
|
||||
(i32.const 16) ;; Pointer to the key
|
||||
(i32.const 100) ;; Pointer to the value
|
||||
(i32.const 32) ;; Length of the value
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "call")
|
||||
;; Read address of destination contract from storage.
|
||||
(call $assert
|
||||
(i32.eq
|
||||
(call $seal_get_storage
|
||||
(i32.const 16) ;; Pointer to the key
|
||||
(i32.const 100) ;; Pointer to the value
|
||||
(i32.const 88) ;; Pointer to the len of the value
|
||||
)
|
||||
(i32.const 0)
|
||||
)
|
||||
)
|
||||
(call $assert
|
||||
(i32.eq
|
||||
(i32.load (i32.const 88))
|
||||
(i32.const 32)
|
||||
)
|
||||
)
|
||||
|
||||
;; Calling the destination contract with non-empty input data should fail.
|
||||
(call $assert
|
||||
(i32.eq
|
||||
(call $seal_call
|
||||
(i32.const 100) ;; Pointer to destination address
|
||||
(i32.const 32) ;; Length of destination address
|
||||
(i64.const 0) ;; How much gas to devote for the execution. 0 = all.
|
||||
(i32.const 0) ;; Pointer to the buffer with value to transfer
|
||||
(i32.const 8) ;; Length of the buffer with value to transfer
|
||||
(i32.const 0) ;; Pointer to input data buffer address
|
||||
(i32.const 1) ;; Length of input data buffer
|
||||
(i32.const 4294967295) ;; u32 max sentinel value: do not copy output
|
||||
(i32.const 0) ;; Length is ignored in this case
|
||||
|
||||
)
|
||||
(i32.const 0x1)
|
||||
)
|
||||
)
|
||||
|
||||
;; Call the destination contract regularly, forcing it to self-destruct.
|
||||
(call $assert
|
||||
(i32.eq
|
||||
(call $seal_call
|
||||
(i32.const 100) ;; Pointer to destination address
|
||||
(i32.const 32) ;; Length of destination address
|
||||
(i64.const 0) ;; How much gas to devote for the execution. 0 = all.
|
||||
(i32.const 8) ;; Pointer to the buffer with value to transfer
|
||||
(i32.const 8) ;; Length of the buffer with value to transfer
|
||||
(i32.const 0) ;; Pointer to input data buffer address
|
||||
(i32.const 0) ;; Length of input data buffer
|
||||
(i32.const 4294967295) ;; u32 max sentinel value: do not copy output
|
||||
(i32.const 0) ;; Length is ignored in this case
|
||||
)
|
||||
(i32.const 0)
|
||||
)
|
||||
)
|
||||
|
||||
;; Calling the destination address with non-empty input data should now work since the
|
||||
;; contract has been removed. Also transfer a balance to the address so we can ensure this
|
||||
;; does not hinder the contract from being removed.
|
||||
(call $assert
|
||||
(i32.eq
|
||||
(call $seal_transfer
|
||||
(i32.const 100) ;; Pointer to destination address
|
||||
(i32.const 32) ;; Length of destination address
|
||||
(i32.const 0) ;; Pointer to the buffer with value to transfer
|
||||
(i32.const 8) ;; Length of the buffer with value to transfer
|
||||
)
|
||||
(i32.const 0)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -1,75 +0,0 @@
|
||||
(module
|
||||
(import "seal0" "seal_balance" (func $seal_balance (param i32 i32)))
|
||||
(import "seal0" "seal_minimum_balance" (func $seal_minimum_balance (param i32 i32)))
|
||||
(import "seal0" "seal_transfer" (func $seal_transfer (param i32 i32 i32 i32) (result i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
;; [0, 8) reserved for $seal_balance output
|
||||
|
||||
;; [8, 16) length of the buffer for $seal_balance
|
||||
(data (i32.const 8) "\08")
|
||||
|
||||
;; [16, 24) reserved for $seal_minimum_balance
|
||||
|
||||
;; [24, 32) length of the buffer for $seal_minimum_balance
|
||||
(data (i32.const 24) "\08")
|
||||
|
||||
;; [32, inf) zero initialized
|
||||
|
||||
(func $assert (param i32)
|
||||
(block $ok
|
||||
(br_if $ok
|
||||
(local.get 0)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "deploy"))
|
||||
|
||||
(func (export "call")
|
||||
;; Send entire remaining balance to the 0 address.
|
||||
(call $seal_balance (i32.const 0) (i32.const 8))
|
||||
|
||||
;; Balance should be encoded as a u64.
|
||||
(call $assert
|
||||
(i32.eq
|
||||
(i32.load (i32.const 8))
|
||||
(i32.const 8)
|
||||
)
|
||||
)
|
||||
|
||||
;; Get the minimum balance.
|
||||
(call $seal_minimum_balance (i32.const 16) (i32.const 24))
|
||||
|
||||
;; Minimum balance should be encoded as a u64.
|
||||
(call $assert
|
||||
(i32.eq
|
||||
(i32.load (i32.const 24))
|
||||
(i32.const 8)
|
||||
)
|
||||
)
|
||||
|
||||
;; Make the transferred value exceed the balance by adding the minimum balance.
|
||||
(i64.store (i32.const 0)
|
||||
(i64.add
|
||||
(i64.load (i32.const 0))
|
||||
(i64.load (i32.const 16))
|
||||
)
|
||||
)
|
||||
|
||||
;; 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
|
||||
(call $assert
|
||||
(i32.eq
|
||||
(call $seal_transfer
|
||||
(i32.const 32) ;; Pointer to destination address
|
||||
(i32.const 48) ;; Length of destination address
|
||||
(i32.const 0) ;; Pointer to the buffer with value to transfer
|
||||
(i32.const 8) ;; Length of the buffer with value to transfer
|
||||
)
|
||||
(i32.const 5) ;; ReturnCode::TransferFailed
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -1,55 +0,0 @@
|
||||
;; This contract:
|
||||
;; 1) Reads signature and message hash from the input
|
||||
;; 2) Calls ecdsa_recover
|
||||
;; 3) Validates that result is Success
|
||||
;; 4) Returns recovered compressed public key
|
||||
(module
|
||||
(import "seal0" "seal_ecdsa_recover" (func $seal_ecdsa_recover (param i32 i32 i32) (result i32)))
|
||||
(import "seal0" "seal_return" (func $seal_return (param i32 i32 i32)))
|
||||
(import "seal0" "seal_input" (func $seal_input (param i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
(func $assert (param i32)
|
||||
(block $ok
|
||||
(br_if $ok
|
||||
(local.get 0)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "deploy"))
|
||||
|
||||
;; [4, 8) len of signature + message hash - 65 bytes + 32 byte = 97 bytes
|
||||
(data (i32.const 4) "\61")
|
||||
|
||||
;; Memory layout during `call`
|
||||
;; [10, 75) signature
|
||||
;; [75, 107) message hash
|
||||
(func (export "call")
|
||||
(local $signature_ptr i32)
|
||||
(local $message_hash_ptr i32)
|
||||
(local $result i32)
|
||||
(local.set $signature_ptr (i32.const 10))
|
||||
(local.set $message_hash_ptr (i32.const 75))
|
||||
;; Read signature and message hash - 97 bytes
|
||||
(call $seal_input (local.get $signature_ptr) (i32.const 4))
|
||||
(local.set
|
||||
$result
|
||||
(call $seal_ecdsa_recover
|
||||
(local.get $signature_ptr)
|
||||
(local.get $message_hash_ptr)
|
||||
(local.get $signature_ptr) ;; Store output into message signature ptr, because we don't need it anymore
|
||||
)
|
||||
)
|
||||
(call $assert
|
||||
(i32.eq
|
||||
(local.get $result) ;; The result of recovery execution
|
||||
(i32.const 0x0) ;; 0x0 - Success result
|
||||
)
|
||||
)
|
||||
|
||||
;; exit with success and return recovered public key
|
||||
(call $seal_return (i32.const 0) (local.get $signature_ptr) (i32.const 33))
|
||||
)
|
||||
)
|
||||
@@ -1,26 +0,0 @@
|
||||
(module
|
||||
(import "seal0" "seal_return" (func $seal_return (param i32 i32 i32)))
|
||||
(import "seal0" "seal_deposit_event" (func $seal_deposit_event (param i32 i32 i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
(func (export "deploy")
|
||||
(call $seal_deposit_event
|
||||
(i32.const 0) ;; The topics buffer
|
||||
(i32.const 0) ;; The topics buffer's length
|
||||
(i32.const 8) ;; The data buffer
|
||||
(i32.const 4) ;; The data buffer's length
|
||||
)
|
||||
(call $seal_return
|
||||
(i32.const 0)
|
||||
(i32.const 8)
|
||||
(i32.const 4)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
|
||||
(func (export "call")
|
||||
(unreachable)
|
||||
)
|
||||
|
||||
(data (i32.const 8) "\01\02\03\04")
|
||||
)
|
||||
@@ -1,39 +0,0 @@
|
||||
(module
|
||||
(import "seal0" "seal_deposit_event" (func $seal_deposit_event (param i32 i32 i32 i32)))
|
||||
(import "seal0" "seal_input" (func $seal_input (param i32 i32)))
|
||||
(import "env" "memory" (memory 16 16))
|
||||
|
||||
;; [0, 4) size of the input buffer
|
||||
(data (i32.const 0) "\04")
|
||||
|
||||
(func $assert (param i32)
|
||||
(block $ok
|
||||
(br_if $ok
|
||||
(local.get 0)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "call")
|
||||
(call $seal_input (i32.const 4) (i32.const 0))
|
||||
|
||||
;; assert input size == 4
|
||||
(call $assert
|
||||
(i32.eq
|
||||
(i32.load (i32.const 0))
|
||||
(i32.const 4)
|
||||
)
|
||||
)
|
||||
|
||||
;; place a garbage value in storage, the size of which is specified by the call input.
|
||||
(call $seal_deposit_event
|
||||
(i32.const 0) ;; topics_ptr
|
||||
(i32.const 0) ;; topics_len
|
||||
(i32.const 0) ;; data_ptr
|
||||
(i32.load (i32.const 4)) ;; data_len
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "deploy"))
|
||||
)
|
||||
@@ -1,12 +0,0 @@
|
||||
;; Module that contains a float instruction which is illegal in deterministic mode
|
||||
(module
|
||||
(import "env" "memory" (memory 1 1))
|
||||
(func (export "call")
|
||||
f32.const 1
|
||||
drop
|
||||
)
|
||||
(func (export "deploy")
|
||||
f32.const 2
|
||||
drop
|
||||
)
|
||||
)
|
||||
@@ -1,47 +0,0 @@
|
||||
;; This instantiats a contract and transfers 100 balance during this call and copies the return code
|
||||
;; of this call to the output buffer.
|
||||
;; The first 32 byte of input is the code hash to instantiate
|
||||
;; The rest of the input is forwarded to the constructor of the callee
|
||||
(module
|
||||
(import "seal0" "seal_input" (func $seal_input (param i32 i32)))
|
||||
(import "seal1" "seal_instantiate" (func $seal_instantiate
|
||||
(param i32 i64 i32 i32 i32 i32 i32 i32 i32 i32 i32) (result i32)
|
||||
))
|
||||
(import "seal0" "seal_return" (func $seal_return (param i32 i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
;; [0, 8) 10_000 balance
|
||||
(data (i32.const 0) "\10\27\00\00\00\00\00\00")
|
||||
|
||||
;; [8, 12) here we store the return code of the transfer
|
||||
|
||||
;; [12, 16) size of the input buffer
|
||||
(data (i32.const 12) "\24")
|
||||
|
||||
;; [16, inf) input buffer
|
||||
;; 32 bye code hash + 4 byte forward
|
||||
|
||||
(func (export "deploy"))
|
||||
|
||||
(func (export "call")
|
||||
(call $seal_input (i32.const 16) (i32.const 12))
|
||||
(i32.store
|
||||
(i32.const 8)
|
||||
(call $seal_instantiate
|
||||
(i32.const 16) ;; Pointer to the code hash.
|
||||
(i64.const 0) ;; How much gas to devote for the execution. 0 = all.
|
||||
(i32.const 0) ;; Pointer to the buffer with value to transfer
|
||||
(i32.const 48) ;; Pointer to input data buffer address
|
||||
(i32.const 4) ;; Length of input data buffer
|
||||
(i32.const 0xffffffff) ;; u32 max sentinel value: do not copy address
|
||||
(i32.const 0) ;; Length is ignored in this case
|
||||
(i32.const 0xffffffff) ;; u32 max sentinel value: do not copy output
|
||||
(i32.const 0) ;; Length is ignored in this case
|
||||
(i32.const 0) ;; salt_ptr
|
||||
(i32.const 0) ;; salt_len
|
||||
)
|
||||
)
|
||||
;; exit with success and take transfer return code to the output buffer
|
||||
(call $seal_return (i32.const 0) (i32.const 8) (i32.const 4))
|
||||
)
|
||||
)
|
||||
@@ -1,5 +0,0 @@
|
||||
;; Valid module but missing the call function
|
||||
(module
|
||||
(import "env" "memory" (memory 1 1))
|
||||
(func (export "deploy"))
|
||||
)
|
||||
@@ -1,54 +0,0 @@
|
||||
;; Does two stores to two seperate storage items
|
||||
;; Expects (len0, len1) as input.
|
||||
(module
|
||||
(import "seal0" "seal_set_storage" (func $seal_set_storage (param i32 i32 i32)))
|
||||
(import "seal0" "seal_input" (func $seal_input (param i32 i32)))
|
||||
(import "env" "memory" (memory 16 16))
|
||||
|
||||
;; [0, 32) storage key 0
|
||||
(data (i32.const 0) "\01")
|
||||
|
||||
;; [32, 64) storage key 1
|
||||
(data (i32.const 32) "\02")
|
||||
|
||||
;; [64, 72) buffer where input is copied (expected sizes of storage items)
|
||||
|
||||
;; [72, 76) size of the input buffer
|
||||
(data (i32.const 72) "\08")
|
||||
|
||||
(func $assert (param i32)
|
||||
(block $ok
|
||||
(br_if $ok
|
||||
(local.get 0)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "call")
|
||||
(call $seal_input (i32.const 64) (i32.const 72))
|
||||
|
||||
;; assert input size == 8
|
||||
(call $assert
|
||||
(i32.eq
|
||||
(i32.load (i32.const 72))
|
||||
(i32.const 8)
|
||||
)
|
||||
)
|
||||
|
||||
;; place a values in storage sizes are specified in the input buffer
|
||||
;; we don't care about the contents of the storage item
|
||||
(call $seal_set_storage
|
||||
(i32.const 0) ;; Pointer to storage key
|
||||
(i32.const 0) ;; Pointer to value
|
||||
(i32.load (i32.const 64)) ;; Size of value
|
||||
)
|
||||
(call $seal_set_storage
|
||||
(i32.const 32) ;; Pointer to storage key
|
||||
(i32.const 0) ;; Pointer to value
|
||||
(i32.load (i32.const 68)) ;; Size of value
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "deploy"))
|
||||
)
|
||||
@@ -1,13 +0,0 @@
|
||||
(module
|
||||
(import "seal0" "seal_return" (func $seal_return (param i32 i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
;; [0, 32) return value
|
||||
(data (i32.const 0) "\02")
|
||||
|
||||
(func (export "deploy"))
|
||||
|
||||
(func (export "call")
|
||||
(call $seal_return (i32.const 0) (i32.const 0) (i32.const 4))
|
||||
)
|
||||
)
|
||||
@@ -1,35 +0,0 @@
|
||||
(module
|
||||
(import "seal0" "seal_input" (func $seal_input (param i32 i32)))
|
||||
(import "seal0" "seal_return" (func $seal_return (param i32 i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
(func (export "deploy")
|
||||
(call $ok_trap_revert)
|
||||
)
|
||||
|
||||
(func (export "call")
|
||||
(call $ok_trap_revert)
|
||||
)
|
||||
|
||||
(func $ok_trap_revert
|
||||
(i32.store (i32.const 4) (i32.const 4))
|
||||
(call $seal_input (i32.const 0) (i32.const 4))
|
||||
(block $IF_2
|
||||
(block $IF_1
|
||||
(block $IF_0
|
||||
(br_table $IF_0 $IF_1 $IF_2
|
||||
(i32.load8_u (i32.const 0))
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
;; 0 = return with success
|
||||
return
|
||||
)
|
||||
;; 1 = revert
|
||||
(call $seal_return (i32.const 1) (i32.const 0) (i32.const 0))
|
||||
(unreachable)
|
||||
)
|
||||
;; 2 = trap
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
@@ -1,76 +0,0 @@
|
||||
;; This fixture recursively tests if reentrance_count returns correct reentrant count value when
|
||||
;; using seal_call to make caller contract call to itself
|
||||
(module
|
||||
(import "seal0" "seal_input" (func $seal_input (param i32 i32)))
|
||||
(import "seal0" "seal_address" (func $seal_address (param i32 i32)))
|
||||
(import "seal1" "seal_call" (func $seal_call (param i32 i32 i64 i32 i32 i32 i32 i32) (result i32)))
|
||||
(import "seal0" "reentrance_count" (func $reentrance_count (result i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
;; [0, 32) reserved for $seal_address output
|
||||
|
||||
;; [32, 36) buffer for the call stack height
|
||||
|
||||
;; [36, 40) size of the input buffer
|
||||
(data (i32.const 36) "\04")
|
||||
|
||||
;; [40, 44) length of the buffer for $seal_address
|
||||
(data (i32.const 40) "\20")
|
||||
|
||||
(func $assert (param i32)
|
||||
(block $ok
|
||||
(br_if $ok
|
||||
(local.get 0)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
(func (export "call")
|
||||
(local $expected_reentrance_count i32)
|
||||
(local $seal_call_exit_code i32)
|
||||
|
||||
;; reading current contract address
|
||||
(call $seal_address (i32.const 0) (i32.const 40))
|
||||
|
||||
;; reading passed input
|
||||
(call $seal_input (i32.const 32) (i32.const 36))
|
||||
|
||||
;; reading manually passed reentrant count
|
||||
(local.set $expected_reentrance_count (i32.load (i32.const 32)))
|
||||
|
||||
;; reentrance count is calculated correctly
|
||||
(call $assert
|
||||
(i32.eq (call $reentrance_count) (local.get $expected_reentrance_count))
|
||||
)
|
||||
|
||||
;; re-enter 5 times in a row and assert that the reentrant counter works as expected
|
||||
(i32.eq (call $reentrance_count) (i32.const 5))
|
||||
(if
|
||||
(then) ;; recursion exit case
|
||||
(else
|
||||
;; incrementing $expected_reentrance_count passed to the contract
|
||||
(i32.store (i32.const 32) (i32.add (i32.load (i32.const 32)) (i32.const 1)))
|
||||
|
||||
;; Call to itself
|
||||
(local.set $seal_call_exit_code
|
||||
(call $seal_call
|
||||
(i32.const 8) ;; Allow reentrancy flag set
|
||||
(i32.const 0) ;; Pointer to "callee" address
|
||||
(i64.const 0) ;; How much gas to devote for the execution. 0 = all.
|
||||
(i32.const 0) ;; Pointer to the buffer with value to transfer
|
||||
(i32.const 32) ;; Pointer to input data buffer address
|
||||
(i32.const 4) ;; Length of input data buffer
|
||||
(i32.const 0xffffffff) ;; u32 max sentinel value: do not copy output
|
||||
(i32.const 0) ;; Ptr to output buffer len
|
||||
)
|
||||
)
|
||||
|
||||
(call $assert
|
||||
(i32.eq (local.get $seal_call_exit_code) (i32.const 0))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "deploy"))
|
||||
)
|
||||
@@ -1,71 +0,0 @@
|
||||
;; This fixture recursively tests if reentrance_count returns correct reentrant count value when
|
||||
;; using seal_delegate_call to make caller contract delegate call to itself
|
||||
(module
|
||||
(import "seal0" "seal_input" (func $seal_input (param i32 i32)))
|
||||
(import "seal0" "seal_set_storage" (func $seal_set_storage (param i32 i32 i32)))
|
||||
(import "seal0" "seal_delegate_call" (func $seal_delegate_call (param i32 i32 i32 i32 i32 i32) (result i32)))
|
||||
(import "seal0" "reentrance_count" (func $reentrance_count (result i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
;; [0, 32) buffer where code hash is copied
|
||||
|
||||
;; [32, 36) buffer for the call stack height
|
||||
|
||||
;; [36, 40) size of the input buffer
|
||||
(data (i32.const 36) "\24")
|
||||
|
||||
(func $assert (param i32)
|
||||
(block $ok
|
||||
(br_if $ok
|
||||
(local.get 0)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
(func (export "call")
|
||||
(local $callstack_height i32)
|
||||
(local $delegate_call_exit_code i32)
|
||||
|
||||
;; Reading input
|
||||
(call $seal_input (i32.const 0) (i32.const 36))
|
||||
|
||||
;; reading passed callstack height
|
||||
(local.set $callstack_height (i32.load (i32.const 32)))
|
||||
|
||||
;; incrementing callstack height
|
||||
(i32.store (i32.const 32) (i32.add (i32.load (i32.const 32)) (i32.const 1)))
|
||||
|
||||
;; reentrance count stays 0
|
||||
(call $assert
|
||||
(i32.eq (call $reentrance_count) (i32.const 0))
|
||||
)
|
||||
|
||||
(i32.eq (local.get $callstack_height) (i32.const 5))
|
||||
(if
|
||||
(then) ;; exit recursion case
|
||||
(else
|
||||
;; Call to itself
|
||||
(local.set $delegate_call_exit_code
|
||||
(call $seal_delegate_call
|
||||
(i32.const 0) ;; Set no call flags
|
||||
(i32.const 0) ;; Pointer to "callee" code_hash.
|
||||
(i32.const 0) ;; Pointer to the input data
|
||||
(i32.const 36) ;; Length of the input
|
||||
(i32.const 4294967295) ;; u32 max sentinel value: do not copy output
|
||||
(i32.const 0) ;; Length is ignored in this case
|
||||
)
|
||||
)
|
||||
|
||||
(call $assert
|
||||
(i32.eq (local.get $delegate_call_exit_code) (i32.const 0))
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
(call $assert
|
||||
(i32.le_s (local.get $callstack_height) (i32.const 5))
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "deploy"))
|
||||
)
|
||||
@@ -1,33 +0,0 @@
|
||||
(module
|
||||
(import "seal0" "seal_input" (func $seal_input (param i32 i32)))
|
||||
(import "seal0" "seal_return" (func $seal_return (param i32 i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
;; [0, 128) buffer where input is copied
|
||||
|
||||
;; [128, 132) length of the input buffer
|
||||
(data (i32.const 128) "\80")
|
||||
|
||||
;; Deploy routine is the same as call.
|
||||
(func (export "deploy")
|
||||
(call $call)
|
||||
)
|
||||
|
||||
;; Call reads the first 4 bytes (LE) as the exit status and returns the rest as output data.
|
||||
(func $call (export "call")
|
||||
;; Copy input into this contracts memory.
|
||||
(call $seal_input (i32.const 0) (i32.const 128))
|
||||
|
||||
;; Copy all but the first 4 bytes of the input data as the output data.
|
||||
;; Use the first byte as exit status
|
||||
(call $seal_return
|
||||
(i32.load8_u (i32.const 0)) ;; Exit status
|
||||
(i32.const 4) ;; Pointer to the data to return.
|
||||
(i32.sub ;; Count of bytes to copy.
|
||||
(i32.load (i32.const 128))
|
||||
(i32.const 4)
|
||||
)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
@@ -1,8 +0,0 @@
|
||||
(module
|
||||
(import "env" "memory" (memory 1 1))
|
||||
(func (export "call")
|
||||
(loop $inf (br $inf)) ;; just run out of gas
|
||||
(unreachable)
|
||||
)
|
||||
(func (export "deploy"))
|
||||
)
|
||||
@@ -1,83 +0,0 @@
|
||||
(module
|
||||
(import "seal0" "seal_input" (func $seal_input (param i32 i32)))
|
||||
(import "seal0" "seal_address" (func $seal_address (param i32 i32)))
|
||||
(import "seal0" "seal_call" (func $seal_call (param i32 i32 i64 i32 i32 i32 i32 i32 i32) (result i32)))
|
||||
(import "seal0" "seal_terminate" (func $seal_terminate (param i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
;; [0, 32) reserved for $seal_address output
|
||||
|
||||
;; [32, 36) length of the buffer
|
||||
(data (i32.const 32) "\20")
|
||||
|
||||
;; [36, 68) Address of django
|
||||
(data (i32.const 36)
|
||||
"\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04"
|
||||
"\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04"
|
||||
)
|
||||
|
||||
;; [68, 72) reserved for output of $seal_input
|
||||
|
||||
;; [72, 76) length of the buffer
|
||||
(data (i32.const 72) "\04")
|
||||
|
||||
;; [76, inf) zero initialized
|
||||
|
||||
(func $assert (param i32)
|
||||
(block $ok
|
||||
(br_if $ok
|
||||
(local.get 0)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "deploy"))
|
||||
|
||||
(func (export "call")
|
||||
;; If the input data is not empty, then recursively call self with empty input data.
|
||||
;; This should trap instead of self-destructing since a contract cannot be removed live in
|
||||
;; the execution stack cannot be removed. If the recursive call traps, then trap here as
|
||||
;; well.
|
||||
(call $seal_input (i32.const 68) (i32.const 72))
|
||||
(if (i32.load (i32.const 72))
|
||||
(then
|
||||
(call $seal_address (i32.const 0) (i32.const 32))
|
||||
|
||||
;; Expect address to be 8 bytes.
|
||||
(call $assert
|
||||
(i32.eq
|
||||
(i32.load (i32.const 32))
|
||||
(i32.const 32)
|
||||
)
|
||||
)
|
||||
|
||||
;; Recursively call self with empty input data.
|
||||
(call $assert
|
||||
(i32.eq
|
||||
(call $seal_call
|
||||
(i32.const 0) ;; Pointer to own address
|
||||
(i32.const 32) ;; Length of own address
|
||||
(i64.const 0) ;; How much gas to devote for the execution. 0 = all.
|
||||
(i32.const 76) ;; Pointer to the buffer with value to transfer
|
||||
(i32.const 8) ;; Length of the buffer with value to transfer
|
||||
(i32.const 0) ;; Pointer to input data buffer address
|
||||
(i32.const 0) ;; Length of input data buffer
|
||||
(i32.const 4294967295) ;; u32 max sentinel value: do not copy output
|
||||
(i32.const 0) ;; Length is ignored in this case
|
||||
)
|
||||
(i32.const 0)
|
||||
)
|
||||
)
|
||||
)
|
||||
(else
|
||||
;; Try to terminate and give balance to django.
|
||||
(call $seal_terminate
|
||||
(i32.const 36) ;; Pointer to beneficiary address
|
||||
(i32.const 32) ;; Length of beneficiary address
|
||||
)
|
||||
(unreachable) ;; seal_terminate never returns
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -1,23 +0,0 @@
|
||||
(module
|
||||
(import "seal0" "seal_terminate" (func $seal_terminate (param i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
(func $assert (param i32)
|
||||
(block $ok
|
||||
(br_if $ok
|
||||
(local.get 0)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "deploy")
|
||||
;; Self-destruct by sending full balance to the 0 address.
|
||||
(call $seal_terminate
|
||||
(i32.const 0) ;; Pointer to destination address
|
||||
(i32.const 32) ;; Length of destination address
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "call"))
|
||||
)
|
||||
@@ -1,43 +0,0 @@
|
||||
(module
|
||||
(import "seal0" "seal_input" (func $seal_input (param i32 i32)))
|
||||
(import "seal0" "seal_return" (func $seal_return (param i32 i32 i32)))
|
||||
(import "seal0" "seal_set_code_hash" (func $seal_set_code_hash (param i32) (result i32)))
|
||||
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
;; [0, 32) here we store input
|
||||
|
||||
;; [32, 36) input size
|
||||
(data (i32.const 32) "\20")
|
||||
|
||||
;; [36, 40) return value
|
||||
(data (i32.const 36) "\01")
|
||||
|
||||
(func $assert (param i32)
|
||||
(block $ok
|
||||
(br_if $ok
|
||||
(local.get 0)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "call")
|
||||
(local $exit_code i32)
|
||||
|
||||
(call $seal_input (i32.const 0) (i32.const 32))
|
||||
|
||||
(local.set $exit_code
|
||||
(call $seal_set_code_hash (i32.const 0)) ;; Pointer to the input data.
|
||||
)
|
||||
(call $assert
|
||||
(i32.eq (local.get $exit_code) (i32.const 0)) ;; ReturnCode::Success
|
||||
)
|
||||
|
||||
;; we return 1 after setting new code_hash
|
||||
;; next `call` will NOT return this value, because contract code has been changed
|
||||
(call $seal_return (i32.const 0) (i32.const 36) (i32.const 4))
|
||||
)
|
||||
|
||||
(func (export "deploy"))
|
||||
)
|
||||
@@ -1,15 +0,0 @@
|
||||
;; This module stores a KV pair into the storage
|
||||
(module
|
||||
(import "seal0" "seal_set_storage" (func $seal_set_storage (param i32 i32 i32)))
|
||||
(import "env" "memory" (memory 16 16))
|
||||
|
||||
(func (export "call")
|
||||
)
|
||||
(func (export "deploy")
|
||||
(call $seal_set_storage
|
||||
(i32.const 0) ;; Pointer to storage key
|
||||
(i32.const 0) ;; Pointer to value
|
||||
(i32.load (i32.const 0)) ;; Size of value
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -1,55 +0,0 @@
|
||||
;; This contract:
|
||||
;; 1) Reads signature, message and public key from the input
|
||||
;; 2) Calls and return the result of sr25519_verify
|
||||
|
||||
(module
|
||||
;; import the host functions from the seal0 module
|
||||
(import "seal0" "sr25519_verify" (func $sr25519_verify (param i32 i32 i32 i32) (result i32)))
|
||||
(import "seal0" "seal_input" (func $seal_input (param i32 i32)))
|
||||
(import "seal0" "seal_return" (func $seal_return (param i32 i32 i32)))
|
||||
|
||||
;; give the program 1 page of memory
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
;; [0, 4) length of signature + message + public key - 64 + 11 + 32 = 107 bytes
|
||||
;; write the length of the input (6b = 107) bytes at offset 0
|
||||
(data (i32.const 0) "\6b")
|
||||
|
||||
(func (export "deploy"))
|
||||
|
||||
(func (export "call")
|
||||
;; define local variables
|
||||
(local $signature_ptr i32)
|
||||
(local $pub_key_ptr i32)
|
||||
(local $message_len i32)
|
||||
(local $message_ptr i32)
|
||||
|
||||
;; set the pointers to the memory locations
|
||||
;; Memory layout during `call`
|
||||
;; [10, 74) signature
|
||||
;; [74, 106) public key
|
||||
;; [106, 117) message (11 bytes)
|
||||
(local.set $signature_ptr (i32.const 10))
|
||||
(local.set $pub_key_ptr (i32.const 74))
|
||||
(local.set $message_ptr (i32.const 106))
|
||||
|
||||
;; store the input into the memory, starting at the signature and
|
||||
;; up to 107 bytes stored at offset 0
|
||||
(call $seal_input (local.get $signature_ptr) (i32.const 0))
|
||||
|
||||
;; call sr25519_verify and store the return code
|
||||
(i32.store
|
||||
(i32.const 0)
|
||||
(call $sr25519_verify
|
||||
(local.get $signature_ptr)
|
||||
(local.get $pub_key_ptr)
|
||||
(i32.const 11)
|
||||
(local.get $message_ptr)
|
||||
)
|
||||
)
|
||||
|
||||
;; exit with success and take transfer return code to the output buffer
|
||||
(call $seal_return (i32.const 0) (i32.const 0) (i32.const 4))
|
||||
)
|
||||
)
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
(module
|
||||
(import "seal0" "seal_get_storage" (func $seal_get_storage (param i32 i32 i32) (result i32)))
|
||||
(import "seal0" "seal_set_storage" (func $seal_set_storage (param i32 i32 i32)))
|
||||
(import "seal0" "seal_input" (func $seal_input (param i32 i32)))
|
||||
(import "env" "memory" (memory 16 16))
|
||||
|
||||
;; [0, 32) storage key
|
||||
(data (i32.const 0) "\01")
|
||||
|
||||
;; [32, 36) buffer where input is copied (expected size of storage item)
|
||||
|
||||
;; [36, 40) size of the input buffer
|
||||
(data (i32.const 36) "\04")
|
||||
|
||||
;; [40, 44) size of buffer for seal_get_storage set to max
|
||||
(data (i32.const 40) "\FF\FF\FF\FF")
|
||||
|
||||
;; [44, inf) seal_get_storage buffer
|
||||
|
||||
(func $assert (param i32)
|
||||
(block $ok
|
||||
(br_if $ok
|
||||
(local.get 0)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "call")
|
||||
(call $seal_input (i32.const 32) (i32.const 36))
|
||||
|
||||
;; assert input size == 4
|
||||
(call $assert
|
||||
(i32.eq
|
||||
(i32.load (i32.const 36))
|
||||
(i32.const 4)
|
||||
)
|
||||
)
|
||||
|
||||
;; place a garbage value in storage, the size of which is specified by the call input.
|
||||
(call $seal_set_storage
|
||||
(i32.const 0) ;; Pointer to storage key
|
||||
(i32.const 0) ;; Pointer to value
|
||||
(i32.load (i32.const 32)) ;; Size of value
|
||||
)
|
||||
|
||||
(call $assert
|
||||
(i32.eq
|
||||
(call $seal_get_storage
|
||||
(i32.const 0) ;; Pointer to storage key
|
||||
(i32.const 44) ;; buffer where to copy result
|
||||
(i32.const 40) ;; pointer to size of buffer
|
||||
)
|
||||
(i32.const 0)
|
||||
)
|
||||
)
|
||||
|
||||
(call $assert
|
||||
(i32.eq
|
||||
(i32.load (i32.const 40))
|
||||
(i32.load (i32.const 32))
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "deploy"))
|
||||
|
||||
)
|
||||
@@ -1,45 +0,0 @@
|
||||
;; Stores a value of the passed size.
|
||||
(module
|
||||
(import "seal0" "seal_set_storage" (func $seal_set_storage (param i32 i32 i32)))
|
||||
(import "seal0" "seal_input" (func $seal_input (param i32 i32)))
|
||||
(import "env" "memory" (memory 16 16))
|
||||
|
||||
;; [0, 32) storage key
|
||||
(data (i32.const 0) "\01")
|
||||
|
||||
;; [32, 36) buffer where input is copied (expected size of storage item)
|
||||
|
||||
;; [36, 40) size of the input buffer
|
||||
(data (i32.const 36) "\04")
|
||||
|
||||
(func $assert (param i32)
|
||||
(block $ok
|
||||
(br_if $ok
|
||||
(local.get 0)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "call")
|
||||
(call $seal_input (i32.const 32) (i32.const 36))
|
||||
|
||||
;; assert input size == 4
|
||||
(call $assert
|
||||
(i32.eq
|
||||
(i32.load (i32.const 36))
|
||||
(i32.const 4)
|
||||
)
|
||||
)
|
||||
|
||||
;; place a value in storage, the size of which is specified by the call input.
|
||||
;; we don't care about the contents of the storage item
|
||||
(call $seal_set_storage
|
||||
(i32.const 0) ;; Pointer to storage key
|
||||
(i32.const 0) ;; Pointer to value
|
||||
(i32.load (i32.const 32)) ;; Size of value
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "deploy"))
|
||||
)
|
||||
@@ -1,45 +0,0 @@
|
||||
;; Stores a value of the passed size in constructor.
|
||||
(module
|
||||
(import "seal0" "seal_set_storage" (func $seal_set_storage (param i32 i32 i32)))
|
||||
(import "seal0" "seal_input" (func $seal_input (param i32 i32)))
|
||||
(import "env" "memory" (memory 16 16))
|
||||
|
||||
;; [0, 32) storage key
|
||||
(data (i32.const 0) "\01")
|
||||
|
||||
;; [32, 36) buffer where input is copied (expected size of storage item)
|
||||
|
||||
;; [36, 40) size of the input buffer
|
||||
(data (i32.const 36) "\04")
|
||||
|
||||
(func $assert (param i32)
|
||||
(block $ok
|
||||
(br_if $ok
|
||||
(local.get 0)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "deploy")
|
||||
(call $seal_input (i32.const 32) (i32.const 36))
|
||||
|
||||
;; assert input size == 4
|
||||
(call $assert
|
||||
(i32.eq
|
||||
(i32.load (i32.const 36))
|
||||
(i32.const 4)
|
||||
)
|
||||
)
|
||||
|
||||
;; place a value in storage, the size of which is specified by the call input.
|
||||
;; we don't care about the contents of the storage item
|
||||
(call $seal_set_storage
|
||||
(i32.const 0) ;; Pointer to storage key
|
||||
(i32.const 0) ;; Pointer to value
|
||||
(i32.load (i32.const 32)) ;; Size of value
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "call"))
|
||||
)
|
||||
@@ -1,34 +0,0 @@
|
||||
;; This transfers 100 balance to the zero account and copies the return code
|
||||
;; of this transfer to the output buffer.
|
||||
(module
|
||||
(import "seal0" "seal_transfer" (func $seal_transfer (param i32 i32 i32 i32) (result i32)))
|
||||
(import "seal0" "seal_return" (func $seal_return (param i32 i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
;; [0, 32) zero-adress
|
||||
(data (i32.const 0)
|
||||
"\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00"
|
||||
"\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00"
|
||||
)
|
||||
|
||||
;; [32, 40) 100 balance
|
||||
(data (i32.const 32) "\64\00\00\00\00\00\00\00")
|
||||
|
||||
;; [40, 44) here we store the return code of the transfer
|
||||
|
||||
(func (export "deploy"))
|
||||
|
||||
(func (export "call")
|
||||
(i32.store
|
||||
(i32.const 40)
|
||||
(call $seal_transfer
|
||||
(i32.const 0) ;; ptr to destination address
|
||||
(i32.const 32) ;; length of destination address
|
||||
(i32.const 32) ;; ptr to value to transfer
|
||||
(i32.const 8) ;; length of value to transfer
|
||||
)
|
||||
)
|
||||
;; exit with success and take transfer return code to the output buffer
|
||||
(call $seal_return (i32.const 0) (i32.const 40) (i32.const 4))
|
||||
)
|
||||
)
|
||||
@@ -1,52 +0,0 @@
|
||||
;; This passes its input to `seal_xcm_execute` and returns the return value to its caller.
|
||||
(module
|
||||
(import "seal0" "xcm_execute" (func $xcm_execute (param i32 i32 i32) (result i32)))
|
||||
(import "seal0" "seal_input" (func $seal_input (param i32 i32)))
|
||||
(import "seal0" "seal_return" (func $seal_return (param i32 i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
;; 0x1000 = 4k in little endian
|
||||
;; Size of input buffer
|
||||
(data (i32.const 0) "\00\10")
|
||||
|
||||
(func $assert (param i32)
|
||||
(block $ok
|
||||
(br_if $ok
|
||||
(local.get 0)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "call")
|
||||
;; Receive the encoded call
|
||||
(call $seal_input
|
||||
(i32.const 4) ;; Pointer to the input buffer
|
||||
(i32.const 0) ;; Pointer to the buffer length (before call) and to the copied data length (after call)
|
||||
)
|
||||
;; Input data layout.
|
||||
;; [0..4) - size of the call
|
||||
;; [4..) - message
|
||||
|
||||
;; Call xcm_execute with provided input.
|
||||
(call $assert
|
||||
(i32.eq
|
||||
(call $xcm_execute
|
||||
(i32.const 4) ;; Pointer where the message is stored
|
||||
(i32.load (i32.const 0)) ;; Size of the message
|
||||
(i32.const 100) ;; Pointer to the where the outcome is stored
|
||||
)
|
||||
(i32.const 0)
|
||||
)
|
||||
)
|
||||
|
||||
(call $seal_return
|
||||
(i32.const 0) ;; flags
|
||||
(i32.const 100) ;; Pointer to returned value
|
||||
(i32.const 10) ;; length of returned value
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "deploy"))
|
||||
)
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
;; This passes its input to `seal_xcm_send` and returns the return value to its caller.
|
||||
(module
|
||||
(import "seal0" "xcm_send" (func $xcm_send (param i32 i32 i32 i32) (result i32)))
|
||||
(import "seal0" "seal_input" (func $seal_input (param i32 i32)))
|
||||
(import "seal0" "seal_return" (func $seal_return (param i32 i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
;; 0x1000 = 4k in little endian
|
||||
;; size of input buffer
|
||||
(data (i32.const 0) "\00\10")
|
||||
|
||||
(func $assert (param i32)
|
||||
(block $ok
|
||||
(br_if $ok
|
||||
(local.get 0)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "call")
|
||||
|
||||
;; Receive the encoded call
|
||||
(call $seal_input
|
||||
(i32.const 4) ;; Pointer to the input buffer
|
||||
(i32.const 0) ;; Size of the length buffer
|
||||
)
|
||||
|
||||
;; Input data layout.
|
||||
;; [0..4) - size of the call
|
||||
;; [4..7) - dest
|
||||
;; [7..) - message
|
||||
|
||||
;; Call xcm_send with provided input.
|
||||
(call $assert
|
||||
(i32.eq
|
||||
(call $xcm_send
|
||||
(i32.const 4) ;; Pointer where the dest is stored
|
||||
(i32.const 7) ;; Pointer where the message is stored
|
||||
(i32.sub
|
||||
(i32.load (i32.const 0)) ;; length of the input buffer
|
||||
(i32.const 3) ;; Size of the XCM dest
|
||||
)
|
||||
(i32.const 100) ;; Pointer to the where the message_id is stored
|
||||
)
|
||||
(i32.const 0)
|
||||
)
|
||||
)
|
||||
|
||||
;; Return the the message_id
|
||||
(call $seal_return
|
||||
(i32.const 0) ;; flags
|
||||
(i32.const 100) ;; Pointer to returned value
|
||||
(i32.const 32) ;; length of returned value
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "deploy"))
|
||||
)
|
||||
@@ -69,8 +69,7 @@ mod test {
|
||||
#[test]
|
||||
fn out_dir_should_have_compiled_mocks() {
|
||||
let out_dir: std::path::PathBuf = env!("OUT_DIR").into();
|
||||
let dummy_wasm = out_dir.join("dummy.wasm");
|
||||
println!("dummy_wasm: {:?}", dummy_wasm);
|
||||
assert!(dummy_wasm.exists());
|
||||
assert!(out_dir.join("dummy.wasm").exists());
|
||||
assert!(out_dir.join("dummy.polkavm").exists());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,7 +178,7 @@ parameter_types! {
|
||||
pub struct TestExtension {
|
||||
enabled: bool,
|
||||
last_seen_buffer: Vec<u8>,
|
||||
last_seen_inputs: (u32, u32, u32, u32),
|
||||
last_seen_input_len: u32,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
@@ -201,14 +201,14 @@ impl TestExtension {
|
||||
TestExtensionTestValue::get().last_seen_buffer.clone()
|
||||
}
|
||||
|
||||
fn last_seen_inputs() -> (u32, u32, u32, u32) {
|
||||
TestExtensionTestValue::get().last_seen_inputs
|
||||
fn last_seen_input_len() -> u32 {
|
||||
TestExtensionTestValue::get().last_seen_input_len
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for TestExtension {
|
||||
fn default() -> Self {
|
||||
Self { enabled: true, last_seen_buffer: vec![], last_seen_inputs: (0, 0, 0, 0) }
|
||||
Self { enabled: true, last_seen_buffer: vec![], last_seen_input_len: 0 }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,9 +231,7 @@ impl ChainExtension<Test> for TestExtension {
|
||||
},
|
||||
1 => {
|
||||
let env = env.only_in();
|
||||
TestExtensionTestValue::mutate(|e| {
|
||||
e.last_seen_inputs = (env.val0(), env.val1(), env.val2(), env.val3())
|
||||
});
|
||||
TestExtensionTestValue::mutate(|e| e.last_seen_input_len = env.val1());
|
||||
Ok(RetVal::Converging(id))
|
||||
},
|
||||
2 => {
|
||||
@@ -2154,8 +2152,7 @@ fn chain_extension_works() {
|
||||
)
|
||||
.result
|
||||
.unwrap();
|
||||
// those values passed in the fixture
|
||||
assert_eq!(TestExtension::last_seen_inputs(), (4, 4, 16, 12));
|
||||
assert_eq!(TestExtension::last_seen_input_len(), 4);
|
||||
|
||||
// 2 = charge some extra weight (amount supplied in the fifth byte)
|
||||
let result = Contracts::bare_call(
|
||||
@@ -3511,7 +3508,7 @@ fn failed_deposit_charge_should_roll_back_call() {
|
||||
let result = execute().unwrap();
|
||||
|
||||
// Bump the deposit per byte to a high value to trigger a FundsUnavailable error.
|
||||
DEPOSIT_PER_BYTE.with(|c| *c.borrow_mut() = ED);
|
||||
DEPOSIT_PER_BYTE.with(|c| *c.borrow_mut() = 20);
|
||||
assert_err_with_weight!(execute(), TokenError::FundsUnavailable, result.actual_weight);
|
||||
}
|
||||
|
||||
|
||||
@@ -2460,7 +2460,7 @@ mod tests {
|
||||
assert_eq!(
|
||||
result,
|
||||
Err(ExecError {
|
||||
error: Error::<Test>::OutOfBounds.into(),
|
||||
error: Error::<Test>::DecodingFailed.into(),
|
||||
origin: ErrorOrigin::Caller,
|
||||
})
|
||||
);
|
||||
@@ -3428,4 +3428,20 @@ mod tests {
|
||||
assert_eq!(delegate_dependencies.len(), 1);
|
||||
assert_eq!(delegate_dependencies[0].as_bytes(), [1; 32]);
|
||||
}
|
||||
|
||||
// This test checks that [`Runtime::read_sandbox_memory_as`] works, when the decoded type has a
|
||||
// max_len greater than the memory size, but the decoded data fits into the memory.
|
||||
#[test]
|
||||
fn read_sandbox_memory_as_works_with_max_len_out_of_bounds_but_fitting_actual_data() {
|
||||
use frame_support::BoundedVec;
|
||||
use sp_core::ConstU32;
|
||||
|
||||
let mut ext = MockExt::default();
|
||||
let runtime = Runtime::new(&mut ext, vec![]);
|
||||
let data = vec![1u8, 2, 3];
|
||||
let memory = data.encode();
|
||||
let decoded: BoundedVec<u8, ConstU32<128>> =
|
||||
runtime.read_sandbox_memory_as(&memory, 0u32).unwrap();
|
||||
assert_eq!(decoded.into_inner(), data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -583,9 +583,8 @@ impl<'a, E: Ext + 'a> Runtime<'a, E> {
|
||||
ptr: u32,
|
||||
) -> Result<D, DispatchError> {
|
||||
let ptr = ptr as usize;
|
||||
let mut bound_checked = memory
|
||||
.get(ptr..ptr + D::max_encoded_len() as usize)
|
||||
.ok_or_else(|| Error::<E::T>::OutOfBounds)?;
|
||||
let mut bound_checked = memory.get(ptr..).ok_or_else(|| Error::<E::T>::OutOfBounds)?;
|
||||
|
||||
let decoded = D::decode_with_depth_limit(MAX_DECODE_NESTING, &mut bound_checked)
|
||||
.map_err(|_| DispatchError::from(Error::<E::T>::DecodingFailed))?;
|
||||
Ok(decoded)
|
||||
|
||||
@@ -38,6 +38,7 @@ macro_rules! hash_fn {
|
||||
|
||||
// TODO remove cfg once used by all targets
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[inline(always)]
|
||||
fn extract_from_slice(output: &mut &mut [u8], new_len: usize) {
|
||||
debug_assert!(new_len <= output.len());
|
||||
let tmp = core::mem::take(output);
|
||||
@@ -45,7 +46,8 @@ fn extract_from_slice(output: &mut &mut [u8], new_len: usize) {
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
fn ptr_len_or_sentinel(data: &mut Option<&mut [u8]>) -> (*mut u8, u32) {
|
||||
#[inline(always)]
|
||||
fn ptr_len_or_sentinel(data: &mut Option<&mut &mut [u8]>) -> (*mut u8, u32) {
|
||||
match data {
|
||||
Some(ref mut data) => (data.as_mut_ptr(), data.len() as _),
|
||||
None => (crate::SENTINEL as _, 0),
|
||||
@@ -53,6 +55,7 @@ fn ptr_len_or_sentinel(data: &mut Option<&mut [u8]>) -> (*mut u8, u32) {
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[inline(always)]
|
||||
fn ptr_or_sentinel(data: &Option<&[u8]>) -> *const u8 {
|
||||
match data {
|
||||
Some(ref data) => data.as_ptr(),
|
||||
@@ -132,7 +135,7 @@ pub trait HostFn {
|
||||
gas: u64,
|
||||
value: &[u8],
|
||||
input_data: &[u8],
|
||||
output: Option<&mut [u8]>,
|
||||
output: Option<&mut &mut [u8]>,
|
||||
) -> Result;
|
||||
|
||||
/// Make a call to another contract.
|
||||
@@ -145,7 +148,7 @@ pub trait HostFn {
|
||||
gas: u64,
|
||||
value: &[u8],
|
||||
input_data: &[u8],
|
||||
output: Option<&mut [u8]>,
|
||||
output: Option<&mut &mut [u8]>,
|
||||
) -> Result;
|
||||
|
||||
/// Call (possibly transferring some amount of funds) into the specified account.
|
||||
@@ -186,7 +189,7 @@ pub trait HostFn {
|
||||
deposit: Option<&[u8]>,
|
||||
value: &[u8],
|
||||
input_data: &[u8],
|
||||
output: Option<&mut [u8]>,
|
||||
output: Option<&mut &mut [u8]>,
|
||||
) -> Result;
|
||||
|
||||
/// Call into the chain extension provided by the chain if any.
|
||||
@@ -211,7 +214,7 @@ pub trait HostFn {
|
||||
/// # Return
|
||||
///
|
||||
/// The chain extension returned value, if executed successfully.
|
||||
fn call_chain_extension(func_id: u32, input: &[u8], output: Option<&mut [u8]>) -> u32;
|
||||
fn call_chain_extension(func_id: u32, input: &[u8], output: Option<&mut &mut [u8]>) -> u32;
|
||||
|
||||
/// Call some dispatchable of the runtime.
|
||||
///
|
||||
@@ -374,7 +377,7 @@ pub trait HostFn {
|
||||
flags: CallFlags,
|
||||
code_hash: &[u8],
|
||||
input_data: &[u8],
|
||||
output: Option<&mut [u8]>,
|
||||
output: Option<&mut &mut [u8]>,
|
||||
) -> Result;
|
||||
|
||||
/// Deposit a contract event with the data buffer and optional list of topics. There is a limit
|
||||
@@ -485,8 +488,8 @@ pub trait HostFn {
|
||||
gas: u64,
|
||||
value: &[u8],
|
||||
input: &[u8],
|
||||
address: Option<&mut [u8]>,
|
||||
output: Option<&mut [u8]>,
|
||||
address: Option<&mut &mut [u8]>,
|
||||
output: Option<&mut &mut [u8]>,
|
||||
salt: &[u8],
|
||||
) -> Result;
|
||||
|
||||
@@ -534,8 +537,8 @@ pub trait HostFn {
|
||||
deposit: Option<&[u8]>,
|
||||
value: &[u8],
|
||||
input: &[u8],
|
||||
address: Option<&mut [u8]>,
|
||||
output: Option<&mut [u8]>,
|
||||
address: Option<&mut &mut [u8]>,
|
||||
output: Option<&mut &mut [u8]>,
|
||||
salt: &[u8],
|
||||
) -> Result;
|
||||
|
||||
|
||||
@@ -84,8 +84,8 @@ impl HostFn for HostFnImpl {
|
||||
gas: u64,
|
||||
value: &[u8],
|
||||
input: &[u8],
|
||||
mut address: Option<&mut [u8]>,
|
||||
mut output: Option<&mut [u8]>,
|
||||
mut address: Option<&mut &mut [u8]>,
|
||||
mut output: Option<&mut &mut [u8]>,
|
||||
salt: &[u8],
|
||||
) -> Result {
|
||||
todo!()
|
||||
@@ -98,8 +98,8 @@ impl HostFn for HostFnImpl {
|
||||
deposit: Option<&[u8]>,
|
||||
value: &[u8],
|
||||
input: &[u8],
|
||||
mut address: Option<&mut [u8]>,
|
||||
mut output: Option<&mut [u8]>,
|
||||
mut address: Option<&mut &mut [u8]>,
|
||||
mut output: Option<&mut &mut [u8]>,
|
||||
salt: &[u8],
|
||||
) -> Result {
|
||||
todo!()
|
||||
@@ -110,7 +110,7 @@ impl HostFn for HostFnImpl {
|
||||
gas: u64,
|
||||
value: &[u8],
|
||||
input_data: &[u8],
|
||||
mut output: Option<&mut [u8]>,
|
||||
mut output: Option<&mut &mut [u8]>,
|
||||
) -> Result {
|
||||
todo!()
|
||||
}
|
||||
@@ -121,7 +121,7 @@ impl HostFn for HostFnImpl {
|
||||
gas: u64,
|
||||
value: &[u8],
|
||||
input_data: &[u8],
|
||||
mut output: Option<&mut [u8]>,
|
||||
mut output: Option<&mut &mut [u8]>,
|
||||
) -> Result {
|
||||
todo!()
|
||||
}
|
||||
@@ -134,7 +134,7 @@ impl HostFn for HostFnImpl {
|
||||
deposit: Option<&[u8]>,
|
||||
value: &[u8],
|
||||
input_data: &[u8],
|
||||
mut output: Option<&mut [u8]>,
|
||||
mut output: Option<&mut &mut [u8]>,
|
||||
) -> Result {
|
||||
todo!()
|
||||
}
|
||||
@@ -147,7 +147,7 @@ impl HostFn for HostFnImpl {
|
||||
flags: CallFlags,
|
||||
code_hash: &[u8],
|
||||
input: &[u8],
|
||||
mut output: Option<&mut [u8]>,
|
||||
mut output: Option<&mut &mut [u8]>,
|
||||
) -> Result {
|
||||
todo!()
|
||||
}
|
||||
@@ -203,7 +203,7 @@ impl HostFn for HostFnImpl {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn call_chain_extension(func_id: u32, input: &[u8], output: Option<&mut [u8]>) -> u32 {
|
||||
fn call_chain_extension(func_id: u32, input: &[u8], output: Option<&mut &mut [u8]>) -> u32 {
|
||||
todo!()
|
||||
}
|
||||
|
||||
|
||||
@@ -336,13 +336,14 @@ macro_rules! impl_hash_fn {
|
||||
}
|
||||
|
||||
impl HostFn for HostFnImpl {
|
||||
#[inline(always)]
|
||||
fn instantiate_v1(
|
||||
code_hash: &[u8],
|
||||
gas: u64,
|
||||
value: &[u8],
|
||||
input: &[u8],
|
||||
mut address: Option<&mut [u8]>,
|
||||
mut output: Option<&mut [u8]>,
|
||||
mut address: Option<&mut &mut [u8]>,
|
||||
mut output: Option<&mut &mut [u8]>,
|
||||
salt: &[u8],
|
||||
) -> Result {
|
||||
let (address_ptr, mut address_len) = ptr_len_or_sentinel(&mut address);
|
||||
@@ -379,8 +380,8 @@ impl HostFn for HostFnImpl {
|
||||
deposit: Option<&[u8]>,
|
||||
value: &[u8],
|
||||
input: &[u8],
|
||||
mut address: Option<&mut [u8]>,
|
||||
mut output: Option<&mut [u8]>,
|
||||
mut address: Option<&mut &mut [u8]>,
|
||||
mut output: Option<&mut &mut [u8]>,
|
||||
salt: &[u8],
|
||||
) -> Result {
|
||||
let (address_ptr, mut address_len) = ptr_len_or_sentinel(&mut address);
|
||||
@@ -418,12 +419,13 @@ impl HostFn for HostFnImpl {
|
||||
ret_code.into()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn call(
|
||||
callee: &[u8],
|
||||
gas: u64,
|
||||
value: &[u8],
|
||||
input_data: &[u8],
|
||||
mut output: Option<&mut [u8]>,
|
||||
mut output: Option<&mut &mut [u8]>,
|
||||
) -> Result {
|
||||
let (output_ptr, mut output_len) = ptr_len_or_sentinel(&mut output);
|
||||
let ret_code = {
|
||||
@@ -449,13 +451,14 @@ impl HostFn for HostFnImpl {
|
||||
ret_code.into()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn call_v1(
|
||||
flags: CallFlags,
|
||||
callee: &[u8],
|
||||
gas: u64,
|
||||
value: &[u8],
|
||||
input_data: &[u8],
|
||||
mut output: Option<&mut [u8]>,
|
||||
mut output: Option<&mut &mut [u8]>,
|
||||
) -> Result {
|
||||
let (output_ptr, mut output_len) = ptr_len_or_sentinel(&mut output);
|
||||
let ret_code = {
|
||||
@@ -488,7 +491,7 @@ impl HostFn for HostFnImpl {
|
||||
deposit: Option<&[u8]>,
|
||||
value: &[u8],
|
||||
input_data: &[u8],
|
||||
mut output: Option<&mut [u8]>,
|
||||
mut output: Option<&mut &mut [u8]>,
|
||||
) -> Result {
|
||||
let (output_ptr, mut output_len) = ptr_len_or_sentinel(&mut output);
|
||||
let deposit_ptr = ptr_or_sentinel(&deposit);
|
||||
@@ -520,11 +523,12 @@ impl HostFn for HostFnImpl {
|
||||
unsafe { sys::caller_is_root() }.into_u32()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn delegate_call(
|
||||
flags: CallFlags,
|
||||
code_hash: &[u8],
|
||||
input: &[u8],
|
||||
mut output: Option<&mut [u8]>,
|
||||
mut output: Option<&mut &mut [u8]>,
|
||||
) -> Result {
|
||||
let (output_ptr, mut output_len) = ptr_len_or_sentinel(&mut output);
|
||||
let ret_code = {
|
||||
@@ -602,6 +606,7 @@ impl HostFn for HostFnImpl {
|
||||
ret_code.into()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn get_storage(key: &[u8], output: &mut &mut [u8]) -> Result {
|
||||
let mut output_len = output.len() as u32;
|
||||
let ret_code =
|
||||
@@ -610,6 +615,7 @@ impl HostFn for HostFnImpl {
|
||||
ret_code.into()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn get_storage_v1(key: &[u8], output: &mut &mut [u8]) -> Result {
|
||||
let mut output_len = output.len() as u32;
|
||||
let ret_code = {
|
||||
@@ -626,6 +632,7 @@ impl HostFn for HostFnImpl {
|
||||
ret_code.into()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn take_storage(key: &[u8], output: &mut &mut [u8]) -> Result {
|
||||
let mut output_len = output.len() as u32;
|
||||
let ret_code = {
|
||||
@@ -665,7 +672,7 @@ impl HostFn for HostFnImpl {
|
||||
unsafe { sys::v1::terminate(beneficiary.as_ptr()) }
|
||||
}
|
||||
|
||||
fn call_chain_extension(func_id: u32, input: &[u8], mut output: Option<&mut [u8]>) -> u32 {
|
||||
fn call_chain_extension(func_id: u32, input: &[u8], mut output: Option<&mut &mut [u8]>) -> u32 {
|
||||
let (output_ptr, mut output_len) = ptr_len_or_sentinel(&mut output);
|
||||
let ret_code = {
|
||||
unsafe {
|
||||
@@ -685,6 +692,7 @@ impl HostFn for HostFnImpl {
|
||||
ret_code.into_u32()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn input(output: &mut &mut [u8]) {
|
||||
let mut output_len = output.len() as u32;
|
||||
{
|
||||
@@ -707,6 +715,7 @@ impl HostFn for HostFnImpl {
|
||||
(v1) => [gas_left],
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn weight_to_fee(gas: u64, output: &mut &mut [u8]) {
|
||||
let mut output_len = output.len() as u32;
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user