From e13904b4c9b75ce53be2cd0b80851192f472f6c2 Mon Sep 17 00:00:00 2001 From: BiancaIalangi Date: Tue, 18 Jun 2024 01:08:51 +0300 Subject: [PATCH 001/185] detect write op --- .../mappers/linked-list-repeat/file.txt | 2150 +++++++++++++++++ .../src/linked_list_repeat.rs | 6 +- .../linked-list-repeat/wasm/src/lib.rs | 6 +- 3 files changed, 2157 insertions(+), 5 deletions(-) create mode 100644 contracts/benchmarks/mappers/linked-list-repeat/file.txt diff --git a/contracts/benchmarks/mappers/linked-list-repeat/file.txt b/contracts/benchmarks/mappers/linked-list-repeat/file.txt new file mode 100644 index 0000000000..799122fd71 --- /dev/null +++ b/contracts/benchmarks/mappers/linked-list-repeat/file.txt @@ -0,0 +1,2150 @@ + /home/bibi/Desktop/mx-sdk-rs/contracts/benchmarks/mappers/linked-list-repeat + +Found 1 contract crates. + +(1/1) +In /home/bibi/Desktop/mx-sdk-rs/contracts/benchmarks/mappers/linked-list-repeat/meta +Calling `cargo run build` +Using workspace target directory: /home/bibi/Desktop/mx-sdk-rs/target ... +Building linked-list-repeat.wasm in /home/bibi/Desktop/mx-sdk-rs/contracts/benchmarks/mappers/linked-list-repeat/wasm ... +RUSTFLAGS="-C link-arg=-s -C link-arg=-zstack-size=131072" cargo build --target=wasm32-unknown-unknown --release --target-dir /home/bibi/Desktop/mx-sdk-rs/target +Copying /home/bibi/Desktop/mx-sdk-rs/target/wasm32-unknown-unknown/release/linked_list_repeat_wasm.wasm to ../output/linked-list-repeat.wasm ... +Calling wasm-opt on ../output/linked-list-repeat.wasm ... +Extracting imports to ../output/linked-list-repeat.imports.json ... +FailAllocator used while memory allocation is accessible in code. Contract may fail unexpectedly when memory allocation is attempted +Instruction: Call { function_index: 24 } +Call instruction: calls function index 24 +Instruction: I32Const { value: 131268 } +Instruction: I32Const { value: 131268 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } +Instruction: I32Const { value: 1 } +Instruction: I32Sub +Instruction: LocalTee { local_index: 0 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } +Instruction: LocalGet { local_index: 0 } +Instruction: End +Instruction: Call { function_index: 2 } +Call instruction: calls function index 2 +Instruction: LocalTee { local_index: 1 } +Instruction: LocalGet { local_index: 0 } +Instruction: Call { function_index: 3 } +Call instruction: calls function index 3 +Instruction: Drop +Instruction: LocalGet { local_index: 1 } +Instruction: End +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 1 } +Instruction: Call { function_index: 4 } +Call instruction: calls function index 4 +Instruction: I32Const { value: 0 } +Instruction: I32GtS +Instruction: End +Instruction: GlobalGet { global_index: 0 } +Instruction: I32Const { value: 96 } +Instruction: I32Sub +Instruction: LocalTee { local_index: 2 } +Instruction: GlobalSet { global_index: 0 } +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 1 } +Instruction: I64Load { memarg: MemArg { align: 3, max_align: 3, offset: 0, memory: 0 } } +Instruction: I64Eqz +Instruction: If { blockty: Type(I64) } +Instruction: I64Const { value: 0 } +Instruction: Else +Instruction: LocalGet { local_index: 2 } +Instruction: I32Const { value: 8 } +Instruction: I32Add +Instruction: LocalGet { local_index: 1 } +Instruction: I32Const { value: 8 } +Instruction: I32Add +Instruction: Call { function_index: 28 } +Call instruction: calls function index 28 +Instruction: LocalGet { local_index: 1 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 16, memory: 0 } } +Instruction: Call { function_index: 25 } +Call instruction: calls function index 25 +Instruction: LocalSet { local_index: 2 } +Instruction: LocalGet { local_index: 1 } +Instruction: I64Load { memarg: MemArg { align: 3, max_align: 3, offset: 0, memory: 0 } } +Instruction: LocalSet { local_index: 5 } +Instruction: LocalGet { local_index: 1 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 20, memory: 0 } } +Instruction: Call { function_index: 23 } +Call instruction: calls function index 23 +Instruction: LocalSet { local_index: 3 } +Instruction: LocalGet { local_index: 1 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 24, memory: 0 } } +Instruction: Call { function_index: 25 } +Call instruction: calls function index 25 +Instruction: LocalSet { local_index: 4 } +Instruction: LocalGet { local_index: 1 } +Instruction: I64Load { memarg: MemArg { align: 3, max_align: 3, offset: 8, memory: 0 } } +Instruction: LocalSet { local_index: 6 } +Instruction: LocalGet { local_index: 1 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 28, memory: 0 } } +Instruction: Call { function_index: 23 } +Call instruction: calls function index 23 +Instruction: LocalSet { local_index: 1 } +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 4 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 24, memory: 0 } } +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 3 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 20, memory: 0 } } +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 5 } +Instruction: I64Store { memarg: MemArg { align: 3, max_align: 3, offset: 0, memory: 0 } } +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 2 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 16, memory: 0 } } +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 1 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 28, memory: 0 } } +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 6 } +Instruction: I64Store { memarg: MemArg { align: 3, max_align: 3, offset: 8, memory: 0 } } +Instruction: End +Instruction: GlobalGet { global_index: 0 } +Instruction: I32Const { value: 48 } +Instruction: I32Sub +Instruction: LocalTee { local_index: 3 } +Instruction: GlobalSet { global_index: 0 } +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 1 } +Instruction: LocalGet { local_index: 2 } +Instruction: Call { function_index: 66 } +Call instruction: calls function index 66 +Instruction: GlobalGet { global_index: 0 } +Instruction: I32Const { value: 32 } +Instruction: I32Sub +Instruction: LocalTee { local_index: 2 } +Instruction: GlobalSet { global_index: 0 } +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 1 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } +Instruction: If { blockty: Type(I32) } +Instruction: LocalGet { local_index: 1 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 4, memory: 0 } } +Instruction: Call { function_index: 25 } +Call instruction: calls function index 25 +Instruction: LocalSet { local_index: 3 } +Instruction: LocalGet { local_index: 1 } +Instruction: I32Const { value: 8 } +Instruction: I32Add +Instruction: LocalTee { local_index: 4 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } +Instruction: LocalSet { local_index: 5 } +Instruction: LocalGet { local_index: 1 } +Instruction: I32Const { value: 16 } +Instruction: I32Add +Instruction: LocalTee { local_index: 6 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } +Instruction: LocalSet { local_index: 7 } +Instruction: LocalGet { local_index: 2 } +Instruction: I32Const { value: 12 } +Instruction: I32Add +Instruction: LocalGet { local_index: 1 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 20, memory: 0 } } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } +Instruction: LocalGet { local_index: 1 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 12, memory: 0 } } +Instruction: LocalTee { local_index: 8 } +Instruction: Call { function_index: 31 } +Call instruction: calls function index 31 +Instruction: GlobalGet { global_index: 0 } +Instruction: I32Const { value: 16 } +Instruction: I32Sub +Instruction: LocalTee { local_index: 3 } +Instruction: GlobalSet { global_index: 0 } +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 1 } +Instruction: LocalGet { local_index: 2 } +Instruction: Call { function_index: 66 } +Call instruction: calls function index 66 +Instruction: LocalGet { local_index: 0 } +Instruction: Call { function_index: 33 } +Call instruction: calls function index 33 +Instruction: GlobalGet { global_index: 0 } +Instruction: I32Const { value: 16 } +Instruction: I32Sub +Instruction: LocalTee { local_index: 1 } +Instruction: GlobalSet { global_index: 0 } +Instruction: LocalGet { local_index: 1 } +Instruction: I32Const { value: 0 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 12, memory: 0 } } +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 1 } +Instruction: I32Const { value: 12 } +Instruction: I32Add +Instruction: I32Const { value: 4 } +Instruction: Call { function_index: 47 } +Call instruction: calls function index 47 +Instruction: LocalGet { local_index: 0 } +Instruction: Call { function_index: 24 } +Call instruction: calls function index 24 +Instruction: LocalTee { local_index: 0 } +Instruction: Call { function_index: 17 } +Call instruction: calls function index 17 +Instruction: Drop +Instruction: LocalGet { local_index: 0 } +Instruction: End +Instruction: LocalGet { local_index: 0 } +Instruction: Call { function_index: 36 } +Call instruction: calls function index 36 +Instruction: GlobalGet { global_index: 0 } +Instruction: I32Const { value: 16 } +Instruction: I32Sub +Instruction: LocalTee { local_index: 1 } +Instruction: GlobalSet { global_index: 0 } +Instruction: LocalGet { local_index: 0 } +Instruction: Call { function_index: 49 } +Call instruction: calls function index 49 +Instruction: Call { function_index: 24 } +Call instruction: calls function index 24 +Instruction: LocalTee { local_index: 2 } +Instruction: LocalGet { local_index: 0 } +Instruction: Call { function_index: 5 } +Call instruction: calls function index 5 +Instruction: Drop +Instruction: LocalGet { local_index: 2 } +Instruction: LocalGet { local_index: 1 } +Instruction: Call { function_index: 38 } +Call instruction: calls function index 38 +Instruction: GlobalGet { global_index: 0 } +Instruction: I32Const { value: 16 } +Instruction: I32Sub +Instruction: LocalTee { local_index: 2 } +Instruction: GlobalSet { global_index: 0 } +Instruction: LocalGet { local_index: 2 } +Instruction: LocalGet { local_index: 0 } +Instruction: Call { function_index: 7 } +Call instruction: calls function index 7 +Instruction: LocalTee { local_index: 3 } +Instruction: I32Const { value: 24 } +Instruction: I32Shl +Instruction: LocalGet { local_index: 3 } +Instruction: I32Const { value: 65280 } +Instruction: I32And +Instruction: I32Const { value: 8 } +Instruction: I32Shl +Instruction: I32Or +Instruction: LocalGet { local_index: 3 } +Instruction: I32Const { value: 8 } +Instruction: I32ShrU +Instruction: I32Const { value: 65280 } +Instruction: I32And +Instruction: LocalGet { local_index: 3 } +Instruction: I32Const { value: 24 } +Instruction: I32ShrU +Instruction: I32Or +Instruction: I32Or +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 12, memory: 0 } } +Instruction: LocalGet { local_index: 1 } +Instruction: LocalGet { local_index: 2 } +Instruction: I32Const { value: 12 } +Instruction: I32Add +Instruction: I32Const { value: 4 } +Instruction: Call { function_index: 73 } +Call instruction: calls function index 73 +Instruction: LocalGet { local_index: 1 } +Instruction: Call { function_index: 24 } +Call instruction: calls function index 24 +Instruction: LocalTee { local_index: 1 } +Instruction: Call { function_index: 6 } +Call instruction: calls function index 6 +Instruction: Drop +Instruction: LocalGet { local_index: 1 } +Instruction: Call { function_index: 7 } +Call instruction: calls function index 7 +Instruction: LocalSet { local_index: 2 } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 0 } +Instruction: I32Store8 { memarg: MemArg { align: 0, max_align: 0, offset: 16, memory: 0 } } +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 2 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 12, memory: 0 } } +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 1 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 8, memory: 0 } } +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 2 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 4, memory: 0 } } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 0 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } +Instruction: End +Instruction: LocalGet { local_index: 0 } +Instruction: Call { function_index: 24 } +Call instruction: calls function index 24 +Instruction: LocalTee { local_index: 0 } +Instruction: Call { function_index: 8 } +Call instruction: calls function index 8 +Instruction: Drop +Instruction: LocalGet { local_index: 0 } +Instruction: End +Instruction: I32Const { value: 131086 } +Instruction: I32Const { value: 23 } +Instruction: Call { function_index: 42 } +Call instruction: calls function index 42 +Instruction: Call { function_index: 24 } +Call instruction: calls function index 24 +Instruction: LocalTee { local_index: 2 } +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 1 } +Instruction: Call { function_index: 16 } +Call instruction: calls function index 16 +Instruction: Drop +Instruction: LocalGet { local_index: 2 } +Instruction: End +Instruction: GlobalGet { global_index: 0 } +Instruction: I32Const { value: 32 } +Instruction: I32Sub +Instruction: LocalTee { local_index: 2 } +Instruction: GlobalSet { global_index: 0 } +Instruction: LocalGet { local_index: 1 } +Instruction: Call { function_index: 40 } +Call instruction: calls function index 40 +Instruction: LocalTee { local_index: 3 } +Instruction: Call { function_index: 7 } +Call instruction: calls function index 7 +Instruction: LocalSet { local_index: 1 } +Instruction: LocalGet { local_index: 2 } +Instruction: I32Const { value: 0 } +Instruction: I32Store8 { memarg: MemArg { align: 0, max_align: 0, offset: 28, memory: 0 } } +Instruction: LocalGet { local_index: 2 } +Instruction: LocalGet { local_index: 1 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 24, memory: 0 } } +Instruction: LocalGet { local_index: 2 } +Instruction: LocalGet { local_index: 3 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 20, memory: 0 } } +Instruction: LocalGet { local_index: 2 } +Instruction: LocalGet { local_index: 1 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 16, memory: 0 } } +Instruction: LocalGet { local_index: 2 } +Instruction: I32Const { value: 0 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 12, memory: 0 } } +Instruction: LocalGet { local_index: 2 } +Instruction: I32Const { value: 12 } +Instruction: I32Add +Instruction: LocalTee { local_index: 3 } +Instruction: Call { function_index: 33 } +Call instruction: calls function index 33 +Instruction: LocalSet { local_index: 1 } +Instruction: LocalGet { local_index: 3 } +Instruction: Call { function_index: 44 } +Call instruction: calls function index 44 +Instruction: GlobalGet { global_index: 0 } +Instruction: I32Const { value: 16 } +Instruction: I32Sub +Instruction: LocalTee { local_index: 2 } +Instruction: GlobalSet { global_index: 0 } +Instruction: LocalGet { local_index: 2 } +Instruction: I64Const { value: 0 } +Instruction: I64Store { memarg: MemArg { align: 3, max_align: 3, offset: 8, memory: 0 } } +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 2 } +Instruction: I32Const { value: 8 } +Instruction: I32Add +Instruction: I32Const { value: 8 } +Instruction: Call { function_index: 47 } +Call instruction: calls function index 47 +Instruction: I32Const { value: 0 } +Instruction: Call { function_index: 11 } +Call instruction: calls function index 11 +Instruction: LocalTee { local_index: 0 } +Instruction: I64Const { value: 4294967296 } +Instruction: I64GeU +Instruction: If { blockty: Empty } +Instruction: I32Const { value: 131189 } +Instruction: I32Const { value: 11 } +Instruction: I32Const { value: 131072 } +Instruction: I32Const { value: 14 } +Instruction: Call { function_index: 41 } +Call instruction: calls function index 41 +Instruction: Unreachable +Instruction: End +Instruction: LocalGet { local_index: 0 } +Instruction: I32WrapI64 +Instruction: End +Instruction: Call { function_index: 12 } +Call instruction: calls function index 12 +Instruction: LocalGet { local_index: 0 } +Instruction: I32Eq +Instruction: If { blockty: Empty } +Instruction: Return +Instruction: End +Instruction: I32Const { value: 131112 } +Instruction: I32Const { value: 25 } +Instruction: Call { function_index: 13 } +Call instruction: calls function index 13 +Instruction: Unreachable +Instruction: End +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 8 } +Instruction: I32Add +Instruction: LocalGet { local_index: 0 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } +Instruction: LocalGet { local_index: 1 } +Instruction: LocalGet { local_index: 2 } +Instruction: Call { function_index: 53 } +Call instruction: calls function index 53 +Instruction: LocalGet { local_index: 1 } +Instruction: LocalGet { local_index: 2 } +Instruction: LocalGet { local_index: 3 } +Instruction: Call { function_index: 2 } +Call instruction: calls function index 2 +Instruction: LocalTee { local_index: 1 } +Instruction: Call { function_index: 18 } +Call instruction: calls function index 18 +Instruction: LocalSet { local_index: 2 } +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 1 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 4, memory: 0 } } +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 2 } +Instruction: I32Eqz +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } +Instruction: End +Instruction: GlobalGet { global_index: 0 } +Instruction: I32Const { value: 16 } +Instruction: I32Sub +Instruction: LocalTee { local_index: 1 } +Instruction: GlobalSet { global_index: 0 } +Instruction: LocalGet { local_index: 1 } +Instruction: I32Const { value: 0 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 12, memory: 0 } } +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 1 } +Instruction: I32Const { value: 12 } +Instruction: I32Add +Instruction: I32Const { value: 4 } +Instruction: Call { function_index: 74 } +Call instruction: calls function index 74 +Instruction: I32Const { value: 131162 } +Instruction: I32Const { value: 22 } +Instruction: Call { function_index: 42 } +Call instruction: calls function index 42 +Instruction: LocalTee { local_index: 2 } +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 1 } +Instruction: Call { function_index: 9 } +Call instruction: calls function index 9 +Instruction: Drop +Instruction: LocalGet { local_index: 2 } +Instruction: Call { function_index: 10 } +Call instruction: calls function index 10 +Instruction: Unreachable +Instruction: End +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 1 } +Instruction: Call { function_index: 14 } +Call instruction: calls function index 14 +Instruction: I32Eqz +Instruction: End +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 1 } +Instruction: LocalGet { local_index: 3 } +Instruction: LocalGet { local_index: 2 } +Instruction: Call { function_index: 15 } +Call instruction: calls function index 15 +Instruction: I32Const { value: 0 } +Instruction: I32Ne +Instruction: End +Instruction: Block { blockty: Empty } +Instruction: Block { blockty: Empty } +Instruction: Block { blockty: Type(I32) } +Instruction: Block { blockty: Empty } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Load8U { memarg: MemArg { align: 0, max_align: 0, offset: 8, memory: 0 } } +Instruction: I32Eqz +Instruction: If { blockty: Empty } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } +Instruction: LocalTee { local_index: 4 } +Instruction: Call { function_index: 7 } +Call instruction: calls function index 7 +Instruction: LocalTee { local_index: 5 } +Instruction: I32Const { value: 10000 } +Instruction: I32GtU +Instruction: BrIf { relative_depth: 1 } +Instruction: I32Const { value: 141276 } +Instruction: I32Load8U { memarg: MemArg { align: 0, max_align: 0, offset: 0, memory: 0 } } +Instruction: BrIf { relative_depth: 1 } +Instruction: I32Const { value: 141272 } +Instruction: LocalGet { local_index: 5 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } +Instruction: I32Const { value: 141276 } +Instruction: I32Const { value: 1 } +Instruction: I32Store8 { memarg: MemArg { align: 0, max_align: 0, offset: 0, memory: 0 } } +Instruction: LocalGet { local_index: 4 } +Instruction: I32Const { value: 0 } +Instruction: I32Const { value: 131272 } +Instruction: LocalGet { local_index: 5 } +Instruction: Call { function_index: 52 } +Call instruction: calls function index 52 +Instruction: Drop +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 1 } +Instruction: I32Store8 { memarg: MemArg { align: 0, max_align: 0, offset: 8, memory: 0 } } +Instruction: End +Instruction: I32Const { value: 1 } +Instruction: LocalGet { local_index: 1 } +Instruction: LocalGet { local_index: 3 } +Instruction: I32Add +Instruction: LocalTee { local_index: 0 } +Instruction: I32Const { value: 141272 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } +Instruction: I32GtU +Instruction: BrIf { relative_depth: 1 } +Instruction: Drop +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 1 } +Instruction: I32LtU +Instruction: BrIf { relative_depth: 2 } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 10000 } +Instruction: I32GtU +Instruction: BrIf { relative_depth: 3 } +Instruction: LocalGet { local_index: 2 } +Instruction: LocalGet { local_index: 1 } +Instruction: I32Const { value: 131272 } +Instruction: I32Add +Instruction: LocalGet { local_index: 3 } +Instruction: Call { function_index: 89 } +Call instruction: calls function index 89 +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: -25 } +Instruction: Call { function_index: 6 } +Call instruction: calls function index 6 +Instruction: Drop +Instruction: I32Const { value: -25 } +Instruction: Call { function_index: 7 } +Call instruction: calls function index 7 +Instruction: End +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 1 } +Instruction: Call { function_index: 56 } +Call instruction: calls function index 56 +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 1 } +Instruction: I32Const { value: 0 } +Instruction: Call { function_index: 42 } +Call instruction: calls function index 42 +Instruction: Call { function_index: 19 } +Call instruction: calls function index 19 +Instruction: LocalGet { local_index: 0 } +Instruction: Call { function_index: 58 } +Call instruction: calls function index 58 +Instruction: LocalGet { local_index: 0 } +Instruction: Call { function_index: 25 } +Call instruction: calls function index 25 +Instruction: LocalTee { local_index: 0 } +Instruction: I32Const { value: 131157 } +Instruction: I32Const { value: 5 } +Instruction: Call { function_index: 9 } +Call instruction: calls function index 9 +Instruction: Drop +Instruction: LocalGet { local_index: 0 } +Instruction: End +Instruction: I32Const { value: 131224 } +Instruction: I32Const { value: 0 } +Instruction: Call { function_index: 42 } +Call instruction: calls function index 42 +Instruction: End +Instruction: GlobalGet { global_index: 0 } +Instruction: I32Const { value: 16 } +Instruction: I32Sub +Instruction: LocalTee { local_index: 2 } +Instruction: GlobalSet { global_index: 0 } +Instruction: LocalGet { local_index: 2 } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 24 } +Instruction: I32Shl +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 65280 } +Instruction: I32And +Instruction: I32Const { value: 8 } +Instruction: I32Shl +Instruction: I32Or +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 8 } +Instruction: I32ShrU +Instruction: I32Const { value: 65280 } +Instruction: I32And +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 24 } +Instruction: I32ShrU +Instruction: I32Or +Instruction: I32Or +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 12, memory: 0 } } +Instruction: LocalGet { local_index: 1 } +Instruction: LocalGet { local_index: 2 } +Instruction: I32Const { value: 12 } +Instruction: I32Add +Instruction: I32Const { value: 4 } +Instruction: Call { function_index: 73 } +Call instruction: calls function index 73 +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 1 } +Instruction: Call { function_index: 19 } +Call instruction: calls function index 19 +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 1 } +Instruction: Call { function_index: 63 } +Call instruction: calls function index 63 +Instruction: GlobalGet { global_index: 0 } +Instruction: I32Const { value: 16 } +Instruction: I32Sub +Instruction: LocalTee { local_index: 2 } +Instruction: GlobalSet { global_index: 0 } +Instruction: LocalGet { local_index: 0 } +Instruction: Call { function_index: 25 } +Call instruction: calls function index 25 +Instruction: LocalTee { local_index: 0 } +Instruction: I32Const { value: 131152 } +Instruction: I32Const { value: 5 } +Instruction: Call { function_index: 9 } +Call instruction: calls function index 9 +Instruction: Drop +Instruction: LocalGet { local_index: 2 } +Instruction: LocalGet { local_index: 1 } +Instruction: I32Const { value: 24 } +Instruction: I32Shl +Instruction: LocalGet { local_index: 1 } +Instruction: I32Const { value: 65280 } +Instruction: I32And +Instruction: I32Const { value: 8 } +Instruction: I32Shl +Instruction: I32Or +Instruction: LocalGet { local_index: 1 } +Instruction: I32Const { value: 8 } +Instruction: I32ShrU +Instruction: I32Const { value: 65280 } +Instruction: I32And +Instruction: LocalGet { local_index: 1 } +Instruction: I32Const { value: 24 } +Instruction: I32ShrU +Instruction: I32Or +Instruction: I32Or +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 12, memory: 0 } } +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 2 } +Instruction: I32Const { value: 12 } +Instruction: I32Add +Instruction: I32Const { value: 4 } +Instruction: Call { function_index: 9 } +Call instruction: calls function index 9 +Instruction: Drop +Instruction: LocalGet { local_index: 2 } +Instruction: I32Const { value: 16 } +Instruction: I32Add +Instruction: GlobalSet { global_index: 0 } +Instruction: LocalGet { local_index: 0 } +Instruction: End +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 1 } +Instruction: Call { function_index: 63 } +Call instruction: calls function index 63 +Instruction: Call { function_index: 59 } +Call instruction: calls function index 59 +Instruction: LocalSet { local_index: 0 } +Instruction: LocalGet { local_index: 2 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 16, memory: 0 } } +Instruction: LocalGet { local_index: 0 } +Instruction: Call { function_index: 38 } +Call instruction: calls function index 38 +Instruction: LocalGet { local_index: 2 } +Instruction: I64Load { memarg: MemArg { align: 3, max_align: 3, offset: 0, memory: 0 } } +Instruction: LocalGet { local_index: 0 } +Instruction: Call { function_index: 65 } +Call instruction: calls function index 65 +Instruction: GlobalGet { global_index: 0 } +Instruction: I32Const { value: 16 } +Instruction: I32Sub +Instruction: LocalTee { local_index: 2 } +Instruction: GlobalSet { global_index: 0 } +Instruction: LocalGet { local_index: 2 } +Instruction: LocalGet { local_index: 0 } +Instruction: I64Const { value: 56 } +Instruction: I64Shl +Instruction: LocalGet { local_index: 0 } +Instruction: I64Const { value: 65280 } +Instruction: I64And +Instruction: I64Const { value: 40 } +Instruction: I64Shl +Instruction: I64Or +Instruction: LocalGet { local_index: 0 } +Instruction: I64Const { value: 16711680 } +Instruction: I64And +Instruction: I64Const { value: 24 } +Instruction: I64Shl +Instruction: LocalGet { local_index: 0 } +Instruction: I64Const { value: 4278190080 } +Instruction: I64And +Instruction: I64Const { value: 8 } +Instruction: I64Shl +Instruction: I64Or +Instruction: I64Or +Instruction: LocalGet { local_index: 0 } +Instruction: I64Const { value: 8 } +Instruction: I64ShrU +Instruction: I64Const { value: 4278190080 } +Instruction: I64And +Instruction: LocalGet { local_index: 0 } +Instruction: I64Const { value: 24 } +Instruction: I64ShrU +Instruction: I64Const { value: 16711680 } +Instruction: I64And +Instruction: I64Or +Instruction: LocalGet { local_index: 0 } +Instruction: I64Const { value: 40 } +Instruction: I64ShrU +Instruction: I64Const { value: 65280 } +Instruction: I64And +Instruction: LocalGet { local_index: 0 } +Instruction: I64Const { value: 56 } +Instruction: I64ShrU +Instruction: I64Or +Instruction: I64Or +Instruction: I64Or +Instruction: I64Store { memarg: MemArg { align: 3, max_align: 3, offset: 8, memory: 0 } } +Instruction: LocalGet { local_index: 1 } +Instruction: LocalGet { local_index: 2 } +Instruction: I32Const { value: 8 } +Instruction: I32Add +Instruction: I32Const { value: 8 } +Instruction: Call { function_index: 73 } +Call instruction: calls function index 73 +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 1 } +Instruction: Call { function_index: 63 } +Call instruction: calls function index 63 +Instruction: Call { function_index: 54 } +Call instruction: calls function index 54 +Instruction: I32Eqz +Instruction: End +Instruction: GlobalGet { global_index: 0 } +Instruction: I32Const { value: 32 } +Instruction: I32Sub +Instruction: LocalTee { local_index: 3 } +Instruction: GlobalSet { global_index: 0 } +Instruction: LocalGet { local_index: 3 } +Instruction: I32Const { value: 12 } +Instruction: I32Add +Instruction: LocalTee { local_index: 4 } +Instruction: LocalGet { local_index: 1 } +Instruction: LocalGet { local_index: 2 } +Instruction: Call { function_index: 63 } +Call instruction: calls function index 63 +Instruction: Call { function_index: 39 } +Call instruction: calls function index 39 +Instruction: LocalGet { local_index: 4 } +Instruction: Call { function_index: 36 } +Call instruction: calls function index 36 +Instruction: LocalSet { local_index: 1 } +Instruction: LocalGet { local_index: 4 } +Instruction: Call { function_index: 49 } +Call instruction: calls function index 49 +Instruction: LocalSet { local_index: 2 } +Instruction: LocalGet { local_index: 3 } +Instruction: I32Const { value: 12 } +Instruction: I32Add +Instruction: Call { function_index: 49 } +Call instruction: calls function index 49 +Instruction: LocalSet { local_index: 4 } +Instruction: LocalGet { local_index: 3 } +Instruction: I32Const { value: 12 } +Instruction: I32Add +Instruction: Call { function_index: 49 } +Call instruction: calls function index 49 +Instruction: LocalSet { local_index: 5 } +Instruction: LocalGet { local_index: 3 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 16, memory: 0 } } +Instruction: LocalGet { local_index: 3 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 12, memory: 0 } } +Instruction: I32Eq +Instruction: If { blockty: Empty } +Instruction: LocalGet { local_index: 3 } +Instruction: I32Load8U { memarg: MemArg { align: 0, max_align: 0, offset: 28, memory: 0 } } +Instruction: If { blockty: Empty } +Instruction: I32Const { value: 141272 } +Instruction: I32Const { value: 0 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } +Instruction: I32Const { value: 141276 } +Instruction: I32Const { value: 0 } +Instruction: I32Store8 { memarg: MemArg { align: 0, max_align: 0, offset: 0, memory: 0 } } +Instruction: End +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 5 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 12, memory: 0 } } +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 4 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 8, memory: 0 } } +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 2 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 4, memory: 0 } } +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 1 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } +Instruction: LocalGet { local_index: 3 } +Instruction: I32Const { value: 32 } +Instruction: I32Add +Instruction: GlobalSet { global_index: 0 } +Instruction: Return +Instruction: End +Instruction: I32Const { value: 131072 } +Instruction: I32Const { value: 14 } +Instruction: Call { function_index: 50 } +Call instruction: calls function index 50 +Instruction: Unreachable +Instruction: End +Instruction: GlobalGet { global_index: 0 } +Instruction: I32Const { value: 32 } +Instruction: I32Sub +Instruction: LocalTee { local_index: 3 } +Instruction: GlobalSet { global_index: 0 } +Instruction: LocalGet { local_index: 3 } +Instruction: I32Const { value: 12 } +Instruction: I32Add +Instruction: LocalTee { local_index: 4 } +Instruction: LocalGet { local_index: 1 } +Instruction: LocalGet { local_index: 2 } +Instruction: Call { function_index: 63 } +Call instruction: calls function index 63 +Instruction: Call { function_index: 39 } +Call instruction: calls function index 39 +Instruction: LocalGet { local_index: 4 } +Instruction: Call { function_index: 36 } +Call instruction: calls function index 36 +Instruction: LocalSet { local_index: 1 } +Instruction: LocalGet { local_index: 4 } +Instruction: Call { function_index: 72 } +Call instruction: calls function index 72 +Instruction: GlobalGet { global_index: 0 } +Instruction: I32Const { value: 48 } +Instruction: I32Sub +Instruction: LocalTee { local_index: 2 } +Instruction: GlobalSet { global_index: 0 } +Instruction: LocalGet { local_index: 2 } +Instruction: I32Const { value: 32 } +Instruction: I32Add +Instruction: LocalGet { local_index: 1 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } +Instruction: LocalTee { local_index: 3 } +Instruction: Call { function_index: 70 } +Call instruction: calls function index 70 +Instruction: GlobalGet { global_index: 0 } +Instruction: I32Const { value: 32 } +Instruction: I32Sub +Instruction: LocalTee { local_index: 2 } +Instruction: GlobalSet { global_index: 0 } +Instruction: Block { blockty: Empty } +Instruction: Block { blockty: Empty } +Instruction: LocalGet { local_index: 1 } +Instruction: Call { function_index: 58 } +Call instruction: calls function index 58 +Instruction: LocalTee { local_index: 1 } +Instruction: Call { function_index: 54 } +Call instruction: calls function index 54 +Instruction: I32Eqz +Instruction: If { blockty: Empty } +Instruction: I32Const { value: 0 } +Instruction: LocalSet { local_index: 1 } +Instruction: Br { relative_depth: 1 } +Instruction: End +Instruction: LocalGet { local_index: 2 } +Instruction: I32Const { value: 12 } +Instruction: I32Add +Instruction: LocalTee { local_index: 3 } +Instruction: LocalGet { local_index: 1 } +Instruction: Call { function_index: 39 } +Call instruction: calls function index 39 +Instruction: LocalGet { local_index: 3 } +Instruction: Call { function_index: 49 } +Call instruction: calls function index 49 +Instruction: LocalSet { local_index: 1 } +Instruction: LocalGet { local_index: 2 } +Instruction: I32Const { value: 12 } +Instruction: I32Add +Instruction: Call { function_index: 49 } +Call instruction: calls function index 49 +Instruction: LocalSet { local_index: 3 } +Instruction: LocalGet { local_index: 2 } +Instruction: I32Const { value: 12 } +Instruction: I32Add +Instruction: Call { function_index: 49 } +Call instruction: calls function index 49 +Instruction: LocalSet { local_index: 4 } +Instruction: LocalGet { local_index: 2 } +Instruction: I32Const { value: 12 } +Instruction: I32Add +Instruction: Call { function_index: 49 } +Call instruction: calls function index 49 +Instruction: LocalSet { local_index: 5 } +Instruction: LocalGet { local_index: 2 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 16, memory: 0 } } +Instruction: LocalGet { local_index: 2 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 12, memory: 0 } } +Instruction: I32Ne +Instruction: BrIf { relative_depth: 1 } +Instruction: LocalGet { local_index: 2 } +Instruction: I32Load8U { memarg: MemArg { align: 0, max_align: 0, offset: 28, memory: 0 } } +Instruction: I32Eqz +Instruction: BrIf { relative_depth: 0 } +Instruction: I32Const { value: 141272 } +Instruction: I32Const { value: 0 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } +Instruction: I32Const { value: 141276 } +Instruction: I32Const { value: 0 } +Instruction: I32Store8 { memarg: MemArg { align: 0, max_align: 0, offset: 0, memory: 0 } } +Instruction: End +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 5 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 12, memory: 0 } } +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 4 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 8, memory: 0 } } +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 3 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 4, memory: 0 } } +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 1 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } +Instruction: LocalGet { local_index: 2 } +Instruction: I32Const { value: 32 } +Instruction: I32Add +Instruction: GlobalSet { global_index: 0 } +Instruction: Return +Instruction: End +Instruction: I32Const { value: 131072 } +Instruction: I32Const { value: 14 } +Instruction: Call { function_index: 50 } +Call instruction: calls function index 50 +Instruction: Unreachable +Instruction: End +Instruction: GlobalGet { global_index: 0 } +Instruction: I32Const { value: 80 } +Instruction: I32Sub +Instruction: LocalTee { local_index: 2 } +Instruction: GlobalSet { global_index: 0 } +Instruction: LocalGet { local_index: 2 } +Instruction: I32Const { value: -64 } +Instruction: I32Sub +Instruction: LocalGet { local_index: 1 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } +Instruction: LocalTee { local_index: 3 } +Instruction: Call { function_index: 70 } +Call instruction: calls function index 70 +Instruction: LocalGet { local_index: 2 } +Instruction: I32Const { value: 8 } +Instruction: I32Add +Instruction: LocalTee { local_index: 4 } +Instruction: LocalGet { local_index: 3 } +Instruction: LocalGet { local_index: 2 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 68, memory: 0 } } +Instruction: Call { function_index: 29 } +Call instruction: calls function index 29 +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 4 } +Instruction: I32Const { value: 56 } +Instruction: Call { function_index: 89 } +Call instruction: calls function index 89 +Instruction: GlobalGet { global_index: 0 } +Instruction: I32Const { value: 16 } +Instruction: I32Sub +Instruction: LocalTee { local_index: 2 } +Instruction: GlobalSet { global_index: 0 } +Instruction: LocalGet { local_index: 2 } +Instruction: I64Const { value: 0 } +Instruction: I64Store { memarg: MemArg { align: 3, max_align: 3, offset: 8, memory: 0 } } +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 2 } +Instruction: I32Const { value: 8 } +Instruction: I32Add +Instruction: I32Const { value: 8 } +Instruction: Call { function_index: 74 } +Call instruction: calls function index 74 +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 1 } +Instruction: LocalGet { local_index: 2 } +Instruction: Call { function_index: 9 } +Call instruction: calls function index 9 +Instruction: Drop +Instruction: End +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 8 } +Instruction: I32Add +Instruction: LocalGet { local_index: 0 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } +Instruction: LocalGet { local_index: 1 } +Instruction: LocalGet { local_index: 2 } +Instruction: Call { function_index: 53 } +Call instruction: calls function index 53 +Instruction: If { blockty: Empty } +Instruction: I32Const { value: 131137 } +Instruction: I32Const { value: 15 } +Instruction: Call { function_index: 50 } +Call instruction: calls function index 50 +Instruction: Unreachable +Instruction: End +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } +Instruction: LocalGet { local_index: 2 } +Instruction: I32Add +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } +Instruction: End +Instruction: I32Const { value: 131200 } +Instruction: I32Const { value: 12 } +Instruction: Call { function_index: 42 } +Call instruction: calls function index 42 +Instruction: End +Instruction: I32Const { value: 131212 } +Instruction: I32Const { value: 9 } +Instruction: Call { function_index: 42 } +Call instruction: calls function index 42 +Instruction: End +Instruction: Call { function_index: 20 } +Call instruction: calls function index 20 +Instruction: I32Const { value: 0 } +Instruction: Call { function_index: 46 } +Call instruction: calls function index 46 +Instruction: End +Instruction: GlobalGet { global_index: 0 } +Instruction: I32Const { value: 32 } +Instruction: I32Sub +Instruction: LocalTee { local_index: 0 } +Instruction: GlobalSet { global_index: 0 } +Instruction: Call { function_index: 20 } +Call instruction: calls function index 20 +Instruction: I32Const { value: 2 } +Instruction: Call { function_index: 46 } +Call instruction: calls function index 46 +Instruction: Call { function_index: 45 } +Call instruction: calls function index 45 +Instruction: LocalSet { local_index: 6 } +Instruction: I32Const { value: 1 } +Instruction: Call { function_index: 40 } +Call instruction: calls function index 40 +Instruction: LocalSet { local_index: 7 } +Instruction: Call { function_index: 76 } +Call instruction: calls function index 76 +Instruction: LocalSet { local_index: 2 } +Instruction: Loop { blockty: Empty } +Instruction: LocalGet { local_index: 1 } +Instruction: LocalGet { local_index: 6 } +Instruction: I32Ne +Instruction: If { blockty: Empty } +Instruction: LocalGet { local_index: 7 } +Instruction: Call { function_index: 25 } +Call instruction: calls function index 25 +Instruction: LocalSet { local_index: 5 } +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 1 } +Instruction: I32Const { value: 24 } +Instruction: I32Shl +Instruction: LocalGet { local_index: 1 } +Instruction: I32Const { value: 65280 } +Instruction: I32And +Instruction: I32Const { value: 8 } +Instruction: I32Shl +Instruction: I32Or +Instruction: LocalGet { local_index: 1 } +Instruction: I32Const { value: 8 } +Instruction: I32ShrU +Instruction: I32Const { value: 65280 } +Instruction: I32And +Instruction: LocalGet { local_index: 1 } +Instruction: I32Const { value: 24 } +Instruction: I32ShrU +Instruction: I32Or +Instruction: I32Or +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 16, memory: 0 } } +Instruction: LocalGet { local_index: 5 } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 16 } +Instruction: I32Add +Instruction: I32Const { value: 4 } +Instruction: Call { function_index: 9 } +Call instruction: calls function index 9 +Instruction: Drop +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 2 } +Instruction: Call { function_index: 70 } +Call instruction: calls function index 70 +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 12, memory: 0 } } +Instruction: I32Const { value: 1 } +Instruction: I32Add +Instruction: LocalTee { local_index: 3 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 12, memory: 0 } } +Instruction: Block { blockty: Empty } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } +Instruction: LocalTee { local_index: 8 } +Instruction: I32Eqz +Instruction: If { blockty: Empty } +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 3 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 4, memory: 0 } } +Instruction: I32Const { value: 0 } +Instruction: LocalSet { local_index: 4 } +Instruction: Br { relative_depth: 1 } +Instruction: End +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 16 } +Instruction: I32Add +Instruction: LocalTee { local_index: 9 } +Instruction: LocalGet { local_index: 2 } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 8, memory: 0 } } +Instruction: LocalTee { local_index: 4 } +Instruction: Call { function_index: 67 } +Call instruction: calls function index 67 +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 3 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 24, memory: 0 } } +Instruction: LocalGet { local_index: 2 } +Instruction: LocalGet { local_index: 4 } +Instruction: LocalGet { local_index: 9 } +Instruction: Call { function_index: 62 } +Call instruction: calls function index 62 +Instruction: End +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 4 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 28, memory: 0 } } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 0 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 24, memory: 0 } } +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 3 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 20, memory: 0 } } +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 5 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 16, memory: 0 } } +Instruction: LocalGet { local_index: 2 } +Instruction: LocalGet { local_index: 3 } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 16 } +Instruction: I32Add +Instruction: Call { function_index: 62 } +Call instruction: calls function index 62 +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 8 } +Instruction: I32Const { value: 1 } +Instruction: I32Add +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 3 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 8, memory: 0 } } +Instruction: LocalGet { local_index: 2 } +Instruction: LocalGet { local_index: 0 } +Instruction: Call { function_index: 57 } +Call instruction: calls function index 57 +Instruction: LocalGet { local_index: 1 } +Instruction: I32Const { value: 1 } +Instruction: I32Add +Instruction: LocalSet { local_index: 1 } +Instruction: Br { relative_depth: 1 } +Instruction: End +Instruction: End +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 32 } +Instruction: I32Add +Instruction: GlobalSet { global_index: 0 } +Instruction: End +Instruction: GlobalGet { global_index: 0 } +Instruction: I32Const { value: -64 } +Instruction: I32Add +Instruction: LocalTee { local_index: 0 } +Instruction: GlobalSet { global_index: 0 } +Instruction: Call { function_index: 20 } +Call instruction: calls function index 20 +Instruction: I32Const { value: 1 } +Instruction: Call { function_index: 46 } +Call instruction: calls function index 46 +Instruction: I32Const { value: 0 } +Instruction: Call { function_index: 40 } +Call instruction: calls function index 40 +Instruction: LocalSet { local_index: 2 } +Instruction: LocalGet { local_index: 0 } +Instruction: Call { function_index: 76 } +Call instruction: calls function index 76 +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 12, memory: 0 } } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 16 } +Instruction: I32Add +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 12 } +Instruction: I32Add +Instruction: Call { function_index: 69 } +Call instruction: calls function index 69 +Instruction: Loop { blockty: Empty } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 44 } +Instruction: I32Add +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 16 } +Instruction: I32Add +Instruction: Call { function_index: 30 } +Call instruction: calls function index 30 +Instruction: LocalGet { local_index: 0 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 44, memory: 0 } } +Instruction: If { blockty: Empty } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 48, memory: 0 } } +Instruction: LocalGet { local_index: 2 } +Instruction: Call { function_index: 26 } +Call instruction: calls function index 26 +Instruction: LocalGet { local_index: 1 } +Instruction: I32Add +Instruction: LocalSet { local_index: 1 } +Instruction: Br { relative_depth: 1 } +Instruction: End +Instruction: End +Instruction: LocalGet { local_index: 1 } +Instruction: I64ExtendI32U +Instruction: Call { function_index: 21 } +Call instruction: calls function index 21 +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: -64 } +Instruction: I32Sub +Instruction: GlobalSet { global_index: 0 } +Instruction: End +Instruction: GlobalGet { global_index: 0 } +Instruction: I32Const { value: -64 } +Instruction: I32Add +Instruction: LocalTee { local_index: 0 } +Instruction: GlobalSet { global_index: 0 } +Instruction: Call { function_index: 20 } +Call instruction: calls function index 20 +Instruction: I32Const { value: 1 } +Instruction: Call { function_index: 46 } +Call instruction: calls function index 46 +Instruction: Call { function_index: 45 } +Call instruction: calls function index 45 +Instruction: LocalSet { local_index: 5 } +Instruction: Call { function_index: 76 } +Call instruction: calls function index 76 +Instruction: LocalSet { local_index: 1 } +Instruction: Block { blockty: Empty } +Instruction: Loop { blockty: Empty } +Instruction: LocalGet { local_index: 5 } +Instruction: If { blockty: Empty } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 12 } +Instruction: I32Add +Instruction: LocalGet { local_index: 1 } +Instruction: Call { function_index: 70 } +Call instruction: calls function index 70 +Instruction: Block { blockty: Empty } +Instruction: LocalGet { local_index: 1 } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 16, memory: 0 } } +Instruction: LocalTee { local_index: 2 } +Instruction: Call { function_index: 66 } +Call instruction: calls function index 66 +Instruction: BrIf { relative_depth: 0 } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 28 } +Instruction: I32Add +Instruction: LocalTee { local_index: 4 } +Instruction: LocalGet { local_index: 1 } +Instruction: LocalGet { local_index: 2 } +Instruction: Call { function_index: 31 } +Call instruction: calls function index 31 +Instruction: LocalGet { local_index: 0 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 28, memory: 0 } } +Instruction: I32Eqz +Instruction: BrIf { relative_depth: 3 } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 44, memory: 0 } } +Instruction: LocalSet { local_index: 2 } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 40, memory: 0 } } +Instruction: LocalSet { local_index: 3 } +Instruction: LocalGet { local_index: 1 } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 36, memory: 0 } } +Instruction: LocalTee { local_index: 6 } +Instruction: Call { function_index: 66 } +Call instruction: calls function index 66 +Instruction: BrIf { relative_depth: 0 } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 48 } +Instruction: I32Add +Instruction: LocalGet { local_index: 1 } +Instruction: Call { function_index: 70 } +Call instruction: calls function index 70 +Instruction: Block { blockty: Empty } +Instruction: LocalGet { local_index: 2 } +Instruction: If { blockty: Empty } +Instruction: LocalGet { local_index: 4 } +Instruction: LocalGet { local_index: 1 } +Instruction: LocalGet { local_index: 2 } +Instruction: Call { function_index: 67 } +Call instruction: calls function index 67 +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 3 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 36, memory: 0 } } +Instruction: LocalGet { local_index: 1 } +Instruction: LocalGet { local_index: 2 } +Instruction: LocalGet { local_index: 4 } +Instruction: Call { function_index: 62 } +Call instruction: calls function index 62 +Instruction: Br { relative_depth: 1 } +Instruction: End +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 3 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 52, memory: 0 } } +Instruction: End +Instruction: Block { blockty: Empty } +Instruction: LocalGet { local_index: 3 } +Instruction: If { blockty: Empty } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 28 } +Instruction: I32Add +Instruction: LocalTee { local_index: 4 } +Instruction: LocalGet { local_index: 1 } +Instruction: LocalGet { local_index: 3 } +Instruction: Call { function_index: 67 } +Call instruction: calls function index 67 +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 2 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 40, memory: 0 } } +Instruction: LocalGet { local_index: 1 } +Instruction: LocalGet { local_index: 3 } +Instruction: LocalGet { local_index: 4 } +Instruction: Call { function_index: 62 } +Call instruction: calls function index 62 +Instruction: Br { relative_depth: 1 } +Instruction: End +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 2 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 56, memory: 0 } } +Instruction: End +Instruction: LocalGet { local_index: 1 } +Instruction: LocalGet { local_index: 6 } +Instruction: Call { function_index: 63 } +Call instruction: calls function index 63 +Instruction: Call { function_index: 55 } +Call instruction: calls function index 55 +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 48, memory: 0 } } +Instruction: I32Const { value: 1 } +Instruction: I32Sub +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 48, memory: 0 } } +Instruction: LocalGet { local_index: 1 } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 48 } +Instruction: I32Add +Instruction: Call { function_index: 57 } +Call instruction: calls function index 57 +Instruction: End +Instruction: LocalGet { local_index: 5 } +Instruction: I32Const { value: 1 } +Instruction: I32Sub +Instruction: LocalSet { local_index: 5 } +Instruction: Br { relative_depth: 1 } +Instruction: End +Instruction: End +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: -64 } +Instruction: I32Sub +Instruction: GlobalSet { global_index: 0 } +Instruction: Return +Instruction: End +Instruction: Call { function_index: 81 } +Call instruction: calls function index 81 +Instruction: Call { function_index: 88 } +Call instruction: calls function index 88 +Instruction: GlobalGet { global_index: 0 } +Instruction: I32Const { value: 48 } +Instruction: I32Sub +Instruction: LocalTee { local_index: 0 } +Instruction: GlobalSet { global_index: 0 } +Instruction: Call { function_index: 20 } +Call instruction: calls function index 20 +Instruction: I32Const { value: 0 } +Instruction: Call { function_index: 46 } +Call instruction: calls function index 46 +Instruction: LocalGet { local_index: 0 } +Instruction: Call { function_index: 76 } +Call instruction: calls function index 76 +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 4 } +Instruction: I32Add +Instruction: LocalGet { local_index: 0 } +Instruction: Call { function_index: 69 } +Call instruction: calls function index 69 +Instruction: Loop { blockty: Empty } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 28 } +Instruction: I32Add +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 4 } +Instruction: I32Add +Instruction: Call { function_index: 30 } +Call instruction: calls function index 30 +Instruction: LocalGet { local_index: 0 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 28, memory: 0 } } +Instruction: If { blockty: Empty } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 32, memory: 0 } } +Instruction: Call { function_index: 22 } +Call instruction: calls function index 22 +Instruction: Drop +Instruction: Br { relative_depth: 1 } +Instruction: End +Instruction: End +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 48 } +Instruction: I32Add +Instruction: GlobalSet { global_index: 0 } +Instruction: End +Instruction: GlobalGet { global_index: 0 } +Instruction: I32Const { value: 128 } +Instruction: I32Sub +Instruction: LocalTee { local_index: 0 } +Instruction: GlobalSet { global_index: 0 } +Instruction: Call { function_index: 20 } +Call instruction: calls function index 20 +Instruction: I32Const { value: 2 } +Instruction: Call { function_index: 46 } +Call instruction: calls function index 46 +Instruction: Call { function_index: 45 } +Call instruction: calls function index 45 +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 32 } +Instruction: I32Add +Instruction: I32Const { value: 1 } +Instruction: Call { function_index: 43 } +Call instruction: calls function index 43 +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 108 } +Instruction: I32Add +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 56 } +Instruction: I32Add +Instruction: LocalTee { local_index: 4 } +Instruction: I64Load { memarg: MemArg { align: 3, max_align: 3, offset: 0, memory: 0 } } +Instruction: LocalTee { local_index: 11 } +Instruction: I64Store { memarg: MemArg { align: 2, max_align: 3, offset: 0, memory: 0 } } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 8 } +Instruction: I32Add +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 40 } +Instruction: I32Add +Instruction: LocalTee { local_index: 5 } +Instruction: I64Load { memarg: MemArg { align: 3, max_align: 3, offset: 0, memory: 0 } } +Instruction: I64Store { memarg: MemArg { align: 3, max_align: 3, offset: 0, memory: 0 } } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 16 } +Instruction: I32Add +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 48 } +Instruction: I32Add +Instruction: LocalTee { local_index: 6 } +Instruction: I64Load { memarg: MemArg { align: 3, max_align: 3, offset: 0, memory: 0 } } +Instruction: I64Store { memarg: MemArg { align: 3, max_align: 3, offset: 0, memory: 0 } } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 24 } +Instruction: I32Add +Instruction: LocalGet { local_index: 11 } +Instruction: I64Store { memarg: MemArg { align: 3, max_align: 3, offset: 0, memory: 0 } } +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 0 } +Instruction: I64Load { memarg: MemArg { align: 3, max_align: 3, offset: 32, memory: 0 } } +Instruction: LocalTee { local_index: 11 } +Instruction: I64Store { memarg: MemArg { align: 2, max_align: 3, offset: 84, memory: 0 } } +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 11 } +Instruction: I64Store { memarg: MemArg { align: 3, max_align: 3, offset: 0, memory: 0 } } +Instruction: I64ExtendI32U +Instruction: LocalSet { local_index: 12 } +Instruction: I64Const { value: 0 } +Instruction: LocalSet { local_index: 11 } +Instruction: Call { function_index: 75 } +Call instruction: calls function index 75 +Instruction: LocalSet { local_index: 1 } +Instruction: Loop { blockty: Empty } +Instruction: LocalGet { local_index: 11 } +Instruction: LocalGet { local_index: 12 } +Instruction: I64Eq +Instruction: I32Eqz +Instruction: If { blockty: Empty } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 80 } +Instruction: I32Add +Instruction: LocalGet { local_index: 0 } +Instruction: Call { function_index: 28 } +Call instruction: calls function index 28 +Instruction: LocalGet { local_index: 5 } +Instruction: LocalGet { local_index: 11 } +Instruction: I64Store { memarg: MemArg { align: 3, max_align: 3, offset: 0, memory: 0 } } +Instruction: LocalGet { local_index: 6 } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 96 } +Instruction: I32Add +Instruction: LocalTee { local_index: 7 } +Instruction: I64Load { memarg: MemArg { align: 3, max_align: 3, offset: 0, memory: 0 } } +Instruction: I64Store { memarg: MemArg { align: 3, max_align: 3, offset: 0, memory: 0 } } +Instruction: LocalGet { local_index: 4 } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 104 } +Instruction: I32Add +Instruction: LocalTee { local_index: 8 } +Instruction: I64Load { memarg: MemArg { align: 3, max_align: 3, offset: 0, memory: 0 } } +Instruction: I64Store { memarg: MemArg { align: 3, max_align: 3, offset: 0, memory: 0 } } +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 11 } +Instruction: I64Store { memarg: MemArg { align: 3, max_align: 3, offset: 32, memory: 0 } } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: -64 } +Instruction: I32Sub +Instruction: LocalGet { local_index: 1 } +Instruction: Call { function_index: 70 } +Call instruction: calls function index 70 +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 76, memory: 0 } } +Instruction: I32Const { value: 1 } +Instruction: I32Add +Instruction: LocalTee { local_index: 2 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 76, memory: 0 } } +Instruction: Block { blockty: Empty } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 64, memory: 0 } } +Instruction: LocalTee { local_index: 9 } +Instruction: I32Eqz +Instruction: If { blockty: Empty } +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 2 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 68, memory: 0 } } +Instruction: I32Const { value: 0 } +Instruction: LocalSet { local_index: 3 } +Instruction: Br { relative_depth: 1 } +Instruction: End +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 80 } +Instruction: I32Add +Instruction: LocalTee { local_index: 10 } +Instruction: LocalGet { local_index: 1 } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 72, memory: 0 } } +Instruction: LocalTee { local_index: 3 } +Instruction: Call { function_index: 68 } +Call instruction: calls function index 68 +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 2 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 116, memory: 0 } } +Instruction: LocalGet { local_index: 1 } +Instruction: LocalGet { local_index: 3 } +Instruction: LocalGet { local_index: 10 } +Instruction: Call { function_index: 64 } +Call instruction: calls function index 64 +Instruction: End +Instruction: LocalGet { local_index: 8 } +Instruction: LocalGet { local_index: 4 } +Instruction: I64Load { memarg: MemArg { align: 3, max_align: 3, offset: 0, memory: 0 } } +Instruction: I64Store { memarg: MemArg { align: 3, max_align: 3, offset: 0, memory: 0 } } +Instruction: LocalGet { local_index: 7 } +Instruction: LocalGet { local_index: 6 } +Instruction: I64Load { memarg: MemArg { align: 3, max_align: 3, offset: 0, memory: 0 } } +Instruction: I64Store { memarg: MemArg { align: 3, max_align: 3, offset: 0, memory: 0 } } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 88 } +Instruction: I32Add +Instruction: LocalGet { local_index: 5 } +Instruction: I64Load { memarg: MemArg { align: 3, max_align: 3, offset: 0, memory: 0 } } +Instruction: I64Store { memarg: MemArg { align: 3, max_align: 3, offset: 0, memory: 0 } } +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 0 } +Instruction: I64Load { memarg: MemArg { align: 3, max_align: 3, offset: 32, memory: 0 } } +Instruction: I64Store { memarg: MemArg { align: 3, max_align: 3, offset: 80, memory: 0 } } +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 3 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 120, memory: 0 } } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 0 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 116, memory: 0 } } +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 2 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 112, memory: 0 } } +Instruction: LocalGet { local_index: 1 } +Instruction: LocalGet { local_index: 2 } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 80 } +Instruction: I32Add +Instruction: Call { function_index: 64 } +Call instruction: calls function index 64 +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 9 } +Instruction: I32Const { value: 1 } +Instruction: I32Add +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 64, memory: 0 } } +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 2 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 72, memory: 0 } } +Instruction: LocalGet { local_index: 1 } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: -64 } +Instruction: I32Sub +Instruction: Call { function_index: 57 } +Call instruction: calls function index 57 +Instruction: LocalGet { local_index: 11 } +Instruction: I64Const { value: 1 } +Instruction: I64Add +Instruction: LocalSet { local_index: 11 } +Instruction: Br { relative_depth: 1 } +Instruction: End +Instruction: End +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 128 } +Instruction: I32Add +Instruction: GlobalSet { global_index: 0 } +Instruction: End +Instruction: GlobalGet { global_index: 0 } +Instruction: I32Const { value: 160 } +Instruction: I32Sub +Instruction: LocalTee { local_index: 0 } +Instruction: GlobalSet { global_index: 0 } +Instruction: Call { function_index: 20 } +Call instruction: calls function index 20 +Instruction: I32Const { value: 1 } +Instruction: Call { function_index: 46 } +Call instruction: calls function index 46 +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 0 } +Instruction: Call { function_index: 43 } +Call instruction: calls function index 43 +Instruction: LocalGet { local_index: 0 } +Instruction: Call { function_index: 75 } +Call instruction: calls function index 75 +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 36, memory: 0 } } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 40 } +Instruction: I32Add +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 36 } +Instruction: I32Add +Instruction: Call { function_index: 71 } +Call instruction: calls function index 71 +Instruction: LocalGet { local_index: 0 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 28, memory: 0 } } +Instruction: LocalSet { local_index: 3 } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 24, memory: 0 } } +Instruction: LocalSet { local_index: 4 } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 20, memory: 0 } } +Instruction: LocalSet { local_index: 5 } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 16, memory: 0 } } +Instruction: LocalSet { local_index: 6 } +Instruction: LocalGet { local_index: 0 } +Instruction: I64Load { memarg: MemArg { align: 3, max_align: 3, offset: 8, memory: 0 } } +Instruction: LocalSet { local_index: 10 } +Instruction: LocalGet { local_index: 0 } +Instruction: I64Load { memarg: MemArg { align: 3, max_align: 3, offset: 0, memory: 0 } } +Instruction: LocalSet { local_index: 11 } +Instruction: Loop { blockty: Empty } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 104 } +Instruction: I32Add +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 40 } +Instruction: I32Add +Instruction: Call { function_index: 27 } +Call instruction: calls function index 27 +Instruction: LocalGet { local_index: 0 } +Instruction: I64Load { memarg: MemArg { align: 3, max_align: 3, offset: 104, memory: 0 } } +Instruction: I64Eqz +Instruction: I32Eqz +Instruction: If { blockty: Empty } +Instruction: LocalGet { local_index: 0 } +Instruction: I64Load { memarg: MemArg { align: 3, max_align: 3, offset: 112, memory: 0 } } +Instruction: LocalSet { local_index: 12 } +Instruction: I32Const { value: 0 } +Instruction: LocalSet { local_index: 2 } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 140, memory: 0 } } +Instruction: LocalSet { local_index: 7 } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 136, memory: 0 } } +Instruction: LocalSet { local_index: 8 } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 132, memory: 0 } } +Instruction: LocalSet { local_index: 9 } +Instruction: LocalGet { local_index: 0 } +Instruction: I64Load { memarg: MemArg { align: 3, max_align: 3, offset: 120, memory: 0 } } +Instruction: LocalSet { local_index: 13 } +Instruction: Block { blockty: Empty } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 128, memory: 0 } } +Instruction: LocalGet { local_index: 6 } +Instruction: Call { function_index: 26 } +Call instruction: calls function index 26 +Instruction: I32Eqz +Instruction: LocalGet { local_index: 11 } +Instruction: LocalGet { local_index: 12 } +Instruction: I64Ne +Instruction: I32Or +Instruction: BrIf { relative_depth: 0 } +Instruction: LocalGet { local_index: 9 } +Instruction: LocalGet { local_index: 5 } +Instruction: Call { function_index: 51 } +Call instruction: calls function index 51 +Instruction: I32Eqz +Instruction: BrIf { relative_depth: 0 } +Instruction: LocalGet { local_index: 8 } +Instruction: LocalGet { local_index: 4 } +Instruction: Call { function_index: 26 } +Call instruction: calls function index 26 +Instruction: I32Eqz +Instruction: LocalGet { local_index: 10 } +Instruction: LocalGet { local_index: 13 } +Instruction: I64Ne +Instruction: I32Or +Instruction: BrIf { relative_depth: 0 } +Instruction: LocalGet { local_index: 7 } +Instruction: LocalGet { local_index: 3 } +Instruction: Call { function_index: 51 } +Call instruction: calls function index 51 +Instruction: LocalSet { local_index: 2 } +Instruction: End +Instruction: LocalGet { local_index: 1 } +Instruction: LocalGet { local_index: 2 } +Instruction: I32Add +Instruction: LocalSet { local_index: 1 } +Instruction: Br { relative_depth: 1 } +Instruction: End +Instruction: End +Instruction: LocalGet { local_index: 1 } +Instruction: I64ExtendI32U +Instruction: Call { function_index: 21 } +Call instruction: calls function index 21 +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 160 } +Instruction: I32Add +Instruction: GlobalSet { global_index: 0 } +Instruction: End +Instruction: GlobalGet { global_index: 0 } +Instruction: I32Const { value: 96 } +Instruction: I32Sub +Instruction: LocalTee { local_index: 0 } +Instruction: GlobalSet { global_index: 0 } +Instruction: Call { function_index: 20 } +Call instruction: calls function index 20 +Instruction: I32Const { value: 1 } +Instruction: Call { function_index: 46 } +Call instruction: calls function index 46 +Instruction: Call { function_index: 45 } +Call instruction: calls function index 45 +Instruction: LocalSet { local_index: 5 } +Instruction: Call { function_index: 75 } +Call instruction: calls function index 75 +Instruction: LocalSet { local_index: 1 } +Instruction: Block { blockty: Empty } +Instruction: Loop { blockty: Empty } +Instruction: LocalGet { local_index: 5 } +Instruction: If { blockty: Empty } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 8 } +Instruction: I32Add +Instruction: LocalGet { local_index: 1 } +Instruction: Call { function_index: 70 } +Call instruction: calls function index 70 +Instruction: Block { blockty: Empty } +Instruction: LocalGet { local_index: 1 } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 12, memory: 0 } } +Instruction: LocalTee { local_index: 2 } +Instruction: Call { function_index: 66 } +Call instruction: calls function index 66 +Instruction: BrIf { relative_depth: 0 } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 24 } +Instruction: I32Add +Instruction: LocalTee { local_index: 4 } +Instruction: LocalGet { local_index: 1 } +Instruction: LocalGet { local_index: 2 } +Instruction: Call { function_index: 29 } +Call instruction: calls function index 29 +Instruction: LocalGet { local_index: 0 } +Instruction: I64Load { memarg: MemArg { align: 3, max_align: 3, offset: 24, memory: 0 } } +Instruction: I64Eqz +Instruction: BrIf { relative_depth: 3 } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 72, memory: 0 } } +Instruction: LocalSet { local_index: 2 } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 68, memory: 0 } } +Instruction: LocalSet { local_index: 3 } +Instruction: LocalGet { local_index: 1 } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 64, memory: 0 } } +Instruction: LocalTee { local_index: 6 } +Instruction: Call { function_index: 66 } +Call instruction: calls function index 66 +Instruction: BrIf { relative_depth: 0 } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 80 } +Instruction: I32Add +Instruction: LocalGet { local_index: 1 } +Instruction: Call { function_index: 70 } +Call instruction: calls function index 70 +Instruction: Block { blockty: Empty } +Instruction: LocalGet { local_index: 2 } +Instruction: If { blockty: Empty } +Instruction: LocalGet { local_index: 4 } +Instruction: LocalGet { local_index: 1 } +Instruction: LocalGet { local_index: 2 } +Instruction: Call { function_index: 68 } +Call instruction: calls function index 68 +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 3 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 60, memory: 0 } } +Instruction: LocalGet { local_index: 1 } +Instruction: LocalGet { local_index: 2 } +Instruction: LocalGet { local_index: 4 } +Instruction: Call { function_index: 64 } +Call instruction: calls function index 64 +Instruction: Br { relative_depth: 1 } +Instruction: End +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 3 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 84, memory: 0 } } +Instruction: End +Instruction: Block { blockty: Empty } +Instruction: LocalGet { local_index: 3 } +Instruction: If { blockty: Empty } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 24 } +Instruction: I32Add +Instruction: LocalTee { local_index: 4 } +Instruction: LocalGet { local_index: 1 } +Instruction: LocalGet { local_index: 3 } +Instruction: Call { function_index: 68 } +Call instruction: calls function index 68 +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 2 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 64, memory: 0 } } +Instruction: LocalGet { local_index: 1 } +Instruction: LocalGet { local_index: 3 } +Instruction: LocalGet { local_index: 4 } +Instruction: Call { function_index: 64 } +Call instruction: calls function index 64 +Instruction: Br { relative_depth: 1 } +Instruction: End +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 2 } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 88, memory: 0 } } +Instruction: End +Instruction: LocalGet { local_index: 1 } +Instruction: LocalGet { local_index: 6 } +Instruction: Call { function_index: 63 } +Call instruction: calls function index 63 +Instruction: Call { function_index: 55 } +Call instruction: calls function index 55 +Instruction: LocalGet { local_index: 0 } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 80, memory: 0 } } +Instruction: I32Const { value: 1 } +Instruction: I32Sub +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 80, memory: 0 } } +Instruction: LocalGet { local_index: 1 } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 80 } +Instruction: I32Add +Instruction: Call { function_index: 57 } +Call instruction: calls function index 57 +Instruction: End +Instruction: LocalGet { local_index: 5 } +Instruction: I32Const { value: 1 } +Instruction: I32Sub +Instruction: LocalSet { local_index: 5 } +Instruction: Br { relative_depth: 1 } +Instruction: End +Instruction: End +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 96 } +Instruction: I32Add +Instruction: GlobalSet { global_index: 0 } +Instruction: Return +Instruction: End +Instruction: Call { function_index: 81 } +Call instruction: calls function index 81 +Instruction: Unreachable +Instruction: End +Instruction: GlobalGet { global_index: 0 } +Instruction: I32Const { value: 128 } +Instruction: I32Sub +Instruction: LocalTee { local_index: 0 } +Instruction: GlobalSet { global_index: 0 } +Instruction: Call { function_index: 20 } +Call instruction: calls function index 20 +Instruction: I32Const { value: 0 } +Instruction: Call { function_index: 46 } +Call instruction: calls function index 46 +Instruction: LocalGet { local_index: 0 } +Instruction: Call { function_index: 75 } +Call instruction: calls function index 75 +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 4, memory: 0 } } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 8 } +Instruction: I32Add +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 4 } +Instruction: I32Add +Instruction: Call { function_index: 71 } +Call instruction: calls function index 71 +Instruction: Loop { blockty: Empty } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 72 } +Instruction: I32Add +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 8 } +Instruction: I32Add +Instruction: Call { function_index: 27 } +Call instruction: calls function index 27 +Instruction: LocalGet { local_index: 0 } +Instruction: I64Load { memarg: MemArg { align: 3, max_align: 3, offset: 72, memory: 0 } } +Instruction: I64Eqz +Instruction: I32Eqz +Instruction: If { blockty: Empty } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 108, memory: 0 } } +Instruction: LocalGet { local_index: 0 } +Instruction: I64Load { memarg: MemArg { align: 3, max_align: 3, offset: 88, memory: 0 } } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 104, memory: 0 } } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 100, memory: 0 } } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 96, memory: 0 } } +Instruction: I32Const { value: 131224 } +Instruction: I32Const { value: 0 } +Instruction: Call { function_index: 42 } +Call instruction: calls function index 42 +Instruction: LocalTee { local_index: 1 } +Instruction: Call { function_index: 38 } +Call instruction: calls function index 38 +Instruction: LocalGet { local_index: 0 } +Instruction: I64Load { memarg: MemArg { align: 3, max_align: 3, offset: 80, memory: 0 } } +Instruction: LocalGet { local_index: 1 } +Instruction: Call { function_index: 65 } +Call instruction: calls function index 65 +Instruction: LocalGet { local_index: 1 } +Instruction: Call { function_index: 37 } +Call instruction: calls function index 37 +Instruction: LocalGet { local_index: 1 } +Instruction: Call { function_index: 38 } +Call instruction: calls function index 38 +Instruction: LocalGet { local_index: 1 } +Instruction: Call { function_index: 65 } +Call instruction: calls function index 65 +Instruction: LocalGet { local_index: 1 } +Instruction: Call { function_index: 37 } +Call instruction: calls function index 37 +Instruction: LocalGet { local_index: 1 } +Instruction: Call { function_index: 22 } +Call instruction: calls function index 22 +Instruction: Drop +Instruction: Br { relative_depth: 1 } +Instruction: End +Instruction: End +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 128 } +Instruction: I32Add +Instruction: GlobalSet { global_index: 0 } +Instruction: End +Instruction: End +Instruction: I32Const { value: 131224 } +Instruction: I32Const { value: 14 } +Instruction: Call { function_index: 13 } +Call instruction: calls function index 13 +Instruction: Unreachable +Instruction: End +Instruction: Block { blockty: Empty } +Instruction: LocalGet { local_index: 2 } +Instruction: LocalTee { local_index: 4 } +Instruction: I32Const { value: 16 } +Instruction: I32LtU +Instruction: If { blockty: Empty } +Instruction: LocalGet { local_index: 0 } +Instruction: LocalSet { local_index: 2 } +Instruction: Br { relative_depth: 1 } +Instruction: End +Instruction: LocalGet { local_index: 0 } +Instruction: I32Const { value: 0 } +Instruction: LocalGet { local_index: 0 } +Instruction: I32Sub +Instruction: I32Const { value: 3 } +Instruction: I32And +Instruction: LocalTee { local_index: 3 } +Instruction: I32Add +Instruction: LocalSet { local_index: 5 } +Instruction: LocalGet { local_index: 3 } +Instruction: If { blockty: Empty } +Instruction: LocalGet { local_index: 0 } +Instruction: LocalSet { local_index: 2 } +Instruction: LocalGet { local_index: 1 } +Instruction: LocalSet { local_index: 6 } +Instruction: Loop { blockty: Empty } +Instruction: LocalGet { local_index: 2 } +Instruction: LocalGet { local_index: 6 } +Instruction: I32Load8U { memarg: MemArg { align: 0, max_align: 0, offset: 0, memory: 0 } } +Instruction: I32Store8 { memarg: MemArg { align: 0, max_align: 0, offset: 0, memory: 0 } } +Instruction: LocalGet { local_index: 6 } +Instruction: I32Const { value: 1 } +Instruction: I32Add +Instruction: LocalSet { local_index: 6 } +Instruction: LocalGet { local_index: 2 } +Instruction: I32Const { value: 1 } +Instruction: I32Add +Instruction: LocalTee { local_index: 2 } +Instruction: LocalGet { local_index: 5 } +Instruction: I32LtU +Instruction: BrIf { relative_depth: 0 } +Instruction: End +Instruction: End +Instruction: LocalGet { local_index: 5 } +Instruction: LocalGet { local_index: 4 } +Instruction: LocalGet { local_index: 3 } +Instruction: I32Sub +Instruction: LocalTee { local_index: 8 } +Instruction: I32Const { value: -4 } +Instruction: I32And +Instruction: LocalTee { local_index: 7 } +Instruction: I32Add +Instruction: LocalSet { local_index: 2 } +Instruction: Block { blockty: Empty } +Instruction: LocalGet { local_index: 1 } +Instruction: LocalGet { local_index: 3 } +Instruction: I32Add +Instruction: LocalTee { local_index: 3 } +Instruction: I32Const { value: 3 } +Instruction: I32And +Instruction: If { blockty: Empty } +Instruction: LocalGet { local_index: 7 } +Instruction: I32Const { value: 0 } +Instruction: I32LeS +Instruction: BrIf { relative_depth: 1 } +Instruction: LocalGet { local_index: 3 } +Instruction: I32Const { value: 3 } +Instruction: I32Shl +Instruction: LocalTee { local_index: 4 } +Instruction: I32Const { value: 24 } +Instruction: I32And +Instruction: LocalSet { local_index: 9 } +Instruction: LocalGet { local_index: 3 } +Instruction: I32Const { value: -4 } +Instruction: I32And +Instruction: LocalTee { local_index: 6 } +Instruction: I32Const { value: 4 } +Instruction: I32Add +Instruction: LocalSet { local_index: 1 } +Instruction: I32Const { value: 0 } +Instruction: LocalGet { local_index: 4 } +Instruction: I32Sub +Instruction: I32Const { value: 24 } +Instruction: I32And +Instruction: LocalSet { local_index: 4 } +Instruction: LocalGet { local_index: 6 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } +Instruction: LocalSet { local_index: 6 } +Instruction: Loop { blockty: Empty } +Instruction: LocalGet { local_index: 5 } +Instruction: LocalGet { local_index: 6 } +Instruction: LocalGet { local_index: 9 } +Instruction: I32ShrU +Instruction: LocalGet { local_index: 1 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } +Instruction: LocalTee { local_index: 6 } +Instruction: LocalGet { local_index: 4 } +Instruction: I32Shl +Instruction: I32Or +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } +Instruction: LocalGet { local_index: 1 } +Instruction: I32Const { value: 4 } +Instruction: I32Add +Instruction: LocalSet { local_index: 1 } +Instruction: LocalGet { local_index: 5 } +Instruction: I32Const { value: 4 } +Instruction: I32Add +Instruction: LocalTee { local_index: 5 } +Instruction: LocalGet { local_index: 2 } +Instruction: I32LtU +Instruction: BrIf { relative_depth: 0 } +Instruction: End +Instruction: Br { relative_depth: 1 } +Instruction: End +Instruction: LocalGet { local_index: 7 } +Instruction: I32Const { value: 0 } +Instruction: I32LeS +Instruction: BrIf { relative_depth: 0 } +Instruction: LocalGet { local_index: 3 } +Instruction: LocalSet { local_index: 1 } +Instruction: Loop { blockty: Empty } +Instruction: LocalGet { local_index: 5 } +Instruction: LocalGet { local_index: 1 } +Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } +Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } +Instruction: LocalGet { local_index: 1 } +Instruction: I32Const { value: 4 } +Instruction: I32Add +Instruction: LocalSet { local_index: 1 } +Instruction: LocalGet { local_index: 5 } +Instruction: I32Const { value: 4 } +Instruction: I32Add +Instruction: LocalTee { local_index: 5 } +Instruction: LocalGet { local_index: 2 } +Instruction: I32LtU +Instruction: BrIf { relative_depth: 0 } +Instruction: End +Instruction: End +Instruction: LocalGet { local_index: 8 } +Instruction: I32Const { value: 3 } +Instruction: I32And +Instruction: LocalSet { local_index: 4 } +Instruction: LocalGet { local_index: 3 } +Instruction: LocalGet { local_index: 7 } +Instruction: I32Add +Instruction: LocalSet { local_index: 1 } +Instruction: End +Instruction: LocalGet { local_index: 4 } +Instruction: If { blockty: Empty } +Instruction: LocalGet { local_index: 2 } +Instruction: LocalGet { local_index: 4 } +Instruction: I32Add +Instruction: LocalSet { local_index: 3 } +Instruction: Loop { blockty: Empty } +Instruction: LocalGet { local_index: 2 } +Instruction: LocalGet { local_index: 1 } +Instruction: I32Load8U { memarg: MemArg { align: 0, max_align: 0, offset: 0, memory: 0 } } +Instruction: I32Store8 { memarg: MemArg { align: 0, max_align: 0, offset: 0, memory: 0 } } +Instruction: LocalGet { local_index: 1 } +Instruction: I32Const { value: 1 } +Instruction: I32Add +Instruction: LocalSet { local_index: 1 } +Instruction: LocalGet { local_index: 2 } +Instruction: I32Const { value: 1 } +Instruction: I32Add +Instruction: LocalTee { local_index: 2 } +Instruction: LocalGet { local_index: 3 } +Instruction: I32LtU +Instruction: BrIf { relative_depth: 0 } +Instruction: End +Instruction: End +Instruction: LocalGet { local_index: 0 } +Instruction: End +Checking EI version: 1.3 ... OK +Packing ../output/linked-list-repeat.mxsc.json ... +Contract size: 6615 bytes. +analyze this via wasm +analyze this via wasm diff --git a/contracts/benchmarks/mappers/linked-list-repeat/src/linked_list_repeat.rs b/contracts/benchmarks/mappers/linked-list-repeat/src/linked_list_repeat.rs index 40dfcba638..cc7d8959ff 100644 --- a/contracts/benchmarks/mappers/linked-list-repeat/src/linked_list_repeat.rs +++ b/contracts/benchmarks/mappers/linked-list-repeat/src/linked_list_repeat.rs @@ -1,8 +1,9 @@ #![no_std] +use benchmark_common::ExampleStruct; + multiversx_sc::imports!(); -use benchmark_common::ExampleStruct; pub mod linked_list_repeat_proxy; #[multiversx_sc::contract] @@ -38,7 +39,8 @@ pub trait LinkedListRepeat: benchmark_common::BenchmarkCommon { #[storage_mapper("benchmark")] fn bench(&self) -> LinkedListMapper; - #[endpoint] + #[view] + // #[endpoint] fn add_struct(&self, num_repeats: usize, value: ExampleStruct) { let mut bench = self.bench_struct(); for i in 0..num_repeats { diff --git a/contracts/benchmarks/mappers/linked-list-repeat/wasm/src/lib.rs b/contracts/benchmarks/mappers/linked-list-repeat/wasm/src/lib.rs index 1e79aa533a..9e22454e98 100644 --- a/contracts/benchmarks/mappers/linked-list-repeat/wasm/src/lib.rs +++ b/contracts/benchmarks/mappers/linked-list-repeat/wasm/src/lib.rs @@ -21,11 +21,11 @@ multiversx_sc_wasm_adapter::endpoints! { add => add count => count remove => remove - bench => bench - add_struct => add_struct + bench___view => bench + add_struct___view => add_struct count_struct => count_struct remove_struct => remove_struct - bench_struct => bench_struct + bench_struct___view => bench_struct ) } From e5bfff759fc02dedba5cc9e9cb7147f7e2af8e35 Mon Sep 17 00:00:00 2001 From: BiancaIalangi Date: Tue, 18 Jun 2024 01:15:16 +0300 Subject: [PATCH 002/185] detect write op --- .../mappers/queue-repeat/wasm/src/lib.rs | 4 +- .../mappers/set-repeat/wasm/src/lib.rs | 4 +- .../mappers/vec-repeat/wasm/src/lib.rs | 4 +- contracts/examples/adder/src/adder.rs | 24 +++- contracts/examples/adder/wasm/src/lib.rs | 4 +- .../src/parse/attributes/endpoint_attr.rs | 2 +- framework/derive/src/parse/endpoint_parse.rs | 8 +- .../src/contract/sc_config/wasm_build.rs | 5 + .../meta-lib/src/tools/wasm_extractor.rs | 110 +++++++++++++++++- 9 files changed, 148 insertions(+), 17 deletions(-) diff --git a/contracts/benchmarks/mappers/queue-repeat/wasm/src/lib.rs b/contracts/benchmarks/mappers/queue-repeat/wasm/src/lib.rs index 887fb0c6e6..c254f43e57 100644 --- a/contracts/benchmarks/mappers/queue-repeat/wasm/src/lib.rs +++ b/contracts/benchmarks/mappers/queue-repeat/wasm/src/lib.rs @@ -21,11 +21,11 @@ multiversx_sc_wasm_adapter::endpoints! { add => add count => count remove => remove - bench => bench + bench___view => bench add_struct => add_struct count_struct => count_struct remove_struct => remove_struct - bench_struct => bench_struct + bench_struct___view => bench_struct ) } diff --git a/contracts/benchmarks/mappers/set-repeat/wasm/src/lib.rs b/contracts/benchmarks/mappers/set-repeat/wasm/src/lib.rs index 7a1a61db74..79d7ac9f8a 100644 --- a/contracts/benchmarks/mappers/set-repeat/wasm/src/lib.rs +++ b/contracts/benchmarks/mappers/set-repeat/wasm/src/lib.rs @@ -21,11 +21,11 @@ multiversx_sc_wasm_adapter::endpoints! { add => add count => count remove => remove - bench => bench + bench___view => bench add_struct => add_struct count_struct => count_struct remove_struct => remove_struct - bench_struct => bench_struct + bench_struct___view => bench_struct ) } diff --git a/contracts/benchmarks/mappers/vec-repeat/wasm/src/lib.rs b/contracts/benchmarks/mappers/vec-repeat/wasm/src/lib.rs index 6f915470d8..4a56536d8a 100644 --- a/contracts/benchmarks/mappers/vec-repeat/wasm/src/lib.rs +++ b/contracts/benchmarks/mappers/vec-repeat/wasm/src/lib.rs @@ -21,11 +21,11 @@ multiversx_sc_wasm_adapter::endpoints! { add => add count => count remove => remove - bench => bench + bench___view => bench add_struct => add_struct count_struct => count_struct remove_struct => remove_struct - bench_struct => bench_struct + bench_struct___view => bench_struct ) } diff --git a/contracts/examples/adder/src/adder.rs b/contracts/examples/adder/src/adder.rs index 307f4112f5..18426a514f 100644 --- a/contracts/examples/adder/src/adder.rs +++ b/contracts/examples/adder/src/adder.rs @@ -1,3 +1,25 @@ +// 0 true, +// 1 true, +// 2 true, +// 3 true, +// 4 false, +// 5 true, +// 6 true, +// 7 true, +// 8 true, +// 9 true, +//10 true, +//11 true, +//12 true, +//13 true, +//14 false, +//15 true, +//16 true, +//17 false, +//18 true, +//19 false, +//20 true, + #![no_std] use multiversx_sc::imports::*; @@ -23,7 +45,7 @@ pub trait Adder { } /// Add desired amount to the storage variable. - #[endpoint] + #[view] fn add(&self, value: BigUint) { self.sum().update(|sum| *sum += value); } diff --git a/contracts/examples/adder/wasm/src/lib.rs b/contracts/examples/adder/wasm/src/lib.rs index 19ea33c7e1..f61318cdc4 100644 --- a/contracts/examples/adder/wasm/src/lib.rs +++ b/contracts/examples/adder/wasm/src/lib.rs @@ -20,8 +20,8 @@ multiversx_sc_wasm_adapter::endpoints! { ( init => init upgrade => upgrade - getSum => sum - add => add + getSum___view => sum + add___view => add ) } diff --git a/framework/derive/src/parse/attributes/endpoint_attr.rs b/framework/derive/src/parse/attributes/endpoint_attr.rs index 678675b202..4b742f5116 100644 --- a/framework/derive/src/parse/attributes/endpoint_attr.rs +++ b/framework/derive/src/parse/attributes/endpoint_attr.rs @@ -57,7 +57,7 @@ pub struct ViewAttribute { pub view_name: Option, } -impl ViewAttribute { +impl ViewAttribute { pub fn parse(attr: &syn::Attribute) -> Option { match is_attr_with_one_opt_token_tree_arg(attr, ATTR_VIEW) { None => None, diff --git a/framework/derive/src/parse/endpoint_parse.rs b/framework/derive/src/parse/endpoint_parse.rs index 5edc30ad08..1262e47571 100644 --- a/framework/derive/src/parse/endpoint_parse.rs +++ b/framework/derive/src/parse/endpoint_parse.rs @@ -133,8 +133,12 @@ pub fn process_view_attribute( .map(|view_attribute| { check_single_role(&*method); let view_ident = match view_attribute.view_name { - Some(ident) => ident, - None => method.name.clone(), + Some(ident) => { + format_ident!("{}___view", ident) + }, + None => { + format_ident!("{}___view", method.name.clone()) + }, }; method.public_role = PublicRole::Endpoint(EndpointMetadata { public_name: view_ident, diff --git a/framework/meta-lib/src/contract/sc_config/wasm_build.rs b/framework/meta-lib/src/contract/sc_config/wasm_build.rs index 5b318da9a0..49ac6bb2d7 100644 --- a/framework/meta-lib/src/contract/sc_config/wasm_build.rs +++ b/framework/meta-lib/src/contract/sc_config/wasm_build.rs @@ -93,6 +93,11 @@ impl ContractVariant { print_pack_mxsc_file(&output_mxsc_path); print_contract_size(compiled_bytes.len()); let mut abi = ContractAbiJson::from(&self.abi); + for endpoint in &abi.endpoints { + if endpoint.name.contains("__view") { + println!("analyze this via wasm"); + } + } let build_info = core::mem::take(&mut abi.build_info).unwrap(); let ei_check_json = EiCheckJson::new(&self.settings.check_ei, wasm_info.ei_check); let report = ReportInfoJson::new(&wasm_info, ei_check_json, compiled_bytes.len()); diff --git a/framework/meta-lib/src/tools/wasm_extractor.rs b/framework/meta-lib/src/tools/wasm_extractor.rs index 50d5b78aff..4c0d171ac8 100644 --- a/framework/meta-lib/src/tools/wasm_extractor.rs +++ b/framework/meta-lib/src/tools/wasm_extractor.rs @@ -1,7 +1,9 @@ use colored::Colorize; -use std::fs; +use semver::Op; +use std::{collections::HashMap, fs}; use wasmparser::{ - BinaryReaderError, DataSectionReader, FunctionBody, ImportSectionReader, Parser, Payload, + BinaryReaderError, DataSectionReader, ExportSectionReader, FunctionBody, ImportSectionReader, + Operator, Parser, Payload, }; use crate::ei::EIVersion; @@ -12,6 +14,12 @@ const PANIC_WITH_MESSAGE: &[u8; 16] = b"panic occurred: "; const PANIC_WITHOUT_MESSAGE: &[u8; 14] = b"panic occurred"; const ERROR_FAIL_ALLOCATOR: &[u8; 27] = b"memory allocation forbidden"; const MEMORY_GROW_OPCODE: u8 = 0x40; +const WRITE_OP: [&str; 1] = [ + // "mBufferAppend", + // "mBufferAppendBytes", + // "mBufferSetBytes", + "mBufferStorageStore", +]; pub struct WasmInfo { pub imports: Vec, @@ -50,12 +58,15 @@ fn populate_wasm_info( let mut ei_check = false; let mut memory_grow_flag = false; let mut has_panic = "none"; + let mut function_names: HashMap = HashMap::new(); + let mut read_functions: Vec = Vec::new(); - let parser = Parser::new(0); + let mut parser = Parser::new(0); for payload in parser.parse_all(&wasm_data) { match payload? { Payload::ImportSection(import_section) => { - imports = extract_imports(import_section, extract_imports_enabled); + imports = + extract_imports(import_section, extract_imports_enabled, &mut read_functions); ei_check = is_ei_valid(imports.clone(), check_ei); }, Payload::DataSection(data_section) => { @@ -67,12 +78,38 @@ fn populate_wasm_info( } }, Payload::CodeSectionEntry(code_section) => { - memory_grow_flag = is_mem_grow(code_section); + memory_grow_flag = is_mem_grow(code_section.clone()); + }, + Payload::ExportSection(export_section) => { + parse_export_section(export_section, &mut function_names); + // println!("{:#?}", function_names); }, _ => (), } } + parser = Parser::new(0); + for payload in parser.parse_all(&wasm_data) { + if let Payload::CodeSectionEntry(body) = payload? { + analyze_function_body(body, &mut read_functions); + } + } + + // println!("{:#?}", read_functions); + for (index, name) in function_names { + let i: usize = index.try_into().unwrap(); + if !read_functions[i] { + println!( + "{} >> {}", + "Write storage in VIEW endpoint entitled " + .to_string() + .red() + .bold(), + name.red().bold() + ); + } + } + let report = ReportCreator { path, has_allocator: allocator_trigger, @@ -88,6 +125,63 @@ fn populate_wasm_info( }) } +fn parse_export_section( + export_section: ExportSectionReader, + function_names: &mut HashMap, +) { + for export in export_section { + let export = export.expect("Failed to read export section"); + if let wasmparser::ExternalKind::Func = export.kind { + if export.name.to_string().ends_with("__view") { + function_names.insert(export.index, export.name.to_string()); + } + } + } +} + +fn analyze_function_body(body: FunctionBody, functions: &mut Vec) { + // Implement your function body analysis here + // For example, you can parse the locals and instructions + // let locals_reader = body + // .get_locals_reader() + // .expect("Failed to get locals reader"); + let mut instructions_reader = body + .get_operators_reader() + .expect("Failed to get operators reader"); + + // println!("Function has {} locals", locals_reader.get_count()); + + let mut value = true; + while let Ok(op) = instructions_reader.read() { + match op { + Operator::Call { function_index } => { + let function_usize: usize = function_index.try_into().unwrap(); + if function_usize >= functions.len() { + functions.push(true); + return; + } + + value &= functions[function_usize]; + + if !value { + functions.push(value); + return; + } + }, + Operator::I32Load { memarg } => { + if memarg.offset > 0 { + functions.push(false); + return; + } + }, + _ => (), + } + } + + functions.push(value); + // println!("===================="); +} + fn is_fail_allocator_triggered(data_section: DataSectionReader) -> bool { for data_fragment in data_section.into_iter().flatten() { if data_fragment @@ -140,6 +234,7 @@ fn is_panic_without_message_triggered(data_section: DataSectionReader) -> bool { pub fn extract_imports( import_section: ImportSectionReader, import_extraction_enabled: bool, + write_or_read_functions: &mut Vec, ) -> Vec { if !import_extraction_enabled { return Vec::new(); @@ -148,6 +243,11 @@ pub fn extract_imports( let mut import_names = Vec::new(); for import in import_section.into_iter().flatten() { import_names.push(import.name.to_string()); + if WRITE_OP.contains(&import.name) { + write_or_read_functions.push(false); + } else { + write_or_read_functions.push(true); + } } import_names.sort(); From a71bd3e625df61364f00a1d6984c3fd182de6224 Mon Sep 17 00:00:00 2001 From: BiancaIalangi Date: Thu, 20 Jun 2024 15:56:17 +0300 Subject: [PATCH 003/185] remove alter of the view endpoint name --- contracts/examples/adder/src/adder.rs | 22 ------------- contracts/examples/adder/wasm/src/lib.rs | 4 +-- framework/derive/src/parse/endpoint_parse.rs | 8 ++--- .../src/contract/sc_config/wasm_build.rs | 32 ++++++++++++++++--- .../meta-lib/src/tools/wasm_extractor.rs | 22 ++++++------- 5 files changed, 40 insertions(+), 48 deletions(-) diff --git a/contracts/examples/adder/src/adder.rs b/contracts/examples/adder/src/adder.rs index 18426a514f..77358e4b7b 100644 --- a/contracts/examples/adder/src/adder.rs +++ b/contracts/examples/adder/src/adder.rs @@ -1,25 +1,3 @@ -// 0 true, -// 1 true, -// 2 true, -// 3 true, -// 4 false, -// 5 true, -// 6 true, -// 7 true, -// 8 true, -// 9 true, -//10 true, -//11 true, -//12 true, -//13 true, -//14 false, -//15 true, -//16 true, -//17 false, -//18 true, -//19 false, -//20 true, - #![no_std] use multiversx_sc::imports::*; diff --git a/contracts/examples/adder/wasm/src/lib.rs b/contracts/examples/adder/wasm/src/lib.rs index f61318cdc4..19ea33c7e1 100644 --- a/contracts/examples/adder/wasm/src/lib.rs +++ b/contracts/examples/adder/wasm/src/lib.rs @@ -20,8 +20,8 @@ multiversx_sc_wasm_adapter::endpoints! { ( init => init upgrade => upgrade - getSum___view => sum - add___view => add + getSum => sum + add => add ) } diff --git a/framework/derive/src/parse/endpoint_parse.rs b/framework/derive/src/parse/endpoint_parse.rs index 1262e47571..5edc30ad08 100644 --- a/framework/derive/src/parse/endpoint_parse.rs +++ b/framework/derive/src/parse/endpoint_parse.rs @@ -133,12 +133,8 @@ pub fn process_view_attribute( .map(|view_attribute| { check_single_role(&*method); let view_ident = match view_attribute.view_name { - Some(ident) => { - format_ident!("{}___view", ident) - }, - None => { - format_ident!("{}___view", method.name.clone()) - }, + Some(ident) => ident, + None => method.name.clone(), }; method.public_role = PublicRole::Endpoint(EndpointMetadata { public_name: view_ident, diff --git a/framework/meta-lib/src/contract/sc_config/wasm_build.rs b/framework/meta-lib/src/contract/sc_config/wasm_build.rs index 49ac6bb2d7..e7a9bec5ed 100644 --- a/framework/meta-lib/src/contract/sc_config/wasm_build.rs +++ b/framework/meta-lib/src/contract/sc_config/wasm_build.rs @@ -93,9 +93,14 @@ impl ContractVariant { print_pack_mxsc_file(&output_mxsc_path); print_contract_size(compiled_bytes.len()); let mut abi = ContractAbiJson::from(&self.abi); + let mut view_endpoints = Vec::new(); for endpoint in &abi.endpoints { - if endpoint.name.contains("__view") { - println!("analyze this via wasm"); + match endpoint.mutability { + crate::abi_json::EndpointMutabilityAbiJson::Readonly => { + view_endpoints.push(&endpoint.name) + }, + crate::abi_json::EndpointMutabilityAbiJson::Mutable => (), + crate::abi_json::EndpointMutabilityAbiJson::Pure => (), } } let build_info = core::mem::take(&mut abi.build_info).unwrap(); @@ -135,11 +140,24 @@ impl ContractVariant { fn extract_wasm_info(&self, build_args: &BuildArgs, output_path: &str) -> WasmInfo { let output_wasm_path = format!("{output_path}/{}", self.wasm_output_name(build_args)); + let abi = ContractAbiJson::from(&self.abi); + let mut view_endpoints = Vec::new(); + for endpoint in &abi.endpoints { + match endpoint.mutability { + crate::abi_json::EndpointMutabilityAbiJson::Readonly => { + view_endpoints.push(endpoint.name.clone()) + }, + crate::abi_json::EndpointMutabilityAbiJson::Mutable => (), + crate::abi_json::EndpointMutabilityAbiJson::Pure => (), + } + } + if !build_args.extract_imports { return WasmInfo::extract_wasm_info( &output_wasm_path, build_args.extract_imports, &self.settings.check_ei, + view_endpoints, ) .expect("error occured while extracting imports from .wasm "); } @@ -151,9 +169,13 @@ impl ContractVariant { ); print_extract_imports(&output_imports_json_path); - let wasm_data = - WasmInfo::extract_wasm_info(&output_wasm_path, true, &self.settings.check_ei) - .expect("error occured while extracting imports from .wasm "); + let wasm_data = WasmInfo::extract_wasm_info( + &output_wasm_path, + true, + &self.settings.check_ei, + view_endpoints, + ) + .expect("error occured while extracting imports from .wasm "); write_imports_output( output_imports_json_path.as_str(), diff --git a/framework/meta-lib/src/tools/wasm_extractor.rs b/framework/meta-lib/src/tools/wasm_extractor.rs index 4c0d171ac8..fa466440da 100644 --- a/framework/meta-lib/src/tools/wasm_extractor.rs +++ b/framework/meta-lib/src/tools/wasm_extractor.rs @@ -1,5 +1,4 @@ use colored::Colorize; -use semver::Op; use std::{collections::HashMap, fs}; use wasmparser::{ BinaryReaderError, DataSectionReader, ExportSectionReader, FunctionBody, ImportSectionReader, @@ -14,12 +13,7 @@ const PANIC_WITH_MESSAGE: &[u8; 16] = b"panic occurred: "; const PANIC_WITHOUT_MESSAGE: &[u8; 14] = b"panic occurred"; const ERROR_FAIL_ALLOCATOR: &[u8; 27] = b"memory allocation forbidden"; const MEMORY_GROW_OPCODE: u8 = 0x40; -const WRITE_OP: [&str; 1] = [ - // "mBufferAppend", - // "mBufferAppendBytes", - // "mBufferSetBytes", - "mBufferStorageStore", -]; +const WRITE_OP: [&str; 1] = ["mBufferStorageStore"]; pub struct WasmInfo { pub imports: Vec, @@ -34,6 +28,7 @@ impl WasmInfo { output_wasm_path: &str, extract_imports_enabled: bool, check_ei: &Option, + view_endpoints: Vec, ) -> Result { let wasm_data = fs::read(output_wasm_path) .expect("error occured while extracting information from .wasm: file not found"); @@ -43,6 +38,7 @@ impl WasmInfo { wasm_data, extract_imports_enabled, check_ei, + view_endpoints, ) } } @@ -52,6 +48,7 @@ fn populate_wasm_info( wasm_data: Vec, extract_imports_enabled: bool, check_ei: &Option, + view_endpoints: Vec, ) -> Result { let mut imports = Vec::new(); let mut allocator_trigger = false; @@ -81,8 +78,7 @@ fn populate_wasm_info( memory_grow_flag = is_mem_grow(code_section.clone()); }, Payload::ExportSection(export_section) => { - parse_export_section(export_section, &mut function_names); - // println!("{:#?}", function_names); + parse_export_section(export_section, &mut function_names, view_endpoints.clone()); }, _ => (), } @@ -95,13 +91,12 @@ fn populate_wasm_info( } } - // println!("{:#?}", read_functions); for (index, name) in function_names { let i: usize = index.try_into().unwrap(); if !read_functions[i] { println!( - "{} >> {}", - "Write storage in VIEW endpoint entitled " + "{} {}", + "Write storage operation in VIEW endpoint:" .to_string() .red() .bold(), @@ -128,11 +123,12 @@ fn populate_wasm_info( fn parse_export_section( export_section: ExportSectionReader, function_names: &mut HashMap, + view_endpoints: Vec, ) { for export in export_section { let export = export.expect("Failed to read export section"); if let wasmparser::ExternalKind::Func = export.kind { - if export.name.to_string().ends_with("__view") { + if view_endpoints.contains(&export.name.to_string()) { function_names.insert(export.index, export.name.to_string()); } } From 2bbca773c676f5271f18b02c9fe64c74d9b44d0b Mon Sep 17 00:00:00 2001 From: BiancaIalangi Date: Mon, 12 Aug 2024 15:33:25 +0300 Subject: [PATCH 004/185] chain-sim - prototype of integration with adder interactor --- contracts/examples/adder/interact/config.toml | 2 +- .../adder/interact/src/basic_interact.rs | 36 ++++++++++--------- .../interactor_scenario/interactor_sc_call.rs | 1 + .../interactor_sc_deploy.rs | 1 + sdk/core/src/gateway.rs | 2 ++ .../src/gateway/gateway_chain_simulator.rs | 32 +++++++++++++++++ 6 files changed, 56 insertions(+), 18 deletions(-) create mode 100644 sdk/core/src/gateway/gateway_chain_simulator.rs diff --git a/contracts/examples/adder/interact/config.toml b/contracts/examples/adder/interact/config.toml index 61ac8dbf87..11eb18de60 100644 --- a/contracts/examples/adder/interact/config.toml +++ b/contracts/examples/adder/interact/config.toml @@ -1 +1 @@ -gateway = 'https://devnet-gateway.multiversx.com' +gateway = 'http://localhost:8085' diff --git a/contracts/examples/adder/interact/src/basic_interact.rs b/contracts/examples/adder/interact/src/basic_interact.rs index 262eb13631..fff69aea1c 100644 --- a/contracts/examples/adder/interact/src/basic_interact.rs +++ b/contracts/examples/adder/interact/src/basic_interact.rs @@ -2,6 +2,8 @@ mod basic_interact_cli; mod basic_interact_config; mod basic_interact_state; +use core::str; + use adder::adder_proxy; use basic_interact_config::Config; use basic_interact_state::State; @@ -63,10 +65,22 @@ impl AdderInteract { .with_tracer(INTERACTOR_SCENARIO_TRACE_PATH) .await; - let adder_owner_address = - interactor.register_wallet(Wallet::from_pem_file("adder-owner.pem").unwrap()); + let adder_owner_address = interactor.register_wallet(test_wallets::alice()); + let wallet_address = interactor.register_wallet(test_wallets::mike()); + interactor + .proxy + .send_user_funds(&Bech32Address::from(&adder_owner_address).to_bech32_string()) + .await; + + interactor + .proxy + .send_user_funds(&Bech32Address::from(&wallet_address).to_bech32_string()) + .await; + + interactor.proxy.generate_blocks(20).await; + Self { interactor, adder_owner_address: adder_owner_address.into(), @@ -75,20 +89,10 @@ impl AdderInteract { } } - async fn set_state(&mut self) { - println!("wallet address: {}", self.wallet_address); - self.interactor - .retrieve_account(&self.adder_owner_address) - .await; - self.interactor.retrieve_account(&self.wallet_address).await; - } - async fn deploy(&mut self) { // warning: multi deploy not yet fully supported // only works with last deployed address - self.set_state().await; - let new_address = self .interactor .tx() @@ -104,7 +108,7 @@ impl AdderInteract { .await; println!("new address: {new_address}"); - self.state.set_adder_address(new_address); + self.state.set_adder_address(new_address.clone()); } async fn multi_deploy(&mut self, count: usize) { @@ -113,7 +117,6 @@ impl AdderInteract { return; } - self.set_state().await; println!("deploying {count} contracts..."); let mut buffer = self.interactor.homogenous_call_buffer(); @@ -141,7 +144,6 @@ impl AdderInteract { } async fn multi_add(&mut self, value: u32, count: usize) { - self.set_state().await; println!("calling contract {count} times..."); let mut buffer = self.interactor.homogenous_call_buffer(); @@ -205,7 +207,7 @@ impl AdderInteract { let response = self .interactor .tx() - .from(&self.wallet_address) + .from(&self.adder_owner_address) .to(self.state.current_adder_address()) .gas(3_000_000) .typed(adder_proxy::AdderProxy) @@ -241,5 +243,5 @@ async fn test() { basic_interact.deploy().await; basic_interact.add(1u32).await; - basic_interact.upgrade(7u32).await; + basic_interact.upgrade(5u32).await; } diff --git a/framework/snippets/src/interactor_scenario/interactor_sc_call.rs b/framework/snippets/src/interactor_scenario/interactor_sc_call.rs index 6802304ae9..6c46301808 100644 --- a/framework/snippets/src/interactor_scenario/interactor_sc_call.rs +++ b/framework/snippets/src/interactor_scenario/interactor_sc_call.rs @@ -14,6 +14,7 @@ impl Interactor { { let sc_call_step = sc_call_step.as_mut(); let tx_hash = self.launch_sc_call(sc_call_step).await; + // self.proxy.generate_blocks(20).await; let tx = self.proxy.retrieve_tx_on_network(tx_hash.clone()).await; sc_call_step.save_response(network_response::parse_tx_response(tx)); diff --git a/framework/snippets/src/interactor_scenario/interactor_sc_deploy.rs b/framework/snippets/src/interactor_scenario/interactor_sc_deploy.rs index 59de249e83..3ff2748f92 100644 --- a/framework/snippets/src/interactor_scenario/interactor_sc_deploy.rs +++ b/framework/snippets/src/interactor_scenario/interactor_sc_deploy.rs @@ -53,6 +53,7 @@ impl Interactor { { let sc_deploy_step = sc_deploy_step.as_mut(); let tx_hash = self.launch_sc_deploy(sc_deploy_step).await; + // self.proxy.generate_blocks(1).await; let tx = self.proxy.retrieve_tx_on_network(tx_hash.clone()).await; let addr = sc_deploy_step.tx.from.clone(); diff --git a/sdk/core/src/gateway.rs b/sdk/core/src/gateway.rs index 35e2668b50..33a263607e 100644 --- a/sdk/core/src/gateway.rs +++ b/sdk/core/src/gateway.rs @@ -4,12 +4,14 @@ mod gateway_network; mod gateway_proxy; mod gateway_tx; mod gateway_tx_retrieve; +mod gateway_chain_simulator; pub use gateway_proxy::GatewayProxy; pub const MAINNET_GATEWAY: &str = "https://gateway.multiversx.com"; pub const TESTNET_GATEWAY: &str = "https://testnet-gateway.multiversx.com"; pub const DEVNET_GATEWAY: &str = "https://devnet-gateway.multiversx.com"; +pub const SIMULATOR_GATEWAY: &str = "http://localhost:8085"; // MetachainShardId will be used to identify a shard ID as metachain pub const METACHAIN_SHARD_ID: u32 = 0xFFFFFFFF; diff --git a/sdk/core/src/gateway/gateway_chain_simulator.rs b/sdk/core/src/gateway/gateway_chain_simulator.rs new file mode 100644 index 0000000000..47c14c99c4 --- /dev/null +++ b/sdk/core/src/gateway/gateway_chain_simulator.rs @@ -0,0 +1,32 @@ +use std::collections::HashMap; + +use super::GatewayProxy; + +const SEND_USER_FUNDS_ENDPOINT: &str = "transaction/send-user-funds"; +const GENERATE_BLOCKS_FUNDS_ENDPOINT: &str = "simulator/generate-blocks"; +const ACCOUNT_DATA: &str = "address/"; + +impl GatewayProxy { + pub async fn send_user_funds(&self, receiver: &String) { + let mut r = HashMap::new(); + r.insert("receiver", receiver); + let endpoint_funds = self.get_endpoint(SEND_USER_FUNDS_ENDPOINT); + let _ = self.client.post(endpoint_funds).json(&r).send().await; + } + + pub async fn generate_blocks(&self, number_blocks: u64) { + let url_gen_blocks: String = + format!("{}/{}", GENERATE_BLOCKS_FUNDS_ENDPOINT, number_blocks); + let endpoint_blocks = self.get_endpoint(&url_gen_blocks); + let _ = self.client.post(endpoint_blocks).send().await; + } + + pub async fn set_state_chain_sim(&self, address: String) { + let endpoint_funds = self.get_endpoint(&format!("{}{}", ACCOUNT_DATA, address)); + let data = self.client.get(endpoint_funds).send().await; + match data { + Ok(d) => println!("{:?}", d.text().await), + Err(_) => todo!(), + } + } +} From c060158e3293d385a765eb78acf13f7c4b2d84ce Mon Sep 17 00:00:00 2001 From: BiancaIalangi Date: Wed, 21 Aug 2024 16:07:35 +0300 Subject: [PATCH 005/185] chain sim - impl in framework --- contracts/examples/adder/interact/config.toml | 2 +- .../adder/interact/src/basic_interact.rs | 31 ++++---- .../interact/src/basic_interact_config.rs | 9 ++- .../interact/src/multisig_interact.rs | 8 +- .../interact/src/bf_interact.rs | 2 +- .../interact/src/comp_interact_controller.rs | 2 +- framework/snippets/src/account_tool.rs | 38 ++++++---- framework/snippets/src/interactor.rs | 7 +- .../interactor_scenario/interactor_sc_call.rs | 5 +- .../interactor_sc_deploy.rs | 5 +- .../interactor_transfer.rs | 5 ++ .../src/multi/interactor_multi_sc_process.rs | 1 + .../src/gateway/gateway_chain_simulator.rs | 76 ++++++++++++++++--- sdk/core/src/gateway/gateway_proxy.rs | 6 ++ 14 files changed, 145 insertions(+), 52 deletions(-) diff --git a/contracts/examples/adder/interact/config.toml b/contracts/examples/adder/interact/config.toml index 11eb18de60..e474de08f5 100644 --- a/contracts/examples/adder/interact/config.toml +++ b/contracts/examples/adder/interact/config.toml @@ -1 +1 @@ -gateway = 'http://localhost:8085' +chain_type = "simulator" diff --git a/contracts/examples/adder/interact/src/basic_interact.rs b/contracts/examples/adder/interact/src/basic_interact.rs index fff69aea1c..937d12641f 100644 --- a/contracts/examples/adder/interact/src/basic_interact.rs +++ b/contracts/examples/adder/interact/src/basic_interact.rs @@ -65,21 +65,10 @@ impl AdderInteract { .with_tracer(INTERACTOR_SCENARIO_TRACE_PATH) .await; - let adder_owner_address = interactor.register_wallet(test_wallets::alice()); + let adder_owner_address = interactor.register_wallet(test_wallets::alice()).await; + let wallet_address = interactor.register_wallet(test_wallets::mike()).await; - let wallet_address = interactor.register_wallet(test_wallets::mike()); - - interactor - .proxy - .send_user_funds(&Bech32Address::from(&adder_owner_address).to_bech32_string()) - .await; - - interactor - .proxy - .send_user_funds(&Bech32Address::from(&wallet_address).to_bech32_string()) - .await; - - interactor.proxy.generate_blocks(20).await; + interactor.proxy.generate_blocks(20).await.unwrap(); Self { interactor, @@ -89,10 +78,20 @@ impl AdderInteract { } } + async fn set_state(&mut self) { + println!("wallet address: {}", self.wallet_address); + self.interactor + .retrieve_account(&self.adder_owner_address) + .await; + self.interactor.retrieve_account(&self.wallet_address).await; + } + async fn deploy(&mut self) { // warning: multi deploy not yet fully supported // only works with last deployed address + self.set_state().await; + let new_address = self .interactor .tx() @@ -108,7 +107,7 @@ impl AdderInteract { .await; println!("new address: {new_address}"); - self.state.set_adder_address(new_address.clone()); + self.state.set_adder_address(new_address); } async fn multi_deploy(&mut self, count: usize) { @@ -117,6 +116,7 @@ impl AdderInteract { return; } + self.set_state().await; println!("deploying {count} contracts..."); let mut buffer = self.interactor.homogenous_call_buffer(); @@ -144,6 +144,7 @@ impl AdderInteract { } async fn multi_add(&mut self, value: u32, count: usize) { + self.set_state().await; println!("calling contract {count} times..."); let mut buffer = self.interactor.homogenous_call_buffer(); diff --git a/contracts/examples/adder/interact/src/basic_interact_config.rs b/contracts/examples/adder/interact/src/basic_interact_config.rs index e17d0cbe65..02773bc1e8 100644 --- a/contracts/examples/adder/interact/src/basic_interact_config.rs +++ b/contracts/examples/adder/interact/src/basic_interact_config.rs @@ -7,7 +7,8 @@ const CONFIG_FILE: &str = "config.toml"; /// Adder Interact configuration #[derive(Debug, Deserialize)] pub struct Config { - gateway: String, + gateway: Option, + chain_type: String, } impl Config { @@ -21,6 +22,10 @@ impl Config { // Returns the gateway pub fn gateway(&self) -> &str { - &self.gateway + match self.chain_type.as_str() { + "real" => self.gateway.as_deref().expect("Please provide gateway!"), + "simulator" => "http://localhost:8085", + _ => "", + } } } diff --git a/contracts/examples/multisig/interact/src/multisig_interact.rs b/contracts/examples/multisig/interact/src/multisig_interact.rs index 497b6636dd..7ab094e04c 100644 --- a/contracts/examples/multisig/interact/src/multisig_interact.rs +++ b/contracts/examples/multisig/interact/src/multisig_interact.rs @@ -19,7 +19,7 @@ async fn main() { env_logger::init(); let mut multisig_interact = MultisigInteract::init().await; - multisig_interact.register_wallets(); + multisig_interact.register_wallets().await; let cli = multisig_interact_cli::InteractCli::parse(); match &cli.command { @@ -90,7 +90,7 @@ impl MultisigInteract { .await .with_tracer(INTERACTOR_SCENARIO_TRACE_PATH) .await; - let wallet_address = interactor.register_wallet(test_wallets::mike()); + let wallet_address = interactor.register_wallet(test_wallets::mike()).await; let multisig_code = BytesValue::interpret_from( "mxsc:../output/multisig.mxsc.json", &InterpreterContext::default(), @@ -106,13 +106,13 @@ impl MultisigInteract { } } - fn register_wallets(&mut self) { + async fn register_wallets(&mut self) { let carol = test_wallets::carol(); let dan = test_wallets::dan(); let eve = test_wallets::eve(); for wallet in &[carol, dan, eve] { - self.interactor.register_wallet(*wallet); + self.interactor.register_wallet(*wallet).await; } } diff --git a/contracts/feature-tests/basic-features/interact/src/bf_interact.rs b/contracts/feature-tests/basic-features/interact/src/bf_interact.rs index e8f269cb71..d14de2d71c 100644 --- a/contracts/feature-tests/basic-features/interact/src/bf_interact.rs +++ b/contracts/feature-tests/basic-features/interact/src/bf_interact.rs @@ -45,7 +45,7 @@ impl BasicFeaturesInteract { .await .with_tracer(INTERACTOR_SCENARIO_TRACE_PATH) .await; - let wallet_address = interactor.register_wallet(test_wallets::mike()); + let wallet_address = interactor.register_wallet(test_wallets::mike()).await; let code_expr = BytesValue::interpret_from( "mxsc:../output/basic-features-storage-bytes.mxsc.json", &InterpreterContext::default(), diff --git a/contracts/feature-tests/composability/interact/src/comp_interact_controller.rs b/contracts/feature-tests/composability/interact/src/comp_interact_controller.rs index 1c2457494b..1ae99af017 100644 --- a/contracts/feature-tests/composability/interact/src/comp_interact_controller.rs +++ b/contracts/feature-tests/composability/interact/src/comp_interact_controller.rs @@ -20,7 +20,7 @@ impl ComposabilityInteract { .await .with_tracer(INTERACTOR_SCENARIO_TRACE_PATH) .await; - let wallet_address = interactor.register_wallet(test_wallets::judy()); + let wallet_address = interactor.register_wallet(test_wallets::judy()).await; let forw_queue_code = BytesValue::interpret_from( "mxsc:../forwarder-queue/output/forwarder-queue.mxsc.json", &InterpreterContext::default(), diff --git a/framework/snippets/src/account_tool.rs b/framework/snippets/src/account_tool.rs index b10baf4a80..c40407e360 100644 --- a/framework/snippets/src/account_tool.rs +++ b/framework/snippets/src/account_tool.rs @@ -40,20 +40,30 @@ pub async fn retrieve_account_as_scenario_set_state( let sdk_address = Address::from_bech32_string(address.to_bech32_str()).unwrap(); let sdk_account = api.get_account(&sdk_address).await.unwrap(); - let account_esdt = api - .get_account_esdt_tokens(&sdk_address) - .await - .unwrap_or_else(|err| { - panic!("failed to retrieve ESDT tokens for address {address}: {err}") - }); - let account_esdt_roles = api - .get_account_esdt_roles(&sdk_address) - .await - .unwrap_or_else(|err| panic!("failed to retrieve ESDT roles for address {address}: {err}")); - let account_storage = api - .get_account_storage_keys(&sdk_address) - .await - .unwrap_or_else(|err| panic!("failed to retrieve storage for address {address}: {err}")); + let (account_esdt, account_esdt_roles, account_storage) = if api.chain_simulator { + (HashMap::new(), HashMap::new(), HashMap::new()) + } else { + let account_esdt = api + .get_account_esdt_tokens(&sdk_address) + .await + .unwrap_or_else(|err| { + panic!("failed to retrieve ESDT tokens for address {address}: {err}") + }); + let account_esdt_roles = api + .get_account_esdt_roles(&sdk_address) + .await + .unwrap_or_else(|err| { + panic!("failed to retrieve ESDT roles for address {address}: {err}") + }); + let account_storage = api + .get_account_storage_keys(&sdk_address) + .await + .unwrap_or_else(|err| { + panic!("failed to retrieve storage for address {address}: {err}") + }); + + (account_esdt, account_esdt_roles, account_storage) + }; let account_state = set_account( sdk_account, diff --git a/framework/snippets/src/interactor.rs b/framework/snippets/src/interactor.rs index bb38873afe..702121c373 100644 --- a/framework/snippets/src/interactor.rs +++ b/framework/snippets/src/interactor.rs @@ -46,8 +46,13 @@ impl Interactor { } } - pub fn register_wallet(&mut self, wallet: Wallet) -> Address { + pub async fn register_wallet(&mut self, wallet: Wallet) -> Address { let address = erdrs_address_to_h256(wallet.address()); + self.proxy + .send_user_funds(&Bech32Address::from(&address).to_bech32_string()) + .await + .unwrap(); + self.sender_map.insert( address.clone(), Sender { diff --git a/framework/snippets/src/interactor_scenario/interactor_sc_call.rs b/framework/snippets/src/interactor_scenario/interactor_sc_call.rs index 6c46301808..a9d3930eb6 100644 --- a/framework/snippets/src/interactor_scenario/interactor_sc_call.rs +++ b/framework/snippets/src/interactor_scenario/interactor_sc_call.rs @@ -14,7 +14,10 @@ impl Interactor { { let sc_call_step = sc_call_step.as_mut(); let tx_hash = self.launch_sc_call(sc_call_step).await; - // self.proxy.generate_blocks(20).await; + self.proxy + .generate_blocks_until_tx_processed(&tx_hash) + .await + .unwrap(); let tx = self.proxy.retrieve_tx_on_network(tx_hash.clone()).await; sc_call_step.save_response(network_response::parse_tx_response(tx)); diff --git a/framework/snippets/src/interactor_scenario/interactor_sc_deploy.rs b/framework/snippets/src/interactor_scenario/interactor_sc_deploy.rs index 3ff2748f92..20d45649d8 100644 --- a/framework/snippets/src/interactor_scenario/interactor_sc_deploy.rs +++ b/framework/snippets/src/interactor_scenario/interactor_sc_deploy.rs @@ -53,7 +53,10 @@ impl Interactor { { let sc_deploy_step = sc_deploy_step.as_mut(); let tx_hash = self.launch_sc_deploy(sc_deploy_step).await; - // self.proxy.generate_blocks(1).await; + self.proxy + .generate_blocks_until_tx_processed(&tx_hash) + .await + .unwrap(); let tx = self.proxy.retrieve_tx_on_network(tx_hash.clone()).await; let addr = sc_deploy_step.tx.from.clone(); diff --git a/framework/snippets/src/interactor_scenario/interactor_transfer.rs b/framework/snippets/src/interactor_scenario/interactor_transfer.rs index 6557e4119f..53da3a64b9 100644 --- a/framework/snippets/src/interactor_scenario/interactor_transfer.rs +++ b/framework/snippets/src/interactor_scenario/interactor_transfer.rs @@ -11,6 +11,11 @@ impl Interactor { self.set_nonce_and_sign_tx(sender_address, &mut transaction) .await; let tx_hash = self.proxy.send_transaction(&transaction).await.unwrap(); + self.proxy + .generate_blocks_until_tx_processed(&tx_hash) + .await + .unwrap(); + println!("transfer tx hash: {tx_hash}"); info!("transfer tx hash: {}", tx_hash); diff --git a/framework/snippets/src/multi/interactor_multi_sc_process.rs b/framework/snippets/src/multi/interactor_multi_sc_process.rs index 3364a4d5ee..076c005d84 100644 --- a/framework/snippets/src/multi/interactor_multi_sc_process.rs +++ b/framework/snippets/src/multi/interactor_multi_sc_process.rs @@ -34,6 +34,7 @@ impl Interactor { futures.push(self.proxy.retrieve_tx_on_network(tx_hash.clone())); } + self.proxy.generate_blocks(4).await.unwrap(); join_all(futures).await } } diff --git a/sdk/core/src/gateway/gateway_chain_simulator.rs b/sdk/core/src/gateway/gateway_chain_simulator.rs index 47c14c99c4..9c9e75b819 100644 --- a/sdk/core/src/gateway/gateway_chain_simulator.rs +++ b/sdk/core/src/gateway/gateway_chain_simulator.rs @@ -1,32 +1,86 @@ use std::collections::HashMap; use super::GatewayProxy; +use anyhow::{anyhow, Error}; +use serde::{Deserialize, Serialize}; const SEND_USER_FUNDS_ENDPOINT: &str = "transaction/send-user-funds"; const GENERATE_BLOCKS_FUNDS_ENDPOINT: &str = "simulator/generate-blocks"; -const ACCOUNT_DATA: &str = "address/"; +const GENERATE_BLOCKS_UNTIL_TX_PROCESSED_ENDPOINT: &str = + "simulator/generate-blocks-until-transaction-processed"; + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct GenerateBlocksResponse { + pub data: serde_json::Value, + pub error: String, + pub code: String, +} impl GatewayProxy { - pub async fn send_user_funds(&self, receiver: &String) { + pub async fn send_user_funds(&self, receiver: &String) -> Result { + if !self.chain_simulator { + return Ok(String::from("no-simulator")); + } + let mut r = HashMap::new(); r.insert("receiver", receiver); let endpoint_funds = self.get_endpoint(SEND_USER_FUNDS_ENDPOINT); - let _ = self.client.post(endpoint_funds).json(&r).send().await; + let resp = self + .client + .post(endpoint_funds) + .json(&r) + .send() + .await? + .json::() + .await?; + + match resp.code.as_str() { + "successful" => Ok(resp.code), + _ => Err(anyhow!("{}", resp.error)), + } } - pub async fn generate_blocks(&self, number_blocks: u64) { + pub async fn generate_blocks(&self, number_blocks: u64) -> Result { + if !self.chain_simulator { + return Ok(String::from("no-simulator")); + } + let url_gen_blocks: String = format!("{}/{}", GENERATE_BLOCKS_FUNDS_ENDPOINT, number_blocks); let endpoint_blocks = self.get_endpoint(&url_gen_blocks); - let _ = self.client.post(endpoint_blocks).send().await; + let resp = self + .client + .post(endpoint_blocks) + .send() + .await? + .json::() + .await?; + + match resp.code.as_str() { + "successful" => Ok(resp.code), + _ => Err(anyhow!("{}", resp.error)), + } } - pub async fn set_state_chain_sim(&self, address: String) { - let endpoint_funds = self.get_endpoint(&format!("{}{}", ACCOUNT_DATA, address)); - let data = self.client.get(endpoint_funds).send().await; - match data { - Ok(d) => println!("{:?}", d.text().await), - Err(_) => todo!(), + pub async fn generate_blocks_until_tx_processed(&self, tx: &String) -> Result { + if !self.chain_simulator { + return Ok(String::from("no-simulator")); + } + + let url_gen_blocks_until_tx_processed: String = + format!("{}/{}", GENERATE_BLOCKS_UNTIL_TX_PROCESSED_ENDPOINT, tx); + let endpoint_blocks = self.get_endpoint(&url_gen_blocks_until_tx_processed); + let resp = self + .client + .post(endpoint_blocks) + .send() + .await? + .json::() + .await?; + + match resp.code.as_str() { + "successful" => Ok(resp.code), + _ => Err(anyhow!("{}", resp.error)), } } } diff --git a/sdk/core/src/gateway/gateway_proxy.rs b/sdk/core/src/gateway/gateway_proxy.rs index 47925cd79f..f3693c6e12 100644 --- a/sdk/core/src/gateway/gateway_proxy.rs +++ b/sdk/core/src/gateway/gateway_proxy.rs @@ -1,17 +1,23 @@ use reqwest::Client; +pub const CHAIN_SIMULATOR_GATEWAY: &str = "http://localhost:8085"; + /// Allows communication with the MultiversX gateway API. #[derive(Clone, Debug)] pub struct GatewayProxy { pub(crate) proxy_url: String, pub(crate) client: Client, + pub chain_simulator: bool, } impl GatewayProxy { pub fn new(proxy_url: String) -> Self { + let chain_simulator = proxy_url == CHAIN_SIMULATOR_GATEWAY; + Self { proxy_url, client: Client::new(), + chain_simulator, } } From 22ea5901960d2c0905476aed63aac42fb211cc90 Mon Sep 17 00:00:00 2001 From: BiancaIalangi Date: Thu, 29 Aug 2024 21:08:08 +0300 Subject: [PATCH 006/185] write op detect - revert contracts --- .../benchmarks/mappers/linked-list-repeat/wasm/src/lib.rs | 6 +++--- contracts/benchmarks/mappers/queue-repeat/wasm/src/lib.rs | 4 ++-- contracts/benchmarks/mappers/set-repeat/wasm/src/lib.rs | 4 ++-- contracts/benchmarks/mappers/vec-repeat/wasm/src/lib.rs | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/contracts/benchmarks/mappers/linked-list-repeat/wasm/src/lib.rs b/contracts/benchmarks/mappers/linked-list-repeat/wasm/src/lib.rs index 9e22454e98..1e79aa533a 100644 --- a/contracts/benchmarks/mappers/linked-list-repeat/wasm/src/lib.rs +++ b/contracts/benchmarks/mappers/linked-list-repeat/wasm/src/lib.rs @@ -21,11 +21,11 @@ multiversx_sc_wasm_adapter::endpoints! { add => add count => count remove => remove - bench___view => bench - add_struct___view => add_struct + bench => bench + add_struct => add_struct count_struct => count_struct remove_struct => remove_struct - bench_struct___view => bench_struct + bench_struct => bench_struct ) } diff --git a/contracts/benchmarks/mappers/queue-repeat/wasm/src/lib.rs b/contracts/benchmarks/mappers/queue-repeat/wasm/src/lib.rs index c254f43e57..887fb0c6e6 100644 --- a/contracts/benchmarks/mappers/queue-repeat/wasm/src/lib.rs +++ b/contracts/benchmarks/mappers/queue-repeat/wasm/src/lib.rs @@ -21,11 +21,11 @@ multiversx_sc_wasm_adapter::endpoints! { add => add count => count remove => remove - bench___view => bench + bench => bench add_struct => add_struct count_struct => count_struct remove_struct => remove_struct - bench_struct___view => bench_struct + bench_struct => bench_struct ) } diff --git a/contracts/benchmarks/mappers/set-repeat/wasm/src/lib.rs b/contracts/benchmarks/mappers/set-repeat/wasm/src/lib.rs index 79d7ac9f8a..7a1a61db74 100644 --- a/contracts/benchmarks/mappers/set-repeat/wasm/src/lib.rs +++ b/contracts/benchmarks/mappers/set-repeat/wasm/src/lib.rs @@ -21,11 +21,11 @@ multiversx_sc_wasm_adapter::endpoints! { add => add count => count remove => remove - bench___view => bench + bench => bench add_struct => add_struct count_struct => count_struct remove_struct => remove_struct - bench_struct___view => bench_struct + bench_struct => bench_struct ) } diff --git a/contracts/benchmarks/mappers/vec-repeat/wasm/src/lib.rs b/contracts/benchmarks/mappers/vec-repeat/wasm/src/lib.rs index 4a56536d8a..6f915470d8 100644 --- a/contracts/benchmarks/mappers/vec-repeat/wasm/src/lib.rs +++ b/contracts/benchmarks/mappers/vec-repeat/wasm/src/lib.rs @@ -21,11 +21,11 @@ multiversx_sc_wasm_adapter::endpoints! { add => add count => count remove => remove - bench___view => bench + bench => bench add_struct => add_struct count_struct => count_struct remove_struct => remove_struct - bench_struct___view => bench_struct + bench_struct => bench_struct ) } From 89128ccb2578f939aa92131bf71f96d8d3730205 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Fri, 6 Sep 2024 20:18:14 +0300 Subject: [PATCH 007/185] system SC proxy - arg reference fix --- .../examples/nft-minter/src/nft_module.rs | 4 +- .../system_proxy/builtin_func_proxy.rs | 58 +++---- .../system_proxy/esdt_system_sc_proxy.rs | 146 +++++++++--------- .../src/system_sc_interact.rs | 72 ++++----- 4 files changed, 140 insertions(+), 140 deletions(-) diff --git a/contracts/examples/nft-minter/src/nft_module.rs b/contracts/examples/nft-minter/src/nft_module.rs index 66f50ea958..12f2c3b868 100644 --- a/contracts/examples/nft-minter/src/nft_module.rs +++ b/contracts/examples/nft-minter/src/nft_module.rs @@ -49,8 +49,8 @@ pub trait NftModule { self.send() .esdt_system_sc_proxy() .set_special_roles( - &self.blockchain().get_sc_address(), - &self.nft_token_id().get(), + self.blockchain().get_sc_address(), + self.nft_token_id().get(), [EsdtLocalRole::NftCreate][..].iter().cloned(), ) .async_call_and_exit() diff --git a/framework/base/src/types/interaction/system_proxy/builtin_func_proxy.rs b/framework/base/src/types/interaction/system_proxy/builtin_func_proxy.rs index 6e4978980a..6755dbbd03 100644 --- a/framework/base/src/types/interaction/system_proxy/builtin_func_proxy.rs +++ b/framework/base/src/types/interaction/system_proxy/builtin_func_proxy.rs @@ -78,7 +78,7 @@ where self.wrapped_tx .payment(NotPayable) .raw_call(CHANGE_OWNER_BUILTIN_FUNC_NAME) - .argument(new_owner) + .argument(&new_owner) .original_result() } @@ -87,26 +87,26 @@ where Arg1: ProxyArg>, >( self, - token: &Arg0, + token: Arg0, nonce: u64, - amount: &Arg1, + amount: Arg1, ) -> TxTypedCall { if nonce == 0 { return self .wrapped_tx .payment(NotPayable) .raw_call(ESDT_LOCAL_BURN_FUNC_NAME) - .argument(token) - .argument(amount) + .argument(&token) + .argument(&amount) .original_result(); } self.wrapped_tx .payment(NotPayable) .raw_call(ESDT_NFT_BURN_FUNC_NAME) - .argument(token) + .argument(&token) .argument(&nonce) - .argument(amount) + .argument(&amount) .original_result() } @@ -115,31 +115,31 @@ where Arg1: ProxyArg>, >( self, - token: &Arg0, + token: Arg0, nonce: u64, - amount: &Arg1, + amount: Arg1, ) -> TxTypedCall { if nonce == 0 { return self .wrapped_tx .payment(NotPayable) .raw_call(ESDT_LOCAL_MINT_FUNC_NAME) - .argument(token) - .argument(amount) + .argument(&token) + .argument(&amount) .original_result(); } self.wrapped_tx .payment(NotPayable) .raw_call(ESDT_NFT_ADD_QUANTITY_FUNC_NAME) - .argument(token) + .argument(&token) .argument(&nonce) - .argument(amount) + .argument(&amount) .original_result() } pub fn nft_add_multiple_uri>>( self, - token_id: &Arg0, + token_id: Arg0, nft_nonce: u64, new_uris: &ManagedVec>, ) -> TxTypedCall { @@ -147,7 +147,7 @@ where .wrapped_tx .payment(NotPayable) .raw_call(ESDT_NFT_ADD_URI_FUNC_NAME) - .argument(token_id) + .argument(&token_id) .argument(&nft_nonce); for uri in new_uris { @@ -159,16 +159,16 @@ where pub fn nft_update_attributes>>( self, - token_id: &Arg0, + token_id: Arg0, nft_nonce: u64, new_attributes: &T, ) -> TxTypedCall { self.wrapped_tx .payment(NotPayable) .raw_call(ESDT_NFT_UPDATE_ATTRIBUTES_FUNC_NAME) - .argument(token_id) + .argument(&token_id) .argument(&nft_nonce) - .argument(new_attributes) + .argument(&new_attributes) .original_result() } @@ -182,11 +182,11 @@ where Arg4: ProxyArg>, >( self, - token: &Arg0, - amount: &Arg1, - name: &Arg2, - royalties: &Arg3, - hash: &Arg4, + token: Arg0, + amount: Arg1, + name: Arg2, + royalties: Arg3, + hash: Arg4, attributes: &T, uris: &ManagedVec>, ) -> TxTypedCall { @@ -194,12 +194,12 @@ where .wrapped_tx .payment(NotPayable) .raw_call(ESDT_NFT_CREATE_FUNC_NAME) - .argument(token) - .argument(amount) - .argument(name) - .argument(royalties) - .argument(hash) - .argument(attributes); + .argument(&token) + .argument(&amount) + .argument(&name) + .argument(&royalties) + .argument(&hash) + .argument(&attributes); if uris.is_empty() { // at least one URI is required, so we push an empty one diff --git a/framework/base/src/types/interaction/system_proxy/esdt_system_sc_proxy.rs b/framework/base/src/types/interaction/system_proxy/esdt_system_sc_proxy.rs index 10730ff0fc..979f9d1d60 100644 --- a/framework/base/src/types/interaction/system_proxy/esdt_system_sc_proxy.rs +++ b/framework/base/src/types/interaction/system_proxy/esdt_system_sc_proxy.rs @@ -70,9 +70,9 @@ where >( self, issue_cost: BigUint, - token_display_name: &Arg0, - token_ticker: &Arg1, - initial_supply: &Arg2, + token_display_name: Arg0, + token_ticker: Arg1, + initial_supply: Arg2, properties: FungibleTokenProperties, ) -> IssueCall { self.issue( @@ -104,8 +104,8 @@ where >( self, issue_cost: BigUint, - token_display_name: &Arg0, - token_ticker: &Arg1, + token_display_name: Arg0, + token_ticker: Arg1, properties: NonFungibleTokenProperties, ) -> IssueCall { let zero = &BigUint::zero(); @@ -138,8 +138,8 @@ where >( self, issue_cost: BigUint, - token_display_name: &Arg0, - token_ticker: &Arg1, + token_display_name: Arg0, + token_ticker: Arg1, properties: SemiFungibleTokenProperties, ) -> IssueCall { let zero = BigUint::zero(); @@ -172,8 +172,8 @@ where >( self, issue_cost: BigUint, - token_display_name: &Arg0, - token_ticker: &Arg1, + token_display_name: Arg0, + token_ticker: Arg1, properties: MetaTokenProperties, ) -> IssueCall { let zero = &BigUint::zero(); @@ -236,9 +236,9 @@ where self, issue_cost: BigUint, token_type: EsdtTokenType, - token_display_name: &Arg0, - token_ticker: &Arg1, - initial_supply: &Arg2, + token_display_name: Arg0, + token_ticker: Arg1, + initial_supply: Arg2, properties: TokenProperties, ) -> IssueCall { let endpoint_name = match token_type { @@ -253,11 +253,11 @@ where .wrapped_tx .raw_call(endpoint_name) .egld(issue_cost) - .argument(token_display_name) - .argument(token_ticker); + .argument(&token_display_name) + .argument(&token_ticker); if token_type == EsdtTokenType::Fungible { - tx = tx.argument(initial_supply); + tx = tx.argument(&initial_supply); tx = tx.argument(&properties.num_decimals); } else if token_type == EsdtTokenType::Meta { tx = tx.argument(&properties.num_decimals); @@ -290,14 +290,14 @@ where /// It will fail if the SC is not the owner of the token. pub fn mint>, Arg1: ProxyArg>>( self, - token_identifier: &Arg0, - amount: &Arg1, + token_identifier: Arg0, + amount: Arg1, ) -> TxTypedCall { self.wrapped_tx .payment(NotPayable) .raw_call("mint") - .argument(token_identifier) - .argument(amount) + .argument(&token_identifier) + .argument(&amount) .original_result() } @@ -305,14 +305,14 @@ where /// which causes it to burn fungible ESDT tokens owned by the SC. pub fn burn>, Arg1: ProxyArg>>( self, - token_identifier: &Arg0, - amount: &Arg1, + token_identifier: Arg0, + amount: Arg1, ) -> TxTypedCall { self.wrapped_tx .payment(NotPayable) .raw_call("ESDTBurn") - .argument(token_identifier) - .argument(amount) + .argument(&token_identifier) + .argument(&amount) .original_result() } @@ -320,24 +320,24 @@ where /// except minting, freezing/unfreezing and wiping. pub fn pause>>( self, - token_identifier: &Arg0, + token_identifier: Arg0, ) -> TxTypedCall { self.wrapped_tx .payment(NotPayable) .raw_call("pause") - .argument(token_identifier) + .argument(&token_identifier) .original_result() } /// The reverse operation of `pause`. pub fn unpause>>( self, - token_identifier: &Arg0, + token_identifier: Arg0, ) -> TxTypedCall { self.wrapped_tx .payment(NotPayable) .raw_call("unPause") - .argument(token_identifier) + .argument(&token_identifier) .original_result() } @@ -349,14 +349,14 @@ where Arg1: ProxyArg>, >( self, - token_identifier: &Arg0, - address: &Arg1, + token_identifier: Arg0, + address: Arg1, ) -> TxTypedCall { self.wrapped_tx .payment(NotPayable) .raw_call("freeze") - .argument(token_identifier) - .argument(address) + .argument(&token_identifier) + .argument(&address) .original_result() } @@ -366,14 +366,14 @@ where Arg1: ProxyArg>, >( self, - token_identifier: &Arg0, - address: &Arg1, + token_identifier: Arg0, + address: Arg1, ) -> TxTypedCall { self.wrapped_tx .payment(NotPayable) .raw_call("unFreeze") - .argument(token_identifier) - .argument(address) + .argument(&token_identifier) + .argument(&address) .original_result() } @@ -386,14 +386,14 @@ where Arg1: ProxyArg>, >( self, - token_identifier: &Arg0, - address: &Arg1, + token_identifier: Arg0, + address: Arg1, ) -> TxTypedCall { self.wrapped_tx .payment(NotPayable) .raw_call("wipe") - .argument(token_identifier) - .argument(address) + .argument(&token_identifier) + .argument(&address) .original_result() } @@ -405,16 +405,16 @@ where Arg1: ProxyArg>, >( self, - token_identifier: &Arg0, + token_identifier: Arg0, nft_nonce: u64, - address: &Arg1, + address: Arg1, ) -> TxTypedCall { self.wrapped_tx .payment(NotPayable) .raw_call("freezeSingleNFT") - .argument(token_identifier) + .argument(&token_identifier) .argument(&nft_nonce) - .argument(address) + .argument(&address) .original_result() } @@ -424,16 +424,16 @@ where Arg1: ProxyArg>, >( self, - token_identifier: &Arg0, + token_identifier: Arg0, nft_nonce: u64, - address: &Arg1, + address: Arg1, ) -> TxTypedCall { self.wrapped_tx .payment(NotPayable) .raw_call("unFreezeSingleNFT") - .argument(token_identifier) + .argument(&token_identifier) .argument(&nft_nonce) - .argument(address) + .argument(&address) .original_result() } @@ -446,16 +446,16 @@ where Arg1: ProxyArg>, >( self, - token_identifier: &Arg0, + token_identifier: Arg0, nft_nonce: u64, - address: &Arg1, + address: Arg1, ) -> TxTypedCall { self.wrapped_tx .payment(NotPayable) .raw_call("wipeSingleNFT") - .argument(token_identifier) + .argument(&token_identifier) .argument(&nft_nonce) - .argument(address) + .argument(&address) .original_result() } @@ -463,13 +463,13 @@ where /// This function as almost all in case of ESDT can be called only by the owner. pub fn change_sft_to_meta_esdt>>( self, - token_identifier: &Arg0, + token_identifier: Arg0, num_decimals: usize, ) -> TxTypedCall { self.wrapped_tx .payment(NotPayable) .raw_call("changeSFTToMetaESDT") - .argument(token_identifier) + .argument(&token_identifier) .argument(&num_decimals) .original_result() } @@ -484,16 +484,16 @@ where Arg1: ProxyArg>, >( self, - address: &Arg0, - token_identifier: &Arg1, + address: Arg0, + token_identifier: Arg1, roles_iter: RoleIter, ) -> TxTypedCall { let mut tx = self .wrapped_tx .payment(NotPayable) .raw_call("setSpecialRole") - .argument(token_identifier) - .argument(address); + .argument(&token_identifier) + .argument(&address); for role in roles_iter { if role != EsdtLocalRole::None { tx = tx.argument(&role.as_role_name()); @@ -513,16 +513,16 @@ where Arg1: ProxyArg>, >( self, - address: &Arg0, - token_identifier: &Arg1, + address: Arg0, + token_identifier: Arg1, roles_iter: RoleIter, ) -> TxTypedCall { let mut tx = self .wrapped_tx .payment(NotPayable) .raw_call("unSetSpecialRole") - .argument(token_identifier) - .argument(address); + .argument(&token_identifier) + .argument(&address); for role in roles_iter { if role != EsdtLocalRole::None { tx = tx.argument(&role.as_role_name()); @@ -537,14 +537,14 @@ where Arg1: ProxyArg>, >( self, - token_identifier: &Arg0, - new_owner: &Arg1, + token_identifier: Arg0, + new_owner: Arg1, ) -> TxTypedCall { self.wrapped_tx .payment(NotPayable) .raw_call("transferOwnership") - .argument(token_identifier) - .argument(new_owner) + .argument(&token_identifier) + .argument(&new_owner) .original_result() } @@ -553,29 +553,29 @@ where Arg1: ProxyArg>, >( self, - token_identifier: &Arg0, - old_creator: &Arg1, - new_creator: &Arg1, + token_identifier: Arg0, + old_creator: Arg1, + new_creator: Arg1, ) -> TxTypedCall { self.wrapped_tx .payment(NotPayable) .raw_call("transferNFTCreateRole") - .argument(token_identifier) - .argument(old_creator) - .argument(new_creator) + .argument(&token_identifier) + .argument(&old_creator) + .argument(&new_creator) .original_result() } pub fn control_changes>>( self, - token_identifier: &Arg0, + token_identifier: Arg0, property_arguments: &TokenPropertyArguments, ) -> TxTypedCall { let mut tx = self .wrapped_tx .payment(NotPayable) .raw_call("controlChanges") - .argument(token_identifier); + .argument(&token_identifier); append_token_property_arguments(&mut tx.data, property_arguments); tx.original_result() } diff --git a/tools/interactor-system-func-calls/src/system_sc_interact.rs b/tools/interactor-system-func-calls/src/system_sc_interact.rs index 0558eba3c1..df47733d47 100644 --- a/tools/interactor-system-func-calls/src/system_sc_interact.rs +++ b/tools/interactor-system-func-calls/src/system_sc_interact.rs @@ -257,9 +257,9 @@ impl SysFuncCallsInteract { .typed(ESDTSystemSCProxy) .issue_fungible( issue_cost.into(), - &token_display_name, - &token_ticker, - &initial_supply, + token_display_name, + token_ticker, + initial_supply, FungibleTokenProperties { num_decimals, can_freeze: true, @@ -297,8 +297,8 @@ impl SysFuncCallsInteract { .typed(ESDTSystemSCProxy) .issue_non_fungible( issue_cost.into(), - &token_display_name, - &token_ticker, + token_display_name, + token_ticker, NonFungibleTokenProperties { can_freeze: true, can_wipe: true, @@ -334,8 +334,8 @@ impl SysFuncCallsInteract { .typed(ESDTSystemSCProxy) .issue_semi_fungible( issue_cost.into(), - &token_display_name, - &token_ticker, + token_display_name, + token_ticker, SemiFungibleTokenProperties { can_freeze: true, can_wipe: true, @@ -397,8 +397,8 @@ impl SysFuncCallsInteract { .gas(100_000_000u64) .typed(ESDTSystemSCProxy) .set_special_roles( - &ManagedAddress::from_address(wallet_address), - &TokenIdentifier::from(token_id), + ManagedAddress::from_address(wallet_address), + TokenIdentifier::from(token_id), roles.into_iter(), ) .prepare_async() @@ -423,11 +423,11 @@ impl SysFuncCallsInteract { .gas(100_000_000u64) .typed(UserBuiltinProxy) .esdt_nft_create( - &token_id, - &amount, - &name, - &royalties, - &hash, + token_id, + amount, + name, + royalties, + hash, &NftDummyAttributes { creation_epoch: 2104, cool_factor: 5, @@ -457,8 +457,8 @@ impl SysFuncCallsInteract { .typed(ESDTSystemSCProxy) .register_meta_esdt( issue_cost.into(), - &token_display_name, - &token_ticker, + token_display_name, + token_ticker, MetaTokenProperties { num_decimals, can_freeze: true, @@ -487,7 +487,7 @@ impl SysFuncCallsInteract { .to(ESDTSystemSCAddress) .gas(100_000_000u64) .typed(ESDTSystemSCProxy) - .change_sft_to_meta_esdt(&token_id, num_decimals) + .change_sft_to_meta_esdt(token_id, num_decimals) .prepare_async() .run() .await; @@ -502,7 +502,7 @@ impl SysFuncCallsInteract { .to(&self.wallet_address) .gas(100_000_000u64) .typed(UserBuiltinProxy) - .esdt_local_mint(&token_id, nonce, &amount) + .esdt_local_mint(token_id, nonce, amount) .prepare_async() .run() .await; @@ -517,7 +517,7 @@ impl SysFuncCallsInteract { .to(&self.wallet_address) .gas(100_000_000u64) .typed(UserBuiltinProxy) - .esdt_local_burn(&token_id, nonce, &amount) + .esdt_local_burn(token_id, nonce, amount) .prepare_async() .run() .await; @@ -532,7 +532,7 @@ impl SysFuncCallsInteract { .to(ESDTSystemSCAddress) .gas(100_000_000u64) .typed(ESDTSystemSCProxy) - .pause(&token_id) + .pause(token_id) .prepare_async() .run() .await; @@ -547,7 +547,7 @@ impl SysFuncCallsInteract { .to(ESDTSystemSCAddress) .gas(100_000_000u64) .typed(ESDTSystemSCProxy) - .unpause(&token_id) + .unpause(token_id) .prepare_async() .run() .await; @@ -562,7 +562,7 @@ impl SysFuncCallsInteract { .to(ESDTSystemSCAddress) .gas(100_000_000u64) .typed(ESDTSystemSCProxy) - .freeze(&token_id, &address) + .freeze(token_id, address) .prepare_async() .run() .await; @@ -577,7 +577,7 @@ impl SysFuncCallsInteract { .to(ESDTSystemSCAddress) .gas(100_000_000u64) .typed(ESDTSystemSCProxy) - .unfreeze(&token_id, &address) + .unfreeze(token_id, address) .prepare_async() .run() .await; @@ -592,7 +592,7 @@ impl SysFuncCallsInteract { .to(ESDTSystemSCAddress) .gas(100_000_000u64) .typed(ESDTSystemSCProxy) - .freeze_nft(&token_id, nonce, &address) + .freeze_nft(token_id, nonce, address) .prepare_async() .run() .await; @@ -607,7 +607,7 @@ impl SysFuncCallsInteract { .to(ESDTSystemSCAddress) .gas(100_000_000u64) .typed(ESDTSystemSCProxy) - .unfreeze_nft(&token_id, nonce, &address) + .unfreeze_nft(token_id, nonce, address) .prepare_async() .run() .await; @@ -622,7 +622,7 @@ impl SysFuncCallsInteract { .to(ESDTSystemSCAddress) .gas(100_000_000u64) .typed(ESDTSystemSCProxy) - .wipe(&token_id, &address) + .wipe(token_id, address) .prepare_async() .run() .await; @@ -637,7 +637,7 @@ impl SysFuncCallsInteract { .to(ESDTSystemSCAddress) .gas(100_000_000u64) .typed(ESDTSystemSCProxy) - .wipe_nft(&token_id, nonce, &address) + .wipe_nft(token_id, nonce, address) .prepare_async() .run() .await; @@ -660,11 +660,11 @@ impl SysFuncCallsInteract { .gas(100_000_000u64) .typed(UserBuiltinProxy) .esdt_nft_create( - &token_id, - &amount, - &name, - &royalties, - &hash, + token_id, + amount, + name, + royalties, + hash, &NftDummyAttributes { creation_epoch: 2104, cool_factor: 5, @@ -690,7 +690,7 @@ impl SysFuncCallsInteract { .to(ESDTSystemSCAddress) .gas(100_000_000u64) .typed(ESDTSystemSCProxy) - .unset_special_roles(&address, &token_id, roles.into_iter()) + .unset_special_roles(address, token_id, roles.into_iter()) .prepare_async() .run() .await; @@ -705,7 +705,7 @@ impl SysFuncCallsInteract { .to(ESDTSystemSCAddress) .gas(100_000_000u64) .typed(ESDTSystemSCProxy) - .transfer_ownership(&token_id, &new_owner) + .transfer_ownership(token_id, new_owner) .prepare_async() .run() .await; @@ -725,7 +725,7 @@ impl SysFuncCallsInteract { .to(ESDTSystemSCAddress) .gas(100_000_000u64) .typed(ESDTSystemSCProxy) - .transfer_nft_create_role(&token_id, &old_owner, &new_owner) + .transfer_nft_create_role(token_id, old_owner, new_owner) .prepare_async() .run() .await; @@ -741,7 +741,7 @@ impl SysFuncCallsInteract { .gas(100_000_000u64) .typed(ESDTSystemSCProxy) .control_changes( - &token_id, + token_id, &TokenPropertyArguments { can_freeze: Some(true), can_wipe: Some(true), From 7515c2f308ccf218e76ca0d302c4560bbd3c24cb Mon Sep 17 00:00:00 2001 From: BiancaIalangi Date: Tue, 10 Sep 2024 18:47:50 +0300 Subject: [PATCH 008/185] detect write in storage in view endpoint --- .../meta-lib/src/tools/wasm_extractor.rs | 123 ++++++++++-------- 1 file changed, 69 insertions(+), 54 deletions(-) diff --git a/framework/meta-lib/src/tools/wasm_extractor.rs b/framework/meta-lib/src/tools/wasm_extractor.rs index fa466440da..a348a40e30 100644 --- a/framework/meta-lib/src/tools/wasm_extractor.rs +++ b/framework/meta-lib/src/tools/wasm_extractor.rs @@ -1,5 +1,8 @@ use colored::Colorize; -use std::{collections::HashMap, fs}; +use std::{ + collections::{HashMap, HashSet}, + fs, +}; use wasmparser::{ BinaryReaderError, DataSectionReader, ExportSectionReader, FunctionBody, ImportSectionReader, Operator, Parser, Payload, @@ -55,19 +58,24 @@ fn populate_wasm_info( let mut ei_check = false; let mut memory_grow_flag = false; let mut has_panic = "none"; - let mut function_names: HashMap = HashMap::new(); - let mut read_functions: Vec = Vec::new(); + let mut call_graph: HashMap> = HashMap::new(); + let mut views_data: HashMap = HashMap::new(); + let mut write_functions: Vec = Vec::new(); let mut parser = Parser::new(0); for payload in parser.parse_all(&wasm_data) { match payload? { Payload::ImportSection(import_section) => { - imports = - extract_imports(import_section, extract_imports_enabled, &mut read_functions); - ei_check = is_ei_valid(imports.clone(), check_ei); + imports = extract_imports( + import_section, + extract_imports_enabled, + &mut call_graph, + &mut write_functions, + ); + ei_check = is_ei_valid(&imports, check_ei); }, Payload::DataSection(data_section) => { - allocator_trigger = is_fail_allocator_triggered(data_section.clone()); + allocator_trigger = is_fail_allocator_triggered(&data_section); if is_panic_with_message_triggered(data_section.clone()) { has_panic = WITH_MESSAGE; } else if is_panic_without_message_triggered(data_section) { @@ -75,10 +83,10 @@ fn populate_wasm_info( } }, Payload::CodeSectionEntry(code_section) => { - memory_grow_flag = is_mem_grow(code_section.clone()); + memory_grow_flag = is_mem_grow(&code_section); }, Payload::ExportSection(export_section) => { - parse_export_section(export_section, &mut function_names, view_endpoints.clone()); + views_data = parse_export_section(export_section, &view_endpoints); }, _ => (), } @@ -87,13 +95,16 @@ fn populate_wasm_info( parser = Parser::new(0); for payload in parser.parse_all(&wasm_data) { if let Payload::CodeSectionEntry(body) = payload? { - analyze_function_body(body, &mut read_functions); + create_call_graph(body, &mut call_graph); } } + let mut visited: HashSet = HashSet::new(); + for (index, _name) in &views_data { + mark_write(*index, &call_graph, &mut write_functions, &mut visited); + } - for (index, name) in function_names { - let i: usize = index.try_into().unwrap(); - if !read_functions[i] { + for (index, name) in views_data { + if write_functions.contains(&index) { println!( "{} {}", "Write storage operation in VIEW endpoint:" @@ -122,64 +133,68 @@ fn populate_wasm_info( fn parse_export_section( export_section: ExportSectionReader, - function_names: &mut HashMap, - view_endpoints: Vec, -) { + view_endpoints: &Vec, +) -> HashMap { + let mut views_data: HashMap = HashMap::new(); for export in export_section { let export = export.expect("Failed to read export section"); if let wasmparser::ExternalKind::Func = export.kind { if view_endpoints.contains(&export.name.to_string()) { - function_names.insert(export.index, export.name.to_string()); + views_data.insert(export.index.try_into().unwrap(), export.name.to_string()); + } + } + } + views_data +} + +fn mark_write( + func: usize, + call_graph: &HashMap>, + write_functions: &mut Vec, + visited: &mut HashSet, +) { + // Return early to prevent cycles. + if visited.contains(&func) { + return; + } + + visited.insert(func); + + if let Some(callees) = call_graph.get(&func) { + for &callee in callees { + if write_functions.contains(&callee) { + write_functions.push(func); + } else { + mark_write(callee, call_graph, write_functions, visited); + if write_functions.contains(&callee) { + write_functions.push(func); + } } } } } -fn analyze_function_body(body: FunctionBody, functions: &mut Vec) { - // Implement your function body analysis here - // For example, you can parse the locals and instructions - // let locals_reader = body - // .get_locals_reader() - // .expect("Failed to get locals reader"); +fn create_call_graph(body: FunctionBody, call_graph: &mut HashMap>) { let mut instructions_reader = body .get_operators_reader() .expect("Failed to get operators reader"); - // println!("Function has {} locals", locals_reader.get_count()); - - let mut value = true; + let mut call_functions = Vec::new(); while let Ok(op) = instructions_reader.read() { match op { Operator::Call { function_index } => { let function_usize: usize = function_index.try_into().unwrap(); - if function_usize >= functions.len() { - functions.push(true); - return; - } - - value &= functions[function_usize]; - - if !value { - functions.push(value); - return; - } - }, - Operator::I32Load { memarg } => { - if memarg.offset > 0 { - functions.push(false); - return; - } + call_functions.push(function_usize); }, _ => (), } } - functions.push(value); - // println!("===================="); + call_graph.insert(call_graph.len(), call_functions); } -fn is_fail_allocator_triggered(data_section: DataSectionReader) -> bool { - for data_fragment in data_section.into_iter().flatten() { +fn is_fail_allocator_triggered(data_section: &DataSectionReader) -> bool { + for data_fragment in data_section.clone().into_iter().flatten() { if data_fragment .data .windows(ERROR_FAIL_ALLOCATOR.len()) @@ -230,19 +245,19 @@ fn is_panic_without_message_triggered(data_section: DataSectionReader) -> bool { pub fn extract_imports( import_section: ImportSectionReader, import_extraction_enabled: bool, - write_or_read_functions: &mut Vec, + call_graph: &mut HashMap>, + write_functions: &mut Vec, ) -> Vec { if !import_extraction_enabled { return Vec::new(); } let mut import_names = Vec::new(); - for import in import_section.into_iter().flatten() { + for (index, import) in import_section.into_iter().flatten().enumerate() { import_names.push(import.name.to_string()); + call_graph.insert(index, vec![]); if WRITE_OP.contains(&import.name) { - write_or_read_functions.push(false); - } else { - write_or_read_functions.push(true); + write_functions.push(index); } } @@ -251,7 +266,7 @@ pub fn extract_imports( import_names } -fn is_ei_valid(imports: Vec, check_ei: &Option) -> bool { +fn is_ei_valid(imports: &Vec, check_ei: &Option) -> bool { if let Some(ei) = check_ei { let mut num_errors = 0; for import in imports { @@ -268,7 +283,7 @@ fn is_ei_valid(imports: Vec, check_ei: &Option) -> bool { false } -fn is_mem_grow(code_section: FunctionBody) -> bool { +fn is_mem_grow(code_section: &FunctionBody) -> bool { let mut code = code_section.get_binary_reader(); while code.bytes_remaining() > 0 { if code.read_u8().unwrap() == MEMORY_GROW_OPCODE { From e166376c5d1bf468e69c36b49261fe4f26173525 Mon Sep 17 00:00:00 2001 From: BiancaIalangi Date: Thu, 12 Sep 2024 18:39:05 +0300 Subject: [PATCH 009/185] detect write op in view storage - cleanup --- .../mappers/linked-list-repeat/file.txt | 2150 ----------------- .../src/linked_list_repeat.rs | 6 +- contracts/examples/adder/src/adder.rs | 2 +- .../src/parse/attributes/endpoint_attr.rs | 2 +- 4 files changed, 4 insertions(+), 2156 deletions(-) delete mode 100644 contracts/benchmarks/mappers/linked-list-repeat/file.txt diff --git a/contracts/benchmarks/mappers/linked-list-repeat/file.txt b/contracts/benchmarks/mappers/linked-list-repeat/file.txt deleted file mode 100644 index 799122fd71..0000000000 --- a/contracts/benchmarks/mappers/linked-list-repeat/file.txt +++ /dev/null @@ -1,2150 +0,0 @@ - /home/bibi/Desktop/mx-sdk-rs/contracts/benchmarks/mappers/linked-list-repeat - -Found 1 contract crates. - -(1/1) -In /home/bibi/Desktop/mx-sdk-rs/contracts/benchmarks/mappers/linked-list-repeat/meta -Calling `cargo run build` -Using workspace target directory: /home/bibi/Desktop/mx-sdk-rs/target ... -Building linked-list-repeat.wasm in /home/bibi/Desktop/mx-sdk-rs/contracts/benchmarks/mappers/linked-list-repeat/wasm ... -RUSTFLAGS="-C link-arg=-s -C link-arg=-zstack-size=131072" cargo build --target=wasm32-unknown-unknown --release --target-dir /home/bibi/Desktop/mx-sdk-rs/target -Copying /home/bibi/Desktop/mx-sdk-rs/target/wasm32-unknown-unknown/release/linked_list_repeat_wasm.wasm to ../output/linked-list-repeat.wasm ... -Calling wasm-opt on ../output/linked-list-repeat.wasm ... -Extracting imports to ../output/linked-list-repeat.imports.json ... -FailAllocator used while memory allocation is accessible in code. Contract may fail unexpectedly when memory allocation is attempted -Instruction: Call { function_index: 24 } -Call instruction: calls function index 24 -Instruction: I32Const { value: 131268 } -Instruction: I32Const { value: 131268 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } -Instruction: I32Const { value: 1 } -Instruction: I32Sub -Instruction: LocalTee { local_index: 0 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } -Instruction: LocalGet { local_index: 0 } -Instruction: End -Instruction: Call { function_index: 2 } -Call instruction: calls function index 2 -Instruction: LocalTee { local_index: 1 } -Instruction: LocalGet { local_index: 0 } -Instruction: Call { function_index: 3 } -Call instruction: calls function index 3 -Instruction: Drop -Instruction: LocalGet { local_index: 1 } -Instruction: End -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 1 } -Instruction: Call { function_index: 4 } -Call instruction: calls function index 4 -Instruction: I32Const { value: 0 } -Instruction: I32GtS -Instruction: End -Instruction: GlobalGet { global_index: 0 } -Instruction: I32Const { value: 96 } -Instruction: I32Sub -Instruction: LocalTee { local_index: 2 } -Instruction: GlobalSet { global_index: 0 } -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 1 } -Instruction: I64Load { memarg: MemArg { align: 3, max_align: 3, offset: 0, memory: 0 } } -Instruction: I64Eqz -Instruction: If { blockty: Type(I64) } -Instruction: I64Const { value: 0 } -Instruction: Else -Instruction: LocalGet { local_index: 2 } -Instruction: I32Const { value: 8 } -Instruction: I32Add -Instruction: LocalGet { local_index: 1 } -Instruction: I32Const { value: 8 } -Instruction: I32Add -Instruction: Call { function_index: 28 } -Call instruction: calls function index 28 -Instruction: LocalGet { local_index: 1 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 16, memory: 0 } } -Instruction: Call { function_index: 25 } -Call instruction: calls function index 25 -Instruction: LocalSet { local_index: 2 } -Instruction: LocalGet { local_index: 1 } -Instruction: I64Load { memarg: MemArg { align: 3, max_align: 3, offset: 0, memory: 0 } } -Instruction: LocalSet { local_index: 5 } -Instruction: LocalGet { local_index: 1 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 20, memory: 0 } } -Instruction: Call { function_index: 23 } -Call instruction: calls function index 23 -Instruction: LocalSet { local_index: 3 } -Instruction: LocalGet { local_index: 1 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 24, memory: 0 } } -Instruction: Call { function_index: 25 } -Call instruction: calls function index 25 -Instruction: LocalSet { local_index: 4 } -Instruction: LocalGet { local_index: 1 } -Instruction: I64Load { memarg: MemArg { align: 3, max_align: 3, offset: 8, memory: 0 } } -Instruction: LocalSet { local_index: 6 } -Instruction: LocalGet { local_index: 1 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 28, memory: 0 } } -Instruction: Call { function_index: 23 } -Call instruction: calls function index 23 -Instruction: LocalSet { local_index: 1 } -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 4 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 24, memory: 0 } } -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 3 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 20, memory: 0 } } -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 5 } -Instruction: I64Store { memarg: MemArg { align: 3, max_align: 3, offset: 0, memory: 0 } } -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 2 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 16, memory: 0 } } -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 1 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 28, memory: 0 } } -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 6 } -Instruction: I64Store { memarg: MemArg { align: 3, max_align: 3, offset: 8, memory: 0 } } -Instruction: End -Instruction: GlobalGet { global_index: 0 } -Instruction: I32Const { value: 48 } -Instruction: I32Sub -Instruction: LocalTee { local_index: 3 } -Instruction: GlobalSet { global_index: 0 } -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 1 } -Instruction: LocalGet { local_index: 2 } -Instruction: Call { function_index: 66 } -Call instruction: calls function index 66 -Instruction: GlobalGet { global_index: 0 } -Instruction: I32Const { value: 32 } -Instruction: I32Sub -Instruction: LocalTee { local_index: 2 } -Instruction: GlobalSet { global_index: 0 } -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 1 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } -Instruction: If { blockty: Type(I32) } -Instruction: LocalGet { local_index: 1 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 4, memory: 0 } } -Instruction: Call { function_index: 25 } -Call instruction: calls function index 25 -Instruction: LocalSet { local_index: 3 } -Instruction: LocalGet { local_index: 1 } -Instruction: I32Const { value: 8 } -Instruction: I32Add -Instruction: LocalTee { local_index: 4 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } -Instruction: LocalSet { local_index: 5 } -Instruction: LocalGet { local_index: 1 } -Instruction: I32Const { value: 16 } -Instruction: I32Add -Instruction: LocalTee { local_index: 6 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } -Instruction: LocalSet { local_index: 7 } -Instruction: LocalGet { local_index: 2 } -Instruction: I32Const { value: 12 } -Instruction: I32Add -Instruction: LocalGet { local_index: 1 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 20, memory: 0 } } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } -Instruction: LocalGet { local_index: 1 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 12, memory: 0 } } -Instruction: LocalTee { local_index: 8 } -Instruction: Call { function_index: 31 } -Call instruction: calls function index 31 -Instruction: GlobalGet { global_index: 0 } -Instruction: I32Const { value: 16 } -Instruction: I32Sub -Instruction: LocalTee { local_index: 3 } -Instruction: GlobalSet { global_index: 0 } -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 1 } -Instruction: LocalGet { local_index: 2 } -Instruction: Call { function_index: 66 } -Call instruction: calls function index 66 -Instruction: LocalGet { local_index: 0 } -Instruction: Call { function_index: 33 } -Call instruction: calls function index 33 -Instruction: GlobalGet { global_index: 0 } -Instruction: I32Const { value: 16 } -Instruction: I32Sub -Instruction: LocalTee { local_index: 1 } -Instruction: GlobalSet { global_index: 0 } -Instruction: LocalGet { local_index: 1 } -Instruction: I32Const { value: 0 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 12, memory: 0 } } -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 1 } -Instruction: I32Const { value: 12 } -Instruction: I32Add -Instruction: I32Const { value: 4 } -Instruction: Call { function_index: 47 } -Call instruction: calls function index 47 -Instruction: LocalGet { local_index: 0 } -Instruction: Call { function_index: 24 } -Call instruction: calls function index 24 -Instruction: LocalTee { local_index: 0 } -Instruction: Call { function_index: 17 } -Call instruction: calls function index 17 -Instruction: Drop -Instruction: LocalGet { local_index: 0 } -Instruction: End -Instruction: LocalGet { local_index: 0 } -Instruction: Call { function_index: 36 } -Call instruction: calls function index 36 -Instruction: GlobalGet { global_index: 0 } -Instruction: I32Const { value: 16 } -Instruction: I32Sub -Instruction: LocalTee { local_index: 1 } -Instruction: GlobalSet { global_index: 0 } -Instruction: LocalGet { local_index: 0 } -Instruction: Call { function_index: 49 } -Call instruction: calls function index 49 -Instruction: Call { function_index: 24 } -Call instruction: calls function index 24 -Instruction: LocalTee { local_index: 2 } -Instruction: LocalGet { local_index: 0 } -Instruction: Call { function_index: 5 } -Call instruction: calls function index 5 -Instruction: Drop -Instruction: LocalGet { local_index: 2 } -Instruction: LocalGet { local_index: 1 } -Instruction: Call { function_index: 38 } -Call instruction: calls function index 38 -Instruction: GlobalGet { global_index: 0 } -Instruction: I32Const { value: 16 } -Instruction: I32Sub -Instruction: LocalTee { local_index: 2 } -Instruction: GlobalSet { global_index: 0 } -Instruction: LocalGet { local_index: 2 } -Instruction: LocalGet { local_index: 0 } -Instruction: Call { function_index: 7 } -Call instruction: calls function index 7 -Instruction: LocalTee { local_index: 3 } -Instruction: I32Const { value: 24 } -Instruction: I32Shl -Instruction: LocalGet { local_index: 3 } -Instruction: I32Const { value: 65280 } -Instruction: I32And -Instruction: I32Const { value: 8 } -Instruction: I32Shl -Instruction: I32Or -Instruction: LocalGet { local_index: 3 } -Instruction: I32Const { value: 8 } -Instruction: I32ShrU -Instruction: I32Const { value: 65280 } -Instruction: I32And -Instruction: LocalGet { local_index: 3 } -Instruction: I32Const { value: 24 } -Instruction: I32ShrU -Instruction: I32Or -Instruction: I32Or -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 12, memory: 0 } } -Instruction: LocalGet { local_index: 1 } -Instruction: LocalGet { local_index: 2 } -Instruction: I32Const { value: 12 } -Instruction: I32Add -Instruction: I32Const { value: 4 } -Instruction: Call { function_index: 73 } -Call instruction: calls function index 73 -Instruction: LocalGet { local_index: 1 } -Instruction: Call { function_index: 24 } -Call instruction: calls function index 24 -Instruction: LocalTee { local_index: 1 } -Instruction: Call { function_index: 6 } -Call instruction: calls function index 6 -Instruction: Drop -Instruction: LocalGet { local_index: 1 } -Instruction: Call { function_index: 7 } -Call instruction: calls function index 7 -Instruction: LocalSet { local_index: 2 } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 0 } -Instruction: I32Store8 { memarg: MemArg { align: 0, max_align: 0, offset: 16, memory: 0 } } -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 2 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 12, memory: 0 } } -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 1 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 8, memory: 0 } } -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 2 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 4, memory: 0 } } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 0 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } -Instruction: End -Instruction: LocalGet { local_index: 0 } -Instruction: Call { function_index: 24 } -Call instruction: calls function index 24 -Instruction: LocalTee { local_index: 0 } -Instruction: Call { function_index: 8 } -Call instruction: calls function index 8 -Instruction: Drop -Instruction: LocalGet { local_index: 0 } -Instruction: End -Instruction: I32Const { value: 131086 } -Instruction: I32Const { value: 23 } -Instruction: Call { function_index: 42 } -Call instruction: calls function index 42 -Instruction: Call { function_index: 24 } -Call instruction: calls function index 24 -Instruction: LocalTee { local_index: 2 } -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 1 } -Instruction: Call { function_index: 16 } -Call instruction: calls function index 16 -Instruction: Drop -Instruction: LocalGet { local_index: 2 } -Instruction: End -Instruction: GlobalGet { global_index: 0 } -Instruction: I32Const { value: 32 } -Instruction: I32Sub -Instruction: LocalTee { local_index: 2 } -Instruction: GlobalSet { global_index: 0 } -Instruction: LocalGet { local_index: 1 } -Instruction: Call { function_index: 40 } -Call instruction: calls function index 40 -Instruction: LocalTee { local_index: 3 } -Instruction: Call { function_index: 7 } -Call instruction: calls function index 7 -Instruction: LocalSet { local_index: 1 } -Instruction: LocalGet { local_index: 2 } -Instruction: I32Const { value: 0 } -Instruction: I32Store8 { memarg: MemArg { align: 0, max_align: 0, offset: 28, memory: 0 } } -Instruction: LocalGet { local_index: 2 } -Instruction: LocalGet { local_index: 1 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 24, memory: 0 } } -Instruction: LocalGet { local_index: 2 } -Instruction: LocalGet { local_index: 3 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 20, memory: 0 } } -Instruction: LocalGet { local_index: 2 } -Instruction: LocalGet { local_index: 1 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 16, memory: 0 } } -Instruction: LocalGet { local_index: 2 } -Instruction: I32Const { value: 0 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 12, memory: 0 } } -Instruction: LocalGet { local_index: 2 } -Instruction: I32Const { value: 12 } -Instruction: I32Add -Instruction: LocalTee { local_index: 3 } -Instruction: Call { function_index: 33 } -Call instruction: calls function index 33 -Instruction: LocalSet { local_index: 1 } -Instruction: LocalGet { local_index: 3 } -Instruction: Call { function_index: 44 } -Call instruction: calls function index 44 -Instruction: GlobalGet { global_index: 0 } -Instruction: I32Const { value: 16 } -Instruction: I32Sub -Instruction: LocalTee { local_index: 2 } -Instruction: GlobalSet { global_index: 0 } -Instruction: LocalGet { local_index: 2 } -Instruction: I64Const { value: 0 } -Instruction: I64Store { memarg: MemArg { align: 3, max_align: 3, offset: 8, memory: 0 } } -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 2 } -Instruction: I32Const { value: 8 } -Instruction: I32Add -Instruction: I32Const { value: 8 } -Instruction: Call { function_index: 47 } -Call instruction: calls function index 47 -Instruction: I32Const { value: 0 } -Instruction: Call { function_index: 11 } -Call instruction: calls function index 11 -Instruction: LocalTee { local_index: 0 } -Instruction: I64Const { value: 4294967296 } -Instruction: I64GeU -Instruction: If { blockty: Empty } -Instruction: I32Const { value: 131189 } -Instruction: I32Const { value: 11 } -Instruction: I32Const { value: 131072 } -Instruction: I32Const { value: 14 } -Instruction: Call { function_index: 41 } -Call instruction: calls function index 41 -Instruction: Unreachable -Instruction: End -Instruction: LocalGet { local_index: 0 } -Instruction: I32WrapI64 -Instruction: End -Instruction: Call { function_index: 12 } -Call instruction: calls function index 12 -Instruction: LocalGet { local_index: 0 } -Instruction: I32Eq -Instruction: If { blockty: Empty } -Instruction: Return -Instruction: End -Instruction: I32Const { value: 131112 } -Instruction: I32Const { value: 25 } -Instruction: Call { function_index: 13 } -Call instruction: calls function index 13 -Instruction: Unreachable -Instruction: End -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 8 } -Instruction: I32Add -Instruction: LocalGet { local_index: 0 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } -Instruction: LocalGet { local_index: 1 } -Instruction: LocalGet { local_index: 2 } -Instruction: Call { function_index: 53 } -Call instruction: calls function index 53 -Instruction: LocalGet { local_index: 1 } -Instruction: LocalGet { local_index: 2 } -Instruction: LocalGet { local_index: 3 } -Instruction: Call { function_index: 2 } -Call instruction: calls function index 2 -Instruction: LocalTee { local_index: 1 } -Instruction: Call { function_index: 18 } -Call instruction: calls function index 18 -Instruction: LocalSet { local_index: 2 } -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 1 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 4, memory: 0 } } -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 2 } -Instruction: I32Eqz -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } -Instruction: End -Instruction: GlobalGet { global_index: 0 } -Instruction: I32Const { value: 16 } -Instruction: I32Sub -Instruction: LocalTee { local_index: 1 } -Instruction: GlobalSet { global_index: 0 } -Instruction: LocalGet { local_index: 1 } -Instruction: I32Const { value: 0 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 12, memory: 0 } } -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 1 } -Instruction: I32Const { value: 12 } -Instruction: I32Add -Instruction: I32Const { value: 4 } -Instruction: Call { function_index: 74 } -Call instruction: calls function index 74 -Instruction: I32Const { value: 131162 } -Instruction: I32Const { value: 22 } -Instruction: Call { function_index: 42 } -Call instruction: calls function index 42 -Instruction: LocalTee { local_index: 2 } -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 1 } -Instruction: Call { function_index: 9 } -Call instruction: calls function index 9 -Instruction: Drop -Instruction: LocalGet { local_index: 2 } -Instruction: Call { function_index: 10 } -Call instruction: calls function index 10 -Instruction: Unreachable -Instruction: End -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 1 } -Instruction: Call { function_index: 14 } -Call instruction: calls function index 14 -Instruction: I32Eqz -Instruction: End -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 1 } -Instruction: LocalGet { local_index: 3 } -Instruction: LocalGet { local_index: 2 } -Instruction: Call { function_index: 15 } -Call instruction: calls function index 15 -Instruction: I32Const { value: 0 } -Instruction: I32Ne -Instruction: End -Instruction: Block { blockty: Empty } -Instruction: Block { blockty: Empty } -Instruction: Block { blockty: Type(I32) } -Instruction: Block { blockty: Empty } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Load8U { memarg: MemArg { align: 0, max_align: 0, offset: 8, memory: 0 } } -Instruction: I32Eqz -Instruction: If { blockty: Empty } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } -Instruction: LocalTee { local_index: 4 } -Instruction: Call { function_index: 7 } -Call instruction: calls function index 7 -Instruction: LocalTee { local_index: 5 } -Instruction: I32Const { value: 10000 } -Instruction: I32GtU -Instruction: BrIf { relative_depth: 1 } -Instruction: I32Const { value: 141276 } -Instruction: I32Load8U { memarg: MemArg { align: 0, max_align: 0, offset: 0, memory: 0 } } -Instruction: BrIf { relative_depth: 1 } -Instruction: I32Const { value: 141272 } -Instruction: LocalGet { local_index: 5 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } -Instruction: I32Const { value: 141276 } -Instruction: I32Const { value: 1 } -Instruction: I32Store8 { memarg: MemArg { align: 0, max_align: 0, offset: 0, memory: 0 } } -Instruction: LocalGet { local_index: 4 } -Instruction: I32Const { value: 0 } -Instruction: I32Const { value: 131272 } -Instruction: LocalGet { local_index: 5 } -Instruction: Call { function_index: 52 } -Call instruction: calls function index 52 -Instruction: Drop -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 1 } -Instruction: I32Store8 { memarg: MemArg { align: 0, max_align: 0, offset: 8, memory: 0 } } -Instruction: End -Instruction: I32Const { value: 1 } -Instruction: LocalGet { local_index: 1 } -Instruction: LocalGet { local_index: 3 } -Instruction: I32Add -Instruction: LocalTee { local_index: 0 } -Instruction: I32Const { value: 141272 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } -Instruction: I32GtU -Instruction: BrIf { relative_depth: 1 } -Instruction: Drop -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 1 } -Instruction: I32LtU -Instruction: BrIf { relative_depth: 2 } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 10000 } -Instruction: I32GtU -Instruction: BrIf { relative_depth: 3 } -Instruction: LocalGet { local_index: 2 } -Instruction: LocalGet { local_index: 1 } -Instruction: I32Const { value: 131272 } -Instruction: I32Add -Instruction: LocalGet { local_index: 3 } -Instruction: Call { function_index: 89 } -Call instruction: calls function index 89 -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: -25 } -Instruction: Call { function_index: 6 } -Call instruction: calls function index 6 -Instruction: Drop -Instruction: I32Const { value: -25 } -Instruction: Call { function_index: 7 } -Call instruction: calls function index 7 -Instruction: End -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 1 } -Instruction: Call { function_index: 56 } -Call instruction: calls function index 56 -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 1 } -Instruction: I32Const { value: 0 } -Instruction: Call { function_index: 42 } -Call instruction: calls function index 42 -Instruction: Call { function_index: 19 } -Call instruction: calls function index 19 -Instruction: LocalGet { local_index: 0 } -Instruction: Call { function_index: 58 } -Call instruction: calls function index 58 -Instruction: LocalGet { local_index: 0 } -Instruction: Call { function_index: 25 } -Call instruction: calls function index 25 -Instruction: LocalTee { local_index: 0 } -Instruction: I32Const { value: 131157 } -Instruction: I32Const { value: 5 } -Instruction: Call { function_index: 9 } -Call instruction: calls function index 9 -Instruction: Drop -Instruction: LocalGet { local_index: 0 } -Instruction: End -Instruction: I32Const { value: 131224 } -Instruction: I32Const { value: 0 } -Instruction: Call { function_index: 42 } -Call instruction: calls function index 42 -Instruction: End -Instruction: GlobalGet { global_index: 0 } -Instruction: I32Const { value: 16 } -Instruction: I32Sub -Instruction: LocalTee { local_index: 2 } -Instruction: GlobalSet { global_index: 0 } -Instruction: LocalGet { local_index: 2 } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 24 } -Instruction: I32Shl -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 65280 } -Instruction: I32And -Instruction: I32Const { value: 8 } -Instruction: I32Shl -Instruction: I32Or -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 8 } -Instruction: I32ShrU -Instruction: I32Const { value: 65280 } -Instruction: I32And -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 24 } -Instruction: I32ShrU -Instruction: I32Or -Instruction: I32Or -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 12, memory: 0 } } -Instruction: LocalGet { local_index: 1 } -Instruction: LocalGet { local_index: 2 } -Instruction: I32Const { value: 12 } -Instruction: I32Add -Instruction: I32Const { value: 4 } -Instruction: Call { function_index: 73 } -Call instruction: calls function index 73 -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 1 } -Instruction: Call { function_index: 19 } -Call instruction: calls function index 19 -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 1 } -Instruction: Call { function_index: 63 } -Call instruction: calls function index 63 -Instruction: GlobalGet { global_index: 0 } -Instruction: I32Const { value: 16 } -Instruction: I32Sub -Instruction: LocalTee { local_index: 2 } -Instruction: GlobalSet { global_index: 0 } -Instruction: LocalGet { local_index: 0 } -Instruction: Call { function_index: 25 } -Call instruction: calls function index 25 -Instruction: LocalTee { local_index: 0 } -Instruction: I32Const { value: 131152 } -Instruction: I32Const { value: 5 } -Instruction: Call { function_index: 9 } -Call instruction: calls function index 9 -Instruction: Drop -Instruction: LocalGet { local_index: 2 } -Instruction: LocalGet { local_index: 1 } -Instruction: I32Const { value: 24 } -Instruction: I32Shl -Instruction: LocalGet { local_index: 1 } -Instruction: I32Const { value: 65280 } -Instruction: I32And -Instruction: I32Const { value: 8 } -Instruction: I32Shl -Instruction: I32Or -Instruction: LocalGet { local_index: 1 } -Instruction: I32Const { value: 8 } -Instruction: I32ShrU -Instruction: I32Const { value: 65280 } -Instruction: I32And -Instruction: LocalGet { local_index: 1 } -Instruction: I32Const { value: 24 } -Instruction: I32ShrU -Instruction: I32Or -Instruction: I32Or -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 12, memory: 0 } } -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 2 } -Instruction: I32Const { value: 12 } -Instruction: I32Add -Instruction: I32Const { value: 4 } -Instruction: Call { function_index: 9 } -Call instruction: calls function index 9 -Instruction: Drop -Instruction: LocalGet { local_index: 2 } -Instruction: I32Const { value: 16 } -Instruction: I32Add -Instruction: GlobalSet { global_index: 0 } -Instruction: LocalGet { local_index: 0 } -Instruction: End -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 1 } -Instruction: Call { function_index: 63 } -Call instruction: calls function index 63 -Instruction: Call { function_index: 59 } -Call instruction: calls function index 59 -Instruction: LocalSet { local_index: 0 } -Instruction: LocalGet { local_index: 2 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 16, memory: 0 } } -Instruction: LocalGet { local_index: 0 } -Instruction: Call { function_index: 38 } -Call instruction: calls function index 38 -Instruction: LocalGet { local_index: 2 } -Instruction: I64Load { memarg: MemArg { align: 3, max_align: 3, offset: 0, memory: 0 } } -Instruction: LocalGet { local_index: 0 } -Instruction: Call { function_index: 65 } -Call instruction: calls function index 65 -Instruction: GlobalGet { global_index: 0 } -Instruction: I32Const { value: 16 } -Instruction: I32Sub -Instruction: LocalTee { local_index: 2 } -Instruction: GlobalSet { global_index: 0 } -Instruction: LocalGet { local_index: 2 } -Instruction: LocalGet { local_index: 0 } -Instruction: I64Const { value: 56 } -Instruction: I64Shl -Instruction: LocalGet { local_index: 0 } -Instruction: I64Const { value: 65280 } -Instruction: I64And -Instruction: I64Const { value: 40 } -Instruction: I64Shl -Instruction: I64Or -Instruction: LocalGet { local_index: 0 } -Instruction: I64Const { value: 16711680 } -Instruction: I64And -Instruction: I64Const { value: 24 } -Instruction: I64Shl -Instruction: LocalGet { local_index: 0 } -Instruction: I64Const { value: 4278190080 } -Instruction: I64And -Instruction: I64Const { value: 8 } -Instruction: I64Shl -Instruction: I64Or -Instruction: I64Or -Instruction: LocalGet { local_index: 0 } -Instruction: I64Const { value: 8 } -Instruction: I64ShrU -Instruction: I64Const { value: 4278190080 } -Instruction: I64And -Instruction: LocalGet { local_index: 0 } -Instruction: I64Const { value: 24 } -Instruction: I64ShrU -Instruction: I64Const { value: 16711680 } -Instruction: I64And -Instruction: I64Or -Instruction: LocalGet { local_index: 0 } -Instruction: I64Const { value: 40 } -Instruction: I64ShrU -Instruction: I64Const { value: 65280 } -Instruction: I64And -Instruction: LocalGet { local_index: 0 } -Instruction: I64Const { value: 56 } -Instruction: I64ShrU -Instruction: I64Or -Instruction: I64Or -Instruction: I64Or -Instruction: I64Store { memarg: MemArg { align: 3, max_align: 3, offset: 8, memory: 0 } } -Instruction: LocalGet { local_index: 1 } -Instruction: LocalGet { local_index: 2 } -Instruction: I32Const { value: 8 } -Instruction: I32Add -Instruction: I32Const { value: 8 } -Instruction: Call { function_index: 73 } -Call instruction: calls function index 73 -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 1 } -Instruction: Call { function_index: 63 } -Call instruction: calls function index 63 -Instruction: Call { function_index: 54 } -Call instruction: calls function index 54 -Instruction: I32Eqz -Instruction: End -Instruction: GlobalGet { global_index: 0 } -Instruction: I32Const { value: 32 } -Instruction: I32Sub -Instruction: LocalTee { local_index: 3 } -Instruction: GlobalSet { global_index: 0 } -Instruction: LocalGet { local_index: 3 } -Instruction: I32Const { value: 12 } -Instruction: I32Add -Instruction: LocalTee { local_index: 4 } -Instruction: LocalGet { local_index: 1 } -Instruction: LocalGet { local_index: 2 } -Instruction: Call { function_index: 63 } -Call instruction: calls function index 63 -Instruction: Call { function_index: 39 } -Call instruction: calls function index 39 -Instruction: LocalGet { local_index: 4 } -Instruction: Call { function_index: 36 } -Call instruction: calls function index 36 -Instruction: LocalSet { local_index: 1 } -Instruction: LocalGet { local_index: 4 } -Instruction: Call { function_index: 49 } -Call instruction: calls function index 49 -Instruction: LocalSet { local_index: 2 } -Instruction: LocalGet { local_index: 3 } -Instruction: I32Const { value: 12 } -Instruction: I32Add -Instruction: Call { function_index: 49 } -Call instruction: calls function index 49 -Instruction: LocalSet { local_index: 4 } -Instruction: LocalGet { local_index: 3 } -Instruction: I32Const { value: 12 } -Instruction: I32Add -Instruction: Call { function_index: 49 } -Call instruction: calls function index 49 -Instruction: LocalSet { local_index: 5 } -Instruction: LocalGet { local_index: 3 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 16, memory: 0 } } -Instruction: LocalGet { local_index: 3 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 12, memory: 0 } } -Instruction: I32Eq -Instruction: If { blockty: Empty } -Instruction: LocalGet { local_index: 3 } -Instruction: I32Load8U { memarg: MemArg { align: 0, max_align: 0, offset: 28, memory: 0 } } -Instruction: If { blockty: Empty } -Instruction: I32Const { value: 141272 } -Instruction: I32Const { value: 0 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } -Instruction: I32Const { value: 141276 } -Instruction: I32Const { value: 0 } -Instruction: I32Store8 { memarg: MemArg { align: 0, max_align: 0, offset: 0, memory: 0 } } -Instruction: End -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 5 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 12, memory: 0 } } -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 4 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 8, memory: 0 } } -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 2 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 4, memory: 0 } } -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 1 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } -Instruction: LocalGet { local_index: 3 } -Instruction: I32Const { value: 32 } -Instruction: I32Add -Instruction: GlobalSet { global_index: 0 } -Instruction: Return -Instruction: End -Instruction: I32Const { value: 131072 } -Instruction: I32Const { value: 14 } -Instruction: Call { function_index: 50 } -Call instruction: calls function index 50 -Instruction: Unreachable -Instruction: End -Instruction: GlobalGet { global_index: 0 } -Instruction: I32Const { value: 32 } -Instruction: I32Sub -Instruction: LocalTee { local_index: 3 } -Instruction: GlobalSet { global_index: 0 } -Instruction: LocalGet { local_index: 3 } -Instruction: I32Const { value: 12 } -Instruction: I32Add -Instruction: LocalTee { local_index: 4 } -Instruction: LocalGet { local_index: 1 } -Instruction: LocalGet { local_index: 2 } -Instruction: Call { function_index: 63 } -Call instruction: calls function index 63 -Instruction: Call { function_index: 39 } -Call instruction: calls function index 39 -Instruction: LocalGet { local_index: 4 } -Instruction: Call { function_index: 36 } -Call instruction: calls function index 36 -Instruction: LocalSet { local_index: 1 } -Instruction: LocalGet { local_index: 4 } -Instruction: Call { function_index: 72 } -Call instruction: calls function index 72 -Instruction: GlobalGet { global_index: 0 } -Instruction: I32Const { value: 48 } -Instruction: I32Sub -Instruction: LocalTee { local_index: 2 } -Instruction: GlobalSet { global_index: 0 } -Instruction: LocalGet { local_index: 2 } -Instruction: I32Const { value: 32 } -Instruction: I32Add -Instruction: LocalGet { local_index: 1 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } -Instruction: LocalTee { local_index: 3 } -Instruction: Call { function_index: 70 } -Call instruction: calls function index 70 -Instruction: GlobalGet { global_index: 0 } -Instruction: I32Const { value: 32 } -Instruction: I32Sub -Instruction: LocalTee { local_index: 2 } -Instruction: GlobalSet { global_index: 0 } -Instruction: Block { blockty: Empty } -Instruction: Block { blockty: Empty } -Instruction: LocalGet { local_index: 1 } -Instruction: Call { function_index: 58 } -Call instruction: calls function index 58 -Instruction: LocalTee { local_index: 1 } -Instruction: Call { function_index: 54 } -Call instruction: calls function index 54 -Instruction: I32Eqz -Instruction: If { blockty: Empty } -Instruction: I32Const { value: 0 } -Instruction: LocalSet { local_index: 1 } -Instruction: Br { relative_depth: 1 } -Instruction: End -Instruction: LocalGet { local_index: 2 } -Instruction: I32Const { value: 12 } -Instruction: I32Add -Instruction: LocalTee { local_index: 3 } -Instruction: LocalGet { local_index: 1 } -Instruction: Call { function_index: 39 } -Call instruction: calls function index 39 -Instruction: LocalGet { local_index: 3 } -Instruction: Call { function_index: 49 } -Call instruction: calls function index 49 -Instruction: LocalSet { local_index: 1 } -Instruction: LocalGet { local_index: 2 } -Instruction: I32Const { value: 12 } -Instruction: I32Add -Instruction: Call { function_index: 49 } -Call instruction: calls function index 49 -Instruction: LocalSet { local_index: 3 } -Instruction: LocalGet { local_index: 2 } -Instruction: I32Const { value: 12 } -Instruction: I32Add -Instruction: Call { function_index: 49 } -Call instruction: calls function index 49 -Instruction: LocalSet { local_index: 4 } -Instruction: LocalGet { local_index: 2 } -Instruction: I32Const { value: 12 } -Instruction: I32Add -Instruction: Call { function_index: 49 } -Call instruction: calls function index 49 -Instruction: LocalSet { local_index: 5 } -Instruction: LocalGet { local_index: 2 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 16, memory: 0 } } -Instruction: LocalGet { local_index: 2 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 12, memory: 0 } } -Instruction: I32Ne -Instruction: BrIf { relative_depth: 1 } -Instruction: LocalGet { local_index: 2 } -Instruction: I32Load8U { memarg: MemArg { align: 0, max_align: 0, offset: 28, memory: 0 } } -Instruction: I32Eqz -Instruction: BrIf { relative_depth: 0 } -Instruction: I32Const { value: 141272 } -Instruction: I32Const { value: 0 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } -Instruction: I32Const { value: 141276 } -Instruction: I32Const { value: 0 } -Instruction: I32Store8 { memarg: MemArg { align: 0, max_align: 0, offset: 0, memory: 0 } } -Instruction: End -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 5 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 12, memory: 0 } } -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 4 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 8, memory: 0 } } -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 3 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 4, memory: 0 } } -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 1 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } -Instruction: LocalGet { local_index: 2 } -Instruction: I32Const { value: 32 } -Instruction: I32Add -Instruction: GlobalSet { global_index: 0 } -Instruction: Return -Instruction: End -Instruction: I32Const { value: 131072 } -Instruction: I32Const { value: 14 } -Instruction: Call { function_index: 50 } -Call instruction: calls function index 50 -Instruction: Unreachable -Instruction: End -Instruction: GlobalGet { global_index: 0 } -Instruction: I32Const { value: 80 } -Instruction: I32Sub -Instruction: LocalTee { local_index: 2 } -Instruction: GlobalSet { global_index: 0 } -Instruction: LocalGet { local_index: 2 } -Instruction: I32Const { value: -64 } -Instruction: I32Sub -Instruction: LocalGet { local_index: 1 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } -Instruction: LocalTee { local_index: 3 } -Instruction: Call { function_index: 70 } -Call instruction: calls function index 70 -Instruction: LocalGet { local_index: 2 } -Instruction: I32Const { value: 8 } -Instruction: I32Add -Instruction: LocalTee { local_index: 4 } -Instruction: LocalGet { local_index: 3 } -Instruction: LocalGet { local_index: 2 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 68, memory: 0 } } -Instruction: Call { function_index: 29 } -Call instruction: calls function index 29 -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 4 } -Instruction: I32Const { value: 56 } -Instruction: Call { function_index: 89 } -Call instruction: calls function index 89 -Instruction: GlobalGet { global_index: 0 } -Instruction: I32Const { value: 16 } -Instruction: I32Sub -Instruction: LocalTee { local_index: 2 } -Instruction: GlobalSet { global_index: 0 } -Instruction: LocalGet { local_index: 2 } -Instruction: I64Const { value: 0 } -Instruction: I64Store { memarg: MemArg { align: 3, max_align: 3, offset: 8, memory: 0 } } -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 2 } -Instruction: I32Const { value: 8 } -Instruction: I32Add -Instruction: I32Const { value: 8 } -Instruction: Call { function_index: 74 } -Call instruction: calls function index 74 -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 1 } -Instruction: LocalGet { local_index: 2 } -Instruction: Call { function_index: 9 } -Call instruction: calls function index 9 -Instruction: Drop -Instruction: End -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 8 } -Instruction: I32Add -Instruction: LocalGet { local_index: 0 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } -Instruction: LocalGet { local_index: 1 } -Instruction: LocalGet { local_index: 2 } -Instruction: Call { function_index: 53 } -Call instruction: calls function index 53 -Instruction: If { blockty: Empty } -Instruction: I32Const { value: 131137 } -Instruction: I32Const { value: 15 } -Instruction: Call { function_index: 50 } -Call instruction: calls function index 50 -Instruction: Unreachable -Instruction: End -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } -Instruction: LocalGet { local_index: 2 } -Instruction: I32Add -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } -Instruction: End -Instruction: I32Const { value: 131200 } -Instruction: I32Const { value: 12 } -Instruction: Call { function_index: 42 } -Call instruction: calls function index 42 -Instruction: End -Instruction: I32Const { value: 131212 } -Instruction: I32Const { value: 9 } -Instruction: Call { function_index: 42 } -Call instruction: calls function index 42 -Instruction: End -Instruction: Call { function_index: 20 } -Call instruction: calls function index 20 -Instruction: I32Const { value: 0 } -Instruction: Call { function_index: 46 } -Call instruction: calls function index 46 -Instruction: End -Instruction: GlobalGet { global_index: 0 } -Instruction: I32Const { value: 32 } -Instruction: I32Sub -Instruction: LocalTee { local_index: 0 } -Instruction: GlobalSet { global_index: 0 } -Instruction: Call { function_index: 20 } -Call instruction: calls function index 20 -Instruction: I32Const { value: 2 } -Instruction: Call { function_index: 46 } -Call instruction: calls function index 46 -Instruction: Call { function_index: 45 } -Call instruction: calls function index 45 -Instruction: LocalSet { local_index: 6 } -Instruction: I32Const { value: 1 } -Instruction: Call { function_index: 40 } -Call instruction: calls function index 40 -Instruction: LocalSet { local_index: 7 } -Instruction: Call { function_index: 76 } -Call instruction: calls function index 76 -Instruction: LocalSet { local_index: 2 } -Instruction: Loop { blockty: Empty } -Instruction: LocalGet { local_index: 1 } -Instruction: LocalGet { local_index: 6 } -Instruction: I32Ne -Instruction: If { blockty: Empty } -Instruction: LocalGet { local_index: 7 } -Instruction: Call { function_index: 25 } -Call instruction: calls function index 25 -Instruction: LocalSet { local_index: 5 } -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 1 } -Instruction: I32Const { value: 24 } -Instruction: I32Shl -Instruction: LocalGet { local_index: 1 } -Instruction: I32Const { value: 65280 } -Instruction: I32And -Instruction: I32Const { value: 8 } -Instruction: I32Shl -Instruction: I32Or -Instruction: LocalGet { local_index: 1 } -Instruction: I32Const { value: 8 } -Instruction: I32ShrU -Instruction: I32Const { value: 65280 } -Instruction: I32And -Instruction: LocalGet { local_index: 1 } -Instruction: I32Const { value: 24 } -Instruction: I32ShrU -Instruction: I32Or -Instruction: I32Or -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 16, memory: 0 } } -Instruction: LocalGet { local_index: 5 } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 16 } -Instruction: I32Add -Instruction: I32Const { value: 4 } -Instruction: Call { function_index: 9 } -Call instruction: calls function index 9 -Instruction: Drop -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 2 } -Instruction: Call { function_index: 70 } -Call instruction: calls function index 70 -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 12, memory: 0 } } -Instruction: I32Const { value: 1 } -Instruction: I32Add -Instruction: LocalTee { local_index: 3 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 12, memory: 0 } } -Instruction: Block { blockty: Empty } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } -Instruction: LocalTee { local_index: 8 } -Instruction: I32Eqz -Instruction: If { blockty: Empty } -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 3 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 4, memory: 0 } } -Instruction: I32Const { value: 0 } -Instruction: LocalSet { local_index: 4 } -Instruction: Br { relative_depth: 1 } -Instruction: End -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 16 } -Instruction: I32Add -Instruction: LocalTee { local_index: 9 } -Instruction: LocalGet { local_index: 2 } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 8, memory: 0 } } -Instruction: LocalTee { local_index: 4 } -Instruction: Call { function_index: 67 } -Call instruction: calls function index 67 -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 3 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 24, memory: 0 } } -Instruction: LocalGet { local_index: 2 } -Instruction: LocalGet { local_index: 4 } -Instruction: LocalGet { local_index: 9 } -Instruction: Call { function_index: 62 } -Call instruction: calls function index 62 -Instruction: End -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 4 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 28, memory: 0 } } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 0 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 24, memory: 0 } } -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 3 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 20, memory: 0 } } -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 5 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 16, memory: 0 } } -Instruction: LocalGet { local_index: 2 } -Instruction: LocalGet { local_index: 3 } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 16 } -Instruction: I32Add -Instruction: Call { function_index: 62 } -Call instruction: calls function index 62 -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 8 } -Instruction: I32Const { value: 1 } -Instruction: I32Add -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 3 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 8, memory: 0 } } -Instruction: LocalGet { local_index: 2 } -Instruction: LocalGet { local_index: 0 } -Instruction: Call { function_index: 57 } -Call instruction: calls function index 57 -Instruction: LocalGet { local_index: 1 } -Instruction: I32Const { value: 1 } -Instruction: I32Add -Instruction: LocalSet { local_index: 1 } -Instruction: Br { relative_depth: 1 } -Instruction: End -Instruction: End -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 32 } -Instruction: I32Add -Instruction: GlobalSet { global_index: 0 } -Instruction: End -Instruction: GlobalGet { global_index: 0 } -Instruction: I32Const { value: -64 } -Instruction: I32Add -Instruction: LocalTee { local_index: 0 } -Instruction: GlobalSet { global_index: 0 } -Instruction: Call { function_index: 20 } -Call instruction: calls function index 20 -Instruction: I32Const { value: 1 } -Instruction: Call { function_index: 46 } -Call instruction: calls function index 46 -Instruction: I32Const { value: 0 } -Instruction: Call { function_index: 40 } -Call instruction: calls function index 40 -Instruction: LocalSet { local_index: 2 } -Instruction: LocalGet { local_index: 0 } -Instruction: Call { function_index: 76 } -Call instruction: calls function index 76 -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 12, memory: 0 } } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 16 } -Instruction: I32Add -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 12 } -Instruction: I32Add -Instruction: Call { function_index: 69 } -Call instruction: calls function index 69 -Instruction: Loop { blockty: Empty } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 44 } -Instruction: I32Add -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 16 } -Instruction: I32Add -Instruction: Call { function_index: 30 } -Call instruction: calls function index 30 -Instruction: LocalGet { local_index: 0 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 44, memory: 0 } } -Instruction: If { blockty: Empty } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 48, memory: 0 } } -Instruction: LocalGet { local_index: 2 } -Instruction: Call { function_index: 26 } -Call instruction: calls function index 26 -Instruction: LocalGet { local_index: 1 } -Instruction: I32Add -Instruction: LocalSet { local_index: 1 } -Instruction: Br { relative_depth: 1 } -Instruction: End -Instruction: End -Instruction: LocalGet { local_index: 1 } -Instruction: I64ExtendI32U -Instruction: Call { function_index: 21 } -Call instruction: calls function index 21 -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: -64 } -Instruction: I32Sub -Instruction: GlobalSet { global_index: 0 } -Instruction: End -Instruction: GlobalGet { global_index: 0 } -Instruction: I32Const { value: -64 } -Instruction: I32Add -Instruction: LocalTee { local_index: 0 } -Instruction: GlobalSet { global_index: 0 } -Instruction: Call { function_index: 20 } -Call instruction: calls function index 20 -Instruction: I32Const { value: 1 } -Instruction: Call { function_index: 46 } -Call instruction: calls function index 46 -Instruction: Call { function_index: 45 } -Call instruction: calls function index 45 -Instruction: LocalSet { local_index: 5 } -Instruction: Call { function_index: 76 } -Call instruction: calls function index 76 -Instruction: LocalSet { local_index: 1 } -Instruction: Block { blockty: Empty } -Instruction: Loop { blockty: Empty } -Instruction: LocalGet { local_index: 5 } -Instruction: If { blockty: Empty } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 12 } -Instruction: I32Add -Instruction: LocalGet { local_index: 1 } -Instruction: Call { function_index: 70 } -Call instruction: calls function index 70 -Instruction: Block { blockty: Empty } -Instruction: LocalGet { local_index: 1 } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 16, memory: 0 } } -Instruction: LocalTee { local_index: 2 } -Instruction: Call { function_index: 66 } -Call instruction: calls function index 66 -Instruction: BrIf { relative_depth: 0 } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 28 } -Instruction: I32Add -Instruction: LocalTee { local_index: 4 } -Instruction: LocalGet { local_index: 1 } -Instruction: LocalGet { local_index: 2 } -Instruction: Call { function_index: 31 } -Call instruction: calls function index 31 -Instruction: LocalGet { local_index: 0 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 28, memory: 0 } } -Instruction: I32Eqz -Instruction: BrIf { relative_depth: 3 } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 44, memory: 0 } } -Instruction: LocalSet { local_index: 2 } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 40, memory: 0 } } -Instruction: LocalSet { local_index: 3 } -Instruction: LocalGet { local_index: 1 } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 36, memory: 0 } } -Instruction: LocalTee { local_index: 6 } -Instruction: Call { function_index: 66 } -Call instruction: calls function index 66 -Instruction: BrIf { relative_depth: 0 } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 48 } -Instruction: I32Add -Instruction: LocalGet { local_index: 1 } -Instruction: Call { function_index: 70 } -Call instruction: calls function index 70 -Instruction: Block { blockty: Empty } -Instruction: LocalGet { local_index: 2 } -Instruction: If { blockty: Empty } -Instruction: LocalGet { local_index: 4 } -Instruction: LocalGet { local_index: 1 } -Instruction: LocalGet { local_index: 2 } -Instruction: Call { function_index: 67 } -Call instruction: calls function index 67 -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 3 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 36, memory: 0 } } -Instruction: LocalGet { local_index: 1 } -Instruction: LocalGet { local_index: 2 } -Instruction: LocalGet { local_index: 4 } -Instruction: Call { function_index: 62 } -Call instruction: calls function index 62 -Instruction: Br { relative_depth: 1 } -Instruction: End -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 3 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 52, memory: 0 } } -Instruction: End -Instruction: Block { blockty: Empty } -Instruction: LocalGet { local_index: 3 } -Instruction: If { blockty: Empty } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 28 } -Instruction: I32Add -Instruction: LocalTee { local_index: 4 } -Instruction: LocalGet { local_index: 1 } -Instruction: LocalGet { local_index: 3 } -Instruction: Call { function_index: 67 } -Call instruction: calls function index 67 -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 2 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 40, memory: 0 } } -Instruction: LocalGet { local_index: 1 } -Instruction: LocalGet { local_index: 3 } -Instruction: LocalGet { local_index: 4 } -Instruction: Call { function_index: 62 } -Call instruction: calls function index 62 -Instruction: Br { relative_depth: 1 } -Instruction: End -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 2 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 56, memory: 0 } } -Instruction: End -Instruction: LocalGet { local_index: 1 } -Instruction: LocalGet { local_index: 6 } -Instruction: Call { function_index: 63 } -Call instruction: calls function index 63 -Instruction: Call { function_index: 55 } -Call instruction: calls function index 55 -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 48, memory: 0 } } -Instruction: I32Const { value: 1 } -Instruction: I32Sub -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 48, memory: 0 } } -Instruction: LocalGet { local_index: 1 } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 48 } -Instruction: I32Add -Instruction: Call { function_index: 57 } -Call instruction: calls function index 57 -Instruction: End -Instruction: LocalGet { local_index: 5 } -Instruction: I32Const { value: 1 } -Instruction: I32Sub -Instruction: LocalSet { local_index: 5 } -Instruction: Br { relative_depth: 1 } -Instruction: End -Instruction: End -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: -64 } -Instruction: I32Sub -Instruction: GlobalSet { global_index: 0 } -Instruction: Return -Instruction: End -Instruction: Call { function_index: 81 } -Call instruction: calls function index 81 -Instruction: Call { function_index: 88 } -Call instruction: calls function index 88 -Instruction: GlobalGet { global_index: 0 } -Instruction: I32Const { value: 48 } -Instruction: I32Sub -Instruction: LocalTee { local_index: 0 } -Instruction: GlobalSet { global_index: 0 } -Instruction: Call { function_index: 20 } -Call instruction: calls function index 20 -Instruction: I32Const { value: 0 } -Instruction: Call { function_index: 46 } -Call instruction: calls function index 46 -Instruction: LocalGet { local_index: 0 } -Instruction: Call { function_index: 76 } -Call instruction: calls function index 76 -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 4 } -Instruction: I32Add -Instruction: LocalGet { local_index: 0 } -Instruction: Call { function_index: 69 } -Call instruction: calls function index 69 -Instruction: Loop { blockty: Empty } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 28 } -Instruction: I32Add -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 4 } -Instruction: I32Add -Instruction: Call { function_index: 30 } -Call instruction: calls function index 30 -Instruction: LocalGet { local_index: 0 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 28, memory: 0 } } -Instruction: If { blockty: Empty } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 32, memory: 0 } } -Instruction: Call { function_index: 22 } -Call instruction: calls function index 22 -Instruction: Drop -Instruction: Br { relative_depth: 1 } -Instruction: End -Instruction: End -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 48 } -Instruction: I32Add -Instruction: GlobalSet { global_index: 0 } -Instruction: End -Instruction: GlobalGet { global_index: 0 } -Instruction: I32Const { value: 128 } -Instruction: I32Sub -Instruction: LocalTee { local_index: 0 } -Instruction: GlobalSet { global_index: 0 } -Instruction: Call { function_index: 20 } -Call instruction: calls function index 20 -Instruction: I32Const { value: 2 } -Instruction: Call { function_index: 46 } -Call instruction: calls function index 46 -Instruction: Call { function_index: 45 } -Call instruction: calls function index 45 -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 32 } -Instruction: I32Add -Instruction: I32Const { value: 1 } -Instruction: Call { function_index: 43 } -Call instruction: calls function index 43 -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 108 } -Instruction: I32Add -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 56 } -Instruction: I32Add -Instruction: LocalTee { local_index: 4 } -Instruction: I64Load { memarg: MemArg { align: 3, max_align: 3, offset: 0, memory: 0 } } -Instruction: LocalTee { local_index: 11 } -Instruction: I64Store { memarg: MemArg { align: 2, max_align: 3, offset: 0, memory: 0 } } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 8 } -Instruction: I32Add -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 40 } -Instruction: I32Add -Instruction: LocalTee { local_index: 5 } -Instruction: I64Load { memarg: MemArg { align: 3, max_align: 3, offset: 0, memory: 0 } } -Instruction: I64Store { memarg: MemArg { align: 3, max_align: 3, offset: 0, memory: 0 } } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 16 } -Instruction: I32Add -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 48 } -Instruction: I32Add -Instruction: LocalTee { local_index: 6 } -Instruction: I64Load { memarg: MemArg { align: 3, max_align: 3, offset: 0, memory: 0 } } -Instruction: I64Store { memarg: MemArg { align: 3, max_align: 3, offset: 0, memory: 0 } } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 24 } -Instruction: I32Add -Instruction: LocalGet { local_index: 11 } -Instruction: I64Store { memarg: MemArg { align: 3, max_align: 3, offset: 0, memory: 0 } } -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 0 } -Instruction: I64Load { memarg: MemArg { align: 3, max_align: 3, offset: 32, memory: 0 } } -Instruction: LocalTee { local_index: 11 } -Instruction: I64Store { memarg: MemArg { align: 2, max_align: 3, offset: 84, memory: 0 } } -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 11 } -Instruction: I64Store { memarg: MemArg { align: 3, max_align: 3, offset: 0, memory: 0 } } -Instruction: I64ExtendI32U -Instruction: LocalSet { local_index: 12 } -Instruction: I64Const { value: 0 } -Instruction: LocalSet { local_index: 11 } -Instruction: Call { function_index: 75 } -Call instruction: calls function index 75 -Instruction: LocalSet { local_index: 1 } -Instruction: Loop { blockty: Empty } -Instruction: LocalGet { local_index: 11 } -Instruction: LocalGet { local_index: 12 } -Instruction: I64Eq -Instruction: I32Eqz -Instruction: If { blockty: Empty } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 80 } -Instruction: I32Add -Instruction: LocalGet { local_index: 0 } -Instruction: Call { function_index: 28 } -Call instruction: calls function index 28 -Instruction: LocalGet { local_index: 5 } -Instruction: LocalGet { local_index: 11 } -Instruction: I64Store { memarg: MemArg { align: 3, max_align: 3, offset: 0, memory: 0 } } -Instruction: LocalGet { local_index: 6 } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 96 } -Instruction: I32Add -Instruction: LocalTee { local_index: 7 } -Instruction: I64Load { memarg: MemArg { align: 3, max_align: 3, offset: 0, memory: 0 } } -Instruction: I64Store { memarg: MemArg { align: 3, max_align: 3, offset: 0, memory: 0 } } -Instruction: LocalGet { local_index: 4 } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 104 } -Instruction: I32Add -Instruction: LocalTee { local_index: 8 } -Instruction: I64Load { memarg: MemArg { align: 3, max_align: 3, offset: 0, memory: 0 } } -Instruction: I64Store { memarg: MemArg { align: 3, max_align: 3, offset: 0, memory: 0 } } -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 11 } -Instruction: I64Store { memarg: MemArg { align: 3, max_align: 3, offset: 32, memory: 0 } } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: -64 } -Instruction: I32Sub -Instruction: LocalGet { local_index: 1 } -Instruction: Call { function_index: 70 } -Call instruction: calls function index 70 -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 76, memory: 0 } } -Instruction: I32Const { value: 1 } -Instruction: I32Add -Instruction: LocalTee { local_index: 2 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 76, memory: 0 } } -Instruction: Block { blockty: Empty } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 64, memory: 0 } } -Instruction: LocalTee { local_index: 9 } -Instruction: I32Eqz -Instruction: If { blockty: Empty } -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 2 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 68, memory: 0 } } -Instruction: I32Const { value: 0 } -Instruction: LocalSet { local_index: 3 } -Instruction: Br { relative_depth: 1 } -Instruction: End -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 80 } -Instruction: I32Add -Instruction: LocalTee { local_index: 10 } -Instruction: LocalGet { local_index: 1 } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 72, memory: 0 } } -Instruction: LocalTee { local_index: 3 } -Instruction: Call { function_index: 68 } -Call instruction: calls function index 68 -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 2 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 116, memory: 0 } } -Instruction: LocalGet { local_index: 1 } -Instruction: LocalGet { local_index: 3 } -Instruction: LocalGet { local_index: 10 } -Instruction: Call { function_index: 64 } -Call instruction: calls function index 64 -Instruction: End -Instruction: LocalGet { local_index: 8 } -Instruction: LocalGet { local_index: 4 } -Instruction: I64Load { memarg: MemArg { align: 3, max_align: 3, offset: 0, memory: 0 } } -Instruction: I64Store { memarg: MemArg { align: 3, max_align: 3, offset: 0, memory: 0 } } -Instruction: LocalGet { local_index: 7 } -Instruction: LocalGet { local_index: 6 } -Instruction: I64Load { memarg: MemArg { align: 3, max_align: 3, offset: 0, memory: 0 } } -Instruction: I64Store { memarg: MemArg { align: 3, max_align: 3, offset: 0, memory: 0 } } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 88 } -Instruction: I32Add -Instruction: LocalGet { local_index: 5 } -Instruction: I64Load { memarg: MemArg { align: 3, max_align: 3, offset: 0, memory: 0 } } -Instruction: I64Store { memarg: MemArg { align: 3, max_align: 3, offset: 0, memory: 0 } } -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 0 } -Instruction: I64Load { memarg: MemArg { align: 3, max_align: 3, offset: 32, memory: 0 } } -Instruction: I64Store { memarg: MemArg { align: 3, max_align: 3, offset: 80, memory: 0 } } -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 3 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 120, memory: 0 } } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 0 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 116, memory: 0 } } -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 2 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 112, memory: 0 } } -Instruction: LocalGet { local_index: 1 } -Instruction: LocalGet { local_index: 2 } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 80 } -Instruction: I32Add -Instruction: Call { function_index: 64 } -Call instruction: calls function index 64 -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 9 } -Instruction: I32Const { value: 1 } -Instruction: I32Add -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 64, memory: 0 } } -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 2 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 72, memory: 0 } } -Instruction: LocalGet { local_index: 1 } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: -64 } -Instruction: I32Sub -Instruction: Call { function_index: 57 } -Call instruction: calls function index 57 -Instruction: LocalGet { local_index: 11 } -Instruction: I64Const { value: 1 } -Instruction: I64Add -Instruction: LocalSet { local_index: 11 } -Instruction: Br { relative_depth: 1 } -Instruction: End -Instruction: End -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 128 } -Instruction: I32Add -Instruction: GlobalSet { global_index: 0 } -Instruction: End -Instruction: GlobalGet { global_index: 0 } -Instruction: I32Const { value: 160 } -Instruction: I32Sub -Instruction: LocalTee { local_index: 0 } -Instruction: GlobalSet { global_index: 0 } -Instruction: Call { function_index: 20 } -Call instruction: calls function index 20 -Instruction: I32Const { value: 1 } -Instruction: Call { function_index: 46 } -Call instruction: calls function index 46 -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 0 } -Instruction: Call { function_index: 43 } -Call instruction: calls function index 43 -Instruction: LocalGet { local_index: 0 } -Instruction: Call { function_index: 75 } -Call instruction: calls function index 75 -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 36, memory: 0 } } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 40 } -Instruction: I32Add -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 36 } -Instruction: I32Add -Instruction: Call { function_index: 71 } -Call instruction: calls function index 71 -Instruction: LocalGet { local_index: 0 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 28, memory: 0 } } -Instruction: LocalSet { local_index: 3 } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 24, memory: 0 } } -Instruction: LocalSet { local_index: 4 } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 20, memory: 0 } } -Instruction: LocalSet { local_index: 5 } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 16, memory: 0 } } -Instruction: LocalSet { local_index: 6 } -Instruction: LocalGet { local_index: 0 } -Instruction: I64Load { memarg: MemArg { align: 3, max_align: 3, offset: 8, memory: 0 } } -Instruction: LocalSet { local_index: 10 } -Instruction: LocalGet { local_index: 0 } -Instruction: I64Load { memarg: MemArg { align: 3, max_align: 3, offset: 0, memory: 0 } } -Instruction: LocalSet { local_index: 11 } -Instruction: Loop { blockty: Empty } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 104 } -Instruction: I32Add -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 40 } -Instruction: I32Add -Instruction: Call { function_index: 27 } -Call instruction: calls function index 27 -Instruction: LocalGet { local_index: 0 } -Instruction: I64Load { memarg: MemArg { align: 3, max_align: 3, offset: 104, memory: 0 } } -Instruction: I64Eqz -Instruction: I32Eqz -Instruction: If { blockty: Empty } -Instruction: LocalGet { local_index: 0 } -Instruction: I64Load { memarg: MemArg { align: 3, max_align: 3, offset: 112, memory: 0 } } -Instruction: LocalSet { local_index: 12 } -Instruction: I32Const { value: 0 } -Instruction: LocalSet { local_index: 2 } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 140, memory: 0 } } -Instruction: LocalSet { local_index: 7 } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 136, memory: 0 } } -Instruction: LocalSet { local_index: 8 } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 132, memory: 0 } } -Instruction: LocalSet { local_index: 9 } -Instruction: LocalGet { local_index: 0 } -Instruction: I64Load { memarg: MemArg { align: 3, max_align: 3, offset: 120, memory: 0 } } -Instruction: LocalSet { local_index: 13 } -Instruction: Block { blockty: Empty } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 128, memory: 0 } } -Instruction: LocalGet { local_index: 6 } -Instruction: Call { function_index: 26 } -Call instruction: calls function index 26 -Instruction: I32Eqz -Instruction: LocalGet { local_index: 11 } -Instruction: LocalGet { local_index: 12 } -Instruction: I64Ne -Instruction: I32Or -Instruction: BrIf { relative_depth: 0 } -Instruction: LocalGet { local_index: 9 } -Instruction: LocalGet { local_index: 5 } -Instruction: Call { function_index: 51 } -Call instruction: calls function index 51 -Instruction: I32Eqz -Instruction: BrIf { relative_depth: 0 } -Instruction: LocalGet { local_index: 8 } -Instruction: LocalGet { local_index: 4 } -Instruction: Call { function_index: 26 } -Call instruction: calls function index 26 -Instruction: I32Eqz -Instruction: LocalGet { local_index: 10 } -Instruction: LocalGet { local_index: 13 } -Instruction: I64Ne -Instruction: I32Or -Instruction: BrIf { relative_depth: 0 } -Instruction: LocalGet { local_index: 7 } -Instruction: LocalGet { local_index: 3 } -Instruction: Call { function_index: 51 } -Call instruction: calls function index 51 -Instruction: LocalSet { local_index: 2 } -Instruction: End -Instruction: LocalGet { local_index: 1 } -Instruction: LocalGet { local_index: 2 } -Instruction: I32Add -Instruction: LocalSet { local_index: 1 } -Instruction: Br { relative_depth: 1 } -Instruction: End -Instruction: End -Instruction: LocalGet { local_index: 1 } -Instruction: I64ExtendI32U -Instruction: Call { function_index: 21 } -Call instruction: calls function index 21 -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 160 } -Instruction: I32Add -Instruction: GlobalSet { global_index: 0 } -Instruction: End -Instruction: GlobalGet { global_index: 0 } -Instruction: I32Const { value: 96 } -Instruction: I32Sub -Instruction: LocalTee { local_index: 0 } -Instruction: GlobalSet { global_index: 0 } -Instruction: Call { function_index: 20 } -Call instruction: calls function index 20 -Instruction: I32Const { value: 1 } -Instruction: Call { function_index: 46 } -Call instruction: calls function index 46 -Instruction: Call { function_index: 45 } -Call instruction: calls function index 45 -Instruction: LocalSet { local_index: 5 } -Instruction: Call { function_index: 75 } -Call instruction: calls function index 75 -Instruction: LocalSet { local_index: 1 } -Instruction: Block { blockty: Empty } -Instruction: Loop { blockty: Empty } -Instruction: LocalGet { local_index: 5 } -Instruction: If { blockty: Empty } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 8 } -Instruction: I32Add -Instruction: LocalGet { local_index: 1 } -Instruction: Call { function_index: 70 } -Call instruction: calls function index 70 -Instruction: Block { blockty: Empty } -Instruction: LocalGet { local_index: 1 } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 12, memory: 0 } } -Instruction: LocalTee { local_index: 2 } -Instruction: Call { function_index: 66 } -Call instruction: calls function index 66 -Instruction: BrIf { relative_depth: 0 } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 24 } -Instruction: I32Add -Instruction: LocalTee { local_index: 4 } -Instruction: LocalGet { local_index: 1 } -Instruction: LocalGet { local_index: 2 } -Instruction: Call { function_index: 29 } -Call instruction: calls function index 29 -Instruction: LocalGet { local_index: 0 } -Instruction: I64Load { memarg: MemArg { align: 3, max_align: 3, offset: 24, memory: 0 } } -Instruction: I64Eqz -Instruction: BrIf { relative_depth: 3 } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 72, memory: 0 } } -Instruction: LocalSet { local_index: 2 } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 68, memory: 0 } } -Instruction: LocalSet { local_index: 3 } -Instruction: LocalGet { local_index: 1 } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 64, memory: 0 } } -Instruction: LocalTee { local_index: 6 } -Instruction: Call { function_index: 66 } -Call instruction: calls function index 66 -Instruction: BrIf { relative_depth: 0 } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 80 } -Instruction: I32Add -Instruction: LocalGet { local_index: 1 } -Instruction: Call { function_index: 70 } -Call instruction: calls function index 70 -Instruction: Block { blockty: Empty } -Instruction: LocalGet { local_index: 2 } -Instruction: If { blockty: Empty } -Instruction: LocalGet { local_index: 4 } -Instruction: LocalGet { local_index: 1 } -Instruction: LocalGet { local_index: 2 } -Instruction: Call { function_index: 68 } -Call instruction: calls function index 68 -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 3 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 60, memory: 0 } } -Instruction: LocalGet { local_index: 1 } -Instruction: LocalGet { local_index: 2 } -Instruction: LocalGet { local_index: 4 } -Instruction: Call { function_index: 64 } -Call instruction: calls function index 64 -Instruction: Br { relative_depth: 1 } -Instruction: End -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 3 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 84, memory: 0 } } -Instruction: End -Instruction: Block { blockty: Empty } -Instruction: LocalGet { local_index: 3 } -Instruction: If { blockty: Empty } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 24 } -Instruction: I32Add -Instruction: LocalTee { local_index: 4 } -Instruction: LocalGet { local_index: 1 } -Instruction: LocalGet { local_index: 3 } -Instruction: Call { function_index: 68 } -Call instruction: calls function index 68 -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 2 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 64, memory: 0 } } -Instruction: LocalGet { local_index: 1 } -Instruction: LocalGet { local_index: 3 } -Instruction: LocalGet { local_index: 4 } -Instruction: Call { function_index: 64 } -Call instruction: calls function index 64 -Instruction: Br { relative_depth: 1 } -Instruction: End -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 2 } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 88, memory: 0 } } -Instruction: End -Instruction: LocalGet { local_index: 1 } -Instruction: LocalGet { local_index: 6 } -Instruction: Call { function_index: 63 } -Call instruction: calls function index 63 -Instruction: Call { function_index: 55 } -Call instruction: calls function index 55 -Instruction: LocalGet { local_index: 0 } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 80, memory: 0 } } -Instruction: I32Const { value: 1 } -Instruction: I32Sub -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 80, memory: 0 } } -Instruction: LocalGet { local_index: 1 } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 80 } -Instruction: I32Add -Instruction: Call { function_index: 57 } -Call instruction: calls function index 57 -Instruction: End -Instruction: LocalGet { local_index: 5 } -Instruction: I32Const { value: 1 } -Instruction: I32Sub -Instruction: LocalSet { local_index: 5 } -Instruction: Br { relative_depth: 1 } -Instruction: End -Instruction: End -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 96 } -Instruction: I32Add -Instruction: GlobalSet { global_index: 0 } -Instruction: Return -Instruction: End -Instruction: Call { function_index: 81 } -Call instruction: calls function index 81 -Instruction: Unreachable -Instruction: End -Instruction: GlobalGet { global_index: 0 } -Instruction: I32Const { value: 128 } -Instruction: I32Sub -Instruction: LocalTee { local_index: 0 } -Instruction: GlobalSet { global_index: 0 } -Instruction: Call { function_index: 20 } -Call instruction: calls function index 20 -Instruction: I32Const { value: 0 } -Instruction: Call { function_index: 46 } -Call instruction: calls function index 46 -Instruction: LocalGet { local_index: 0 } -Instruction: Call { function_index: 75 } -Call instruction: calls function index 75 -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 4, memory: 0 } } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 8 } -Instruction: I32Add -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 4 } -Instruction: I32Add -Instruction: Call { function_index: 71 } -Call instruction: calls function index 71 -Instruction: Loop { blockty: Empty } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 72 } -Instruction: I32Add -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 8 } -Instruction: I32Add -Instruction: Call { function_index: 27 } -Call instruction: calls function index 27 -Instruction: LocalGet { local_index: 0 } -Instruction: I64Load { memarg: MemArg { align: 3, max_align: 3, offset: 72, memory: 0 } } -Instruction: I64Eqz -Instruction: I32Eqz -Instruction: If { blockty: Empty } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 108, memory: 0 } } -Instruction: LocalGet { local_index: 0 } -Instruction: I64Load { memarg: MemArg { align: 3, max_align: 3, offset: 88, memory: 0 } } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 104, memory: 0 } } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 100, memory: 0 } } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 96, memory: 0 } } -Instruction: I32Const { value: 131224 } -Instruction: I32Const { value: 0 } -Instruction: Call { function_index: 42 } -Call instruction: calls function index 42 -Instruction: LocalTee { local_index: 1 } -Instruction: Call { function_index: 38 } -Call instruction: calls function index 38 -Instruction: LocalGet { local_index: 0 } -Instruction: I64Load { memarg: MemArg { align: 3, max_align: 3, offset: 80, memory: 0 } } -Instruction: LocalGet { local_index: 1 } -Instruction: Call { function_index: 65 } -Call instruction: calls function index 65 -Instruction: LocalGet { local_index: 1 } -Instruction: Call { function_index: 37 } -Call instruction: calls function index 37 -Instruction: LocalGet { local_index: 1 } -Instruction: Call { function_index: 38 } -Call instruction: calls function index 38 -Instruction: LocalGet { local_index: 1 } -Instruction: Call { function_index: 65 } -Call instruction: calls function index 65 -Instruction: LocalGet { local_index: 1 } -Instruction: Call { function_index: 37 } -Call instruction: calls function index 37 -Instruction: LocalGet { local_index: 1 } -Instruction: Call { function_index: 22 } -Call instruction: calls function index 22 -Instruction: Drop -Instruction: Br { relative_depth: 1 } -Instruction: End -Instruction: End -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 128 } -Instruction: I32Add -Instruction: GlobalSet { global_index: 0 } -Instruction: End -Instruction: End -Instruction: I32Const { value: 131224 } -Instruction: I32Const { value: 14 } -Instruction: Call { function_index: 13 } -Call instruction: calls function index 13 -Instruction: Unreachable -Instruction: End -Instruction: Block { blockty: Empty } -Instruction: LocalGet { local_index: 2 } -Instruction: LocalTee { local_index: 4 } -Instruction: I32Const { value: 16 } -Instruction: I32LtU -Instruction: If { blockty: Empty } -Instruction: LocalGet { local_index: 0 } -Instruction: LocalSet { local_index: 2 } -Instruction: Br { relative_depth: 1 } -Instruction: End -Instruction: LocalGet { local_index: 0 } -Instruction: I32Const { value: 0 } -Instruction: LocalGet { local_index: 0 } -Instruction: I32Sub -Instruction: I32Const { value: 3 } -Instruction: I32And -Instruction: LocalTee { local_index: 3 } -Instruction: I32Add -Instruction: LocalSet { local_index: 5 } -Instruction: LocalGet { local_index: 3 } -Instruction: If { blockty: Empty } -Instruction: LocalGet { local_index: 0 } -Instruction: LocalSet { local_index: 2 } -Instruction: LocalGet { local_index: 1 } -Instruction: LocalSet { local_index: 6 } -Instruction: Loop { blockty: Empty } -Instruction: LocalGet { local_index: 2 } -Instruction: LocalGet { local_index: 6 } -Instruction: I32Load8U { memarg: MemArg { align: 0, max_align: 0, offset: 0, memory: 0 } } -Instruction: I32Store8 { memarg: MemArg { align: 0, max_align: 0, offset: 0, memory: 0 } } -Instruction: LocalGet { local_index: 6 } -Instruction: I32Const { value: 1 } -Instruction: I32Add -Instruction: LocalSet { local_index: 6 } -Instruction: LocalGet { local_index: 2 } -Instruction: I32Const { value: 1 } -Instruction: I32Add -Instruction: LocalTee { local_index: 2 } -Instruction: LocalGet { local_index: 5 } -Instruction: I32LtU -Instruction: BrIf { relative_depth: 0 } -Instruction: End -Instruction: End -Instruction: LocalGet { local_index: 5 } -Instruction: LocalGet { local_index: 4 } -Instruction: LocalGet { local_index: 3 } -Instruction: I32Sub -Instruction: LocalTee { local_index: 8 } -Instruction: I32Const { value: -4 } -Instruction: I32And -Instruction: LocalTee { local_index: 7 } -Instruction: I32Add -Instruction: LocalSet { local_index: 2 } -Instruction: Block { blockty: Empty } -Instruction: LocalGet { local_index: 1 } -Instruction: LocalGet { local_index: 3 } -Instruction: I32Add -Instruction: LocalTee { local_index: 3 } -Instruction: I32Const { value: 3 } -Instruction: I32And -Instruction: If { blockty: Empty } -Instruction: LocalGet { local_index: 7 } -Instruction: I32Const { value: 0 } -Instruction: I32LeS -Instruction: BrIf { relative_depth: 1 } -Instruction: LocalGet { local_index: 3 } -Instruction: I32Const { value: 3 } -Instruction: I32Shl -Instruction: LocalTee { local_index: 4 } -Instruction: I32Const { value: 24 } -Instruction: I32And -Instruction: LocalSet { local_index: 9 } -Instruction: LocalGet { local_index: 3 } -Instruction: I32Const { value: -4 } -Instruction: I32And -Instruction: LocalTee { local_index: 6 } -Instruction: I32Const { value: 4 } -Instruction: I32Add -Instruction: LocalSet { local_index: 1 } -Instruction: I32Const { value: 0 } -Instruction: LocalGet { local_index: 4 } -Instruction: I32Sub -Instruction: I32Const { value: 24 } -Instruction: I32And -Instruction: LocalSet { local_index: 4 } -Instruction: LocalGet { local_index: 6 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } -Instruction: LocalSet { local_index: 6 } -Instruction: Loop { blockty: Empty } -Instruction: LocalGet { local_index: 5 } -Instruction: LocalGet { local_index: 6 } -Instruction: LocalGet { local_index: 9 } -Instruction: I32ShrU -Instruction: LocalGet { local_index: 1 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } -Instruction: LocalTee { local_index: 6 } -Instruction: LocalGet { local_index: 4 } -Instruction: I32Shl -Instruction: I32Or -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } -Instruction: LocalGet { local_index: 1 } -Instruction: I32Const { value: 4 } -Instruction: I32Add -Instruction: LocalSet { local_index: 1 } -Instruction: LocalGet { local_index: 5 } -Instruction: I32Const { value: 4 } -Instruction: I32Add -Instruction: LocalTee { local_index: 5 } -Instruction: LocalGet { local_index: 2 } -Instruction: I32LtU -Instruction: BrIf { relative_depth: 0 } -Instruction: End -Instruction: Br { relative_depth: 1 } -Instruction: End -Instruction: LocalGet { local_index: 7 } -Instruction: I32Const { value: 0 } -Instruction: I32LeS -Instruction: BrIf { relative_depth: 0 } -Instruction: LocalGet { local_index: 3 } -Instruction: LocalSet { local_index: 1 } -Instruction: Loop { blockty: Empty } -Instruction: LocalGet { local_index: 5 } -Instruction: LocalGet { local_index: 1 } -Instruction: I32Load { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } -Instruction: I32Store { memarg: MemArg { align: 2, max_align: 2, offset: 0, memory: 0 } } -Instruction: LocalGet { local_index: 1 } -Instruction: I32Const { value: 4 } -Instruction: I32Add -Instruction: LocalSet { local_index: 1 } -Instruction: LocalGet { local_index: 5 } -Instruction: I32Const { value: 4 } -Instruction: I32Add -Instruction: LocalTee { local_index: 5 } -Instruction: LocalGet { local_index: 2 } -Instruction: I32LtU -Instruction: BrIf { relative_depth: 0 } -Instruction: End -Instruction: End -Instruction: LocalGet { local_index: 8 } -Instruction: I32Const { value: 3 } -Instruction: I32And -Instruction: LocalSet { local_index: 4 } -Instruction: LocalGet { local_index: 3 } -Instruction: LocalGet { local_index: 7 } -Instruction: I32Add -Instruction: LocalSet { local_index: 1 } -Instruction: End -Instruction: LocalGet { local_index: 4 } -Instruction: If { blockty: Empty } -Instruction: LocalGet { local_index: 2 } -Instruction: LocalGet { local_index: 4 } -Instruction: I32Add -Instruction: LocalSet { local_index: 3 } -Instruction: Loop { blockty: Empty } -Instruction: LocalGet { local_index: 2 } -Instruction: LocalGet { local_index: 1 } -Instruction: I32Load8U { memarg: MemArg { align: 0, max_align: 0, offset: 0, memory: 0 } } -Instruction: I32Store8 { memarg: MemArg { align: 0, max_align: 0, offset: 0, memory: 0 } } -Instruction: LocalGet { local_index: 1 } -Instruction: I32Const { value: 1 } -Instruction: I32Add -Instruction: LocalSet { local_index: 1 } -Instruction: LocalGet { local_index: 2 } -Instruction: I32Const { value: 1 } -Instruction: I32Add -Instruction: LocalTee { local_index: 2 } -Instruction: LocalGet { local_index: 3 } -Instruction: I32LtU -Instruction: BrIf { relative_depth: 0 } -Instruction: End -Instruction: End -Instruction: LocalGet { local_index: 0 } -Instruction: End -Checking EI version: 1.3 ... OK -Packing ../output/linked-list-repeat.mxsc.json ... -Contract size: 6615 bytes. -analyze this via wasm -analyze this via wasm diff --git a/contracts/benchmarks/mappers/linked-list-repeat/src/linked_list_repeat.rs b/contracts/benchmarks/mappers/linked-list-repeat/src/linked_list_repeat.rs index cc7d8959ff..40dfcba638 100644 --- a/contracts/benchmarks/mappers/linked-list-repeat/src/linked_list_repeat.rs +++ b/contracts/benchmarks/mappers/linked-list-repeat/src/linked_list_repeat.rs @@ -1,9 +1,8 @@ #![no_std] -use benchmark_common::ExampleStruct; - multiversx_sc::imports!(); +use benchmark_common::ExampleStruct; pub mod linked_list_repeat_proxy; #[multiversx_sc::contract] @@ -39,8 +38,7 @@ pub trait LinkedListRepeat: benchmark_common::BenchmarkCommon { #[storage_mapper("benchmark")] fn bench(&self) -> LinkedListMapper; - #[view] - // #[endpoint] + #[endpoint] fn add_struct(&self, num_repeats: usize, value: ExampleStruct) { let mut bench = self.bench_struct(); for i in 0..num_repeats { diff --git a/contracts/examples/adder/src/adder.rs b/contracts/examples/adder/src/adder.rs index 77358e4b7b..307f4112f5 100644 --- a/contracts/examples/adder/src/adder.rs +++ b/contracts/examples/adder/src/adder.rs @@ -23,7 +23,7 @@ pub trait Adder { } /// Add desired amount to the storage variable. - #[view] + #[endpoint] fn add(&self, value: BigUint) { self.sum().update(|sum| *sum += value); } diff --git a/framework/derive/src/parse/attributes/endpoint_attr.rs b/framework/derive/src/parse/attributes/endpoint_attr.rs index 4b742f5116..678675b202 100644 --- a/framework/derive/src/parse/attributes/endpoint_attr.rs +++ b/framework/derive/src/parse/attributes/endpoint_attr.rs @@ -57,7 +57,7 @@ pub struct ViewAttribute { pub view_name: Option, } -impl ViewAttribute { +impl ViewAttribute { pub fn parse(attr: &syn::Attribute) -> Option { match is_attr_with_one_opt_token_tree_arg(attr, ATTR_VIEW) { None => None, From 9e9bba15bf5d4aa7ec1807be56a43a8e219048ee Mon Sep 17 00:00:00 2001 From: BiancaIalangi Date: Fri, 13 Sep 2024 14:20:19 +0300 Subject: [PATCH 010/185] detect write op in view storage - fix clippy --- .../meta-lib/src/tools/wasm_extractor.rs | 23 ++++++++----------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/framework/meta-lib/src/tools/wasm_extractor.rs b/framework/meta-lib/src/tools/wasm_extractor.rs index a348a40e30..4cd80507d4 100644 --- a/framework/meta-lib/src/tools/wasm_extractor.rs +++ b/framework/meta-lib/src/tools/wasm_extractor.rs @@ -75,7 +75,7 @@ fn populate_wasm_info( ei_check = is_ei_valid(&imports, check_ei); }, Payload::DataSection(data_section) => { - allocator_trigger = is_fail_allocator_triggered(&data_section); + allocator_trigger = is_fail_allocator_triggered(data_section.clone()); if is_panic_with_message_triggered(data_section.clone()) { has_panic = WITH_MESSAGE; } else if is_panic_without_message_triggered(data_section) { @@ -99,8 +99,8 @@ fn populate_wasm_info( } } let mut visited: HashSet = HashSet::new(); - for (index, _name) in &views_data { - mark_write(*index, &call_graph, &mut write_functions, &mut visited); + for key in views_data.keys() { + mark_write(*key, &call_graph, &mut write_functions, &mut visited); } for (index, name) in views_data { @@ -133,7 +133,7 @@ fn populate_wasm_info( fn parse_export_section( export_section: ExportSectionReader, - view_endpoints: &Vec, + view_endpoints: &[String], ) -> HashMap { let mut views_data: HashMap = HashMap::new(); for export in export_section { @@ -181,20 +181,17 @@ fn create_call_graph(body: FunctionBody, call_graph: &mut HashMap { - let function_usize: usize = function_index.try_into().unwrap(); - call_functions.push(function_usize); - }, - _ => (), + if let Operator::Call { function_index } = op { + let function_usize: usize = function_index.try_into().unwrap(); + call_functions.push(function_usize); } } call_graph.insert(call_graph.len(), call_functions); } -fn is_fail_allocator_triggered(data_section: &DataSectionReader) -> bool { - for data_fragment in data_section.clone().into_iter().flatten() { +fn is_fail_allocator_triggered(data_section: DataSectionReader) -> bool { + for data_fragment in data_section.into_iter().flatten() { if data_fragment .data .windows(ERROR_FAIL_ALLOCATOR.len()) @@ -266,7 +263,7 @@ pub fn extract_imports( import_names } -fn is_ei_valid(imports: &Vec, check_ei: &Option) -> bool { +fn is_ei_valid(imports: &[String], check_ei: &Option) -> bool { if let Some(ei) = check_ei { let mut num_errors = 0; for import in imports { From d145b73eba13d4b2bb095ab10ae5fcc576c054bd Mon Sep 17 00:00:00 2001 From: BiancaIalangi Date: Fri, 13 Sep 2024 19:11:46 +0300 Subject: [PATCH 011/185] detect write op in view storage - refactor: removed has_format, changed data structure for view_endpoints, impl default for WasmInfo and ReportCreator --- .../src/contract/sc_config/wasm_build.rs | 20 +-- .../meta-lib/src/tools/report_creator.rs | 10 ++ .../meta-lib/src/tools/wasm_extractor.rs | 143 ++++++++---------- 3 files changed, 83 insertions(+), 90 deletions(-) diff --git a/framework/meta-lib/src/contract/sc_config/wasm_build.rs b/framework/meta-lib/src/contract/sc_config/wasm_build.rs index e7a9bec5ed..4311bd0979 100644 --- a/framework/meta-lib/src/contract/sc_config/wasm_build.rs +++ b/framework/meta-lib/src/contract/sc_config/wasm_build.rs @@ -1,4 +1,4 @@ -use std::{ffi::OsStr, fs, process::Command}; +use std::{collections::HashMap, ffi::OsStr, fs, process::Command}; use super::ContractVariant; use crate::{ @@ -95,12 +95,8 @@ impl ContractVariant { let mut abi = ContractAbiJson::from(&self.abi); let mut view_endpoints = Vec::new(); for endpoint in &abi.endpoints { - match endpoint.mutability { - crate::abi_json::EndpointMutabilityAbiJson::Readonly => { - view_endpoints.push(&endpoint.name) - }, - crate::abi_json::EndpointMutabilityAbiJson::Mutable => (), - crate::abi_json::EndpointMutabilityAbiJson::Pure => (), + if let crate::abi_json::EndpointMutabilityAbiJson::Readonly = endpoint.mutability { + view_endpoints.push(&endpoint.name) } } let build_info = core::mem::take(&mut abi.build_info).unwrap(); @@ -141,14 +137,10 @@ impl ContractVariant { let output_wasm_path = format!("{output_path}/{}", self.wasm_output_name(build_args)); let abi = ContractAbiJson::from(&self.abi); - let mut view_endpoints = Vec::new(); + let mut view_endpoints: HashMap<&str, usize> = HashMap::new(); for endpoint in &abi.endpoints { - match endpoint.mutability { - crate::abi_json::EndpointMutabilityAbiJson::Readonly => { - view_endpoints.push(endpoint.name.clone()) - }, - crate::abi_json::EndpointMutabilityAbiJson::Mutable => (), - crate::abi_json::EndpointMutabilityAbiJson::Pure => (), + if let crate::abi_json::EndpointMutabilityAbiJson::Readonly = endpoint.mutability { + view_endpoints.insert(&endpoint.name, 0); } } diff --git a/framework/meta-lib/src/tools/report_creator.rs b/framework/meta-lib/src/tools/report_creator.rs index 37af10fa4e..60de81dc31 100644 --- a/framework/meta-lib/src/tools/report_creator.rs +++ b/framework/meta-lib/src/tools/report_creator.rs @@ -8,3 +8,13 @@ pub struct ReportCreator { } impl ReportCreator {} + +impl Default for ReportCreator { + fn default() -> Self { + ReportCreator { + path: String::new(), + has_allocator: false, + has_panic: "none".to_string(), + } + } +} diff --git a/framework/meta-lib/src/tools/wasm_extractor.rs b/framework/meta-lib/src/tools/wasm_extractor.rs index 4cd80507d4..63dad6b3ad 100644 --- a/framework/meta-lib/src/tools/wasm_extractor.rs +++ b/framework/meta-lib/src/tools/wasm_extractor.rs @@ -12,18 +12,21 @@ use crate::ei::EIVersion; use super::report_creator::{ReportCreator, WITHOUT_MESSAGE, WITH_MESSAGE}; +type CallGraph = HashMap>; + const PANIC_WITH_MESSAGE: &[u8; 16] = b"panic occurred: "; const PANIC_WITHOUT_MESSAGE: &[u8; 14] = b"panic occurred"; const ERROR_FAIL_ALLOCATOR: &[u8; 27] = b"memory allocation forbidden"; const MEMORY_GROW_OPCODE: u8 = 0x40; const WRITE_OP: [&str; 1] = ["mBufferStorageStore"]; +#[derive(Default)] pub struct WasmInfo { pub imports: Vec, pub ei_check: bool, pub memory_grow_flag: bool, - pub has_format: bool, pub report: ReportCreator, + pub call_graph: CallGraph, } impl WasmInfo { @@ -31,7 +34,7 @@ impl WasmInfo { output_wasm_path: &str, extract_imports_enabled: bool, check_ei: &Option, - view_endpoints: Vec, + view_endpoints: HashMap<&str, usize>, ) -> Result { let wasm_data = fs::read(output_wasm_path) .expect("error occured while extracting information from .wasm: file not found"); @@ -51,60 +54,67 @@ fn populate_wasm_info( wasm_data: Vec, extract_imports_enabled: bool, check_ei: &Option, - view_endpoints: Vec, + mut view_endpoints: HashMap<&str, usize>, ) -> Result { - let mut imports = Vec::new(); - let mut allocator_trigger = false; - let mut ei_check = false; - let mut memory_grow_flag = false; - let mut has_panic = "none"; - let mut call_graph: HashMap> = HashMap::new(); - let mut views_data: HashMap = HashMap::new(); - let mut write_functions: Vec = Vec::new(); - - let mut parser = Parser::new(0); + let mut wasm_info = WasmInfo::default(); + let mut write_functions: HashSet = HashSet::new(); + + let parser = Parser::new(0); for payload in parser.parse_all(&wasm_data) { match payload? { Payload::ImportSection(import_section) => { - imports = extract_imports( - import_section, - extract_imports_enabled, - &mut call_graph, - &mut write_functions, - ); - ei_check = is_ei_valid(&imports, check_ei); + write_functions = + process_imports(import_section, extract_imports_enabled, &mut wasm_info); + wasm_info.ei_check = is_ei_valid(&wasm_info.imports, check_ei); }, Payload::DataSection(data_section) => { - allocator_trigger = is_fail_allocator_triggered(data_section.clone()); + wasm_info.report.has_allocator = is_fail_allocator_triggered(data_section.clone()); if is_panic_with_message_triggered(data_section.clone()) { - has_panic = WITH_MESSAGE; + wasm_info.report.has_panic = WITH_MESSAGE.to_owned(); } else if is_panic_without_message_triggered(data_section) { - has_panic = WITHOUT_MESSAGE; + wasm_info.report.has_panic = WITHOUT_MESSAGE.to_owned(); } }, Payload::CodeSectionEntry(code_section) => { - memory_grow_flag = is_mem_grow(&code_section); + wasm_info.memory_grow_flag = is_mem_grow(&code_section); + create_call_graph(code_section, &mut wasm_info.call_graph); }, Payload::ExportSection(export_section) => { - views_data = parse_export_section(export_section, &view_endpoints); + parse_export_section(export_section, &mut view_endpoints); }, _ => (), } } - parser = Parser::new(0); - for payload in parser.parse_all(&wasm_data) { - if let Payload::CodeSectionEntry(body) = payload? { - create_call_graph(body, &mut call_graph); - } - } + detect_write_operations_in_views(&view_endpoints, &wasm_info.call_graph, &mut write_functions); + + let report = ReportCreator { + path, + has_allocator: wasm_info.report.has_allocator, + has_panic: wasm_info.report.has_panic, + }; + + Ok(WasmInfo { + imports: wasm_info.imports, + ei_check: wasm_info.ei_check, + memory_grow_flag: wasm_info.memory_grow_flag, + call_graph: wasm_info.call_graph, + report, + }) +} + +fn detect_write_operations_in_views( + views_data: &HashMap<&str, usize>, + call_graph: &CallGraph, + write_functions: &mut HashSet, +) { let mut visited: HashSet = HashSet::new(); - for key in views_data.keys() { - mark_write(*key, &call_graph, &mut write_functions, &mut visited); + for index in views_data.values() { + mark_write(*index, call_graph, write_functions, &mut visited); } - for (index, name) in views_data { - if write_functions.contains(&index) { + for (name, index) in views_data { + if write_functions.contains(index) { println!( "{} {}", "Write storage operation in VIEW endpoint:" @@ -115,42 +125,26 @@ fn populate_wasm_info( ); } } - - let report = ReportCreator { - path, - has_allocator: allocator_trigger, - has_panic: has_panic.to_string(), - }; - - Ok(WasmInfo { - imports, - ei_check, - memory_grow_flag, - has_format: true, - report, - }) } fn parse_export_section( export_section: ExportSectionReader, - view_endpoints: &[String], -) -> HashMap { - let mut views_data: HashMap = HashMap::new(); + view_endpoints: &mut HashMap<&str, usize>, +) { for export in export_section { let export = export.expect("Failed to read export section"); if let wasmparser::ExternalKind::Func = export.kind { - if view_endpoints.contains(&export.name.to_string()) { - views_data.insert(export.index.try_into().unwrap(), export.name.to_string()); + if let Some(endpoint_index) = view_endpoints.get_mut(export.name) { + *endpoint_index = export.index.try_into().unwrap(); } } } - views_data } fn mark_write( func: usize, - call_graph: &HashMap>, - write_functions: &mut Vec, + call_graph: &CallGraph, + write_functions: &mut HashSet, visited: &mut HashSet, ) { // Return early to prevent cycles. @@ -163,27 +157,27 @@ fn mark_write( if let Some(callees) = call_graph.get(&func) { for &callee in callees { if write_functions.contains(&callee) { - write_functions.push(func); + write_functions.insert(func); } else { mark_write(callee, call_graph, write_functions, visited); if write_functions.contains(&callee) { - write_functions.push(func); + write_functions.insert(func); } } } } } -fn create_call_graph(body: FunctionBody, call_graph: &mut HashMap>) { +fn create_call_graph(body: FunctionBody, call_graph: &mut CallGraph) { let mut instructions_reader = body .get_operators_reader() .expect("Failed to get operators reader"); - let mut call_functions = Vec::new(); + let mut call_functions = HashSet::new(); while let Ok(op) = instructions_reader.read() { if let Operator::Call { function_index } = op { let function_usize: usize = function_index.try_into().unwrap(); - call_functions.push(function_usize); + call_functions.insert(function_usize); } } @@ -239,28 +233,25 @@ fn is_panic_without_message_triggered(data_section: DataSectionReader) -> bool { false } -pub fn extract_imports( +pub fn process_imports( import_section: ImportSectionReader, import_extraction_enabled: bool, - call_graph: &mut HashMap>, - write_functions: &mut Vec, -) -> Vec { - if !import_extraction_enabled { - return Vec::new(); - } - - let mut import_names = Vec::new(); + wasm_info: &mut WasmInfo, +) -> HashSet { + let mut write_functions = HashSet::new(); for (index, import) in import_section.into_iter().flatten().enumerate() { - import_names.push(import.name.to_string()); - call_graph.insert(index, vec![]); + if import_extraction_enabled { + wasm_info.imports.push(import.name.to_string()); + } + wasm_info.call_graph.insert(index, HashSet::new()); if WRITE_OP.contains(&import.name) { - write_functions.push(index); + write_functions.insert(index); } } - import_names.sort(); + wasm_info.imports.sort(); - import_names + write_functions } fn is_ei_valid(imports: &[String], check_ei: &Option) -> bool { From 6616577997850059e2f6d7bfd5ed4f0d25fdcc0b Mon Sep 17 00:00:00 2001 From: BiancaIalangi Date: Fri, 13 Sep 2024 19:28:49 +0300 Subject: [PATCH 012/185] detect write op in view storage - fix clippy --- framework/meta-lib/src/tools/wasm_extractor.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/framework/meta-lib/src/tools/wasm_extractor.rs b/framework/meta-lib/src/tools/wasm_extractor.rs index 63dad6b3ad..3f58ef1fac 100644 --- a/framework/meta-lib/src/tools/wasm_extractor.rs +++ b/framework/meta-lib/src/tools/wasm_extractor.rs @@ -70,9 +70,9 @@ fn populate_wasm_info( Payload::DataSection(data_section) => { wasm_info.report.has_allocator = is_fail_allocator_triggered(data_section.clone()); if is_panic_with_message_triggered(data_section.clone()) { - wasm_info.report.has_panic = WITH_MESSAGE.to_owned(); + WITH_MESSAGE.clone_into(&mut wasm_info.report.has_panic); } else if is_panic_without_message_triggered(data_section) { - wasm_info.report.has_panic = WITHOUT_MESSAGE.to_owned(); + WITHOUT_MESSAGE.clone_into(&mut wasm_info.report.has_panic); } }, Payload::CodeSectionEntry(code_section) => { From bd9be2e26c158d0ef8d1dcaefbd11d9b366bfc27 Mon Sep 17 00:00:00 2001 From: Mihai Calin Luca Date: Fri, 13 Sep 2024 18:52:19 +0200 Subject: [PATCH 013/185] impl for interactor --- .../scenario/src/facade/result_handlers.rs | 2 ++ .../facade/result_handlers/returns_tx_hash.rs | 24 +++++++++++++++++++ .../scenario/model/transaction/tx_response.rs | 2 ++ framework/snippets/src/network_response.rs | 6 +++++ 4 files changed, 34 insertions(+) create mode 100644 framework/scenario/src/facade/result_handlers/returns_tx_hash.rs diff --git a/framework/scenario/src/facade/result_handlers.rs b/framework/scenario/src/facade/result_handlers.rs index 33b5b1a495..88e90d0cd5 100644 --- a/framework/scenario/src/facade/result_handlers.rs +++ b/framework/scenario/src/facade/result_handlers.rs @@ -7,6 +7,7 @@ mod returns_message; mod returns_new_bech32_address; mod returns_new_token_identifier; mod returns_status; +mod returns_tx_hash; mod with_tx_raw_response; pub use expect_error::ExpectError; @@ -18,4 +19,5 @@ pub use returns_message::ReturnsMessage; pub use returns_new_bech32_address::ReturnsNewBech32Address; pub use returns_new_token_identifier::ReturnsNewTokenIdentifier; pub use returns_status::ReturnsStatus; +pub use returns_tx_hash::ReturnsTxHash; pub use with_tx_raw_response::WithRawTxResponse; diff --git a/framework/scenario/src/facade/result_handlers/returns_tx_hash.rs b/framework/scenario/src/facade/result_handlers/returns_tx_hash.rs new file mode 100644 index 0000000000..7494b41edc --- /dev/null +++ b/framework/scenario/src/facade/result_handlers/returns_tx_hash.rs @@ -0,0 +1,24 @@ +use multiversx_sc::types::RHListItemExec; + +use crate::{ + multiversx_sc::types::{RHListItem, TxEnv}, + scenario_model::TxResponse, +}; + +pub struct ReturnsTxHash; + +impl RHListItem for ReturnsTxHash +where + Env: TxEnv, +{ + type Returns = String; +} + +impl RHListItemExec for ReturnsTxHash +where + Env: TxEnv, +{ + fn item_process_result(self, raw_result: &TxResponse) -> Self::Returns { + raw_result.tx_hash.clone() + } +} diff --git a/framework/scenario/src/scenario/model/transaction/tx_response.rs b/framework/scenario/src/scenario/model/transaction/tx_response.rs index 8a7a5c4bf9..b230fd1878 100644 --- a/framework/scenario/src/scenario/model/transaction/tx_response.rs +++ b/framework/scenario/src/scenario/model/transaction/tx_response.rs @@ -20,6 +20,8 @@ pub struct TxResponse { pub gas: u64, /// The refund of the transaction. pub refund: u64, + /// The transaction hash + pub tx_hash: String, } impl TxResponse { diff --git a/framework/snippets/src/network_response.rs b/framework/snippets/src/network_response.rs index 0140dd839e..4684fdce3c 100644 --- a/framework/snippets/src/network_response.rs +++ b/framework/snippets/src/network_response.rs @@ -17,6 +17,7 @@ pub fn parse_tx_response(tx: TransactionOnNetwork) -> TxResponse { if !tx_error.is_success() { return TxResponse { tx_error, + tx_hash: process_tx_hash(&tx).to_string(), ..Default::default() }; } @@ -45,10 +46,15 @@ fn process_success(tx: &TransactionOnNetwork) -> TxResponse { new_deployed_address: process_new_deployed_address(tx), new_issued_token_identifier: process_new_issued_token_identifier(tx), logs: process_logs(tx), + tx_hash: process_tx_hash(tx).to_string(), ..Default::default() } } +fn process_tx_hash(tx: &TransactionOnNetwork) -> &str { + tx.hash.as_deref().unwrap_or("") +} + fn process_out(tx: &TransactionOnNetwork) -> Vec> { let out_scr = tx.smart_contract_results.iter().find(is_out_scr); From 3905c2c88763c0899a783102eb7ee3aa0570fbf7 Mon Sep 17 00:00:00 2001 From: BiancaIalangi Date: Tue, 17 Sep 2024 18:54:07 +0300 Subject: [PATCH 014/185] chain sim - fix test --- tools/interactor-system-func-calls/src/system_sc_interact.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/interactor-system-func-calls/src/system_sc_interact.rs b/tools/interactor-system-func-calls/src/system_sc_interact.rs index df47733d47..4ec3c6647e 100644 --- a/tools/interactor-system-func-calls/src/system_sc_interact.rs +++ b/tools/interactor-system-func-calls/src/system_sc_interact.rs @@ -229,7 +229,7 @@ impl SysFuncCallsInteract { let config = Config::load_config(); let mut interactor = Interactor::new(config.gateway()).await; - let wallet_address = interactor.register_wallet(test_wallets::alice()); + let wallet_address = interactor.register_wallet(test_wallets::alice()).await; Self { interactor, From b72c23db19ba2c6985827b838ea5ad7fddaf8dce Mon Sep 17 00:00:00 2001 From: Mihai Calin Luca Date: Thu, 19 Sep 2024 09:58:15 +0200 Subject: [PATCH 015/185] tx hash in scenario --- .../facade/world_tx/scenario_tx_whitebox.rs | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/framework/scenario/src/facade/world_tx/scenario_tx_whitebox.rs b/framework/scenario/src/facade/world_tx/scenario_tx_whitebox.rs index 62842a6e25..e20538ce0e 100644 --- a/framework/scenario/src/facade/world_tx/scenario_tx_whitebox.rs +++ b/framework/scenario/src/facade/world_tx/scenario_tx_whitebox.rs @@ -1,3 +1,5 @@ +use core::str; + use crate::debug_executor::contract_instance_wrapped_execution; use crate::scenario::tx_to_step::TxToQueryStep; use crate::{ @@ -68,6 +70,15 @@ where }); let mut response = TxResponse::from_tx_result(tx_result); + if let Some(tx_hash) = &step_wrapper.env.data.tx_hash { + let tx_hash_bytes = tx_hash.as_bytes(); + response.tx_hash = str::from_utf8(tx_hash_bytes) + .expect("tx hash not utf8 valid") + .to_string(); + } else { + response.tx_hash = String::from(""); + } + response.new_deployed_address = Some(new_address); step_wrapper.step.save_response(response); step_wrapper.process_result() @@ -140,7 +151,16 @@ where }); }); - let response = TxResponse::from_tx_result(tx_result); + let mut response = TxResponse::from_tx_result(tx_result); + if let Some(tx_hash) = &step_wrapper.env.data.tx_hash { + let tx_hash_bytes = tx_hash.as_bytes(); + response.tx_hash = str::from_utf8(tx_hash_bytes) + .expect("tx hash not utf8 valid") + .to_string(); + } else { + response.tx_hash = String::from(""); + } + step_wrapper.step.save_response(response); step_wrapper.process_result() } From d305c74d291032432ee93abed3afd3272081f461 Mon Sep 17 00:00:00 2001 From: BiancaIalangi Date: Thu, 19 Sep 2024 19:37:18 +0300 Subject: [PATCH 016/185] chain sim - pass URI from the interactor --- .../adder/interact/src/basic_interact.rs | 21 +++++++++-------- .../interact/src/basic_interact_config.rs | 20 +++++++++++----- .../examples/multisig/interact/config.toml | 3 ++- .../interact/src/multisig_interact.rs | 2 +- .../interact/src/multisig_interact_config.rs | 20 +++++++++++++++- .../basic-features/interact/config.toml | 3 ++- .../interact/src/bf_interact.rs | 2 +- .../interact/src/bf_interact_config.rs | 21 +++++++++++++---- .../composability/interact/config.toml | 9 ++++---- .../interact/src/comp_interact_config.rs | 21 +++++++++++++---- .../interact/src/comp_interact_controller.rs | 2 +- framework/meta/src/cli/cli_args_standalone.rs | 10 +++++++- framework/meta/src/cmd/retrieve_address.rs | 8 ++++++- framework/snippets/src/account_tool.rs | 3 ++- framework/snippets/src/interactor.rs | 4 ++-- sdk/core/examples/account.rs | 4 ++-- sdk/core/examples/account_storage.rs | 4 ++-- sdk/core/examples/get_esdt_tokens.rs | 4 ++-- sdk/core/examples/get_hyper_block_by_hash.rs | 4 ++-- sdk/core/examples/get_hyper_block_by_nonce.rs | 4 ++-- sdk/core/examples/get_hyper_block_latest.rs | 4 ++-- sdk/core/examples/get_network_config.rs | 4 ++-- sdk/core/examples/get_network_economics.rs | 4 ++-- sdk/core/examples/sign_tx.rs | 4 ++-- sdk/core/examples/sign_txs.rs | 4 ++-- sdk/core/examples/tx_cost.rs | 4 ++-- sdk/core/examples/tx_default_args.rs | 4 ++-- sdk/core/examples/tx_info.rs | 4 ++-- sdk/core/examples/vm_query.rs | 4 ++-- sdk/core/src/gateway.rs | 4 +++- sdk/core/src/gateway/gateway_proxy.rs | 12 ++++------ .../interactor-system-func-calls/config.toml | 3 ++- .../src/system_sc_interact.rs | 3 ++- .../src/system_sc_interact_config.rs | 23 +++++++++++++++---- 34 files changed, 168 insertions(+), 82 deletions(-) diff --git a/contracts/examples/adder/interact/src/basic_interact.rs b/contracts/examples/adder/interact/src/basic_interact.rs index ee88d2e9d5..9f3f82a43b 100644 --- a/contracts/examples/adder/interact/src/basic_interact.rs +++ b/contracts/examples/adder/interact/src/basic_interact.rs @@ -63,22 +63,25 @@ struct AdderInteract { impl AdderInteract { async fn init() -> Self { let config = Config::load_config(); - let mut interactor = Interactor::new(config.gateway()) + let mut interactor = Interactor::new(config.gateway_uri(), config.use_chain_simulator()) .await .with_tracer(INTERACTOR_SCENARIO_TRACE_PATH) .await; - let adder_owner_address = - interactor.register_wallet(Wallet::from_pem_file("adder-owner.pem").unwrap()).await; + let adder_owner_address = interactor + .register_wallet(Wallet::from_pem_file("adder-owner.pem").unwrap()) + .await; // PASSWORD: "alice" // InsertPassword::Plaintext("alice".to_string()) || InsertPassword::StandardInput - let wallet_address = interactor.register_wallet( - Wallet::from_keystore_secret( - "alice.json", - InsertPassword::Plaintext("alice".to_string()), + let wallet_address = interactor + .register_wallet( + Wallet::from_keystore_secret( + "alice.json", + InsertPassword::Plaintext("alice".to_string()), + ) + .unwrap(), ) - .unwrap(), - ).await; + .await; Self { interactor, diff --git a/contracts/examples/adder/interact/src/basic_interact_config.rs b/contracts/examples/adder/interact/src/basic_interact_config.rs index 02773bc1e8..2ab2577ceb 100644 --- a/contracts/examples/adder/interact/src/basic_interact_config.rs +++ b/contracts/examples/adder/interact/src/basic_interact_config.rs @@ -7,7 +7,7 @@ const CONFIG_FILE: &str = "config.toml"; /// Adder Interact configuration #[derive(Debug, Deserialize)] pub struct Config { - gateway: Option, + gateway_uri: String, chain_type: String, } @@ -20,12 +20,20 @@ impl Config { toml::from_str(&content).unwrap() } - // Returns the gateway - pub fn gateway(&self) -> &str { + // Returns the gateway URI + pub fn gateway_uri(&self) -> &str { + &self.gateway_uri + } + + // Returns if chain type is chain simulator + pub fn use_chain_simulator(&self) -> bool { match self.chain_type.as_str() { - "real" => self.gateway.as_deref().expect("Please provide gateway!"), - "simulator" => "http://localhost:8085", - _ => "", + "simulator" => return true, + "real" => return false, + _ => panic!( + "Invalid chain type: {}. Expected 'simulator' or 'real'.", + self.chain_type + ), } } } diff --git a/contracts/examples/multisig/interact/config.toml b/contracts/examples/multisig/interact/config.toml index 029fab5ac7..148ebb5803 100644 --- a/contracts/examples/multisig/interact/config.toml +++ b/contracts/examples/multisig/interact/config.toml @@ -1,3 +1,4 @@ -gateway = 'https://devnet-gateway.multiversx.com' +chain_type = 'real' +gateway_uri = 'https://devnet-gateway.multiversx.com' quorum = 2 wegld_address = "erd1qqqqqqqqqqqqqpgqqkwzsxkjc83vlfex9dmznwm7tjvxlqqkpauqx0n782" diff --git a/contracts/examples/multisig/interact/src/multisig_interact.rs b/contracts/examples/multisig/interact/src/multisig_interact.rs index 7ab094e04c..0701841b6a 100644 --- a/contracts/examples/multisig/interact/src/multisig_interact.rs +++ b/contracts/examples/multisig/interact/src/multisig_interact.rs @@ -86,7 +86,7 @@ struct MultisigInteract { impl MultisigInteract { async fn init() -> Self { let config = Config::load_config(); - let mut interactor = Interactor::new(&config.gateway) + let mut interactor = Interactor::new(config.gateway_uri(), config.use_chain_simulator()) .await .with_tracer(INTERACTOR_SCENARIO_TRACE_PATH) .await; diff --git a/contracts/examples/multisig/interact/src/multisig_interact_config.rs b/contracts/examples/multisig/interact/src/multisig_interact_config.rs index 4aa9903cc0..ec280f4807 100644 --- a/contracts/examples/multisig/interact/src/multisig_interact_config.rs +++ b/contracts/examples/multisig/interact/src/multisig_interact_config.rs @@ -8,7 +8,8 @@ const CONFIG_FILE: &str = "config.toml"; /// Multisig Interact configuration #[derive(Debug, Deserialize)] pub struct Config { - pub gateway: String, + pub gateway_uri: String, + pub chain_type: String, pub quorum: usize, pub wegld_address: Bech32Address, } @@ -21,4 +22,21 @@ impl Config { file.read_to_string(&mut content).unwrap(); toml::from_str(&content).unwrap() } + + // Returns the gateway URI + pub fn gateway_uri(&self) -> &str { + &self.gateway_uri + } + + // Returns if chain type is chain simulator + pub fn use_chain_simulator(&self) -> bool { + match self.chain_type.as_str() { + "simulator" => return true, + "real" => return false, + _ => panic!( + "Invalid chain type: {}. Expected 'simulator' or 'real'.", + self.chain_type + ), + } + } } diff --git a/contracts/feature-tests/basic-features/interact/config.toml b/contracts/feature-tests/basic-features/interact/config.toml index 61ac8dbf87..dfc1ba62a6 100644 --- a/contracts/feature-tests/basic-features/interact/config.toml +++ b/contracts/feature-tests/basic-features/interact/config.toml @@ -1 +1,2 @@ -gateway = 'https://devnet-gateway.multiversx.com' +chain_type = 'real' +gateway_uri = 'https://devnet-gateway.multiversx.com' diff --git a/contracts/feature-tests/basic-features/interact/src/bf_interact.rs b/contracts/feature-tests/basic-features/interact/src/bf_interact.rs index d14de2d71c..b971818f2b 100644 --- a/contracts/feature-tests/basic-features/interact/src/bf_interact.rs +++ b/contracts/feature-tests/basic-features/interact/src/bf_interact.rs @@ -41,7 +41,7 @@ struct BasicFeaturesInteract { impl BasicFeaturesInteract { async fn init() -> Self { let config = Config::load_config(); - let mut interactor = Interactor::new(config.gateway()) + let mut interactor = Interactor::new(config.gateway_uri(), config.use_chain_simulator()) .await .with_tracer(INTERACTOR_SCENARIO_TRACE_PATH) .await; diff --git a/contracts/feature-tests/basic-features/interact/src/bf_interact_config.rs b/contracts/feature-tests/basic-features/interact/src/bf_interact_config.rs index e17d0cbe65..9c6cb6ef0f 100644 --- a/contracts/feature-tests/basic-features/interact/src/bf_interact_config.rs +++ b/contracts/feature-tests/basic-features/interact/src/bf_interact_config.rs @@ -7,7 +7,8 @@ const CONFIG_FILE: &str = "config.toml"; /// Adder Interact configuration #[derive(Debug, Deserialize)] pub struct Config { - gateway: String, + gateway_uri: String, + chain_type: String, } impl Config { @@ -19,8 +20,20 @@ impl Config { toml::from_str(&content).unwrap() } - // Returns the gateway - pub fn gateway(&self) -> &str { - &self.gateway + // Returns the gateway URI + pub fn gateway_uri(&self) -> &str { + &self.gateway_uri + } + + // Returns if true if chain type is chain simulator + pub fn use_chain_simulator(&self) -> bool { + match self.chain_type.as_str() { + "simulator" => return true, + "real" => return false, + _ => panic!( + "Invalid chain type: {}. Expected 'simulator' or 'real'.", + self.chain_type + ), + } } } diff --git a/contracts/feature-tests/composability/interact/config.toml b/contracts/feature-tests/composability/interact/config.toml index accfdf2fa5..992112c225 100644 --- a/contracts/feature-tests/composability/interact/config.toml +++ b/contracts/feature-tests/composability/interact/config.toml @@ -1,6 +1,7 @@ -gateway = 'https://testnet-gateway.multiversx.com' -call_type = "LegacyAsync" # Sync / LegacyAsync / TransferExecute +chain_type = 'real' +gateway_uri = 'https://testnet-gateway.multiversx.com' +call_type = "LegacyAsync" # Sync / LegacyAsync / TransferExecute # token_id = "CMPT-4e9332" token_id = "EGLD" -token_nonce = 0 # is 0 if fungible -amount = '50000000000000000' \ No newline at end of file +token_nonce = 0 # is 0 if fungible +amount = '50000000000000000' diff --git a/contracts/feature-tests/composability/interact/src/comp_interact_config.rs b/contracts/feature-tests/composability/interact/src/comp_interact_config.rs index d09c2323f7..96524d1bde 100644 --- a/contracts/feature-tests/composability/interact/src/comp_interact_config.rs +++ b/contracts/feature-tests/composability/interact/src/comp_interact_config.rs @@ -11,7 +11,8 @@ const CONFIG_FILE: &str = "config.toml"; /// Multisig Interact configuration #[derive(Debug, Deserialize)] pub struct Config { - gateway: String, + gateway_uri: String, + chain_type: String, call_type: String, token_id: String, token_nonce: u64, @@ -27,9 +28,21 @@ impl Config { toml::from_str(&content).unwrap() } - // Returns the gateway - pub fn gateway(&self) -> &str { - &self.gateway + // Returns the gateway URI + pub fn gateway_uri(&self) -> &str { + &self.gateway_uri + } + + // Returns if chain type is chain simulator + pub fn use_chain_simulator(&self) -> bool { + match self.chain_type.as_str() { + "simulator" => return true, + "real" => return false, + _ => panic!( + "Invalid chain type: {}. Expected 'simulator' or 'real'.", + self.chain_type + ), + } } pub fn call_type(&self) -> QueuedCallType { diff --git a/contracts/feature-tests/composability/interact/src/comp_interact_controller.rs b/contracts/feature-tests/composability/interact/src/comp_interact_controller.rs index 1ae99af017..e486c6d522 100644 --- a/contracts/feature-tests/composability/interact/src/comp_interact_controller.rs +++ b/contracts/feature-tests/composability/interact/src/comp_interact_controller.rs @@ -16,7 +16,7 @@ pub struct ComposabilityInteract { impl ComposabilityInteract { pub async fn init() -> Self { let config = Config::load_config(); - let mut interactor = Interactor::new(config.gateway()) + let mut interactor = Interactor::new(config.gateway_uri(), config.use_chain_simulator()) .await .with_tracer(INTERACTOR_SCENARIO_TRACE_PATH) .await; diff --git a/framework/meta/src/cli/cli_args_standalone.rs b/framework/meta/src/cli/cli_args_standalone.rs index ce2c3b66a6..28b47d51e1 100644 --- a/framework/meta/src/cli/cli_args_standalone.rs +++ b/framework/meta/src/cli/cli_args_standalone.rs @@ -408,11 +408,19 @@ pub struct InstallWasmOptArgs {} #[derive(Default, Clone, PartialEq, Eq, Debug, Args)] pub struct AccountArgs { - /// Provide the target API you want the real data to come from + /// Provide the target API you want the data to come from #[arg(long = "api")] #[clap(global = true)] pub api: Option, + /// Provide if the API is a chain simulator or not + #[arg( + long = "chain-simulator", + default_value = "false", + verbatim_doc_comment + )] + pub chain_simulator: Option, + /// Provide the address you want to retrieve data from #[arg(long = "address", verbatim_doc_comment)] pub address: String, diff --git a/framework/meta/src/cmd/retrieve_address.rs b/framework/meta/src/cmd/retrieve_address.rs index f20b5b8e05..15335408ef 100644 --- a/framework/meta/src/cmd/retrieve_address.rs +++ b/framework/meta/src/cmd/retrieve_address.rs @@ -5,5 +5,11 @@ use crate::cli::AccountArgs; /// Interprets arguments and call the account tool from `multiversx_sc_snippets`. pub async fn retrieve_address(args: &AccountArgs) { let api_string = args.api.clone().expect("API needs to be specified"); - account_tool::print_account_as_scenario_set_state(api_string, args.address.to_string()).await; + let use_chain_simulator = args.chain_simulator.unwrap_or_default(); + account_tool::print_account_as_scenario_set_state( + api_string, + use_chain_simulator, + args.address.to_string(), + ) + .await; } diff --git a/framework/snippets/src/account_tool.rs b/framework/snippets/src/account_tool.rs index c40407e360..3370fc738e 100644 --- a/framework/snippets/src/account_tool.rs +++ b/framework/snippets/src/account_tool.rs @@ -15,9 +15,10 @@ use std::collections::{BTreeMap, HashMap}; /// then formats it as a scenario set state step. pub async fn print_account_as_scenario_set_state( api_string: String, + use_chain_simulator: bool, address_bech32_string: String, ) { - let api = GatewayProxy::new(api_string); + let api = GatewayProxy::new(api_string, use_chain_simulator); let address = Bech32Address::from_bech32_string(address_bech32_string); let set_state = retrieve_account_as_scenario_set_state(&api, &address).await; let scenario = build_scenario(set_state); diff --git a/framework/snippets/src/interactor.rs b/framework/snippets/src/interactor.rs index 702121c373..3102d88d64 100644 --- a/framework/snippets/src/interactor.rs +++ b/framework/snippets/src/interactor.rs @@ -32,8 +32,8 @@ pub struct Interactor { } impl Interactor { - pub async fn new(gateway_url: &str) -> Self { - let proxy = GatewayProxy::new(gateway_url.to_string()); + pub async fn new(gateway_uri: &str, use_chain_simulator: bool) -> Self { + let proxy = GatewayProxy::new(gateway_uri.to_string(), use_chain_simulator); let network_config = proxy.get_network_config().await.unwrap(); Self { proxy, diff --git a/sdk/core/examples/account.rs b/sdk/core/examples/account.rs index 5e9456f4b0..92e3914717 100644 --- a/sdk/core/examples/account.rs +++ b/sdk/core/examples/account.rs @@ -1,6 +1,6 @@ use multiversx_sdk::{ data::address::Address, - gateway::{GatewayProxy, DEVNET_GATEWAY}, + gateway::{GatewayProxy, DEFAULT_USE_CHAIN_SIMULATOR, DEVNET_GATEWAY}, }; #[tokio::main] @@ -10,7 +10,7 @@ async fn main() { ) .unwrap(); - let blockchain = GatewayProxy::new(DEVNET_GATEWAY.to_string()); + let blockchain = GatewayProxy::new(DEVNET_GATEWAY.to_string(), DEFAULT_USE_CHAIN_SIMULATOR); let account = blockchain.get_account(&addr).await.unwrap(); println!("account: {account:#?}"); diff --git a/sdk/core/examples/account_storage.rs b/sdk/core/examples/account_storage.rs index 7693c26e08..c7d5bda76e 100644 --- a/sdk/core/examples/account_storage.rs +++ b/sdk/core/examples/account_storage.rs @@ -1,6 +1,6 @@ use multiversx_sdk::{ data::address::Address, - gateway::{GatewayProxy, DEVNET_GATEWAY}, + gateway::{GatewayProxy, DEFAULT_USE_CHAIN_SIMULATOR, DEVNET_GATEWAY}, }; #[tokio::main] @@ -10,7 +10,7 @@ async fn main() { ) .unwrap(); - let blockchain = GatewayProxy::new(DEVNET_GATEWAY.to_string()); + let blockchain = GatewayProxy::new(DEVNET_GATEWAY.to_string(), DEFAULT_USE_CHAIN_SIMULATOR); let account_storage = blockchain.get_account_storage_keys(&addr).await.unwrap(); println!("Account Storage: {account_storage:#?}"); diff --git a/sdk/core/examples/get_esdt_tokens.rs b/sdk/core/examples/get_esdt_tokens.rs index fac424da27..6c2f663e09 100644 --- a/sdk/core/examples/get_esdt_tokens.rs +++ b/sdk/core/examples/get_esdt_tokens.rs @@ -1,6 +1,6 @@ use multiversx_sdk::{ data::address::Address, - gateway::{GatewayProxy, DEVNET_GATEWAY}, + gateway::{GatewayProxy, DEFAULT_USE_CHAIN_SIMULATOR, DEVNET_GATEWAY}, }; #[tokio::main] @@ -10,7 +10,7 @@ async fn main() { ) .unwrap(); - let blockchain = GatewayProxy::new(DEVNET_GATEWAY.to_string()); + let blockchain = GatewayProxy::new(DEVNET_GATEWAY.to_string(), DEFAULT_USE_CHAIN_SIMULATOR); let balances = blockchain.get_account_esdt_tokens(&addr).await.unwrap(); println!("{balances:#?}"); diff --git a/sdk/core/examples/get_hyper_block_by_hash.rs b/sdk/core/examples/get_hyper_block_by_hash.rs index 1d7f969ce1..a67ea311d3 100644 --- a/sdk/core/examples/get_hyper_block_by_hash.rs +++ b/sdk/core/examples/get_hyper_block_by_hash.rs @@ -1,8 +1,8 @@ -use multiversx_sdk::gateway::{GatewayProxy, DEVNET_GATEWAY}; +use multiversx_sdk::gateway::{GatewayProxy, DEFAULT_USE_CHAIN_SIMULATOR, DEVNET_GATEWAY}; #[tokio::main] async fn main() { - let blockchain = GatewayProxy::new(DEVNET_GATEWAY.to_string()); + let blockchain = GatewayProxy::new(DEVNET_GATEWAY.to_string(), DEFAULT_USE_CHAIN_SIMULATOR); let result = blockchain .get_hyper_block_by_hash("20b14ba0e68c465810c5ded091f220e51dad41629d7ccd87dab572206185e419") .await; diff --git a/sdk/core/examples/get_hyper_block_by_nonce.rs b/sdk/core/examples/get_hyper_block_by_nonce.rs index 575255d6c9..68ec349081 100644 --- a/sdk/core/examples/get_hyper_block_by_nonce.rs +++ b/sdk/core/examples/get_hyper_block_by_nonce.rs @@ -1,8 +1,8 @@ -use multiversx_sdk::gateway::{GatewayProxy, DEVNET_GATEWAY}; +use multiversx_sdk::gateway::{GatewayProxy, DEFAULT_USE_CHAIN_SIMULATOR, DEVNET_GATEWAY}; #[tokio::main] async fn main() { - let blockchain = GatewayProxy::new(DEVNET_GATEWAY.to_string()); + let blockchain = GatewayProxy::new(DEVNET_GATEWAY.to_string(), DEFAULT_USE_CHAIN_SIMULATOR); let result = blockchain.get_hyper_block_by_nonce(7468).await; println!("block by nonce result: {result:?}") diff --git a/sdk/core/examples/get_hyper_block_latest.rs b/sdk/core/examples/get_hyper_block_latest.rs index 934358fdbf..fe49fa7f1e 100644 --- a/sdk/core/examples/get_hyper_block_latest.rs +++ b/sdk/core/examples/get_hyper_block_latest.rs @@ -1,8 +1,8 @@ -use multiversx_sdk::gateway::{GatewayProxy, DEVNET_GATEWAY}; +use multiversx_sdk::gateway::{GatewayProxy, DEFAULT_USE_CHAIN_SIMULATOR, DEVNET_GATEWAY}; #[tokio::main] async fn main() { - let blockchain = GatewayProxy::new(DEVNET_GATEWAY.to_string()); + let blockchain = GatewayProxy::new(DEVNET_GATEWAY.to_string(), DEFAULT_USE_CHAIN_SIMULATOR); let result = blockchain.get_latest_hyper_block_nonce(false).await; println!("latest block result: {result:?}") diff --git a/sdk/core/examples/get_network_config.rs b/sdk/core/examples/get_network_config.rs index d53e0e7ce1..481cc31da3 100644 --- a/sdk/core/examples/get_network_config.rs +++ b/sdk/core/examples/get_network_config.rs @@ -1,8 +1,8 @@ -use multiversx_sdk::gateway::{GatewayProxy, DEVNET_GATEWAY}; +use multiversx_sdk::gateway::{GatewayProxy, DEFAULT_USE_CHAIN_SIMULATOR, DEVNET_GATEWAY}; #[tokio::main] async fn main() { - let blockchain = GatewayProxy::new(DEVNET_GATEWAY.to_string()); + let blockchain = GatewayProxy::new(DEVNET_GATEWAY.to_string(), DEFAULT_USE_CHAIN_SIMULATOR); let network_config = blockchain.get_network_config().await.unwrap(); println!("network_config: {network_config:#?}") diff --git a/sdk/core/examples/get_network_economics.rs b/sdk/core/examples/get_network_economics.rs index bb0410c8f0..f7cf9e808b 100644 --- a/sdk/core/examples/get_network_economics.rs +++ b/sdk/core/examples/get_network_economics.rs @@ -1,8 +1,8 @@ -use multiversx_sdk::gateway::{GatewayProxy, DEVNET_GATEWAY}; +use multiversx_sdk::gateway::{GatewayProxy, DEFAULT_USE_CHAIN_SIMULATOR, DEVNET_GATEWAY}; #[tokio::main] async fn main() { - let blockchain = GatewayProxy::new(DEVNET_GATEWAY.to_string()); + let blockchain = GatewayProxy::new(DEVNET_GATEWAY.to_string(), DEFAULT_USE_CHAIN_SIMULATOR); let network_economics = blockchain.get_network_economics().await.unwrap(); println!("network_economics: {network_economics:#?}") diff --git a/sdk/core/examples/sign_tx.rs b/sdk/core/examples/sign_tx.rs index aa3f977321..50d2a885d6 100644 --- a/sdk/core/examples/sign_tx.rs +++ b/sdk/core/examples/sign_tx.rs @@ -1,6 +1,6 @@ use multiversx_sdk::{ data::transaction::Transaction, - gateway::{GatewayProxy, DEVNET_GATEWAY}, + gateway::{GatewayProxy, DEFAULT_USE_CHAIN_SIMULATOR, DEVNET_GATEWAY}, wallet::Wallet, }; @@ -11,7 +11,7 @@ async fn main() { ) .unwrap(); let addr = wl.address(); - let blockchain = GatewayProxy::new(DEVNET_GATEWAY.to_string()); + let blockchain = GatewayProxy::new(DEVNET_GATEWAY.to_string(), DEFAULT_USE_CHAIN_SIMULATOR); let network_config = blockchain.get_network_config().await.unwrap(); let arg = blockchain diff --git a/sdk/core/examples/sign_txs.rs b/sdk/core/examples/sign_txs.rs index 2860d528f7..35cc6d2e01 100644 --- a/sdk/core/examples/sign_txs.rs +++ b/sdk/core/examples/sign_txs.rs @@ -1,6 +1,6 @@ use multiversx_sdk::{ data::transaction::Transaction, - gateway::{GatewayProxy, DEVNET_GATEWAY}, + gateway::{GatewayProxy, DEFAULT_USE_CHAIN_SIMULATOR, DEVNET_GATEWAY}, wallet::Wallet, }; @@ -11,7 +11,7 @@ async fn main() { ) .unwrap(); let addr = wl.address(); - let blockchain = GatewayProxy::new(DEVNET_GATEWAY.to_string()); + let blockchain = GatewayProxy::new(DEVNET_GATEWAY.to_string(), DEFAULT_USE_CHAIN_SIMULATOR); let network_config = blockchain.get_network_config().await.unwrap(); let arg = blockchain diff --git a/sdk/core/examples/tx_cost.rs b/sdk/core/examples/tx_cost.rs index a982b130ec..1d24230c12 100644 --- a/sdk/core/examples/tx_cost.rs +++ b/sdk/core/examples/tx_cost.rs @@ -1,6 +1,6 @@ use multiversx_sdk::{ data::{address::Address, transaction::Transaction}, - gateway::{GatewayProxy, DEVNET_GATEWAY}, + gateway::{GatewayProxy, DEFAULT_USE_CHAIN_SIMULATOR, DEVNET_GATEWAY}, utils::base64_encode, }; @@ -26,7 +26,7 @@ async fn main() { signature: None, }; - let blockchain = GatewayProxy::new(DEVNET_GATEWAY.to_string()); + let blockchain = GatewayProxy::new(DEVNET_GATEWAY.to_string(), DEFAULT_USE_CHAIN_SIMULATOR); let cost = blockchain.request_transaction_cost(&tx).await.unwrap(); println!("tx cost: {cost:#?}"); diff --git a/sdk/core/examples/tx_default_args.rs b/sdk/core/examples/tx_default_args.rs index 01b91aa5a6..76412b34d4 100644 --- a/sdk/core/examples/tx_default_args.rs +++ b/sdk/core/examples/tx_default_args.rs @@ -1,11 +1,11 @@ use multiversx_sdk::{ data::address::Address, - gateway::{GatewayProxy, DEVNET_GATEWAY}, + gateway::{GatewayProxy, DEFAULT_USE_CHAIN_SIMULATOR, DEVNET_GATEWAY}, }; #[tokio::main] async fn main() { - let blockchain = GatewayProxy::new(DEVNET_GATEWAY.to_string()); + let blockchain = GatewayProxy::new(DEVNET_GATEWAY.to_string(), DEFAULT_USE_CHAIN_SIMULATOR); let network_config = blockchain.get_network_config().await.unwrap(); let addr = Address::from_bech32_string( "erd1qqqqqqqqqqqqqpgqfzydqmdw7m2vazsp6u5p95yxz76t2p9rd8ss0zp9ts", diff --git a/sdk/core/examples/tx_info.rs b/sdk/core/examples/tx_info.rs index f7126daca9..11481d2ec1 100644 --- a/sdk/core/examples/tx_info.rs +++ b/sdk/core/examples/tx_info.rs @@ -1,9 +1,9 @@ -use multiversx_sdk::gateway::{GatewayProxy, DEVNET_GATEWAY}; +use multiversx_sdk::gateway::{GatewayProxy, DEFAULT_USE_CHAIN_SIMULATOR, DEVNET_GATEWAY}; #[tokio::main] async fn main() { let tx_hash = "49edb289892a655a0e988b360c19326c21107f9696c6197b435667c6e8c6e1a3"; - let blockchain = GatewayProxy::new(DEVNET_GATEWAY.to_string()); + let blockchain = GatewayProxy::new(DEVNET_GATEWAY.to_string(), DEFAULT_USE_CHAIN_SIMULATOR); let status = blockchain.get_transaction_status(tx_hash).await; println!("tx status: {status:?}"); diff --git a/sdk/core/examples/vm_query.rs b/sdk/core/examples/vm_query.rs index d07f49b856..750316fee6 100644 --- a/sdk/core/examples/vm_query.rs +++ b/sdk/core/examples/vm_query.rs @@ -1,6 +1,6 @@ use multiversx_sdk::{ data::{address::Address, vm::VmValueRequest}, - gateway::{GatewayProxy, DEVNET_GATEWAY}, + gateway::{GatewayProxy, DEFAULT_USE_CHAIN_SIMULATOR, DEVNET_GATEWAY}, wallet::Wallet, }; @@ -11,7 +11,7 @@ async fn main() { ) .unwrap(); let addr = wl.address(); - let blockchain = GatewayProxy::new(DEVNET_GATEWAY.to_string()); + let blockchain = GatewayProxy::new(DEVNET_GATEWAY.to_string(), DEFAULT_USE_CHAIN_SIMULATOR); let req = VmValueRequest { sc_address: Address::from_bech32_string( "erd1qqqqqqqqqqqqqpgqhn3ae8dpc957t7jadn7kywtg503dy7pnj9ts3umqxx", diff --git a/sdk/core/src/gateway.rs b/sdk/core/src/gateway.rs index 33a263607e..c0fc0062d2 100644 --- a/sdk/core/src/gateway.rs +++ b/sdk/core/src/gateway.rs @@ -1,10 +1,10 @@ mod gateway_account; mod gateway_block; +mod gateway_chain_simulator; mod gateway_network; mod gateway_proxy; mod gateway_tx; mod gateway_tx_retrieve; -mod gateway_chain_simulator; pub use gateway_proxy::GatewayProxy; @@ -15,3 +15,5 @@ pub const SIMULATOR_GATEWAY: &str = "http://localhost:8085"; // MetachainShardId will be used to identify a shard ID as metachain pub const METACHAIN_SHARD_ID: u32 = 0xFFFFFFFF; + +pub const DEFAULT_USE_CHAIN_SIMULATOR: bool = false; diff --git a/sdk/core/src/gateway/gateway_proxy.rs b/sdk/core/src/gateway/gateway_proxy.rs index f3693c6e12..46e48455e5 100644 --- a/sdk/core/src/gateway/gateway_proxy.rs +++ b/sdk/core/src/gateway/gateway_proxy.rs @@ -1,27 +1,23 @@ use reqwest::Client; -pub const CHAIN_SIMULATOR_GATEWAY: &str = "http://localhost:8085"; - /// Allows communication with the MultiversX gateway API. #[derive(Clone, Debug)] pub struct GatewayProxy { - pub(crate) proxy_url: String, + pub(crate) proxy_uri: String, pub(crate) client: Client, pub chain_simulator: bool, } impl GatewayProxy { - pub fn new(proxy_url: String) -> Self { - let chain_simulator = proxy_url == CHAIN_SIMULATOR_GATEWAY; - + pub fn new(proxy_uri: String, chain_simulator: bool) -> Self { Self { - proxy_url, + proxy_uri, client: Client::new(), chain_simulator, } } pub(crate) fn get_endpoint(&self, endpoint: &str) -> String { - format!("{}/{}", self.proxy_url, endpoint) + format!("{}/{}", self.proxy_uri, endpoint) } } diff --git a/tools/interactor-system-func-calls/config.toml b/tools/interactor-system-func-calls/config.toml index 61ac8dbf87..dfc1ba62a6 100644 --- a/tools/interactor-system-func-calls/config.toml +++ b/tools/interactor-system-func-calls/config.toml @@ -1 +1,2 @@ -gateway = 'https://devnet-gateway.multiversx.com' +chain_type = 'real' +gateway_uri = 'https://devnet-gateway.multiversx.com' diff --git a/tools/interactor-system-func-calls/src/system_sc_interact.rs b/tools/interactor-system-func-calls/src/system_sc_interact.rs index 4ec3c6647e..dbfa11a14e 100644 --- a/tools/interactor-system-func-calls/src/system_sc_interact.rs +++ b/tools/interactor-system-func-calls/src/system_sc_interact.rs @@ -227,7 +227,8 @@ struct SysFuncCallsInteract { impl SysFuncCallsInteract { async fn init() -> Self { let config = Config::load_config(); - let mut interactor = Interactor::new(config.gateway()).await; + let mut interactor = + Interactor::new(config.gateway_uri(), config.use_chain_simulator()).await; let wallet_address = interactor.register_wallet(test_wallets::alice()).await; diff --git a/tools/interactor-system-func-calls/src/system_sc_interact_config.rs b/tools/interactor-system-func-calls/src/system_sc_interact_config.rs index 4495f069b8..5058d06268 100644 --- a/tools/interactor-system-func-calls/src/system_sc_interact_config.rs +++ b/tools/interactor-system-func-calls/src/system_sc_interact_config.rs @@ -2,12 +2,13 @@ use serde::Deserialize; use std::io::Read; /// Config file -const CONFIG_FILE: &str = "../config.toml"; +const CONFIG_FILE: &str = "config.toml"; /// SysFuncCalls Interact configuration #[derive(Debug, Deserialize)] pub struct Config { - gateway: String, + gateway_uri: String, + chain_type: String, } impl Config { @@ -19,8 +20,20 @@ impl Config { toml::from_str(&content).unwrap() } - // Returns the gateway - pub fn gateway(&self) -> &str { - &self.gateway + // Returns the gateway URI + pub fn gateway_uri(&self) -> &str { + &self.gateway_uri + } + + // Returns if chain type is chain simulator + pub fn use_chain_simulator(&self) -> bool { + match self.chain_type.as_str() { + "simulator" => return true, + "real" => return false, + _ => panic!( + "Invalid chain type: {}. Expected 'simulator' or 'real'.", + self.chain_type + ), + } } } From eb7dd570c109be75d9cab8919bf134efe5ba292a Mon Sep 17 00:00:00 2001 From: BiancaIalangi Date: Fri, 20 Sep 2024 09:32:37 +0300 Subject: [PATCH 017/185] chain sim - add gateway_uri in adder config --- contracts/examples/adder/interact/config.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contracts/examples/adder/interact/config.toml b/contracts/examples/adder/interact/config.toml index e474de08f5..d40bebad7f 100644 --- a/contracts/examples/adder/interact/config.toml +++ b/contracts/examples/adder/interact/config.toml @@ -1 +1,2 @@ -chain_type = "simulator" +chain_type = 'real' +gateway_uri = 'http://localhost:8085' \ No newline at end of file From 69d09a5467bf4cf31bb242bdcf53a8ea3d8f90c0 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Fri, 20 Sep 2024 15:38:09 +0300 Subject: [PATCH 018/185] unified syntax - tx hash in blackbox/whitebox tests --- .../scenario-tester/tests/st_blackbox_test.rs | 42 +++++++++++++++++++ .../scenario-tester/tests/st_whitebox_test.rs | 33 +++++++++++++++ framework/base/src/types/interaction/tx.rs | 6 +-- .../facade/result_handlers/returns_tx_hash.rs | 5 ++- .../facade/world_tx/scenario_tx_whitebox.rs | 24 ++--------- .../src/scenario/model/step/sc_call_step.rs | 3 +- .../src/scenario/model/step/sc_deploy_step.rs | 7 ++-- .../scenario/model/transaction/tx_response.rs | 6 +-- framework/snippets/src/network_response.rs | 14 ++++--- 9 files changed, 102 insertions(+), 38 deletions(-) diff --git a/contracts/feature-tests/scenario-tester/tests/st_blackbox_test.rs b/contracts/feature-tests/scenario-tester/tests/st_blackbox_test.rs index cdcf610b25..d3f78692e8 100644 --- a/contracts/feature-tests/scenario-tester/tests/st_blackbox_test.rs +++ b/contracts/feature-tests/scenario-tester/tests/st_blackbox_test.rs @@ -244,3 +244,45 @@ fn set_state_test() { .balance(600) .esdt_balance(TOKEN_ID, 60); } + +#[test] +fn st_blackbox_tx_hash() { + let mut world = world(); + + world + .account(OWNER_ADDRESS) + .nonce(1) + .balance(100) + .account(OTHER_ADDRESS) + .nonce(2) + .balance(300) + .esdt_balance(TOKEN_ID, 500) + .commit(); + + let (new_address, tx_hash) = world + .tx() + .from(OWNER_ADDRESS) + .typed(scenario_tester_proxy::ScenarioTesterProxy) + .init(5u32) + .code(CODE_PATH) + .new_address(ST_ADDRESS) + .tx_hash([11u8; 32]) + .returns(ReturnsNewAddress) + .returns(ReturnsTxHash) + .run(); + + assert_eq!(new_address, ST_ADDRESS.to_address()); + assert_eq!(tx_hash.as_array(), &[11u8; 32]); + + let tx_hash = world + .tx() + .from(OWNER_ADDRESS) + .to(ST_ADDRESS) + .typed(scenario_tester_proxy::ScenarioTesterProxy) + .add(1u32) + .tx_hash([22u8; 32]) + .returns(ReturnsTxHash) + .run(); + + assert_eq!(tx_hash.as_array(), &[22u8; 32]); +} diff --git a/contracts/feature-tests/scenario-tester/tests/st_whitebox_test.rs b/contracts/feature-tests/scenario-tester/tests/st_whitebox_test.rs index 61dd6cdc2d..99e56d29f1 100644 --- a/contracts/feature-tests/scenario-tester/tests/st_whitebox_test.rs +++ b/contracts/feature-tests/scenario-tester/tests/st_whitebox_test.rs @@ -52,3 +52,36 @@ fn st_whitebox() { .check_account(SCENARIO_TESTER) .check_storage("str:sum", "8"); } + +#[test] +fn st_whitebox_tx_hash() { + let mut world = world(); + + world.account(OWNER).nonce(1); + + let (new_address, tx_hash) = world + .tx() + .from(OWNER) + .raw_deploy() + .code(ST_PATH_EXPR) + .new_address(SCENARIO_TESTER) + .tx_hash([11u8; 32]) + .returns(ReturnsNewBech32Address) + .returns(ReturnsTxHash) + .whitebox(scenario_tester::contract_obj, |sc| { + sc.init(BigUint::from(5u64)); + }); + + assert_eq!(new_address.to_address(), SCENARIO_TESTER.to_address()); + assert_eq!(tx_hash.as_array(), &[11u8; 32]); + + let tx_hash = world + .tx() + .from(OWNER) + .to(SCENARIO_TESTER) + .tx_hash([22u8; 32]) + .returns(ReturnsTxHash) + .whitebox(scenario_tester::contract_obj, |sc| sc.add(3u32.into())); + + assert_eq!(tx_hash.as_array(), &[22u8; 32]); +} diff --git a/framework/base/src/types/interaction/tx.rs b/framework/base/src/types/interaction/tx.rs index 905b9af8fc..b216ce0f28 100644 --- a/framework/base/src/types/interaction/tx.rs +++ b/framework/base/src/types/interaction/tx.rs @@ -908,11 +908,11 @@ where impl Tx where Env: TxEnvWithTxHash, - From: TxFromSpecified, + From: TxFrom, To: TxTo, - Payment: TxPaymentEgldOnly, + Payment: TxPayment, Gas: TxGas, - Data: TxDataFunctionCall, + Data: TxData, RH: TxResultHandler, { /// Sets the mock transaction hash to be used in a test. diff --git a/framework/scenario/src/facade/result_handlers/returns_tx_hash.rs b/framework/scenario/src/facade/result_handlers/returns_tx_hash.rs index 7494b41edc..fb30ea1ff3 100644 --- a/framework/scenario/src/facade/result_handlers/returns_tx_hash.rs +++ b/framework/scenario/src/facade/result_handlers/returns_tx_hash.rs @@ -1,3 +1,4 @@ +use multiversx_chain_vm::types::H256; use multiversx_sc::types::RHListItemExec; use crate::{ @@ -11,7 +12,7 @@ impl RHListItem for ReturnsTxHash where Env: TxEnv, { - type Returns = String; + type Returns = H256; } impl RHListItemExec for ReturnsTxHash @@ -19,6 +20,6 @@ where Env: TxEnv, { fn item_process_result(self, raw_result: &TxResponse) -> Self::Returns { - raw_result.tx_hash.clone() + raw_result.tx_hash.clone().expect("missing tx hash") } } diff --git a/framework/scenario/src/facade/world_tx/scenario_tx_whitebox.rs b/framework/scenario/src/facade/world_tx/scenario_tx_whitebox.rs index e20538ce0e..f8d03dc6da 100644 --- a/framework/scenario/src/facade/world_tx/scenario_tx_whitebox.rs +++ b/framework/scenario/src/facade/world_tx/scenario_tx_whitebox.rs @@ -1,5 +1,3 @@ -use core::str; - use crate::debug_executor::contract_instance_wrapped_execution; use crate::scenario::tx_to_step::TxToQueryStep; use crate::{ @@ -57,6 +55,7 @@ where let contract_obj = contract_obj_builder(); let mut step_wrapper = self.tx_to_step(); + step_wrapper.step.explicit_tx_hash = core::mem::take(&mut step_wrapper.env.data.tx_hash); let (new_address, tx_result) = step_wrapper .env .world @@ -70,15 +69,6 @@ where }); let mut response = TxResponse::from_tx_result(tx_result); - if let Some(tx_hash) = &step_wrapper.env.data.tx_hash { - let tx_hash_bytes = tx_hash.as_bytes(); - response.tx_hash = str::from_utf8(tx_hash_bytes) - .expect("tx hash not utf8 valid") - .to_string(); - } else { - response.tx_hash = String::from(""); - } - response.new_deployed_address = Some(new_address); step_wrapper.step.save_response(response); step_wrapper.process_result() @@ -133,6 +123,7 @@ where let contract_obj = contract_obj_builder(); let mut step_wrapper = self.tx_to_step(); + step_wrapper.step.explicit_tx_hash = core::mem::take(&mut step_wrapper.env.data.tx_hash); // no endpoint is called per se, but if it is empty, the VM thinks it is a simple transfer of value if step_wrapper.step.tx.function.is_empty() { @@ -151,16 +142,7 @@ where }); }); - let mut response = TxResponse::from_tx_result(tx_result); - if let Some(tx_hash) = &step_wrapper.env.data.tx_hash { - let tx_hash_bytes = tx_hash.as_bytes(); - response.tx_hash = str::from_utf8(tx_hash_bytes) - .expect("tx hash not utf8 valid") - .to_string(); - } else { - response.tx_hash = String::from(""); - } - + let response = TxResponse::from_tx_result(tx_result); step_wrapper.step.save_response(response); step_wrapper.process_result() } diff --git a/framework/scenario/src/scenario/model/step/sc_call_step.rs b/framework/scenario/src/scenario/model/step/sc_call_step.rs index 4a68bfa000..2a25fb2c2f 100644 --- a/framework/scenario/src/scenario/model/step/sc_call_step.rs +++ b/framework/scenario/src/scenario/model/step/sc_call_step.rs @@ -205,12 +205,13 @@ impl ScCallStep { .expect("SC call response not yet available") } - pub fn save_response(&mut self, tx_response: TxResponse) { + pub fn save_response(&mut self, mut tx_response: TxResponse) { if let Some(expect) = &mut self.expect { if expect.build_from_response { expect.update_from_response(&tx_response) } } + tx_response.tx_hash = self.explicit_tx_hash.as_ref().map(|vm_hash| vm_hash.as_array().into()); self.response = Some(tx_response); } } diff --git a/framework/scenario/src/scenario/model/step/sc_deploy_step.rs b/framework/scenario/src/scenario/model/step/sc_deploy_step.rs index 7e520e1a17..3b22522f69 100644 --- a/framework/scenario/src/scenario/model/step/sc_deploy_step.rs +++ b/framework/scenario/src/scenario/model/step/sc_deploy_step.rs @@ -135,13 +135,14 @@ impl ScDeployStep { .expect("SC deploy response not yet available") } - pub fn save_response(&mut self, response: TxResponse) { + pub fn save_response(&mut self, mut tx_response: TxResponse) { if let Some(expect) = &mut self.expect { if expect.build_from_response { - expect.update_from_response(&response) + expect.update_from_response(&tx_response) } } - self.response = Some(response); + tx_response.tx_hash = self.explicit_tx_hash.as_ref().map(|vm_hash| vm_hash.as_array().into()); + self.response = Some(tx_response); } } diff --git a/framework/scenario/src/scenario/model/transaction/tx_response.rs b/framework/scenario/src/scenario/model/transaction/tx_response.rs index b230fd1878..547b381338 100644 --- a/framework/scenario/src/scenario/model/transaction/tx_response.rs +++ b/framework/scenario/src/scenario/model/transaction/tx_response.rs @@ -1,4 +1,4 @@ -use multiversx_chain_vm::tx_mock::TxResult; +use multiversx_chain_vm::{tx_mock::TxResult, types::H256}; use multiversx_sc::types::Address; use super::{Log, TxExpect, TxResponseStatus}; @@ -20,8 +20,8 @@ pub struct TxResponse { pub gas: u64, /// The refund of the transaction. pub refund: u64, - /// The transaction hash - pub tx_hash: String, + /// The transaction hash, if available. + pub tx_hash: Option, } impl TxResponse { diff --git a/framework/snippets/src/network_response.rs b/framework/snippets/src/network_response.rs index 4684fdce3c..b5839e2e10 100644 --- a/framework/snippets/src/network_response.rs +++ b/framework/snippets/src/network_response.rs @@ -1,6 +1,6 @@ use multiversx_sc_scenario::{ imports::{Address, ESDTSystemSCAddress}, - multiversx_chain_vm::crypto_functions::keccak256, + multiversx_chain_vm::{crypto_functions::keccak256, types::H256}, scenario_model::{Log, TxResponse, TxResponseStatus}, }; use multiversx_sdk::{ @@ -17,7 +17,7 @@ pub fn parse_tx_response(tx: TransactionOnNetwork) -> TxResponse { if !tx_error.is_success() { return TxResponse { tx_error, - tx_hash: process_tx_hash(&tx).to_string(), + tx_hash: process_tx_hash(&tx), ..Default::default() }; } @@ -46,13 +46,17 @@ fn process_success(tx: &TransactionOnNetwork) -> TxResponse { new_deployed_address: process_new_deployed_address(tx), new_issued_token_identifier: process_new_issued_token_identifier(tx), logs: process_logs(tx), - tx_hash: process_tx_hash(tx).to_string(), + tx_hash: process_tx_hash(tx), ..Default::default() } } -fn process_tx_hash(tx: &TransactionOnNetwork) -> &str { - tx.hash.as_deref().unwrap_or("") +fn process_tx_hash(tx: &TransactionOnNetwork) -> Option { + tx.hash.as_ref().map(|encoded_hash| { + let decoded = hex::decode(encoded_hash).expect("error decoding tx hash from hex"); + assert_eq!(decoded.len(), 32); + H256::from_slice(&decoded) + }) } fn process_out(tx: &TransactionOnNetwork) -> Vec> { From b8853bc338e7e65b9f92eaa22dd9bcb348bb2e41 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Fri, 20 Sep 2024 15:55:56 +0300 Subject: [PATCH 019/185] unified syntax - tx hash refactor --- framework/base/src/types/interaction/tx_env.rs | 3 +++ .../src/facade/world_tx/scenario_exec_call.rs | 9 +++++---- .../src/facade/world_tx/scenario_exec_deploy.rs | 1 - .../src/facade/world_tx/scenario_tx_env.rs | 13 ++++++++++++- .../src/facade/world_tx/scenario_tx_whitebox.rs | 2 -- .../src/scenario/model/step/sc_call_step.rs | 5 ++++- .../src/scenario/model/step/sc_deploy_step.rs | 5 ++++- .../src/scenario/tx_to_step/tx_to_step_call.rs | 9 +++++---- .../src/scenario/tx_to_step/tx_to_step_deploy.rs | 8 +++++--- .../src/interactor_tx/interactor_exec_env.rs | 14 +++++++++++++- 10 files changed, 51 insertions(+), 18 deletions(-) diff --git a/framework/base/src/types/interaction/tx_env.rs b/framework/base/src/types/interaction/tx_env.rs index 37e18d7dec..188e304311 100644 --- a/framework/base/src/types/interaction/tx_env.rs +++ b/framework/base/src/types/interaction/tx_env.rs @@ -27,4 +27,7 @@ pub trait TxEnvMockDeployAddress: TxEnv { pub trait TxEnvWithTxHash: TxEnv { fn set_tx_hash(&mut self, tx_hash: H256); + + /// Retrieves current tx hash, while resetting it in self. + fn take_tx_hash(&mut self) -> Option; } diff --git a/framework/scenario/src/facade/world_tx/scenario_exec_call.rs b/framework/scenario/src/facade/world_tx/scenario_exec_call.rs index 8905c7d14d..ca09b9d318 100644 --- a/framework/scenario/src/facade/world_tx/scenario_exec_call.rs +++ b/framework/scenario/src/facade/world_tx/scenario_exec_call.rs @@ -85,7 +85,6 @@ where fn run(self) -> Self::Returns { let mut step_wrapper = self.tx_to_step(); - step_wrapper.step.explicit_tx_hash = core::mem::take(&mut step_wrapper.env.data.tx_hash); step_wrapper.env.world.sc_call(&mut step_wrapper.step); step_wrapper.process_result() } @@ -111,7 +110,6 @@ where fn run(self) -> Self::Returns { let mut step_wrapper = self.tx_to_step(); - step_wrapper.step.explicit_tx_hash = core::mem::take(&mut step_wrapper.env.data.tx_hash); step_wrapper.env.world.sc_call(&mut step_wrapper.step); step_wrapper.process_result() } @@ -119,8 +117,11 @@ where impl<'w> TxEnvWithTxHash for ScenarioEnvExec<'w> { fn set_tx_hash(&mut self, tx_hash: H256) { - assert!(self.data.tx_hash.is_none(), "tx hash set twice"); - self.data.tx_hash = Some(tx_hash); + self.data.set_tx_hash(tx_hash); + } + + fn take_tx_hash(&mut self) -> Option { + self.data.take_tx_hash() } } diff --git a/framework/scenario/src/facade/world_tx/scenario_exec_deploy.rs b/framework/scenario/src/facade/world_tx/scenario_exec_deploy.rs index 40fbbaa878..866d4f562f 100644 --- a/framework/scenario/src/facade/world_tx/scenario_exec_deploy.rs +++ b/framework/scenario/src/facade/world_tx/scenario_exec_deploy.rs @@ -35,7 +35,6 @@ where fn run(self) -> Self::Returns { let mut step_wrapper = self.tx_to_step(); - step_wrapper.step.explicit_tx_hash = core::mem::take(&mut step_wrapper.env.data.tx_hash); step_wrapper.env.world.sc_deploy(&mut step_wrapper.step); step_wrapper.process_result() } diff --git a/framework/scenario/src/facade/world_tx/scenario_tx_env.rs b/framework/scenario/src/facade/world_tx/scenario_tx_env.rs index 339ed9b38b..c3a2a1c204 100644 --- a/framework/scenario/src/facade/world_tx/scenario_tx_env.rs +++ b/framework/scenario/src/facade/world_tx/scenario_tx_env.rs @@ -1,5 +1,5 @@ use multiversx_chain_scenario_format::interpret_trait::InterpreterContext; -use multiversx_sc::types::{ManagedAddress, ManagedBuffer, TxEnv, H256}; +use multiversx_sc::types::{ManagedAddress, ManagedBuffer, TxEnv, TxEnvWithTxHash, H256}; use crate::{api::StaticApi, scenario_model::TxExpect, ScenarioWorld}; @@ -33,6 +33,17 @@ impl TxEnv for ScenarioTxEnvData { } } +impl TxEnvWithTxHash for ScenarioTxEnvData { + fn set_tx_hash(&mut self, tx_hash: H256) { + assert!(self.tx_hash.is_none(), "tx hash set twice"); + self.tx_hash = Some(tx_hash); + } + + fn take_tx_hash(&mut self) -> Option { + core::mem::take(&mut self.tx_hash) + } +} + impl ScenarioTxEnvData { pub fn interpreter_context(&self) -> InterpreterContext { self.interpreter_context.clone() diff --git a/framework/scenario/src/facade/world_tx/scenario_tx_whitebox.rs b/framework/scenario/src/facade/world_tx/scenario_tx_whitebox.rs index f8d03dc6da..62842a6e25 100644 --- a/framework/scenario/src/facade/world_tx/scenario_tx_whitebox.rs +++ b/framework/scenario/src/facade/world_tx/scenario_tx_whitebox.rs @@ -55,7 +55,6 @@ where let contract_obj = contract_obj_builder(); let mut step_wrapper = self.tx_to_step(); - step_wrapper.step.explicit_tx_hash = core::mem::take(&mut step_wrapper.env.data.tx_hash); let (new_address, tx_result) = step_wrapper .env .world @@ -123,7 +122,6 @@ where let contract_obj = contract_obj_builder(); let mut step_wrapper = self.tx_to_step(); - step_wrapper.step.explicit_tx_hash = core::mem::take(&mut step_wrapper.env.data.tx_hash); // no endpoint is called per se, but if it is empty, the VM thinks it is a simple transfer of value if step_wrapper.step.tx.function.is_empty() { diff --git a/framework/scenario/src/scenario/model/step/sc_call_step.rs b/framework/scenario/src/scenario/model/step/sc_call_step.rs index 2a25fb2c2f..8d8d71b0e8 100644 --- a/framework/scenario/src/scenario/model/step/sc_call_step.rs +++ b/framework/scenario/src/scenario/model/step/sc_call_step.rs @@ -211,7 +211,10 @@ impl ScCallStep { expect.update_from_response(&tx_response) } } - tx_response.tx_hash = self.explicit_tx_hash.as_ref().map(|vm_hash| vm_hash.as_array().into()); + tx_response.tx_hash = self + .explicit_tx_hash + .as_ref() + .map(|vm_hash| vm_hash.as_array().into()); self.response = Some(tx_response); } } diff --git a/framework/scenario/src/scenario/model/step/sc_deploy_step.rs b/framework/scenario/src/scenario/model/step/sc_deploy_step.rs index 3b22522f69..6090cfd492 100644 --- a/framework/scenario/src/scenario/model/step/sc_deploy_step.rs +++ b/framework/scenario/src/scenario/model/step/sc_deploy_step.rs @@ -141,7 +141,10 @@ impl ScDeployStep { expect.update_from_response(&tx_response) } } - tx_response.tx_hash = self.explicit_tx_hash.as_ref().map(|vm_hash| vm_hash.as_array().into()); + tx_response.tx_hash = self + .explicit_tx_hash + .as_ref() + .map(|vm_hash| vm_hash.as_array().into()); self.response = Some(tx_response); } } diff --git a/framework/scenario/src/scenario/tx_to_step/tx_to_step_call.rs b/framework/scenario/src/scenario/tx_to_step/tx_to_step_call.rs index 475326eac7..1d1eb2c9a2 100644 --- a/framework/scenario/src/scenario/tx_to_step/tx_to_step_call.rs +++ b/framework/scenario/src/scenario/tx_to_step/tx_to_step_call.rs @@ -1,6 +1,6 @@ use multiversx_sc::types::{ - Code, FunctionCall, NotPayable, RHListExec, Tx, TxEnv, TxFromSpecified, TxGas, TxPayment, - TxToSpecified, UpgradeCall, + Code, FunctionCall, NotPayable, RHListExec, Tx, TxEnv, TxEnvWithTxHash, TxFromSpecified, TxGas, + TxPayment, TxToSpecified, UpgradeCall, }; use crate::{ @@ -14,7 +14,7 @@ use super::{address_annotated, gas_annotated, StepWrapper, TxToStep}; impl TxToStep for Tx, RH> where - Env: TxEnv, + Env: TxEnvWithTxHash, From: TxFromSpecified, To: TxToSpecified, Payment: TxPayment, @@ -23,7 +23,7 @@ where { type Step = ScCallStep; - fn tx_to_step(self) -> StepWrapper { + fn tx_to_step(mut self) -> StepWrapper { let mut step = tx_to_sc_call_step( &self.env, self.from, @@ -32,6 +32,7 @@ where self.gas, self.data, ); + step.explicit_tx_hash = self.env.take_tx_hash(); step.expect = Some(self.result_handler.list_tx_expect()); StepWrapper { diff --git a/framework/scenario/src/scenario/tx_to_step/tx_to_step_deploy.rs b/framework/scenario/src/scenario/tx_to_step/tx_to_step_deploy.rs index 4e49be51b4..1c7532e27a 100644 --- a/framework/scenario/src/scenario/tx_to_step/tx_to_step_deploy.rs +++ b/framework/scenario/src/scenario/tx_to_step/tx_to_step_deploy.rs @@ -1,5 +1,6 @@ use multiversx_sc::types::{ - Code, DeployCall, RHListExec, Tx, TxCodeValue, TxEnv, TxFromSpecified, TxGas, TxPayment, + Code, DeployCall, RHListExec, Tx, TxCodeValue, TxEnv, TxEnvWithTxHash, TxFromSpecified, TxGas, + TxPayment, }; use crate::scenario_model::{ScDeployStep, TxExpect, TxResponse}; @@ -9,7 +10,7 @@ use super::{address_annotated, code_annotated, gas_annotated, StepWrapper, TxToS impl TxToStep for Tx>, RH> where - Env: TxEnv, + Env: TxEnvWithTxHash, From: TxFromSpecified, Payment: TxPayment, Gas: TxGas, @@ -18,9 +19,10 @@ where { type Step = ScDeployStep; - fn tx_to_step(self) -> StepWrapper { + fn tx_to_step(mut self) -> StepWrapper { let mut step = tx_to_sc_deploy_step(&self.env, self.from, self.payment, self.gas, self.data); + step.explicit_tx_hash = self.env.take_tx_hash(); step.expect = Some(self.result_handler.list_tx_expect()); StepWrapper { diff --git a/framework/snippets/src/interactor_tx/interactor_exec_env.rs b/framework/snippets/src/interactor_tx/interactor_exec_env.rs index 6473c50a91..436e65ac0c 100644 --- a/framework/snippets/src/interactor_tx/interactor_exec_env.rs +++ b/framework/snippets/src/interactor_tx/interactor_exec_env.rs @@ -1,6 +1,8 @@ use multiversx_sc_scenario::{ api::StaticApi, - multiversx_sc::types::{ManagedAddress, ManagedBuffer, Tx, TxBaseWithEnv, TxEnv}, + multiversx_sc::types::{ + ManagedAddress, ManagedBuffer, Tx, TxBaseWithEnv, TxEnv, TxEnvWithTxHash, H256, + }, scenario_model::TxExpect, ScenarioTxEnv, ScenarioTxEnvData, }; @@ -44,3 +46,13 @@ impl<'w> ScenarioTxEnv for InteractorEnvExec<'w> { &self.data } } + +impl<'w> TxEnvWithTxHash for InteractorEnvExec<'w> { + fn set_tx_hash(&mut self, tx_hash: H256) { + self.data.set_tx_hash(tx_hash); + } + + fn take_tx_hash(&mut self) -> Option { + self.data.take_tx_hash() + } +} From 09c8e3491f9a6e7fbcf0f99af77640096aa4b396 Mon Sep 17 00:00:00 2001 From: BiancaIalangi Date: Fri, 20 Sep 2024 17:28:16 +0300 Subject: [PATCH 020/185] fix interactor tests --- sdk/core/examples/account_storage.rs | 2 +- sdk/core/examples/get_hyper_block_by_hash.rs | 2 +- sdk/core/examples/get_hyper_block_latest.rs | 2 +- sdk/core/examples/tx_info.rs | 2 +- sdk/core/examples/vm_query.rs | 9 +++------ sdk/core/src/gateway/gateway_block.rs | 8 ++------ 6 files changed, 9 insertions(+), 16 deletions(-) diff --git a/sdk/core/examples/account_storage.rs b/sdk/core/examples/account_storage.rs index c7d5bda76e..148cc644da 100644 --- a/sdk/core/examples/account_storage.rs +++ b/sdk/core/examples/account_storage.rs @@ -6,7 +6,7 @@ use multiversx_sdk::{ #[tokio::main] async fn main() { let addr = Address::from_bech32_string( - "erd1932eft30w753xyvme8d49qejgkjc09n5e49w4mwdjtm0neld797su0dlxp", + "erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th", ) .unwrap(); diff --git a/sdk/core/examples/get_hyper_block_by_hash.rs b/sdk/core/examples/get_hyper_block_by_hash.rs index a67ea311d3..d6f36e2aba 100644 --- a/sdk/core/examples/get_hyper_block_by_hash.rs +++ b/sdk/core/examples/get_hyper_block_by_hash.rs @@ -4,7 +4,7 @@ use multiversx_sdk::gateway::{GatewayProxy, DEFAULT_USE_CHAIN_SIMULATOR, DEVNET_ async fn main() { let blockchain = GatewayProxy::new(DEVNET_GATEWAY.to_string(), DEFAULT_USE_CHAIN_SIMULATOR); let result = blockchain - .get_hyper_block_by_hash("20b14ba0e68c465810c5ded091f220e51dad41629d7ccd87dab572206185e419") + .get_hyper_block_by_hash("d59e0dc7d407b1175655357cb8056ec3bb77961192753cddda2fb700c6ce71c6") .await; println!("block by hash result: {result:?}"); diff --git a/sdk/core/examples/get_hyper_block_latest.rs b/sdk/core/examples/get_hyper_block_latest.rs index fe49fa7f1e..91ddd9e9c7 100644 --- a/sdk/core/examples/get_hyper_block_latest.rs +++ b/sdk/core/examples/get_hyper_block_latest.rs @@ -3,7 +3,7 @@ use multiversx_sdk::gateway::{GatewayProxy, DEFAULT_USE_CHAIN_SIMULATOR, DEVNET_ #[tokio::main] async fn main() { let blockchain = GatewayProxy::new(DEVNET_GATEWAY.to_string(), DEFAULT_USE_CHAIN_SIMULATOR); - let result = blockchain.get_latest_hyper_block_nonce(false).await; + let result = blockchain.get_latest_hyper_block_nonce().await; println!("latest block result: {result:?}") } diff --git a/sdk/core/examples/tx_info.rs b/sdk/core/examples/tx_info.rs index 11481d2ec1..d2c4cc93ef 100644 --- a/sdk/core/examples/tx_info.rs +++ b/sdk/core/examples/tx_info.rs @@ -2,7 +2,7 @@ use multiversx_sdk::gateway::{GatewayProxy, DEFAULT_USE_CHAIN_SIMULATOR, DEVNET_ #[tokio::main] async fn main() { - let tx_hash = "49edb289892a655a0e988b360c19326c21107f9696c6197b435667c6e8c6e1a3"; + let tx_hash = "fd21782ddb9e2217a3239e849e39d1d2c8fa74142a73f2dda3adb3028c0514e9"; let blockchain = GatewayProxy::new(DEVNET_GATEWAY.to_string(), DEFAULT_USE_CHAIN_SIMULATOR); let status = blockchain.get_transaction_status(tx_hash).await; diff --git a/sdk/core/examples/vm_query.rs b/sdk/core/examples/vm_query.rs index 750316fee6..51e37f6f68 100644 --- a/sdk/core/examples/vm_query.rs +++ b/sdk/core/examples/vm_query.rs @@ -6,18 +6,15 @@ use multiversx_sdk::{ #[tokio::main] async fn main() { - let wl = Wallet::from_private_key( - "1648ad209d6b157a289884933e3bb30f161ec7113221ec16f87c3578b05830b0", - ) - .unwrap(); + let wl = Wallet::from_pem_file("sdk/core/tests/alice.pem").unwrap(); let addr = wl.address(); let blockchain = GatewayProxy::new(DEVNET_GATEWAY.to_string(), DEFAULT_USE_CHAIN_SIMULATOR); let req = VmValueRequest { sc_address: Address::from_bech32_string( - "erd1qqqqqqqqqqqqqpgqhn3ae8dpc957t7jadn7kywtg503dy7pnj9ts3umqxx", + "erd1qqqqqqqqqqqqqpgq5dvvkmka7sujfsx7cfmygnx0n7luv8k0d8sskpqcec", ) .unwrap(), - func_name: "get".to_string(), + func_name: "empty".to_string(), args: vec![], caller: addr.clone(), value: "0".to_string(), diff --git a/sdk/core/src/gateway/gateway_block.rs b/sdk/core/src/gateway/gateway_block.rs index b6daf57abb..5e1af681ee 100644 --- a/sdk/core/src/gateway/gateway_block.rs +++ b/sdk/core/src/gateway/gateway_block.rs @@ -41,12 +41,8 @@ impl GatewayProxy { } // get_latest_hyper_block_nonce retrieves the latest hyper block (metachain) nonce from the network - pub async fn get_latest_hyper_block_nonce(&self, with_metachain: bool) -> Result { - let mut endpoint = GET_NETWORK_STATUS_ENDPOINT.to_string(); - - if with_metachain { - endpoint = format!("{GET_NETWORK_STATUS_ENDPOINT}/{METACHAIN_SHARD_ID}"); - } + pub async fn get_latest_hyper_block_nonce(&self) -> Result { + let endpoint = format!("{GET_NETWORK_STATUS_ENDPOINT}/{METACHAIN_SHARD_ID}"); let endpoint = self.get_endpoint(endpoint.as_str()); From c69e89adcb200946475b5ed51a7527cdd551f358 Mon Sep 17 00:00:00 2001 From: BiancaIalangi Date: Fri, 20 Sep 2024 17:35:45 +0300 Subject: [PATCH 021/185] chain sim - fix clippy --- .../examples/adder/interact/src/basic_interact_config.rs | 4 ++-- .../multisig/interact/src/multisig_interact_config.rs | 4 ++-- .../basic-features/interact/src/bf_interact_config.rs | 4 ++-- .../composability/interact/src/comp_interact_config.rs | 4 ++-- .../src/system_sc_interact_config.rs | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/contracts/examples/adder/interact/src/basic_interact_config.rs b/contracts/examples/adder/interact/src/basic_interact_config.rs index 2ab2577ceb..a49cc6ff7a 100644 --- a/contracts/examples/adder/interact/src/basic_interact_config.rs +++ b/contracts/examples/adder/interact/src/basic_interact_config.rs @@ -28,8 +28,8 @@ impl Config { // Returns if chain type is chain simulator pub fn use_chain_simulator(&self) -> bool { match self.chain_type.as_str() { - "simulator" => return true, - "real" => return false, + "simulator" => true, + "real" => false, _ => panic!( "Invalid chain type: {}. Expected 'simulator' or 'real'.", self.chain_type diff --git a/contracts/examples/multisig/interact/src/multisig_interact_config.rs b/contracts/examples/multisig/interact/src/multisig_interact_config.rs index ec280f4807..dd73c46092 100644 --- a/contracts/examples/multisig/interact/src/multisig_interact_config.rs +++ b/contracts/examples/multisig/interact/src/multisig_interact_config.rs @@ -31,8 +31,8 @@ impl Config { // Returns if chain type is chain simulator pub fn use_chain_simulator(&self) -> bool { match self.chain_type.as_str() { - "simulator" => return true, - "real" => return false, + "simulator" => true, + "real" => false, _ => panic!( "Invalid chain type: {}. Expected 'simulator' or 'real'.", self.chain_type diff --git a/contracts/feature-tests/basic-features/interact/src/bf_interact_config.rs b/contracts/feature-tests/basic-features/interact/src/bf_interact_config.rs index 9c6cb6ef0f..0257511464 100644 --- a/contracts/feature-tests/basic-features/interact/src/bf_interact_config.rs +++ b/contracts/feature-tests/basic-features/interact/src/bf_interact_config.rs @@ -28,8 +28,8 @@ impl Config { // Returns if true if chain type is chain simulator pub fn use_chain_simulator(&self) -> bool { match self.chain_type.as_str() { - "simulator" => return true, - "real" => return false, + "simulator" => true, + "real" => false, _ => panic!( "Invalid chain type: {}. Expected 'simulator' or 'real'.", self.chain_type diff --git a/contracts/feature-tests/composability/interact/src/comp_interact_config.rs b/contracts/feature-tests/composability/interact/src/comp_interact_config.rs index 96524d1bde..3a261b3f55 100644 --- a/contracts/feature-tests/composability/interact/src/comp_interact_config.rs +++ b/contracts/feature-tests/composability/interact/src/comp_interact_config.rs @@ -36,8 +36,8 @@ impl Config { // Returns if chain type is chain simulator pub fn use_chain_simulator(&self) -> bool { match self.chain_type.as_str() { - "simulator" => return true, - "real" => return false, + "simulator" => true, + "real" => false, _ => panic!( "Invalid chain type: {}. Expected 'simulator' or 'real'.", self.chain_type diff --git a/tools/interactor-system-func-calls/src/system_sc_interact_config.rs b/tools/interactor-system-func-calls/src/system_sc_interact_config.rs index 5058d06268..4fff392c11 100644 --- a/tools/interactor-system-func-calls/src/system_sc_interact_config.rs +++ b/tools/interactor-system-func-calls/src/system_sc_interact_config.rs @@ -28,8 +28,8 @@ impl Config { // Returns if chain type is chain simulator pub fn use_chain_simulator(&self) -> bool { match self.chain_type.as_str() { - "simulator" => return true, - "real" => return false, + "simulator" => true, + "real" => false, _ => panic!( "Invalid chain type: {}. Expected 'simulator' or 'real'.", self.chain_type From 265a9fa6c92805b5190ae56f7c89c212e3283463 Mon Sep 17 00:00:00 2001 From: BiancaIalangi Date: Fri, 20 Sep 2024 23:14:11 +0300 Subject: [PATCH 022/185] wasm-extractor - fix report parameters --- contracts/examples/empty/src/empty.rs | 4 +- framework/meta-lib/src/code_report_json.rs | 2 +- .../meta-lib/src/tools/report_creator.rs | 24 +++++++++-- .../meta-lib/src/tools/wasm_extractor.rs | 40 ++++++++++++------- 4 files changed, 50 insertions(+), 20 deletions(-) diff --git a/contracts/examples/empty/src/empty.rs b/contracts/examples/empty/src/empty.rs index 81353a08d9..e7495881d3 100644 --- a/contracts/examples/empty/src/empty.rs +++ b/contracts/examples/empty/src/empty.rs @@ -7,7 +7,9 @@ use multiversx_sc::imports::*; #[multiversx_sc::contract] pub trait EmptyContract { #[init] - fn init(&self) {} + fn init(&self) -> u32 { + 64 + } #[upgrade] fn upgrade(&self) {} diff --git a/framework/meta-lib/src/code_report_json.rs b/framework/meta-lib/src/code_report_json.rs index a0b997bb6e..b1ec390436 100644 --- a/framework/meta-lib/src/code_report_json.rs +++ b/framework/meta-lib/src/code_report_json.rs @@ -24,7 +24,7 @@ impl CodeReportJson { path: report.path.clone(), size, has_allocator: report.has_allocator, - has_panic: report.has_panic.clone(), + has_panic: report.has_panic.to_string(), } } } diff --git a/framework/meta-lib/src/tools/report_creator.rs b/framework/meta-lib/src/tools/report_creator.rs index 37af10fa4e..93cc44e14c 100644 --- a/framework/meta-lib/src/tools/report_creator.rs +++ b/framework/meta-lib/src/tools/report_creator.rs @@ -1,10 +1,28 @@ -pub const WITH_MESSAGE: &str = "with message"; -pub const WITHOUT_MESSAGE: &str = "without message"; +use std::fmt::Display; + +#[derive(Default)] +pub enum PanicMessage { + #[default] + None, + WithoutMessage, + WithMessage, +} + +impl Display for PanicMessage { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let panic_status = match self { + PanicMessage::None => "None", + PanicMessage::WithoutMessage => "without message", + PanicMessage::WithMessage => "with message", + }; + write!(f, "{}", panic_status) + } +} pub struct ReportCreator { pub path: String, pub has_allocator: bool, - pub has_panic: String, + pub has_panic: PanicMessage, } impl ReportCreator {} diff --git a/framework/meta-lib/src/tools/wasm_extractor.rs b/framework/meta-lib/src/tools/wasm_extractor.rs index 50d5b78aff..e2e7d8ddd6 100644 --- a/framework/meta-lib/src/tools/wasm_extractor.rs +++ b/framework/meta-lib/src/tools/wasm_extractor.rs @@ -1,17 +1,17 @@ use colored::Colorize; use std::fs; use wasmparser::{ - BinaryReaderError, DataSectionReader, FunctionBody, ImportSectionReader, Parser, Payload, + BinaryReaderError, DataSectionReader, FunctionBody, ImportSectionReader, Operator, Parser, + Payload, }; use crate::ei::EIVersion; -use super::report_creator::{ReportCreator, WITHOUT_MESSAGE, WITH_MESSAGE}; +use super::report_creator::{PanicMessage, ReportCreator}; const PANIC_WITH_MESSAGE: &[u8; 16] = b"panic occurred: "; const PANIC_WITHOUT_MESSAGE: &[u8; 14] = b"panic occurred"; const ERROR_FAIL_ALLOCATOR: &[u8; 27] = b"memory allocation forbidden"; -const MEMORY_GROW_OPCODE: u8 = 0x40; pub struct WasmInfo { pub imports: Vec, @@ -49,25 +49,35 @@ fn populate_wasm_info( let mut allocator_trigger = false; let mut ei_check = false; let mut memory_grow_flag = false; - let mut has_panic = "none"; + let mut has_panic: PanicMessage = PanicMessage::default(); let parser = Parser::new(0); for payload in parser.parse_all(&wasm_data) { match payload? { Payload::ImportSection(import_section) => { imports = extract_imports(import_section, extract_imports_enabled); - ei_check = is_ei_valid(imports.clone(), check_ei); + ei_check |= is_ei_valid(imports.clone(), check_ei); }, Payload::DataSection(data_section) => { - allocator_trigger = is_fail_allocator_triggered(data_section.clone()); - if is_panic_with_message_triggered(data_section.clone()) { - has_panic = WITH_MESSAGE; - } else if is_panic_without_message_triggered(data_section) { - has_panic = WITHOUT_MESSAGE; + allocator_trigger |= is_fail_allocator_triggered(data_section.clone()); + match has_panic { + PanicMessage::None => { + if is_panic_with_message_triggered(data_section.clone()) { + has_panic = PanicMessage::WithMessage; + } else if is_panic_without_message_triggered(data_section) { + has_panic = PanicMessage::WithoutMessage; + } + }, + PanicMessage::WithoutMessage => { + if is_panic_with_message_triggered(data_section.clone()) { + has_panic = PanicMessage::WithMessage; + } + }, + PanicMessage::WithMessage => continue, } }, Payload::CodeSectionEntry(code_section) => { - memory_grow_flag = is_mem_grow(code_section); + memory_grow_flag |= is_mem_grow(code_section); }, _ => (), } @@ -76,7 +86,7 @@ fn populate_wasm_info( let report = ReportCreator { path, has_allocator: allocator_trigger, - has_panic: has_panic.to_string(), + has_panic, }; Ok(WasmInfo { @@ -173,9 +183,9 @@ fn is_ei_valid(imports: Vec, check_ei: &Option) -> bool { } fn is_mem_grow(code_section: FunctionBody) -> bool { - let mut code = code_section.get_binary_reader(); - while code.bytes_remaining() > 0 { - if code.read_u8().unwrap() == MEMORY_GROW_OPCODE { + for op_reader in code_section.get_operators_reader().iter_mut() { + let op = op_reader.read().unwrap(); + if let Operator::MemoryGrow { mem: _ } = op { return true; } } From c096aae07b8bae2e4477bf5ca592df3b64acf4bc Mon Sep 17 00:00:00 2001 From: BiancaIalangi Date: Sat, 21 Sep 2024 23:54:44 +0300 Subject: [PATCH 023/185] wasm-extractor - fix mem_grow, create unitests --- Cargo.lock | 44 +++ framework/meta-lib/Cargo.toml | 1 + framework/meta-lib/src/tools.rs | 1 + .../meta-lib/src/tools/wasm_extractor.rs | 10 +- .../meta-lib/src/tools/wasm_extractor_test.rs | 297 ++++++++++++++++++ 5 files changed, 350 insertions(+), 3 deletions(-) create mode 100644 framework/meta-lib/src/tools/wasm_extractor_test.rs diff --git a/Cargo.lock b/Cargo.lock index b865897548..21b721ed78 100755 --- a/Cargo.lock +++ b/Cargo.lock @@ -1718,6 +1718,12 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +[[package]] +name = "leb128" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" + [[package]] name = "libc" version = "0.2.158" @@ -2090,6 +2096,7 @@ dependencies = [ "toml", "wasmparser", "wasmprinter", + "wat", ] [[package]] @@ -3680,6 +3687,12 @@ version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" +[[package]] +name = "unicode-width" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" + [[package]] name = "untrusted" version = "0.9.0" @@ -3873,6 +3886,15 @@ version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" +[[package]] +name = "wasm-encoder" +version = "0.217.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b88b0814c9a2b323a9b46c687e726996c255ac8b64aa237dd11c81ed4854760" +dependencies = [ + "leb128", +] + [[package]] name = "wasmparser" version = "0.216.0" @@ -3898,6 +3920,28 @@ dependencies = [ "wasmparser", ] +[[package]] +name = "wast" +version = "217.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79004ecebded92d3c710d4841383368c7f04b63d0992ddd6b0c7d5029b7629b7" +dependencies = [ + "bumpalo", + "leb128", + "memchr", + "unicode-width", + "wasm-encoder", +] + +[[package]] +name = "wat" +version = "1.217.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c126271c3d92ca0f7c63e4e462e40c69cca52fd4245fcda730d1cf558fb55088" +dependencies = [ + "wast", +] + [[package]] name = "web-sys" version = "0.3.70" diff --git a/framework/meta-lib/Cargo.toml b/framework/meta-lib/Cargo.toml index 8e9209fa9a..37d726fc0b 100644 --- a/framework/meta-lib/Cargo.toml +++ b/framework/meta-lib/Cargo.toml @@ -29,6 +29,7 @@ hex = "0.4" wasmparser = "0.216" wasmprinter = "0.216" semver = "1.0.20" +wat = "1.217.0" [dependencies.multiversx-sc] version = "=0.53.0" diff --git a/framework/meta-lib/src/tools.rs b/framework/meta-lib/src/tools.rs index e0a8962d9b..26fe22aaed 100644 --- a/framework/meta-lib/src/tools.rs +++ b/framework/meta-lib/src/tools.rs @@ -3,6 +3,7 @@ mod git_describe; pub(crate) mod report_creator; pub mod twiggy; mod wasm_extractor; +mod wasm_extractor_test; mod wasm_opt; mod wasm_to_wat; diff --git a/framework/meta-lib/src/tools/wasm_extractor.rs b/framework/meta-lib/src/tools/wasm_extractor.rs index e2e7d8ddd6..20173c88c3 100644 --- a/framework/meta-lib/src/tools/wasm_extractor.rs +++ b/framework/meta-lib/src/tools/wasm_extractor.rs @@ -39,7 +39,7 @@ impl WasmInfo { } } -fn populate_wasm_info( +pub(crate) fn populate_wasm_info( path: String, wasm_data: Vec, extract_imports_enabled: bool, @@ -183,11 +183,15 @@ fn is_ei_valid(imports: Vec, check_ei: &Option) -> bool { } fn is_mem_grow(code_section: FunctionBody) -> bool { - for op_reader in code_section.get_operators_reader().iter_mut() { - let op = op_reader.read().unwrap(); + let mut instructions_reader = code_section + .get_operators_reader() + .expect("Failed to get operators reader"); + + while let Ok(op) = instructions_reader.read() { if let Operator::MemoryGrow { mem: _ } = op { return true; } } + false } diff --git a/framework/meta-lib/src/tools/wasm_extractor_test.rs b/framework/meta-lib/src/tools/wasm_extractor_test.rs new file mode 100644 index 0000000000..e99e94f179 --- /dev/null +++ b/framework/meta-lib/src/tools/wasm_extractor_test.rs @@ -0,0 +1,297 @@ +#[cfg(test)] +pub mod tests { + use wat::Parser; + + use crate::tools::{report_creator::PanicMessage, wasm_extractor::populate_wasm_info}; + + const EMPTY_WITH_FAIL_ALLOCATOR: &str = r#" +(module $empty_wasm.wasm + (type (;0;) (func (result i32))) + (type (;1;) (func (param i32 i32))) + (type (;2;) (func)) + (import "env" "getNumArguments" (func $getNumArguments (;0;) (type 0))) + (import "env" "signalError" (func $signalError (;1;) (type 1))) + (import "env" "checkNoPayment" (func $checkNoPayment (;2;) (type 2))) + (func $_ZN13multiversx_sc2io16arg_nested_tuple22check_num_arguments_eq17hd731b4a37a0ab09aE (;3;) (type 2) + block ;; label = @1 + call $getNumArguments + br_if 0 (;@1;) + return + end + i32.const 131072 + i32.const 25 + call $signalError + unreachable + ) + (func $__rust_alloc (;4;) (type 2) + call $_ZN122_$LT$multiversx_sc_wasm_adapter..wasm_alloc..fail_allocator..FailAllocator$u20$as$u20$core..alloc..global..GlobalAlloc$GT$5alloc17hf044a79dd04bdcb1E + unreachable + ) + (func $_ZN122_$LT$multiversx_sc_wasm_adapter..wasm_alloc..fail_allocator..FailAllocator$u20$as$u20$core..alloc..global..GlobalAlloc$GT$5alloc17hf044a79dd04bdcb1E (;5;) (type 2) + call $_ZN26multiversx_sc_wasm_adapter10wasm_alloc14fail_allocator29signal_allocation_not_allowed17hb15b243b5f851b48E + unreachable + ) + (func $init (;6;) (type 2) + call $checkNoPayment + call $_ZN13multiversx_sc2io16arg_nested_tuple22check_num_arguments_eq17hd731b4a37a0ab09aE + i32.const 0 + i32.load8_u offset=131124 + drop + call $__rust_alloc + unreachable + ) + (func $upgrade (;7;) (type 2) + call $checkNoPayment + call $_ZN13multiversx_sc2io16arg_nested_tuple22check_num_arguments_eq17hd731b4a37a0ab09aE + ) + (func $callBack (;8;) (type 2)) + (func $_ZN26multiversx_sc_wasm_adapter10wasm_alloc14fail_allocator29signal_allocation_not_allowed17hb15b243b5f851b48E (;9;) (type 2) + i32.const 131097 + i32.const 27 + call $signalError + unreachable + ) + (memory (;0;) 3) + (global $__stack_pointer (;0;) (mut i32) i32.const 131072) + (global (;1;) i32 i32.const 131125) + (global (;2;) i32 i32.const 131136) + (export "memory" (memory 0)) + (export "init" (func $init)) + (export "upgrade" (func $upgrade)) + (export "callBack" (func $callBack)) + (export "__data_end" (global 1)) + (export "__heap_base" (global 2)) + (data $.rodata (;0;) (i32.const 131072) "wrong number of argumentsmemory allocation forbidden") +) +"#; + + const EMPTY_WITH_MEM_GROW: &str = r#" +(module $empty_wasm.wasm + (type (;0;) (func (result i32))) + (type (;1;) (func (param i32 i32))) + (type (;2;) (func)) + (type (;3;) (func (param i64))) + (import "env" "getNumArguments" (func $getNumArguments (;0;) (type 0))) + (import "env" "signalError" (func $signalError (;1;) (type 1))) + (import "env" "checkNoPayment" (func $checkNoPayment (;2;) (type 2))) + (import "env" "smallIntFinishUnsigned" (func $smallIntFinishUnsigned (;3;) (type 3))) + (func $_ZN13multiversx_sc2io16arg_nested_tuple22check_num_arguments_eq17hd731b4a37a0ab09aE (;4;) (type 2) + block ;; label = @1 + call $getNumArguments + br_if 0 (;@1;) + return + end + i32.const 131072 + i32.const 25 + call $signalError + unreachable + ) + (func $rust_begin_unwind (;5;) (type 2) + call $_ZN26multiversx_sc_wasm_adapter5panic9panic_fmt17he68b14ffa9b6b21eE + unreachable + ) + (func $_ZN26multiversx_sc_wasm_adapter5panic9panic_fmt17he68b14ffa9b6b21eE (;6;) (type 2) + i32.const 131097 + i32.const 14 + call $signalError + unreachable + ) + (func $init (;7;) (type 2) + (local i32 i32) + call $checkNoPayment + call $_ZN13multiversx_sc2io16arg_nested_tuple22check_num_arguments_eq17hd731b4a37a0ab09aE + i32.const 0 + i32.load8_u offset=131120 + drop + block ;; label = @1 + i32.const 0 + i32.load offset=131112 + local.tee 0 + i32.const 3 + i32.and + i32.eqz + br_if 0 (;@1;) + i32.const 0 + local.get 0 + i32.const -4 + i32.and + i32.const 4 + i32.add + local.tee 0 + i32.store offset=131112 + end + block ;; label = @1 + local.get 0 + i32.const 4 + i32.add + local.tee 1 + i32.const 0 + i32.load offset=131116 + i32.le_u + br_if 0 (;@1;) + i32.const 1 + memory.grow + local.set 0 + i32.const 0 + i32.load offset=131116 + local.set 1 + i32.const 0 + local.get 0 + i32.const 16 + i32.shl + local.tee 0 + i32.const 65536 + i32.add + i32.store offset=131116 + i32.const 0 + i32.load offset=131112 + local.get 0 + local.get 0 + local.get 1 + i32.eq + select + local.tee 0 + i32.const 4 + i32.add + local.set 1 + end + i32.const 0 + local.get 1 + i32.store offset=131112 + block ;; label = @1 + local.get 0 + i32.eqz + br_if 0 (;@1;) + local.get 0 + i32.const 42 + i32.store + i64.const 1 + call $smallIntFinishUnsigned + return + end + call $_ZN5alloc5alloc18handle_alloc_error17he71533634a7a5ac5E + unreachable + ) + (func $_ZN5alloc5alloc18handle_alloc_error17he71533634a7a5ac5E (;8;) (type 2) + call $__rust_alloc_error_handler + unreachable + ) + (func $upgrade (;9;) (type 2) + call $checkNoPayment + call $_ZN13multiversx_sc2io16arg_nested_tuple22check_num_arguments_eq17hd731b4a37a0ab09aE + ) + (func $callBack (;10;) (type 2)) + (func $__rust_alloc_error_handler (;11;) (type 2) + call $__rdl_oom + unreachable + ) + (func $__rdl_oom (;12;) (type 2) + call $_ZN4core9panicking18panic_nounwind_fmt17h21a92179d680342aE + unreachable + ) + (func $_ZN4core9panicking18panic_nounwind_fmt17h21a92179d680342aE (;13;) (type 2) + call $rust_begin_unwind + unreachable + ) + (memory (;0;) 3) + (global $__stack_pointer (;0;) (mut i32) i32.const 131072) + (global (;1;) i32 i32.const 131121) + (global (;2;) i32 i32.const 131136) + (export "memory" (memory 0)) + (export "init" (func $init)) + (export "upgrade" (func $upgrade)) + (export "callBack" (func $callBack)) + (export "__data_end" (global 1)) + (export "__heap_base" (global 2)) + (data $.rodata (;0;) (i32.const 131072) "wrong number of argumentspanic occurred") +) +"#; + + const EMPTY_DBG_WAT: &str = r#" +(module $empty_wasm.wasm + (type (;0;) (func (result i32))) + (type (;1;) (func (param i32 i32))) + (type (;2;) (func)) + (type (;3;) (func (param i64))) + (import "env" "getNumArguments" (func $getNumArguments (;0;) (type 0))) + (import "env" "signalError" (func $signalError (;1;) (type 1))) + (import "env" "checkNoPayment" (func $checkNoPayment (;2;) (type 2))) + (import "env" "smallIntFinishUnsigned" (func $smallIntFinishUnsigned (;3;) (type 3))) + (func $_ZN13multiversx_sc2io16arg_nested_tuple22check_num_arguments_eq17hd731b4a37a0ab09aE (;4;) (type 2) + block ;; label = @1 + call $getNumArguments + br_if 0 (;@1;) + return + end + i32.const 131072 + i32.const 25 + call $signalError + unreachable + ) + (func $init (;5;) (type 2) + call $checkNoPayment + call $_ZN13multiversx_sc2io16arg_nested_tuple22check_num_arguments_eq17hd731b4a37a0ab09aE + i64.const 64 + call $smallIntFinishUnsigned + ) + (func $upgrade (;6;) (type 2) + call $checkNoPayment + call $_ZN13multiversx_sc2io16arg_nested_tuple22check_num_arguments_eq17hd731b4a37a0ab09aE + ) + (func $callBack (;7;) (type 2)) + (memory (;0;) 3) + (global $__stack_pointer (;0;) (mut i32) i32.const 131072) + (global (;1;) i32 i32.const 131097) + (global (;2;) i32 i32.const 131104) + (export "memory" (memory 0)) + (export "init" (func $init)) + (export "upgrade" (func $upgrade)) + (export "callBack" (func $callBack)) + (export "__data_end" (global 1)) + (export "__heap_base" (global 2)) + (data $.rodata (;0;) (i32.const 131072) "wrong number of arguments") +) +"#; + + #[test] + fn test_empty() { + if let Ok(content) = Parser::new().parse_bytes(None, EMPTY_DBG_WAT.as_bytes()) { + let wasm_info = populate_wasm_info(String::new(), content.to_vec(), false, &None) + .expect("Unable to parse WASM content."); + assert!(!wasm_info.memory_grow_flag); + assert!(!wasm_info.report.has_allocator); + assert_eq!( + PanicMessage::None.to_string(), + wasm_info.report.has_panic.to_string() + ); + } + } + + #[test] + fn test_empty_with_mem_grow() { + if let Ok(content) = Parser::new().parse_bytes(None, EMPTY_WITH_MEM_GROW.as_bytes()) { + let wasm_info = populate_wasm_info(String::new(), content.to_vec(), false, &None) + .expect("Unable to parse WASM content."); + assert!(wasm_info.memory_grow_flag); + assert!(!wasm_info.report.has_allocator); + assert_eq!( + PanicMessage::WithoutMessage.to_string(), + wasm_info.report.has_panic.to_string() + ); + } + } + + #[test] + fn test_empty_with_fail_allocator() { + if let Ok(content) = Parser::new().parse_bytes(None, EMPTY_WITH_FAIL_ALLOCATOR.as_bytes()) { + let wasm_info = populate_wasm_info(String::new(), content.to_vec(), false, &None) + .expect("Unable to parse WASM content."); + assert!(!wasm_info.memory_grow_flag); + assert!(wasm_info.report.has_allocator); + assert_eq!( + PanicMessage::None.to_string(), + wasm_info.report.has_panic.to_string() + ); + } + } +} From 0dea313dcfabd8b1883c008da68d4c3c610a36b2 Mon Sep 17 00:00:00 2001 From: BiancaIalangi Date: Sun, 22 Sep 2024 00:00:51 +0300 Subject: [PATCH 024/185] wasm-extractor - clean empty contract --- contracts/examples/empty/src/empty.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/contracts/examples/empty/src/empty.rs b/contracts/examples/empty/src/empty.rs index e7495881d3..81353a08d9 100644 --- a/contracts/examples/empty/src/empty.rs +++ b/contracts/examples/empty/src/empty.rs @@ -7,9 +7,7 @@ use multiversx_sc::imports::*; #[multiversx_sc::contract] pub trait EmptyContract { #[init] - fn init(&self) -> u32 { - 64 - } + fn init(&self) {} #[upgrade] fn upgrade(&self) {} From 6957fe482f85119abf5acc53b43610ade4f1b231 Mon Sep 17 00:00:00 2001 From: Mihai Calin Luca Date: Tue, 24 Sep 2024 15:07:06 +0200 Subject: [PATCH 025/185] sdk-wbg crate impl with dapp example, wasm target compatible interactor --- .gitignore | 1 + Cargo.toml | 3 + contracts/examples/adder/interact/Cargo.toml | 1 + .../examples/multisig/interact/Cargo.toml | 1 + .../basic-features/interact/Cargo.toml | 1 + .../composability/interact/Cargo.toml | 1 + framework/snippets/Cargo.toml | 6 +- framework/snippets/src/account_tool.rs | 4 +- framework/snippets/src/imports.rs | 5 +- framework/snippets/src/interactor.rs | 6 +- .../interactor_scenario/interactor_sc_call.rs | 2 +- .../interactor_sc_deploy.rs | 2 +- .../interactor_vm_query.rs | 2 +- framework/snippets/src/interactor_sender.rs | 2 +- framework/snippets/src/lib.rs | 7 +- .../src/multi/interactor_multi_sc_exec.rs | 2 +- .../src/multi/interactor_multi_sc_process.rs | 2 +- .../snippets/src/multi/interactor_step.rs | 2 +- framework/snippets/src/network_response.rs | 2 +- framework/snippets/src/test_wallets.rs | 2 +- .../tests/test_tx_deployed_address.rs | 4 +- .../tests/test_tx_issued_token_identifier.rs | 2 +- .../tests/test_tx_multi_contract_sc_result.rs | 2 +- .../tests/test_tx_multiple_sc_results.rs | 2 +- framework/snippets/tests/test_tx_sc_result.rs | 2 +- sdk-wbg/README.md | 3 + sdk-wbg/core/Cargo.toml | 42 + sdk-wbg/core/README.md | 5 + .../core/examples/ping-pong-dapp/Cargo.toml | 20 + .../core/examples/ping-pong-dapp/index.html | 12 + .../ping-pong-dapp/interactor/Cargo.toml | 13 + .../ping-pong-dapp/interactor/interactor.rs | 57 + .../examples/ping-pong-dapp/interactor/lib.rs | 2 + .../interactor/ping-pong-egld.wasm | Bin 0 -> 6567 bytes .../core/examples/ping-pong-dapp/readme.md | 9 + .../ping-pong-dapp/src/components/button.rs | 18 + .../ping-pong-dapp/src/components/footer.rs | 15 + .../ping-pong-dapp/src/components/mod.rs | 7 + .../src/components/network_status.rs | 17 + .../examples/ping-pong-dapp/src/context.rs | 66 + .../core/examples/ping-pong-dapp/src/main.rs | 31 + .../examples/ping-pong-dapp/src/pages/home.rs | 115 + .../examples/ping-pong-dapp/src/pages/mod.rs | 3 + .../ping-pong-dapp/src/requests/mod.rs | 3 + .../ping-pong-dapp/src/requests/proxy.rs | 264 ++ .../ping-pong-dapp/src/requests/query.rs | 18 + .../src/requests/transaction.rs | 68 + .../examples/ping-pong-dapp/src/routes.rs | 16 + .../examples/ping-pong-dapp/src/styles.css | 29 + .../core/examples/ping-pong-dapp/trunk.toml | 7 + .../edwards25519/completed_group_element.rs | 42 + .../core/src/crypto/edwards25519/constant.rs | 3654 +++++++++++++++++ .../edwards25519/extended_group_element.rs | 103 + .../src/crypto/edwards25519/field_element.rs | 637 +++ sdk-wbg/core/src/crypto/edwards25519/mod.rs | 848 ++++ .../pre_computed_group_element.rs | 50 + .../edwards25519/projective_group_element.rs | 24 + sdk-wbg/core/src/crypto/mod.rs | 3 + sdk-wbg/core/src/crypto/private_key.rs | 154 + sdk-wbg/core/src/crypto/public_key.rs | 73 + sdk-wbg/core/src/data/account.rs | 31 + sdk-wbg/core/src/data/account_storage.rs | 16 + sdk-wbg/core/src/data/address.rs | 107 + sdk-wbg/core/src/data/esdt.rs | 38 + sdk-wbg/core/src/data/hyperblock.rs | 38 + sdk-wbg/core/src/data/keystore.rs | 61 + sdk-wbg/core/src/data/mod.rs | 11 + sdk-wbg/core/src/data/network_config.rs | 47 + sdk-wbg/core/src/data/network_economics.rs | 33 + sdk-wbg/core/src/data/network_status.rs | 35 + sdk-wbg/core/src/data/transaction.rs | 292 ++ sdk-wbg/core/src/data/vm.rs | 113 + sdk-wbg/core/src/gateway.rs | 15 + sdk-wbg/core/src/gateway/gateway_account.rs | 106 + sdk-wbg/core/src/gateway/gateway_block.rs | 63 + sdk-wbg/core/src/gateway/gateway_network.rs | 61 + sdk-wbg/core/src/gateway/gateway_proxy.rs | 15 + sdk-wbg/core/src/gateway/gateway_tx.rs | 191 + .../core/src/gateway/gateway_tx_retrieve.rs | 104 + sdk-wbg/core/src/lib.rs | 5 + sdk-wbg/core/src/utils.rs | 15 + sdk-wbg/core/src/wallet.rs | 368 ++ sdk-wbg/core/tests/alice.pem | 5 + sdk-wbg/core/tests/wallet_test.rs | 116 + tools/interactor-system-func-calls/Cargo.toml | 1 + 85 files changed, 8354 insertions(+), 27 deletions(-) create mode 100644 sdk-wbg/README.md create mode 100644 sdk-wbg/core/Cargo.toml create mode 100644 sdk-wbg/core/README.md create mode 100644 sdk-wbg/core/examples/ping-pong-dapp/Cargo.toml create mode 100644 sdk-wbg/core/examples/ping-pong-dapp/index.html create mode 100644 sdk-wbg/core/examples/ping-pong-dapp/interactor/Cargo.toml create mode 100644 sdk-wbg/core/examples/ping-pong-dapp/interactor/interactor.rs create mode 100644 sdk-wbg/core/examples/ping-pong-dapp/interactor/lib.rs create mode 100644 sdk-wbg/core/examples/ping-pong-dapp/interactor/ping-pong-egld.wasm create mode 100644 sdk-wbg/core/examples/ping-pong-dapp/readme.md create mode 100644 sdk-wbg/core/examples/ping-pong-dapp/src/components/button.rs create mode 100644 sdk-wbg/core/examples/ping-pong-dapp/src/components/footer.rs create mode 100644 sdk-wbg/core/examples/ping-pong-dapp/src/components/mod.rs create mode 100644 sdk-wbg/core/examples/ping-pong-dapp/src/components/network_status.rs create mode 100644 sdk-wbg/core/examples/ping-pong-dapp/src/context.rs create mode 100644 sdk-wbg/core/examples/ping-pong-dapp/src/main.rs create mode 100644 sdk-wbg/core/examples/ping-pong-dapp/src/pages/home.rs create mode 100644 sdk-wbg/core/examples/ping-pong-dapp/src/pages/mod.rs create mode 100644 sdk-wbg/core/examples/ping-pong-dapp/src/requests/mod.rs create mode 100644 sdk-wbg/core/examples/ping-pong-dapp/src/requests/proxy.rs create mode 100644 sdk-wbg/core/examples/ping-pong-dapp/src/requests/query.rs create mode 100644 sdk-wbg/core/examples/ping-pong-dapp/src/requests/transaction.rs create mode 100644 sdk-wbg/core/examples/ping-pong-dapp/src/routes.rs create mode 100644 sdk-wbg/core/examples/ping-pong-dapp/src/styles.css create mode 100644 sdk-wbg/core/examples/ping-pong-dapp/trunk.toml create mode 100644 sdk-wbg/core/src/crypto/edwards25519/completed_group_element.rs create mode 100644 sdk-wbg/core/src/crypto/edwards25519/constant.rs create mode 100644 sdk-wbg/core/src/crypto/edwards25519/extended_group_element.rs create mode 100644 sdk-wbg/core/src/crypto/edwards25519/field_element.rs create mode 100644 sdk-wbg/core/src/crypto/edwards25519/mod.rs create mode 100644 sdk-wbg/core/src/crypto/edwards25519/pre_computed_group_element.rs create mode 100644 sdk-wbg/core/src/crypto/edwards25519/projective_group_element.rs create mode 100644 sdk-wbg/core/src/crypto/mod.rs create mode 100644 sdk-wbg/core/src/crypto/private_key.rs create mode 100644 sdk-wbg/core/src/crypto/public_key.rs create mode 100644 sdk-wbg/core/src/data/account.rs create mode 100644 sdk-wbg/core/src/data/account_storage.rs create mode 100644 sdk-wbg/core/src/data/address.rs create mode 100644 sdk-wbg/core/src/data/esdt.rs create mode 100644 sdk-wbg/core/src/data/hyperblock.rs create mode 100644 sdk-wbg/core/src/data/keystore.rs create mode 100644 sdk-wbg/core/src/data/mod.rs create mode 100644 sdk-wbg/core/src/data/network_config.rs create mode 100644 sdk-wbg/core/src/data/network_economics.rs create mode 100644 sdk-wbg/core/src/data/network_status.rs create mode 100644 sdk-wbg/core/src/data/transaction.rs create mode 100644 sdk-wbg/core/src/data/vm.rs create mode 100644 sdk-wbg/core/src/gateway.rs create mode 100644 sdk-wbg/core/src/gateway/gateway_account.rs create mode 100644 sdk-wbg/core/src/gateway/gateway_block.rs create mode 100644 sdk-wbg/core/src/gateway/gateway_network.rs create mode 100644 sdk-wbg/core/src/gateway/gateway_proxy.rs create mode 100644 sdk-wbg/core/src/gateway/gateway_tx.rs create mode 100644 sdk-wbg/core/src/gateway/gateway_tx_retrieve.rs create mode 100644 sdk-wbg/core/src/lib.rs create mode 100644 sdk-wbg/core/src/utils.rs create mode 100644 sdk-wbg/core/src/wallet.rs create mode 100644 sdk-wbg/core/tests/alice.pem create mode 100644 sdk-wbg/core/tests/wallet_test.rs diff --git a/.gitignore b/.gitignore index 8295450d89..00a4be02e9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ # Generated by Cargo # will have compiled files and executables **/target/** +**/dist # Remove Cargo.lock from the framework, but not from the wasm contracts. # In contracts it helps with tracing builds. diff --git a/Cargo.toml b/Cargo.toml index 651456eebd..cab4a379fd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,9 @@ members = [ "sdk/core", "sdk/scenario-format", + "sdk-wbg/core", + "sdk-wbg/core/examples/ping-pong-dapp", + "tools/mxpy-snippet-generator", "tools/payload-macro-generator", # "tools/plotter", diff --git a/contracts/examples/adder/interact/Cargo.toml b/contracts/examples/adder/interact/Cargo.toml index b9c18b391b..0663180c81 100644 --- a/contracts/examples/adder/interact/Cargo.toml +++ b/contracts/examples/adder/interact/Cargo.toml @@ -13,6 +13,7 @@ path = "src/basic_interact.rs" clap = { version = "4.4.7", features = ["derive"] } serde = { version = "1.0", features = ["derive"] } toml = "0.8.6" +tokio = { version = "1.24" } [dependencies.adder] path = ".." diff --git a/contracts/examples/multisig/interact/Cargo.toml b/contracts/examples/multisig/interact/Cargo.toml index 7d6914bd60..e161ee4a42 100644 --- a/contracts/examples/multisig/interact/Cargo.toml +++ b/contracts/examples/multisig/interact/Cargo.toml @@ -13,6 +13,7 @@ path = "src/multisig_interact.rs" clap = { version = "4.4.7", features = ["derive"] } serde = { version = "1.0", features = ["derive"] } toml = "0.8.6" +tokio = { version = "1.24" } [dependencies.multisig] path = ".." diff --git a/contracts/feature-tests/basic-features/interact/Cargo.toml b/contracts/feature-tests/basic-features/interact/Cargo.toml index 69597ba7e3..735d08b890 100644 --- a/contracts/feature-tests/basic-features/interact/Cargo.toml +++ b/contracts/feature-tests/basic-features/interact/Cargo.toml @@ -12,6 +12,7 @@ path = "src/bf_interact.rs" [dependencies] clap = { version = "4.4.7", features = ["derive"] } serde = { version = "1.0", features = ["derive"] } +tokio = { version = "1.24" } toml = "0.8.6" [dependencies.basic-features] diff --git a/contracts/feature-tests/composability/interact/Cargo.toml b/contracts/feature-tests/composability/interact/Cargo.toml index e06ae3c915..b6c02ee16b 100644 --- a/contracts/feature-tests/composability/interact/Cargo.toml +++ b/contracts/feature-tests/composability/interact/Cargo.toml @@ -12,6 +12,7 @@ path = "src/comp_interact_main.rs" [dependencies] clap = { version = "4.4.7", features = ["derive"] } serde = { version = "1.0", features = ["derive"] } +tokio = { version = "1.24" } toml = "0.8.6" [dependencies.multiversx-sc] diff --git a/framework/snippets/Cargo.toml b/framework/snippets/Cargo.toml index 43ca798a69..6d9ad95fc2 100644 --- a/framework/snippets/Cargo.toml +++ b/framework/snippets/Cargo.toml @@ -14,7 +14,7 @@ keywords = ["multiversx", "blockchain", "contract", "snippets"] categories = ["cryptography::cryptocurrencies"] [dependencies] -tokio = { version = "1.24", features = ["full"] } +gloo-timers = { version = "0.3.0", features = ["futures"] } hex = "0.4" base64 = "0.22" log = "0.4.17" @@ -29,9 +29,9 @@ path = "../scenario" version = "0.23.0" path = "../../sdk/scenario-format" -[dependencies.multiversx-sdk] +[dependencies.multiversx-sdk-wbg] version = "=0.6.0" -path = "../../sdk/core" +path = "../../sdk-wbg/core" [dev-dependencies] serde_json = "1.0" diff --git a/framework/snippets/src/account_tool.rs b/framework/snippets/src/account_tool.rs index b10baf4a80..fad13ab314 100644 --- a/framework/snippets/src/account_tool.rs +++ b/framework/snippets/src/account_tool.rs @@ -3,7 +3,7 @@ use multiversx_sc_scenario::{ imports::Bech32Address, scenario_model::{Account, BytesKey, BytesValue, Scenario, SetStateStep, Step}, }; -use multiversx_sdk::{ +use multiversx_sdk_wbg::{ data::{address::Address, esdt::EsdtBalance}, gateway::GatewayProxy, }; @@ -67,7 +67,7 @@ pub async fn retrieve_account_as_scenario_set_state( } fn set_account( - account: multiversx_sdk::data::account::Account, + account: multiversx_sdk_wbg::data::account::Account, account_storage: HashMap, account_esdt: HashMap, account_esdt_roles: HashMap>, diff --git a/framework/snippets/src/imports.rs b/framework/snippets/src/imports.rs index a22c969887..3bdfaf062a 100644 --- a/framework/snippets/src/imports.rs +++ b/framework/snippets/src/imports.rs @@ -4,7 +4,8 @@ pub use crate::{ dns_address_for_name, test_wallets, Interactor, InteractorPrepareAsync, StepBuffer, }; -pub use multiversx_sdk::{data::keystore::InsertPassword, wallet::Wallet}; +pub use multiversx_sdk_wbg::{data::keystore::InsertPassword, wallet::Wallet}; pub use env_logger; -pub use tokio; +pub use gloo_timers; +// pub use tokio; diff --git a/framework/snippets/src/interactor.rs b/framework/snippets/src/interactor.rs index bb38873afe..d4b685f157 100644 --- a/framework/snippets/src/interactor.rs +++ b/framework/snippets/src/interactor.rs @@ -4,7 +4,7 @@ use multiversx_sc_scenario::{ multiversx_sc::types::Address, scenario_model::AddressValue, }; -use multiversx_sdk::{ +use multiversx_sdk_wbg::{ data::{address::Address as ErdrsAddress, network_config::NetworkConfig}, gateway::GatewayProxy, wallet::Wallet, @@ -61,7 +61,9 @@ impl Interactor { pub async fn sleep(&mut self, duration: Duration) { self.waiting_time_ms += duration.as_millis() as u64; - tokio::time::sleep(duration).await; + gloo_timers::future::sleep(duration).await; + + // tokio::time::sleep(duration).await; } pub async fn with_tracer>(mut self, path: P) -> Self { diff --git a/framework/snippets/src/interactor_scenario/interactor_sc_call.rs b/framework/snippets/src/interactor_scenario/interactor_sc_call.rs index 6802304ae9..de75ff16b1 100644 --- a/framework/snippets/src/interactor_scenario/interactor_sc_call.rs +++ b/framework/snippets/src/interactor_scenario/interactor_sc_call.rs @@ -5,7 +5,7 @@ use multiversx_sc_scenario::{ scenario::ScenarioRunner, scenario_model::{ScCallStep, SetStateStep, TxCall}, }; -use multiversx_sdk::{data::transaction::Transaction, utils::base64_encode}; +use multiversx_sdk_wbg::{data::transaction::Transaction, utils::base64_encode}; impl Interactor { pub async fn sc_call(&mut self, mut sc_call_step: S) diff --git a/framework/snippets/src/interactor_scenario/interactor_sc_deploy.rs b/framework/snippets/src/interactor_scenario/interactor_sc_deploy.rs index 59de249e83..83bcd10f94 100644 --- a/framework/snippets/src/interactor_scenario/interactor_sc_deploy.rs +++ b/framework/snippets/src/interactor_scenario/interactor_sc_deploy.rs @@ -5,7 +5,7 @@ use multiversx_sc_scenario::{ mandos_system::ScenarioRunner, scenario_model::{ScDeployStep, SetStateStep}, }; -use multiversx_sdk::{ +use multiversx_sdk_wbg::{ data::{address::Address as ErdrsAddress, transaction::Transaction}, utils::base64_encode, }; diff --git a/framework/snippets/src/interactor_scenario/interactor_vm_query.rs b/framework/snippets/src/interactor_scenario/interactor_vm_query.rs index aa9f87efb7..24839d5c0a 100644 --- a/framework/snippets/src/interactor_scenario/interactor_vm_query.rs +++ b/framework/snippets/src/interactor_scenario/interactor_vm_query.rs @@ -8,7 +8,7 @@ use multiversx_sc_scenario::{ multiversx_sc::{abi::TypeAbiFrom, codec::TopDecodeMulti, types::ContractCall}, scenario_model::{ScQueryStep, TxResponse}, }; -use multiversx_sdk::{data::vm::VmValueRequest, utils::base64_decode}; +use multiversx_sdk_wbg::{data::vm::VmValueRequest, utils::base64_decode}; impl Interactor { pub async fn sc_query(&mut self, mut step: S) -> &mut Self diff --git a/framework/snippets/src/interactor_sender.rs b/framework/snippets/src/interactor_sender.rs index 86d6abcada..8bff6b42dc 100644 --- a/framework/snippets/src/interactor_sender.rs +++ b/framework/snippets/src/interactor_sender.rs @@ -1,6 +1,6 @@ use log::debug; use multiversx_sc_scenario::multiversx_sc::types::Address; -use multiversx_sdk::{data::transaction::Transaction, wallet::Wallet}; +use multiversx_sdk_wbg::{data::transaction::Transaction, wallet::Wallet}; use crate::{address_h256_to_erdrs, Interactor}; diff --git a/framework/snippets/src/lib.rs b/framework/snippets/src/lib.rs index 7d3b52c696..3ffbabbc33 100644 --- a/framework/snippets/src/lib.rs +++ b/framework/snippets/src/lib.rs @@ -17,9 +17,10 @@ pub use interactor_tx::*; pub use log; pub use multi::*; pub use multiversx_sc_scenario::{self, multiversx_sc}; -pub use multiversx_sdk as erdrs; // TODO: remove -pub use multiversx_sdk as sdk; -pub use tokio; +pub use multiversx_sdk_wbg as erdrs; // TODO: remove +pub use multiversx_sdk_wbg as sdk; +// pub use tokio; +pub use gloo_timers; /// Imports normally needed in interactors, grouped together. pub mod imports; diff --git a/framework/snippets/src/multi/interactor_multi_sc_exec.rs b/framework/snippets/src/multi/interactor_multi_sc_exec.rs index 8ac6a4eba9..0b8eee4891 100644 --- a/framework/snippets/src/multi/interactor_multi_sc_exec.rs +++ b/framework/snippets/src/multi/interactor_multi_sc_exec.rs @@ -1,6 +1,6 @@ use super::interactor_multi_sc_process::{update_nonces_and_sign_tx, SenderSet, Txs}; use crate::{network_response, Interactor, InteractorStep, StepBuffer}; -use multiversx_sdk::data::transaction::Transaction; +use multiversx_sdk_wbg::data::transaction::Transaction; impl Interactor { pub async fn multi_sc_exec(&mut self, mut buffer: StepBuffer<'_>) { diff --git a/framework/snippets/src/multi/interactor_multi_sc_process.rs b/framework/snippets/src/multi/interactor_multi_sc_process.rs index 3364a4d5ee..f03785f510 100644 --- a/framework/snippets/src/multi/interactor_multi_sc_process.rs +++ b/framework/snippets/src/multi/interactor_multi_sc_process.rs @@ -1,6 +1,6 @@ use crate::{multiversx_sc::types::Address, Interactor, Sender}; use futures::future::join_all; -use multiversx_sdk::data::transaction::{Transaction, TransactionOnNetwork}; +use multiversx_sdk_wbg::data::transaction::{Transaction, TransactionOnNetwork}; use std::collections::HashSet; pub(crate) type Txs = Vec; diff --git a/framework/snippets/src/multi/interactor_step.rs b/framework/snippets/src/multi/interactor_step.rs index be172bbb82..8b8d0fbc71 100644 --- a/framework/snippets/src/multi/interactor_step.rs +++ b/framework/snippets/src/multi/interactor_step.rs @@ -2,7 +2,7 @@ use multiversx_sc_scenario::{ mandos_system::ScenarioRunner, scenario_model::{AddressValue, ScCallStep, ScDeployStep, TxResponse}, }; -use multiversx_sdk::data::transaction::Transaction; +use multiversx_sdk_wbg::data::transaction::Transaction; use crate::Interactor; diff --git a/framework/snippets/src/network_response.rs b/framework/snippets/src/network_response.rs index 0140dd839e..e77525fa16 100644 --- a/framework/snippets/src/network_response.rs +++ b/framework/snippets/src/network_response.rs @@ -3,7 +3,7 @@ use multiversx_sc_scenario::{ multiversx_chain_vm::crypto_functions::keccak256, scenario_model::{Log, TxResponse, TxResponseStatus}, }; -use multiversx_sdk::{ +use multiversx_sdk_wbg::{ data::transaction::{ApiSmartContractResult, Events, TransactionOnNetwork}, utils::base64_decode, }; diff --git a/framework/snippets/src/test_wallets.rs b/framework/snippets/src/test_wallets.rs index 341f93ef29..2b79cc948d 100644 --- a/framework/snippets/src/test_wallets.rs +++ b/framework/snippets/src/test_wallets.rs @@ -1,4 +1,4 @@ -use multiversx_sdk::wallet::Wallet; +use multiversx_sdk_wbg::wallet::Wallet; fn test_wallet(pem_file_contents: &str) -> Wallet { Wallet::from_pem_file_contents(pem_file_contents.to_string()).unwrap() diff --git a/framework/snippets/tests/test_tx_deployed_address.rs b/framework/snippets/tests/test_tx_deployed_address.rs index 377a0e779f..b518219de3 100644 --- a/framework/snippets/tests/test_tx_deployed_address.rs +++ b/framework/snippets/tests/test_tx_deployed_address.rs @@ -1,6 +1,6 @@ use multiversx_sc_scenario::imports::Address; use multiversx_sc_snippets::network_response; -use multiversx_sdk::data::transaction::{TransactionInfo, TransactionOnNetwork}; +use multiversx_sdk_wbg::data::transaction::{TransactionInfo, TransactionOnNetwork}; #[test] fn test_deployed_address() { @@ -55,7 +55,7 @@ fn test_deployed_address() { .transaction; let tx_response = network_response::parse_tx_response(tx_on_network); let opt_address = tx_response.new_deployed_address.map(|e| { - multiversx_sdk::data::address::Address::from_bytes(*e.as_array()) + multiversx_sdk_wbg::data::address::Address::from_bytes(*e.as_array()) .to_bech32_string() .unwrap() }); diff --git a/framework/snippets/tests/test_tx_issued_token_identifier.rs b/framework/snippets/tests/test_tx_issued_token_identifier.rs index 3539c4e757..f90bb7d207 100644 --- a/framework/snippets/tests/test_tx_issued_token_identifier.rs +++ b/framework/snippets/tests/test_tx_issued_token_identifier.rs @@ -1,5 +1,5 @@ use multiversx_sc_snippets::network_response; -use multiversx_sdk::data::transaction::{TransactionInfo, TransactionOnNetwork}; +use multiversx_sdk_wbg::data::transaction::{TransactionInfo, TransactionOnNetwork}; #[test] fn test_process_issued_token_identifier_fungible() { diff --git a/framework/snippets/tests/test_tx_multi_contract_sc_result.rs b/framework/snippets/tests/test_tx_multi_contract_sc_result.rs index a9b64d8941..7cc145552a 100644 --- a/framework/snippets/tests/test_tx_multi_contract_sc_result.rs +++ b/framework/snippets/tests/test_tx_multi_contract_sc_result.rs @@ -1,5 +1,5 @@ use multiversx_sc_snippets::network_response; -use multiversx_sdk::data::transaction::{TransactionInfo, TransactionOnNetwork}; +use multiversx_sdk_wbg::data::transaction::{TransactionInfo, TransactionOnNetwork}; #[test] fn test_with_multi_contract_same_shard_tx_that_has_no_sc_result() { diff --git a/framework/snippets/tests/test_tx_multiple_sc_results.rs b/framework/snippets/tests/test_tx_multiple_sc_results.rs index 4fee781b7f..9415ce9576 100644 --- a/framework/snippets/tests/test_tx_multiple_sc_results.rs +++ b/framework/snippets/tests/test_tx_multiple_sc_results.rs @@ -1,5 +1,5 @@ use multiversx_sc_snippets::network_response::{self, is_out_scr}; -use multiversx_sdk::data::transaction::{TransactionInfo, TransactionOnNetwork}; +use multiversx_sdk_wbg::data::transaction::{TransactionInfo, TransactionOnNetwork}; #[test] fn test_transaction_multiple_sc_results() { diff --git a/framework/snippets/tests/test_tx_sc_result.rs b/framework/snippets/tests/test_tx_sc_result.rs index b3809eb2f8..039ff98d73 100644 --- a/framework/snippets/tests/test_tx_sc_result.rs +++ b/framework/snippets/tests/test_tx_sc_result.rs @@ -1,5 +1,5 @@ use multiversx_sc_snippets::network_response; -use multiversx_sdk::data::transaction::{TransactionInfo, TransactionOnNetwork}; +use multiversx_sdk_wbg::data::transaction::{TransactionInfo, TransactionOnNetwork}; #[test] fn test_with_tx_that_has_sc_result() { diff --git a/sdk-wbg/README.md b/sdk-wbg/README.md new file mode 100644 index 0000000000..2dab196709 --- /dev/null +++ b/sdk-wbg/README.md @@ -0,0 +1,3 @@ +# MultiversX tools and SDKs + +This directory contains various tools and SDKs written in Rust for the MultiversX ecosystem specifically for the WASM targets, compatible with `wasm-bindgen`. diff --git a/sdk-wbg/core/Cargo.toml b/sdk-wbg/core/Cargo.toml new file mode 100644 index 0000000000..2eb5fac0b5 --- /dev/null +++ b/sdk-wbg/core/Cargo.toml @@ -0,0 +1,42 @@ +[package] +name = "multiversx-sdk-wbg" +version = "0.6.0" +edition = "2021" + +authors = ["MultiversX "] +license = "MIT" +readme = "README.md" +repository = "https://github.com/multiversx/mx-sdk-rs" +homepage = "https://multiversx.com/" +documentation = "https://docs.multiversx.com/" +description = "SDK for interacting with the MultiversX blockchain for WASM environments" +categories = ["cryptography::cryptocurrencies", "api-bindings"] +keywords = ["multiversx", "blockchain", "sdk", "api", "wasm", "wasm-bindgen"] + +[dependencies] +rand = { version = "0.8.5" } +getrandom = { version = "0.2.15", features = ["js"] } +wasm-bindgen = { version = "0.2.93" } +wasm-bindgen-futures = { version = "0.4.43" } +gloo-net = { version = "0.6.0" } +gloo-timers = { version = "0.3.0", features = ["futures"] } +serde = { version = "1.0.130", features = ["derive"] } +serde_json = { version = "1.0.68", features = ["preserve_order"] } +serde_repr = "0.1.8" +anyhow = "1.0.44" +bip39 = { version = "2.0.0", features = ["rand"] } +sha2 = "0.10.8" +sha3 = "0.10.8" +hmac = { version = "0.12.1", features = ["std"] } +hex = "0.4.3" +base64 = "0.22" +pbkdf2 = { version = "0.12.2", default-features = false } +zeroize = "1.4.2" +bech32 = "0.11" +itertools = "0.13.0" +pem = "3.0.2" +log = "0.4.17" +scrypt = "0.11" +aes = "0.8" +ctr = "0.9.2" +uuid = { version = "1.10.0", features = ["v4"] } diff --git a/sdk-wbg/core/README.md b/sdk-wbg/core/README.md new file mode 100644 index 0000000000..adaf311e41 --- /dev/null +++ b/sdk-wbg/core/README.md @@ -0,0 +1,5 @@ +# MultiversX SDK for Rust + +General purpose collection of tools & SDKs to interact with the MultiversX blockchain from Rust projects, wasm-bindgen compatible. + +More examples in `./examples`. diff --git a/sdk-wbg/core/examples/ping-pong-dapp/Cargo.toml b/sdk-wbg/core/examples/ping-pong-dapp/Cargo.toml new file mode 100644 index 0000000000..940efd99be --- /dev/null +++ b/sdk-wbg/core/examples/ping-pong-dapp/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "ping-pong-dapp" +version = "0.1.0" +edition = "2021" + +[dependencies] +console_log = "0.2" +log = "0.4" +serde = "1.0.210" +serde_json = "1.0" +wasm-bindgen-futures = "0.4" +yew = { version = "0.20.0", features = ["csr"] } +yew_icons = { version = "0.7.3", features = ["BootstrapHeartFill"] } +yew-router = { version = "0.17.0" } + +[dependencies.interactor] +path = "interactor" + +[dependencies.multiversx-sc-snippets] +path = "../../../../framework/snippets" diff --git a/sdk-wbg/core/examples/ping-pong-dapp/index.html b/sdk-wbg/core/examples/ping-pong-dapp/index.html new file mode 100644 index 0000000000..162a2a7a50 --- /dev/null +++ b/sdk-wbg/core/examples/ping-pong-dapp/index.html @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/sdk-wbg/core/examples/ping-pong-dapp/interactor/Cargo.toml b/sdk-wbg/core/examples/ping-pong-dapp/interactor/Cargo.toml new file mode 100644 index 0000000000..57820be136 --- /dev/null +++ b/sdk-wbg/core/examples/ping-pong-dapp/interactor/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "interactor" +version = "0.1.0" +edition = "2021" + +[lib] +path = "lib.rs" + +[dependencies] +serde = { version = "1.0", features = ["derive"] } + +[dependencies.multiversx-sc-snippets] +path = "../../../../../framework/snippets" diff --git a/sdk-wbg/core/examples/ping-pong-dapp/interactor/interactor.rs b/sdk-wbg/core/examples/ping-pong-dapp/interactor/interactor.rs new file mode 100644 index 0000000000..4db907e042 --- /dev/null +++ b/sdk-wbg/core/examples/ping-pong-dapp/interactor/interactor.rs @@ -0,0 +1,57 @@ +use imports::{Address, Bech32Address, BytesValue}; +use multiversx_sc_snippets::*; +use serde::{Deserialize, Serialize}; + +const GATEWAY: &str = sdk::gateway::DEVNET_GATEWAY; +const CONTRACT_ADDRESS: &str = "erd1qqqqqqqqqqqqqpgq6tqvj5f59xrgxwrtwy30elgpu7l4zrv6d8ssnjdwxq"; +const PING_PONG_CODE: &[u8] = include_bytes!("ping-pong-egld.wasm"); + +#[derive(Debug, Default, Serialize, Deserialize)] +pub struct Config { + gateway: String, + contract_address: String, +} + +impl Config { + // Deserializes state from file + pub fn new() -> Self { + Config { + gateway: GATEWAY.to_string(), + contract_address: CONTRACT_ADDRESS.to_string(), + } + } + + /// Sets the contract address + pub fn set_address(&mut self, address: Bech32Address) { + self.contract_address = address.to_string() + } + + /// Returns the contract address + pub fn current_address(&self) -> &String { + &self.contract_address + } +} + +pub struct ContractInteract { + pub interactor: Interactor, + pub wallet_address: Address, + pub contract_code: BytesValue, + pub config: Config, +} + +impl ContractInteract { + pub async fn new() -> Self { + let config = Config::new(); + let mut interactor = Interactor::new(&config.gateway).await; + let wallet_address = interactor.register_wallet(test_wallets::mike()); + + let contract_code = BytesValue::from(PING_PONG_CODE); + + ContractInteract { + interactor, + wallet_address, + contract_code, + config, + } + } +} diff --git a/sdk-wbg/core/examples/ping-pong-dapp/interactor/lib.rs b/sdk-wbg/core/examples/ping-pong-dapp/interactor/lib.rs new file mode 100644 index 0000000000..cf8d1d5292 --- /dev/null +++ b/sdk-wbg/core/examples/ping-pong-dapp/interactor/lib.rs @@ -0,0 +1,2 @@ +pub mod interactor; +pub use interactor::ContractInteract; diff --git a/sdk-wbg/core/examples/ping-pong-dapp/interactor/ping-pong-egld.wasm b/sdk-wbg/core/examples/ping-pong-dapp/interactor/ping-pong-egld.wasm new file mode 100644 index 0000000000000000000000000000000000000000..7426d32c86531d3e08abaa22389ff9c4c03ade7a GIT binary patch literal 6567 zcmai3YiwLc6`sf4hkfmMlDLUuyY1Yq+c>o8yGcl2p3TEa<0fvMrfFJmZg#KjUGKx$ zz3aqMWt+w-k)VPqOC38 zJ9p;Hne+J0IWuDxHmjU5#)~^H@(sRmk+F*mFR`(~=z%6jOK#A&hbQ&WmmT2iAYOO< zM83{0a{Q$>Hr6c#F<8GS)-4A-#fRyfjB2ZXv$R+XE5{m*dV@*o>96Kn3ky->baaIY z>KIHq%*sksD>ARQ?|7+JYA!KGeS0pI7EjjV=_r1sMqHz!X)Ly?Q7v|iRl)}ZGf{0Z zPNof3!&)MQyV;E3mXq`qwin0HpSl8!a2VEh?!^%2jZ z#V9`AsD~{MUr-L){tBq2O)fS!m`kZ@@R976IZH1+%uzb2c8?IR&bDFvxw#--Rh2^uQ zYSfHF5cgYyIU66FJ9@UgZer&h9n=s2tS}A(Dv@*Uh$$8uQM2i~M>_P!uEtRV*v*HP zum<~E^d?eb3QN<%{aAQ9Y|carv6Cdd;2>+MhaIy!Txv{B$ewqy-97LK)HXwu=*e*SRAAZ|UN^&OCyW|Epo10mGgPEJR z?CV3kGJodV)77Y2Z>$OCLE4zT;jNTvi|i}jN*%ASX6R)q6*jM+-YdEi--v=MLb(gwlI_kF%vdzKU>Te;K6)YSY}I^*2-cdEJo~&{`vW07>Dyn9g_R= z^Gi{YVK#5;fARRe>)BA%?ZskSKCIl@G}fVa?~H7 z_ud>+o@V|YkeR=3W$ABHVDfT~9T1@K=eXFoj~TU`6BA5>kJ^`$DwShqB-YGq{#RZ$ z*|>pbcGZ5NHL}`h91sJVYheb;##3KHQ>q8?smc?~x6Y#Um% zTa5VwP6?*c5a?kN^_|VE*{vpWkR5tuMzv?&LzlEoNa-3X%lyZ{&t%J*K`pz+m%S~OKV!r#etQk@dGapRsuqZ=ke-F*Lev9mI+M62k%^$&ehk_i#Oo8^e?fg4B_fTgK z`HUU;B}TT>h;P{_pO|LBR6V5zYy-_{e+WHf7N|XF*mT=d&T;S*^N&N*Uej|jIiTJ) zIq#SpBZsEF@V`yyN z%IXw^rXIr&GY0E2^N%g`ssj*=`m(;^Bz+k`06mz21;#W#IS7zAo)XexS~*}^8g&M% z3IhR`jl7)m%0WtdBuKy|1~kXwv=%qK91wDN8L&;A9E2ft3U>0AbJDzdIhQU6LSUZu z$~h0Lz$0zg%pixDGS0ykmxB!2Ak7*q!>}e_rrthHg4*>`5I(c&tiW|&47@UkP2@U- zS1zRmEj_?}#~sTB41%WYoX?>4p{KkYKvoSY0W3*6!%B&cFuv6hCZvTD9bq!)XxI?I zWiXz_bQl02KHv}es>JNyAmp?0st6mMukGzGv#7R@;*s+EL5Zk%PCakIsdDhq$H4kF ziVhli5DX?bU&jZKnB)0P{HP1$40GKQ9)s-shC{6ZpPfWWd~RVlZTWP0|Gt;^A@Kg0 z;2t4YyQIO@)08p-kKBKljX*W;fEXqX4+!PH259Vn$Xc9EY3~>mwAABxA$)}yFB=Zo zk2(qgyY6S>+XNHvkeC$NKn@59O_jh5DpJ65?41v@s-r|a4j0)uDaA>wNr(Z6QGCg6 ze92CHVFdA&gJ0DSz+386Igo}Eg4N-`vjPlgIgK$$H3H!&C`cg}MC5eJGEkc`76lii z)5wMJIZqOiwRzY6`(g4s6Bnd&NsDMP4m4|*v>u|Y_z4^_hO8*zER+G+&54Lan_ht_ z4Gf!b~5tr5I&^(&Ys}MSMIA&4sC|eZ z+X5hR>X5&K3d}*k+ZIhl7^VQTMw?JONBw(2V0GduW%RU-l)qie8fAgT{cmwDH_Z3n zf*xihkYdXHg8dnF+!~TE1FKxZ-RewUs97@*Nc9rF@;R=aLDu~dO$LO`$Ck@>;2Fr~ z>P3vdtWM-a9wOs+cvPLr5t3g(nh@%wy34Qt$cIrKx&+YW4-+1~fr8!-JaCA92zB;J zboLY!=P6`fU@==(uYd(2!9F}SgHBtl`tS!^H@X`Z@$-Op8lwmVLTzi@%#w~kc9NlqlZHo7SH zCFrtgu!An%BPZ{X6AZ4SIB@s|k;G2X;ma!xKMUdKY@_y=w`kVdT@BFCB` znm4TE=ql$p2 zPjqkzmvrF!qzclS6I*T&=i?OfVhSJQ*nuHvft}8l)o>&d@%p=NVtU9Xfi29 z6?KA}hdPKCc+qQIJ*r;D9&aBq9twjRfhy{PPV4NOYF53b(|EofFf1!<0;FU)L*m-3 znG^8GIp`wPB>9liCgdZP{CA~D;o`*Q9#jeEH8G|3&^k|m&*Ow>Ix|SxzB*N`{hvYHpggpE!0#%HZb6VeJs0~OQ~5(Kk7Lcm|9Hb@dX>T5qw9bKq2@sa_tWF z5HO9BfFlK3n06-5;fGUpwHIjfL?r-bqhyW4$_-TJ`|0#yeuqgDcKW~2y4$wC2bMc+ z>w|XdmCgYV0jhSx7mvX)BV;J-2uU^Qfbu}K>REN#VmrqP*X<>L4OaJ9>Cj33f}p?U z@VH1k?sXXB1fmdlZRRh*OkAB;&s)pFx~InMP8qG^@YOx}pT6@Er+ukscS6>b>NNcA ztMl3!)%<1)TR-Dd^v$Q&Ey?4ld0sV9+CQrGJRC^eP zK1gN-!M#}BR>DsN&vfgjGZoyPf)Y|43_QaFCUF=6KY6MF7>ErzF1QMhPxC(ZXIf2A zY@)71ETTMvz((wAdD0#U5HeqM%JZo3BMG7=XGX0t4$_eW88wBpz#sxvr85jqj$GJR zV+yo{6)_20F1z`)TOjPjzThNJJ0#5mN=!J=&^|s{1uSo01<`9)v1fj_$^gpC=U)`y zE~3L-I79!i7d*DK5Grj<1C=hCDIMAf?oDGJVF^KeAA)$&+J27Qq2>f2L~+T$=p5M} zVQG^U=qN8@*B0Y}ZGpSZfTfb#42*P+*1U7HX6k-8%A#Uh5;Rskjcb(z7#Gx&-H+Gs zF@r6l%YdCggBXY`E<^GP-^-e?U>+X74QiM)bulW`i;<4#s#{O)JFFL4HC%huYr0sEnz~kxbyz4wE3u|)O1#n@y8Ca5cHs?YYvxb)2rXs+XdMt}k>4O0|_%tZ7086y2}pQoRw|qpkm* zoDbdg=6qbAFBRttbVWxEd?q7UlJ0%)P+&P)JFM#~@jUMNlDoV4xP9x|!bKgJ6vEox zSkpz_L%J5NLOi-hjEb$=a;<))rim=9G;kHTrmvLZrD7wzQj3?Ow(`2#YR1quE-Y#4 zUMO9Sin`gV;&QwZ>q2tPnAi?tM0zcXi^9X6*O1ETB)Gxg+i;*h>DD^7k%##D);{YkkMP2 literal 0 HcmV?d00001 diff --git a/sdk-wbg/core/examples/ping-pong-dapp/readme.md b/sdk-wbg/core/examples/ping-pong-dapp/readme.md new file mode 100644 index 0000000000..032b2c3d29 --- /dev/null +++ b/sdk-wbg/core/examples/ping-pong-dapp/readme.md @@ -0,0 +1,9 @@ +# Ping pong dapp example + +## Prerequisites +- trunk + +```bash +cargo install trunk +``` +Run this example locally with `trunk serve --open`. \ No newline at end of file diff --git a/sdk-wbg/core/examples/ping-pong-dapp/src/components/button.rs b/sdk-wbg/core/examples/ping-pong-dapp/src/components/button.rs new file mode 100644 index 0000000000..cdb898bd59 --- /dev/null +++ b/sdk-wbg/core/examples/ping-pong-dapp/src/components/button.rs @@ -0,0 +1,18 @@ +use yew::prelude::*; + +#[derive(Properties, PartialEq)] +pub struct ButtonProps { + pub name: String, + pub class_name: String, + pub button_type: String, + pub on_click: Callback, +} + +#[function_component(Button)] +pub fn button(props: &ButtonProps) -> Html { + html! { + + } +} diff --git a/sdk-wbg/core/examples/ping-pong-dapp/src/components/footer.rs b/sdk-wbg/core/examples/ping-pong-dapp/src/components/footer.rs new file mode 100644 index 0000000000..e5d7066c55 --- /dev/null +++ b/sdk-wbg/core/examples/ping-pong-dapp/src/components/footer.rs @@ -0,0 +1,15 @@ +use yew::prelude::*; +use yew_icons::{Icon, IconId}; + +#[function_component(Footer)] +pub fn footer() -> Html { + html! { +
+

+ { "Made with " } + + { " by the MultiversX team" } +

+
+ } +} diff --git a/sdk-wbg/core/examples/ping-pong-dapp/src/components/mod.rs b/sdk-wbg/core/examples/ping-pong-dapp/src/components/mod.rs new file mode 100644 index 0000000000..f55f57e4d0 --- /dev/null +++ b/sdk-wbg/core/examples/ping-pong-dapp/src/components/mod.rs @@ -0,0 +1,7 @@ +pub mod button; +pub mod footer; +pub mod network_status; + +pub use button::Button; +pub use footer::Footer; +pub use network_status::NetworkStatusComponent; diff --git a/sdk-wbg/core/examples/ping-pong-dapp/src/components/network_status.rs b/sdk-wbg/core/examples/ping-pong-dapp/src/components/network_status.rs new file mode 100644 index 0000000000..74f085f23c --- /dev/null +++ b/sdk-wbg/core/examples/ping-pong-dapp/src/components/network_status.rs @@ -0,0 +1,17 @@ +use yew::prelude::*; + +use crate::context::ConfigContext; + +#[function_component(NetworkStatusComponent)] +pub fn network_status() -> Html { + let context = use_context::().unwrap(); + let response = format!("{:?}", &context.network_status); + + html! { +
+

+ {&response} +

+
+ } +} diff --git a/sdk-wbg/core/examples/ping-pong-dapp/src/context.rs b/sdk-wbg/core/examples/ping-pong-dapp/src/context.rs new file mode 100644 index 0000000000..78f71590d8 --- /dev/null +++ b/sdk-wbg/core/examples/ping-pong-dapp/src/context.rs @@ -0,0 +1,66 @@ +use crate::requests::query; + +use html::ChildrenProps; +use multiversx_sc_snippets::sdk::data::network_status::NetworkStatus; +use yew::prelude::*; + +#[derive(Clone, Debug, PartialEq)] +pub struct ConfigContext { + pub network_status: NetworkStatus, + pub set_network_status: Callback, +} + +pub async fn refresh_context() -> NetworkStatus { + log::info!("refreshing context"); + query::get_network_status().await.unwrap_or_default() +} + +impl Default for ConfigContext { + fn default() -> Self { + ConfigContext { + network_status: NetworkStatus::default(), + set_network_status: Callback::noop(), + } + } +} + +#[function_component(ConfigProvider)] +pub fn config_provider(props: &ChildrenProps) -> Html { + let network_status = use_state(NetworkStatus::default); + + // Clone the state here for use in the callback + let set_network_status = { + let network_status = network_status.clone(); + Callback::from(move |new_status: NetworkStatus| { + network_status.set(new_status); + }) + }; + + // Clone the callback for async usage in the effect + let set_network_status_async = set_network_status.clone(); + + // refresh context on component mount + use_effect_with_deps( + move |_| { + wasm_bindgen_futures::spawn_local(async move { + let new_status = refresh_context().await; + + // Emit the new status inside the async block + set_network_status_async.emit(new_status); + }); + || () // no cleanup fn + }, + (), // empty dependency array, run once on mount + ); + + let context = ConfigContext { + network_status: (*network_status).clone(), + set_network_status, + }; + + html! { + context={context}> + { for props.children.iter() } + > + } +} diff --git a/sdk-wbg/core/examples/ping-pong-dapp/src/main.rs b/sdk-wbg/core/examples/ping-pong-dapp/src/main.rs new file mode 100644 index 0000000000..552e2593be --- /dev/null +++ b/sdk-wbg/core/examples/ping-pong-dapp/src/main.rs @@ -0,0 +1,31 @@ +use components::Footer; +use context::ConfigProvider; +use log::Level; +use routes::{switch, Route}; +use yew::prelude::*; +use yew_router::{BrowserRouter, Switch}; +mod components; +mod context; +mod pages; +mod requests; +mod routes; + +#[function_component(App)] +fn app() -> Html { + html! { + + + render={switch} /> +