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:
PG Herveou
2024-01-12 21:10:54 +01:00
committed by GitHub
parent c421b87978
commit bd80dcf685
101 changed files with 2352 additions and 2602 deletions
@@ -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);
};
}