diff --git a/tests/xcm-simulator/Cargo.toml b/tests/xcm-simulator/Cargo.toml index 61aad4a6f7..2d608d3d2b 100644 --- a/tests/xcm-simulator/Cargo.toml +++ b/tests/xcm-simulator/Cargo.toml @@ -92,5 +92,6 @@ runtime-benchmarks = [ "xcm-executor/runtime-benchmarks", "polkadot-runtime-parachains/runtime-benchmarks", "polkadot-parachain/runtime-benchmarks", + "orml-xtokens/runtime-benchmarks", "astar-primitives/runtime-benchmarks", ] diff --git a/tests/xcm-simulator/fixtures/README.md b/tests/xcm-simulator/fixtures/README.md index 6ed582ed8b..5c71d97488 100644 --- a/tests/xcm-simulator/fixtures/README.md +++ b/tests/xcm-simulator/fixtures/README.md @@ -4,3 +4,4 @@ This directory contains contracts which are used in experimental scenarios. Files in this directory are used by experimental scenarios in `src/experimental.rs`. The json files are for informational purposes only and are not consumed by the tests. +The source code for the contracts can be found at https://github.com/AstarNetwork/ink-test-contracts diff --git a/tests/xcm-simulator/fixtures/async-xcm-call-no-ce.json b/tests/xcm-simulator/fixtures/async-xcm-call-no-ce.json new file mode 100644 index 0000000000..cf2fc3d26f --- /dev/null +++ b/tests/xcm-simulator/fixtures/async-xcm-call-no-ce.json @@ -0,0 +1,1509 @@ +{ + "source": { + "hash": "0xea6312435caaa3765aee3a8640b33fa45317e13d097a1d51a4d211fdfe2d2088", + "language": "ink! 4.2.0", + "compiler": "rustc 1.68.0-nightly", + "build_info": { + "build_mode": "Debug", + "cargo_contract_version": "2.2.1", + "rust_toolchain": "nightly-aarch64-apple-darwin", + "wasm_opt_settings": { + "keep_debug_symbols": true, + "optimization_passes": "Z" + } + } + }, + "contract": { + "name": "async_xcm_call_contract", + "version": "0.1.0", + "authors": [ + "Stake Technologies " + ], + "repository": "https://github.com/AstarNetwork/Astar", + "homepage": "https://astar.network/" + }, + "spec": { + "constructors": [ + { + "args": [ + { + "label": "here_para_id", + "type": { + "displayName": [ + "u32" + ], + "type": 1 + } + } + ], + "default": false, + "docs": [], + "label": "new", + "payable": false, + "returnType": { + "displayName": [ + "ink_primitives", + "ConstructorResult" + ], + "type": 2 + }, + "selector": "0x00001111" + } + ], + "docs": [], + "environment": { + "accountId": { + "displayName": [ + "AccountId" + ], + "type": 33 + }, + "balance": { + "displayName": [ + "Balance" + ], + "type": 21 + }, + "blockNumber": { + "displayName": [ + "BlockNumber" + ], + "type": 1 + }, + "chainExtension": { + "displayName": [ + "ChainExtension" + ], + "type": 35 + }, + "hash": { + "displayName": [ + "Hash" + ], + "type": 34 + }, + "maxEventTopics": 4, + "timestamp": { + "displayName": [ + "Timestamp" + ], + "type": 17 + } + }, + "events": [], + "lang_error": { + "displayName": [ + "ink", + "LangError" + ], + "type": 4 + }, + "messages": [ + { + "args": [ + { + "label": "parachain_id", + "type": { + "displayName": [ + "u32" + ], + "type": 1 + } + }, + { + "label": "remark", + "type": { + "displayName": [ + "Vec" + ], + "type": 5 + } + }, + { + "label": "weight_and_fees", + "type": { + "displayName": [ + "WeightsAndFees" + ], + "type": 7 + } + } + ], + "default": false, + "docs": [ + " Attempt to perform remark operation on given parachain by", + " sending a XCM using `call_runtime`." + ], + "label": "attempt_remark_via_xcm", + "mutates": true, + "payable": false, + "returnType": { + "displayName": [ + "ink", + "MessageResult" + ], + "type": 30 + }, + "selector": "0x00002222" + }, + { + "args": [ + { + "label": "success", + "type": { + "displayName": [ + "bool" + ], + "type": 0 + } + } + ], + "default": false, + "docs": [], + "label": "handle_response", + "mutates": true, + "payable": false, + "returnType": { + "displayName": [ + "ink", + "MessageResult" + ], + "type": 2 + }, + "selector": "0x00003333" + }, + { + "args": [], + "default": false, + "docs": [], + "label": "result", + "mutates": false, + "payable": false, + "returnType": { + "displayName": [ + "ink", + "MessageResult" + ], + "type": 31 + }, + "selector": "0x00004444" + } + ] + }, + "storage": { + "root": { + "layout": { + "struct": { + "fields": [ + { + "layout": { + "enum": { + "dispatchKey": "0x00000000", + "name": "Option", + "variants": { + "0": { + "fields": [], + "name": "None" + }, + "1": { + "fields": [ + { + "layout": { + "leaf": { + "key": "0x00000000", + "ty": 0 + } + }, + "name": "0" + } + ], + "name": "Some" + } + } + } + }, + "name": "result" + }, + { + "layout": { + "leaf": { + "key": "0x00000000", + "ty": 1 + } + }, + "name": "here_para_id" + } + ], + "name": "AsyncCall" + } + }, + "root_key": "0x00000000" + } + }, + "types": [ + { + "id": 0, + "type": { + "def": { + "primitive": "bool" + } + } + }, + { + "id": 1, + "type": { + "def": { + "primitive": "u32" + } + } + }, + { + "id": 2, + "type": { + "def": { + "variant": { + "variants": [ + { + "fields": [ + { + "type": 3 + } + ], + "index": 0, + "name": "Ok" + }, + { + "fields": [ + { + "type": 4 + } + ], + "index": 1, + "name": "Err" + } + ] + } + }, + "params": [ + { + "name": "T", + "type": 3 + }, + { + "name": "E", + "type": 4 + } + ], + "path": [ + "Result" + ] + } + }, + { + "id": 3, + "type": { + "def": { + "tuple": [] + } + } + }, + { + "id": 4, + "type": { + "def": { + "variant": { + "variants": [ + { + "index": 1, + "name": "CouldNotReadInput" + } + ] + } + }, + "path": [ + "ink_primitives", + "LangError" + ] + } + }, + { + "id": 5, + "type": { + "def": { + "sequence": { + "type": 6 + } + } + } + }, + { + "id": 6, + "type": { + "def": { + "primitive": "u8" + } + } + }, + { + "id": 7, + "type": { + "def": { + "composite": { + "fields": [ + { + "name": "foreign_base_fee", + "type": 8, + "typeName": "MultiAsset" + }, + { + "name": "foreign_transact_weight", + "type": 29, + "typeName": "Weight" + }, + { + "name": "foreign_transcat_pallet_xcm", + "type": 29, + "typeName": "Weight" + }, + { + "name": "here_callback_base_fee", + "type": 8, + "typeName": "MultiAsset" + }, + { + "name": "here_callback_transact_weight", + "type": 29, + "typeName": "Weight" + }, + { + "name": "here_callback_contract_weight", + "type": 29, + "typeName": "Weight" + } + ] + } + }, + "path": [ + "async_xcm_call_contract", + "async_xcm_call_no_ce", + "WeightsAndFees" + ] + } + }, + { + "id": 8, + "type": { + "def": { + "composite": { + "fields": [ + { + "name": "id", + "type": 9, + "typeName": "AssetId" + }, + { + "name": "fun", + "type": 25, + "typeName": "Fungibility" + } + ] + } + }, + "path": [ + "xcm", + "v3", + "multiasset", + "MultiAsset" + ] + } + }, + { + "id": 9, + "type": { + "def": { + "variant": { + "variants": [ + { + "fields": [ + { + "type": 10, + "typeName": "MultiLocation" + } + ], + "index": 0, + "name": "Concrete" + }, + { + "fields": [ + { + "type": 16, + "typeName": "[u8; 32]" + } + ], + "index": 1, + "name": "Abstract" + } + ] + } + }, + "path": [ + "xcm", + "v3", + "multiasset", + "AssetId" + ] + } + }, + { + "id": 10, + "type": { + "def": { + "composite": { + "fields": [ + { + "name": "parents", + "type": 6, + "typeName": "u8" + }, + { + "name": "interior", + "type": 11, + "typeName": "Junctions" + } + ] + } + }, + "path": [ + "xcm", + "v3", + "multilocation", + "MultiLocation" + ] + } + }, + { + "id": 11, + "type": { + "def": { + "variant": { + "variants": [ + { + "index": 0, + "name": "Here" + }, + { + "fields": [ + { + "type": 12, + "typeName": "Junction" + } + ], + "index": 1, + "name": "X1" + }, + { + "fields": [ + { + "type": 12, + "typeName": "Junction" + }, + { + "type": 12, + "typeName": "Junction" + } + ], + "index": 2, + "name": "X2" + }, + { + "fields": [ + { + "type": 12, + "typeName": "Junction" + }, + { + "type": 12, + "typeName": "Junction" + }, + { + "type": 12, + "typeName": "Junction" + } + ], + "index": 3, + "name": "X3" + }, + { + "fields": [ + { + "type": 12, + "typeName": "Junction" + }, + { + "type": 12, + "typeName": "Junction" + }, + { + "type": 12, + "typeName": "Junction" + }, + { + "type": 12, + "typeName": "Junction" + } + ], + "index": 4, + "name": "X4" + }, + { + "fields": [ + { + "type": 12, + "typeName": "Junction" + }, + { + "type": 12, + "typeName": "Junction" + }, + { + "type": 12, + "typeName": "Junction" + }, + { + "type": 12, + "typeName": "Junction" + }, + { + "type": 12, + "typeName": "Junction" + } + ], + "index": 5, + "name": "X5" + }, + { + "fields": [ + { + "type": 12, + "typeName": "Junction" + }, + { + "type": 12, + "typeName": "Junction" + }, + { + "type": 12, + "typeName": "Junction" + }, + { + "type": 12, + "typeName": "Junction" + }, + { + "type": 12, + "typeName": "Junction" + }, + { + "type": 12, + "typeName": "Junction" + } + ], + "index": 6, + "name": "X6" + }, + { + "fields": [ + { + "type": 12, + "typeName": "Junction" + }, + { + "type": 12, + "typeName": "Junction" + }, + { + "type": 12, + "typeName": "Junction" + }, + { + "type": 12, + "typeName": "Junction" + }, + { + "type": 12, + "typeName": "Junction" + }, + { + "type": 12, + "typeName": "Junction" + }, + { + "type": 12, + "typeName": "Junction" + } + ], + "index": 7, + "name": "X7" + }, + { + "fields": [ + { + "type": 12, + "typeName": "Junction" + }, + { + "type": 12, + "typeName": "Junction" + }, + { + "type": 12, + "typeName": "Junction" + }, + { + "type": 12, + "typeName": "Junction" + }, + { + "type": 12, + "typeName": "Junction" + }, + { + "type": 12, + "typeName": "Junction" + }, + { + "type": 12, + "typeName": "Junction" + }, + { + "type": 12, + "typeName": "Junction" + } + ], + "index": 8, + "name": "X8" + } + ] + } + }, + "path": [ + "xcm", + "v3", + "junctions", + "Junctions" + ] + } + }, + { + "id": 12, + "type": { + "def": { + "variant": { + "variants": [ + { + "fields": [ + { + "type": 13, + "typeName": "u32" + } + ], + "index": 0, + "name": "Parachain" + }, + { + "fields": [ + { + "name": "network", + "type": 14, + "typeName": "Option" + }, + { + "name": "id", + "type": 16, + "typeName": "[u8; 32]" + } + ], + "index": 1, + "name": "AccountId32" + }, + { + "fields": [ + { + "name": "network", + "type": 14, + "typeName": "Option" + }, + { + "name": "index", + "type": 18, + "typeName": "u64" + } + ], + "index": 2, + "name": "AccountIndex64" + }, + { + "fields": [ + { + "name": "network", + "type": 14, + "typeName": "Option" + }, + { + "name": "key", + "type": 19, + "typeName": "[u8; 20]" + } + ], + "index": 3, + "name": "AccountKey20" + }, + { + "fields": [ + { + "type": 6, + "typeName": "u8" + } + ], + "index": 4, + "name": "PalletInstance" + }, + { + "fields": [ + { + "type": 20, + "typeName": "u128" + } + ], + "index": 5, + "name": "GeneralIndex" + }, + { + "fields": [ + { + "name": "length", + "type": 6, + "typeName": "u8" + }, + { + "name": "data", + "type": 16, + "typeName": "[u8; 32]" + } + ], + "index": 6, + "name": "GeneralKey" + }, + { + "index": 7, + "name": "OnlyChild" + }, + { + "fields": [ + { + "name": "id", + "type": 22, + "typeName": "BodyId" + }, + { + "name": "part", + "type": 24, + "typeName": "BodyPart" + } + ], + "index": 8, + "name": "Plurality" + }, + { + "fields": [ + { + "type": 15, + "typeName": "NetworkId" + } + ], + "index": 9, + "name": "GlobalConsensus" + } + ] + } + }, + "path": [ + "xcm", + "v3", + "junction", + "Junction" + ] + } + }, + { + "id": 13, + "type": { + "def": { + "compact": { + "type": 1 + } + } + } + }, + { + "id": 14, + "type": { + "def": { + "variant": { + "variants": [ + { + "index": 0, + "name": "None" + }, + { + "fields": [ + { + "type": 15 + } + ], + "index": 1, + "name": "Some" + } + ] + } + }, + "params": [ + { + "name": "T", + "type": 15 + } + ], + "path": [ + "Option" + ] + } + }, + { + "id": 15, + "type": { + "def": { + "variant": { + "variants": [ + { + "fields": [ + { + "type": 16, + "typeName": "[u8; 32]" + } + ], + "index": 0, + "name": "ByGenesis" + }, + { + "fields": [ + { + "name": "block_number", + "type": 17, + "typeName": "u64" + }, + { + "name": "block_hash", + "type": 16, + "typeName": "[u8; 32]" + } + ], + "index": 1, + "name": "ByFork" + }, + { + "index": 2, + "name": "Polkadot" + }, + { + "index": 3, + "name": "Kusama" + }, + { + "index": 4, + "name": "Westend" + }, + { + "index": 5, + "name": "Rococo" + }, + { + "index": 6, + "name": "Wococo" + }, + { + "fields": [ + { + "name": "chain_id", + "type": 18, + "typeName": "u64" + } + ], + "index": 7, + "name": "Ethereum" + }, + { + "index": 8, + "name": "BitcoinCore" + }, + { + "index": 9, + "name": "BitcoinCash" + } + ] + } + }, + "path": [ + "xcm", + "v3", + "junction", + "NetworkId" + ] + } + }, + { + "id": 16, + "type": { + "def": { + "array": { + "len": 32, + "type": 6 + } + } + } + }, + { + "id": 17, + "type": { + "def": { + "primitive": "u64" + } + } + }, + { + "id": 18, + "type": { + "def": { + "compact": { + "type": 17 + } + } + } + }, + { + "id": 19, + "type": { + "def": { + "array": { + "len": 20, + "type": 6 + } + } + } + }, + { + "id": 20, + "type": { + "def": { + "compact": { + "type": 21 + } + } + } + }, + { + "id": 21, + "type": { + "def": { + "primitive": "u128" + } + } + }, + { + "id": 22, + "type": { + "def": { + "variant": { + "variants": [ + { + "index": 0, + "name": "Unit" + }, + { + "fields": [ + { + "type": 23, + "typeName": "[u8; 4]" + } + ], + "index": 1, + "name": "Moniker" + }, + { + "fields": [ + { + "type": 13, + "typeName": "u32" + } + ], + "index": 2, + "name": "Index" + }, + { + "index": 3, + "name": "Executive" + }, + { + "index": 4, + "name": "Technical" + }, + { + "index": 5, + "name": "Legislative" + }, + { + "index": 6, + "name": "Judicial" + }, + { + "index": 7, + "name": "Defense" + }, + { + "index": 8, + "name": "Administration" + }, + { + "index": 9, + "name": "Treasury" + } + ] + } + }, + "path": [ + "xcm", + "v3", + "junction", + "BodyId" + ] + } + }, + { + "id": 23, + "type": { + "def": { + "array": { + "len": 4, + "type": 6 + } + } + } + }, + { + "id": 24, + "type": { + "def": { + "variant": { + "variants": [ + { + "index": 0, + "name": "Voice" + }, + { + "fields": [ + { + "name": "count", + "type": 13, + "typeName": "u32" + } + ], + "index": 1, + "name": "Members" + }, + { + "fields": [ + { + "name": "nom", + "type": 13, + "typeName": "u32" + }, + { + "name": "denom", + "type": 13, + "typeName": "u32" + } + ], + "index": 2, + "name": "Fraction" + }, + { + "fields": [ + { + "name": "nom", + "type": 13, + "typeName": "u32" + }, + { + "name": "denom", + "type": 13, + "typeName": "u32" + } + ], + "index": 3, + "name": "AtLeastProportion" + }, + { + "fields": [ + { + "name": "nom", + "type": 13, + "typeName": "u32" + }, + { + "name": "denom", + "type": 13, + "typeName": "u32" + } + ], + "index": 4, + "name": "MoreThanProportion" + } + ] + } + }, + "path": [ + "xcm", + "v3", + "junction", + "BodyPart" + ] + } + }, + { + "id": 25, + "type": { + "def": { + "variant": { + "variants": [ + { + "fields": [ + { + "type": 20, + "typeName": "u128" + } + ], + "index": 0, + "name": "Fungible" + }, + { + "fields": [ + { + "type": 26, + "typeName": "AssetInstance" + } + ], + "index": 1, + "name": "NonFungible" + } + ] + } + }, + "path": [ + "xcm", + "v3", + "multiasset", + "Fungibility" + ] + } + }, + { + "id": 26, + "type": { + "def": { + "variant": { + "variants": [ + { + "index": 0, + "name": "Undefined" + }, + { + "fields": [ + { + "type": 20, + "typeName": "u128" + } + ], + "index": 1, + "name": "Index" + }, + { + "fields": [ + { + "type": 23, + "typeName": "[u8; 4]" + } + ], + "index": 2, + "name": "Array4" + }, + { + "fields": [ + { + "type": 27, + "typeName": "[u8; 8]" + } + ], + "index": 3, + "name": "Array8" + }, + { + "fields": [ + { + "type": 28, + "typeName": "[u8; 16]" + } + ], + "index": 4, + "name": "Array16" + }, + { + "fields": [ + { + "type": 16, + "typeName": "[u8; 32]" + } + ], + "index": 5, + "name": "Array32" + } + ] + } + }, + "path": [ + "xcm", + "v3", + "multiasset", + "AssetInstance" + ] + } + }, + { + "id": 27, + "type": { + "def": { + "array": { + "len": 8, + "type": 6 + } + } + } + }, + { + "id": 28, + "type": { + "def": { + "array": { + "len": 16, + "type": 6 + } + } + } + }, + { + "id": 29, + "type": { + "def": { + "composite": { + "fields": [ + { + "name": "ref_time", + "type": 18, + "typeName": "u64" + }, + { + "name": "proof_size", + "type": 18, + "typeName": "u64" + } + ] + } + }, + "path": [ + "sp_weights", + "weight_v2", + "Weight" + ] + } + }, + { + "id": 30, + "type": { + "def": { + "variant": { + "variants": [ + { + "fields": [ + { + "type": 0 + } + ], + "index": 0, + "name": "Ok" + }, + { + "fields": [ + { + "type": 4 + } + ], + "index": 1, + "name": "Err" + } + ] + } + }, + "params": [ + { + "name": "T", + "type": 0 + }, + { + "name": "E", + "type": 4 + } + ], + "path": [ + "Result" + ] + } + }, + { + "id": 31, + "type": { + "def": { + "variant": { + "variants": [ + { + "fields": [ + { + "type": 32 + } + ], + "index": 0, + "name": "Ok" + }, + { + "fields": [ + { + "type": 4 + } + ], + "index": 1, + "name": "Err" + } + ] + } + }, + "params": [ + { + "name": "T", + "type": 32 + }, + { + "name": "E", + "type": 4 + } + ], + "path": [ + "Result" + ] + } + }, + { + "id": 32, + "type": { + "def": { + "variant": { + "variants": [ + { + "index": 0, + "name": "None" + }, + { + "fields": [ + { + "type": 0 + } + ], + "index": 1, + "name": "Some" + } + ] + } + }, + "params": [ + { + "name": "T", + "type": 0 + } + ], + "path": [ + "Option" + ] + } + }, + { + "id": 33, + "type": { + "def": { + "composite": { + "fields": [ + { + "type": 16, + "typeName": "[u8; 32]" + } + ] + } + }, + "path": [ + "ink_primitives", + "types", + "AccountId" + ] + } + }, + { + "id": 34, + "type": { + "def": { + "composite": { + "fields": [ + { + "type": 16, + "typeName": "[u8; 32]" + } + ] + } + }, + "path": [ + "ink_primitives", + "types", + "Hash" + ] + } + }, + { + "id": 35, + "type": { + "def": { + "variant": {} + }, + "path": [ + "ink_env", + "types", + "NoChainExtension" + ] + } + } + ], + "version": "4" +} \ No newline at end of file diff --git a/tests/xcm-simulator/fixtures/async-xcm-call-no-ce.wasm b/tests/xcm-simulator/fixtures/async-xcm-call-no-ce.wasm new file mode 100644 index 0000000000..b00d619810 Binary files /dev/null and b/tests/xcm-simulator/fixtures/async-xcm-call-no-ce.wasm differ diff --git a/tests/xcm-simulator/fixtures/flipper.json b/tests/xcm-simulator/fixtures/flipper.json index b3cebf039f..f262449163 100644 --- a/tests/xcm-simulator/fixtures/flipper.json +++ b/tests/xcm-simulator/fixtures/flipper.json @@ -1,14 +1,14 @@ { "source": { - "hash": "0xdd6430401e759bba008f829d53364435923d211c22f3aa14434d306ea0dc3cbd", - "language": "ink! 4.1.0", - "compiler": "rustc 1.68.2", + "hash": "0xe8dbb2816fed4f8414c4a9fde5e9e89a00ab561c022cae1bd90c071aa0a1275a", + "language": "ink! 4.2.0", + "compiler": "rustc 1.68.0-nightly", "build_info": { - "build_mode": "Release", - "cargo_contract_version": "2.0.0", - "rust_toolchain": "stable-x86_64-unknown-linux-gnu", + "build_mode": "Debug", + "cargo_contract_version": "2.2.1", + "rust_toolchain": "nightly-aarch64-apple-darwin", "wasm_opt_settings": { - "keep_debug_symbols": false, + "keep_debug_symbols": true, "optimization_passes": "Z" } } @@ -17,8 +17,10 @@ "name": "flipper", "version": "0.1.0", "authors": [ - "[your_name] <[your_email]>" - ] + "Stake Technologies " + ], + "repository": "https://github.com/AstarNetwork/Astar", + "homepage": "https://astar.network/" }, "spec": { "constructors": [ @@ -34,6 +36,7 @@ } } ], + "default": false, "docs": [ "Constructor that initializes the `bool` value to the given `init_value`." ], @@ -50,6 +53,45 @@ } ], "docs": [], + "environment": { + "accountId": { + "displayName": [ + "AccountId" + ], + "type": 5 + }, + "balance": { + "displayName": [ + "Balance" + ], + "type": 8 + }, + "blockNumber": { + "displayName": [ + "BlockNumber" + ], + "type": 11 + }, + "chainExtension": { + "displayName": [ + "ChainExtension" + ], + "type": 12 + }, + "hash": { + "displayName": [ + "Hash" + ], + "type": 9 + }, + "maxEventTopics": 4, + "timestamp": { + "displayName": [ + "Timestamp" + ], + "type": 10 + } + }, "events": [], "lang_error": { "displayName": [ @@ -61,6 +103,7 @@ "messages": [ { "args": [], + "default": false, "docs": [ " A message that can be called on instantiated contracts.", " This one flips the value of the stored `bool` from `true`", @@ -80,6 +123,7 @@ }, { "args": [], + "default": false, "docs": [ " Simply returns the current value of our `bool`." ], @@ -237,6 +281,102 @@ "Result" ] } + }, + { + "id": 5, + "type": { + "def": { + "composite": { + "fields": [ + { + "type": 6, + "typeName": "[u8; 32]" + } + ] + } + }, + "path": [ + "ink_primitives", + "types", + "AccountId" + ] + } + }, + { + "id": 6, + "type": { + "def": { + "array": { + "len": 32, + "type": 7 + } + } + } + }, + { + "id": 7, + "type": { + "def": { + "primitive": "u8" + } + } + }, + { + "id": 8, + "type": { + "def": { + "primitive": "u128" + } + } + }, + { + "id": 9, + "type": { + "def": { + "composite": { + "fields": [ + { + "type": 6, + "typeName": "[u8; 32]" + } + ] + } + }, + "path": [ + "ink_primitives", + "types", + "Hash" + ] + } + }, + { + "id": 10, + "type": { + "def": { + "primitive": "u64" + } + } + }, + { + "id": 11, + "type": { + "def": { + "primitive": "u32" + } + } + }, + { + "id": 12, + "type": { + "def": { + "variant": {} + }, + "path": [ + "ink_env", + "types", + "NoChainExtension" + ] + } } ], "version": "4" diff --git a/tests/xcm-simulator/fixtures/flipper.wasm b/tests/xcm-simulator/fixtures/flipper.wasm index ee816fbe7f..a064cb4252 100644 Binary files a/tests/xcm-simulator/fixtures/flipper.wasm and b/tests/xcm-simulator/fixtures/flipper.wasm differ diff --git a/tests/xcm-simulator/src/README.md b/tests/xcm-simulator/src/README.md index 1e9fdc18ce..c15363a4f1 100644 --- a/tests/xcm-simulator/src/README.md +++ b/tests/xcm-simulator/src/README.md @@ -19,4 +19,4 @@ It's possible that in the future we decide to define a different runtime type (p Running tests is same as with any other unit tests: -`cargo test -p xcm-simulator-tests` \ No newline at end of file +`cargo test -p xcm-simulator-tests` diff --git a/tests/xcm-simulator/src/mocks/mod.rs b/tests/xcm-simulator/src/mocks/mod.rs index 336233d592..d9d37f83e5 100644 --- a/tests/xcm-simulator/src/mocks/mod.rs +++ b/tests/xcm-simulator/src/mocks/mod.rs @@ -22,7 +22,9 @@ pub(crate) mod relay_chain; use frame_support::traits::{Currency, IsType, OnFinalize, OnInitialize}; use frame_support::weights::Weight; -use pallet_contracts_primitives::Code; +use pallet_contracts::Determinism; +use pallet_contracts_primitives::{Code, ReturnFlags}; +use parity_scale_codec::Decode; use sp_runtime::traits::{Bounded, Hash, StaticLookup}; use sp_runtime::DispatchResult; use xcm::latest::prelude::*; @@ -80,7 +82,6 @@ pub type RelayChainPalletXcm = pallet_xcm::Pallet; pub type ParachainPalletXcm = pallet_xcm::Pallet; pub type ParachainAssets = pallet_assets::Pallet; pub type ParachainBalances = pallet_balances::Pallet; -pub type ParachainContracts = pallet_contracts::Pallet; pub type ParachainXtokens = orml_xtokens::Pallet; pub fn parent_account_id() -> parachain::AccountId { @@ -305,3 +306,44 @@ pub fn deploy_contract( ); (result.account_id, hash) } + +/// Call the wasm contract method and returns the decoded return +/// values along with return flags and consumed weight +pub fn call_contract_method( + origin: T::AccountId, + dest: T::AccountId, + value: ContractBalanceOf, + gas_limit: Weight, + storage_deposit_limit: Option>, + data: Vec, + debug: bool, +) -> (V, ReturnFlags, Weight) { + let outcome = pallet_contracts::Pallet::::bare_call( + origin, + dest, + value, + gas_limit, + storage_deposit_limit, + data, + debug, + Determinism::Deterministic, + ); + + if debug { + println!( + "Contract debug buffer - {:?}", + String::from_utf8(outcome.debug_message.clone()) + ); + println!("Contract outcome - {outcome:?}"); + } + + let res = outcome.result.unwrap(); + // check for revert + assert!(!res.did_revert(), "Contract reverted!"); + + ( + V::decode(&mut res.data.as_ref()).unwrap(), + res.flags, + outcome.gas_consumed, + ) +} diff --git a/tests/xcm-simulator/src/mocks/parachain.rs b/tests/xcm-simulator/src/mocks/parachain.rs index 8e68c9c1c0..fafb4d5ebd 100644 --- a/tests/xcm-simulator/src/mocks/parachain.rs +++ b/tests/xcm-simulator/src/mocks/parachain.rs @@ -23,8 +23,8 @@ use frame_support::{ dispatch::DispatchClass, match_types, parameter_types, traits::{ - AsEnsureOriginWithArg, ConstU128, ConstU32, ConstU64, Currency, Everything, Imbalance, - InstanceFilter, Nothing, OnUnbalanced, + AsEnsureOriginWithArg, ConstU128, ConstU32, ConstU64, Contains, Currency, Everything, + Imbalance, InstanceFilter, Nothing, OnUnbalanced, }, weights::{ constants::{BlockExecutionWeight, ExtrinsicBaseWeight, WEIGHT_REF_TIME_PER_SECOND}, @@ -218,6 +218,18 @@ impl Convert for Runtime { } } +pub struct CallFilter; +impl Contains for CallFilter { + fn contains(call: &RuntimeCall) -> bool { + match call { + // allow pallet_xcm::send() + RuntimeCall::PolkadotXcm(pallet_xcm::Call::send { .. }) => true, + // no other calls allowed + _ => false, + } + } +} + impl pallet_contracts::Config for Runtime { type Time = Timestamp; type Randomness = Randomness; @@ -230,7 +242,7 @@ impl pallet_contracts::Config for Runtime { /// and make sure they are stable. Dispatchables exposed to contracts are not allowed to /// change because that would break already deployed contracts. The `Call` structure itself /// is not allowed to change the indices of existing pallets, too. - type CallFilter = Nothing; + type CallFilter = CallFilter; type DepositPerItem = DepositPerItem; type DepositPerByte = DepositPerByte; type CallStack = [pallet_contracts::Frame; 5]; @@ -244,7 +256,7 @@ impl pallet_contracts::Config for Runtime { type AddressGenerator = pallet_contracts::DefaultAddressGenerator; type MaxCodeLen = ConstU32<{ 123 * 1024 }>; type MaxStorageKeyLen = ConstU32<128>; - type UnsafeUnstableInterface = ConstBool; + type UnsafeUnstableInterface = ConstBool; type MaxDebugBufferLen = ConstU32<{ 2 * 1024 * 1024 }>; } diff --git a/tests/xcm-simulator/src/tests/experimental.rs b/tests/xcm-simulator/src/tests/experimental.rs index 835ac7097a..6f47ed74de 100644 --- a/tests/xcm-simulator/src/tests/experimental.rs +++ b/tests/xcm-simulator/src/tests/experimental.rs @@ -23,8 +23,7 @@ use crate::mocks::{ }; use frame_support::{assert_ok, weights::Weight}; -use pallet_contracts::Determinism; -use parity_scale_codec::{Decode, Encode}; +use parity_scale_codec::Encode; use sp_runtime::traits::Bounded; use xcm::{prelude::*, v3::Response}; use xcm_simulator::TestExt; @@ -183,7 +182,7 @@ fn xcm_remote_transact_contract() { ); // check for flip status - let outcome = ParachainContracts::bare_call( + let (res, _, _) = call_contract_method::>( ALICE.into(), contract_id.clone(), 0, @@ -191,14 +190,8 @@ fn xcm_remote_transact_contract() { None, SELECTOR_GET.to_vec(), true, - Determinism::Deterministic, ); - let res = outcome.result.unwrap(); - // check for revert - assert!(!res.did_revert()); - // decode the return value - let flag = Result::::decode(&mut res.data.as_ref()).unwrap(); - assert_eq!(flag, Ok(true)); + assert_eq!(res, Ok(true)); }); ParaB::execute_with(|| { @@ -235,7 +228,7 @@ fn xcm_remote_transact_contract() { // check for flip status, it should be false ParaA::execute_with(|| { - let outcome = ParachainContracts::bare_call( + let (res, _, _) = call_contract_method::>( ALICE.into(), contract_id.clone(), 0, @@ -243,13 +236,142 @@ fn xcm_remote_transact_contract() { None, SELECTOR_GET.to_vec(), true, - Determinism::Deterministic, ); - let res = outcome.result.unwrap(); - // check for revert - assert!(res.did_revert() == false); - // decode the return value, it should be false - let flag = Result::::decode(&mut res.data.as_ref()).unwrap(); - assert_eq!(flag, Ok(false)); + assert_eq!(res, Ok(false)); + }); +} + +#[test] +fn test_async_xcm_contract_call_no_ce() { + /// All the fees and weights values required for the whole + /// operation. + #[derive(Encode)] + pub struct WeightsAndFees { + /// Max fee for whole XCM operation in foreign chain + /// This includes fees for sending XCM back to original + /// chain via Transact(pallet_xcm::send). + pub foreign_base_fee: MultiAsset, + /// Max weight for operation (remark) + pub foreign_transact_weight: Weight, + /// Max weight for Transact(pallet_xcm::send) operation + pub foreign_transcat_pallet_xcm: Weight, + /// Max fee for the callback operation + /// send by foreign chain + pub here_callback_base_fee: MultiAsset, + /// Max weight for Transact(pallet_contracts::call) + pub here_callback_transact_weight: Weight, + /// Max weight for contract call + pub here_callback_contract_weight: Weight, + } + + const CONSTRUCTOR_SELECTOR: [u8; 4] = [0x00, 0x00, 0x11, 0x11]; + const ATTEMPT_REMARK_SELECTOR: [u8; 4] = [0x00, 0x00, 0x22, 0x22]; + const RESULT_REMARK_SELECTOR: [u8; 4] = [0x00, 0x00, 0x44, 0x44]; + + // + // Setup + // + let contract_id = ParaA::execute_with(|| { + // deploy contract + let (contract_id, _) = deploy_contract::( + "async-xcm-call-no-ce", + ALICE.into(), + 0, + GAS_LIMIT, + None, + [CONSTRUCTOR_SELECTOR.to_vec(), 1.encode()].concat(), + ); + + // topup soverigin account of contract's derieve account in ParaB + assert_ok!(ParachainBalances::set_balance( + parachain::RuntimeOrigin::root(), + sibling_para_account_account_id( + 2, + sibling_para_account_account_id(1, contract_id.clone()) + ), + INITIAL_BALANCE, + 100_000 + )); + + contract_id + }); + + ParaB::execute_with(|| { + // topup contract's ParaB derieve account + assert_ok!(ParachainBalances::set_balance( + parachain::RuntimeOrigin::root(), + sibling_para_account_account_id(1, contract_id.clone()), + INITIAL_BALANCE, + 100_000 + )); + }); + + // + // Send the XCM + // + ParaA::execute_with(|| { + assert_eq!( + call_contract_method::>( + ALICE.into(), + contract_id.clone(), + 0, + Weight::max_value(), + None, + [ + ATTEMPT_REMARK_SELECTOR.to_vec(), + 2u32.encode(), + [1u8, 2u8, 3u8].to_vec().encode(), + WeightsAndFees { + foreign_base_fee: (Here, 100_000_000_000_000_000_000_u128).into(), + foreign_transact_weight: Weight::from_parts(7_800_000, 0), + foreign_transcat_pallet_xcm: Weight::from_parts( + 2_000_000_000_000, + 3 * 1024 * 1024 + ), + here_callback_base_fee: (Here, 100_000_000_000_000_000_u128).into(), + here_callback_contract_weight: Weight::from_parts( + 400_000_000_000, + 1024 * 1024, + ), + here_callback_transact_weight: Weight::from_parts( + 500_000_000_000, + 2 * 1024 * 1024 + ), + } + .encode(), + ] + .concat(), + true, + ) + .0, + Ok(true) + ); + }); + + // check for if remark was executed in ParaB + ParaB::execute_with(|| { + use parachain::{RuntimeEvent, System}; + // check remark events + assert!(System::events().iter().any(|r| matches!( + r.event, + RuntimeEvent::System(frame_system::Event::Remarked { .. }) + ))); + }); + + // Check for contract method called + ParaA::execute_with(|| { + assert_eq!( + call_contract_method::, ()>>( + ALICE.into(), + contract_id.clone(), + 0, + GAS_LIMIT, + None, + RESULT_REMARK_SELECTOR.to_vec(), + true, + ) + .0, + Ok(Some(true)) + ); }); }