diff --git a/Cargo.lock b/Cargo.lock index 704f110190..e535533af8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -167,15 +167,6 @@ dependencies = [ "opaque-debug 0.3.0", ] -[[package]] -name = "affix" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50e7ea84d3fa2009f355f8429a0b418a96849135a4188fadf384f59127d5d4bc" -dependencies = [ - "convert_case 0.5.0", -] - [[package]] name = "ahash" version = "0.7.6" @@ -611,15 +602,6 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" -[[package]] -name = "basic-toml" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bfc506e7a2370ec239e1d072507b2a80c833083699d3c6fa176fbb4de8448c6" -dependencies = [ - "serde", -] - [[package]] name = "beef" version = "0.5.2" @@ -1254,12 +1236,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" -[[package]] -name = "convert_case" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb4a24b1aaf0fd0ce8b45161144d6f42cd91677fd5940fd431183eb023b3a2b8" - [[package]] name = "core-foundation" version = "0.9.3" @@ -2283,19 +2259,13 @@ version = "0.99.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" dependencies = [ - "convert_case 0.4.0", + "convert_case", "proc-macro2", "quote", "rustc_version", "syn 1.0.109", ] -[[package]] -name = "diff" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" - [[package]] name = "difflib" version = "0.4.0" @@ -2892,7 +2862,7 @@ dependencies = [ [[package]] name = "fc-consensus" version = "2.0.0-dev" -source = "git+https://github.com/moonbeam-foundation/frontier?branch=moonbeam-polkadot-v0.9.43#2d131f31e3d405439a4a9bbb8824906eea3b9336" +source = "git+https://github.com/moonbeam-foundation/frontier?branch=cem-precompiles-moonbeam-polkadot-v0.9.43#cc79225df53ae247b69c52d5776ebc8d3fceb92c" dependencies = [ "async-trait", "fp-consensus", @@ -2908,7 +2878,7 @@ dependencies = [ [[package]] name = "fc-db" version = "2.0.0-dev" -source = "git+https://github.com/moonbeam-foundation/frontier?branch=moonbeam-polkadot-v0.9.43#2d131f31e3d405439a4a9bbb8824906eea3b9336" +source = "git+https://github.com/moonbeam-foundation/frontier?branch=cem-precompiles-moonbeam-polkadot-v0.9.43#cc79225df53ae247b69c52d5776ebc8d3fceb92c" dependencies = [ "async-trait", "ethereum", @@ -2938,7 +2908,7 @@ dependencies = [ [[package]] name = "fc-mapping-sync" version = "2.0.0-dev" -source = "git+https://github.com/moonbeam-foundation/frontier?branch=moonbeam-polkadot-v0.9.43#2d131f31e3d405439a4a9bbb8824906eea3b9336" +source = "git+https://github.com/moonbeam-foundation/frontier?branch=cem-precompiles-moonbeam-polkadot-v0.9.43#cc79225df53ae247b69c52d5776ebc8d3fceb92c" dependencies = [ "fc-db", "fc-storage", @@ -2961,7 +2931,7 @@ dependencies = [ [[package]] name = "fc-rpc" version = "2.0.0-dev" -source = "git+https://github.com/moonbeam-foundation/frontier?branch=moonbeam-polkadot-v0.9.43#2d131f31e3d405439a4a9bbb8824906eea3b9336" +source = "git+https://github.com/moonbeam-foundation/frontier?branch=cem-precompiles-moonbeam-polkadot-v0.9.43#cc79225df53ae247b69c52d5776ebc8d3fceb92c" dependencies = [ "ethereum", "ethereum-types", @@ -3011,7 +2981,7 @@ dependencies = [ [[package]] name = "fc-rpc-core" version = "1.1.0-dev" -source = "git+https://github.com/moonbeam-foundation/frontier?branch=moonbeam-polkadot-v0.9.43#2d131f31e3d405439a4a9bbb8824906eea3b9336" +source = "git+https://github.com/moonbeam-foundation/frontier?branch=cem-precompiles-moonbeam-polkadot-v0.9.43#cc79225df53ae247b69c52d5776ebc8d3fceb92c" dependencies = [ "ethereum", "ethereum-types", @@ -3024,7 +2994,7 @@ dependencies = [ [[package]] name = "fc-storage" version = "1.0.0-dev" -source = "git+https://github.com/moonbeam-foundation/frontier?branch=moonbeam-polkadot-v0.9.43#2d131f31e3d405439a4a9bbb8824906eea3b9336" +source = "git+https://github.com/moonbeam-foundation/frontier?branch=cem-precompiles-moonbeam-polkadot-v0.9.43#cc79225df53ae247b69c52d5776ebc8d3fceb92c" dependencies = [ "ethereum", "ethereum-types", @@ -3204,7 +3174,7 @@ dependencies = [ [[package]] name = "fp-account" version = "1.0.0-dev" -source = "git+https://github.com/moonbeam-foundation/frontier?branch=moonbeam-polkadot-v0.9.43#2d131f31e3d405439a4a9bbb8824906eea3b9336" +source = "git+https://github.com/moonbeam-foundation/frontier?branch=cem-precompiles-moonbeam-polkadot-v0.9.43#05015e6f2f66cc8a4f6b365dce948d831d6d7d0c" dependencies = [ "hex", "impl-serde 0.4.0", @@ -3223,7 +3193,7 @@ dependencies = [ [[package]] name = "fp-consensus" version = "2.0.0-dev" -source = "git+https://github.com/moonbeam-foundation/frontier?branch=moonbeam-polkadot-v0.9.43#2d131f31e3d405439a4a9bbb8824906eea3b9336" +source = "git+https://github.com/moonbeam-foundation/frontier?branch=cem-precompiles-moonbeam-polkadot-v0.9.43#cc79225df53ae247b69c52d5776ebc8d3fceb92c" dependencies = [ "ethereum", "parity-scale-codec", @@ -3235,7 +3205,7 @@ dependencies = [ [[package]] name = "fp-ethereum" version = "1.0.0-dev" -source = "git+https://github.com/moonbeam-foundation/frontier?branch=moonbeam-polkadot-v0.9.43#2d131f31e3d405439a4a9bbb8824906eea3b9336" +source = "git+https://github.com/moonbeam-foundation/frontier?branch=cem-precompiles-moonbeam-polkadot-v0.9.43#cc79225df53ae247b69c52d5776ebc8d3fceb92c" dependencies = [ "ethereum", "ethereum-types", @@ -3249,7 +3219,7 @@ dependencies = [ [[package]] name = "fp-evm" version = "3.0.0-dev" -source = "git+https://github.com/moonbeam-foundation/frontier?branch=moonbeam-polkadot-v0.9.43#2d131f31e3d405439a4a9bbb8824906eea3b9336" +source = "git+https://github.com/moonbeam-foundation/frontier?branch=cem-precompiles-moonbeam-polkadot-v0.9.43#05015e6f2f66cc8a4f6b365dce948d831d6d7d0c" dependencies = [ "evm", "frame-support", @@ -3264,7 +3234,7 @@ dependencies = [ [[package]] name = "fp-rpc" version = "3.0.0-dev" -source = "git+https://github.com/moonbeam-foundation/frontier?branch=moonbeam-polkadot-v0.9.43#2d131f31e3d405439a4a9bbb8824906eea3b9336" +source = "git+https://github.com/moonbeam-foundation/frontier?branch=cem-precompiles-moonbeam-polkadot-v0.9.43#cc79225df53ae247b69c52d5776ebc8d3fceb92c" dependencies = [ "ethereum", "ethereum-types", @@ -3281,7 +3251,7 @@ dependencies = [ [[package]] name = "fp-self-contained" version = "1.0.0-dev" -source = "git+https://github.com/moonbeam-foundation/frontier?branch=moonbeam-polkadot-v0.9.43#2d131f31e3d405439a4a9bbb8824906eea3b9336" +source = "git+https://github.com/moonbeam-foundation/frontier?branch=cem-precompiles-moonbeam-polkadot-v0.9.43#cc79225df53ae247b69c52d5776ebc8d3fceb92c" dependencies = [ "frame-support", "parity-scale-codec", @@ -3293,7 +3263,7 @@ dependencies = [ [[package]] name = "fp-storage" version = "2.0.0" -source = "git+https://github.com/moonbeam-foundation/frontier?branch=moonbeam-polkadot-v0.9.43#2d131f31e3d405439a4a9bbb8824906eea3b9336" +source = "git+https://github.com/moonbeam-foundation/frontier?branch=cem-precompiles-moonbeam-polkadot-v0.9.43#cc79225df53ae247b69c52d5776ebc8d3fceb92c" dependencies = [ "parity-scale-codec", "serde", @@ -5461,21 +5431,6 @@ dependencies = [ "libc", ] -[[package]] -name = "macrotest" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7489ae0986ce45414b7b3122c2e316661343ecf396b206e3e15f07c846616f10" -dependencies = [ - "diff", - "glob", - "prettyplease 0.1.25", - "serde", - "serde_json", - "syn 1.0.109", - "toml 0.5.11", -] - [[package]] name = "manual-xcm-rpc" version = "0.1.0" @@ -7569,7 +7524,7 @@ dependencies = [ [[package]] name = "pallet-base-fee" version = "1.0.0" -source = "git+https://github.com/moonbeam-foundation/frontier?branch=moonbeam-polkadot-v0.9.43#2d131f31e3d405439a4a9bbb8824906eea3b9336" +source = "git+https://github.com/moonbeam-foundation/frontier?branch=cem-precompiles-moonbeam-polkadot-v0.9.43#cc79225df53ae247b69c52d5776ebc8d3fceb92c" dependencies = [ "fp-evm", "frame-support", @@ -7811,7 +7766,7 @@ dependencies = [ [[package]] name = "pallet-ethereum" version = "4.0.0-dev" -source = "git+https://github.com/moonbeam-foundation/frontier?branch=moonbeam-polkadot-v0.9.43#2d131f31e3d405439a4a9bbb8824906eea3b9336" +source = "git+https://github.com/moonbeam-foundation/frontier?branch=cem-precompiles-moonbeam-polkadot-v0.9.43#cc79225df53ae247b69c52d5776ebc8d3fceb92c" dependencies = [ "environmental", "ethereum", @@ -7878,7 +7833,7 @@ dependencies = [ [[package]] name = "pallet-evm" version = "6.0.0-dev" -source = "git+https://github.com/moonbeam-foundation/frontier?branch=moonbeam-polkadot-v0.9.43#2d131f31e3d405439a4a9bbb8824906eea3b9336" +source = "git+https://github.com/moonbeam-foundation/frontier?branch=cem-precompiles-moonbeam-polkadot-v0.9.43#05015e6f2f66cc8a4f6b365dce948d831d6d7d0c" dependencies = [ "environmental", "evm", @@ -7986,7 +7941,7 @@ dependencies = [ [[package]] name = "pallet-evm-precompile-blake2" version = "2.0.0-dev" -source = "git+https://github.com/moonbeam-foundation/frontier?branch=moonbeam-polkadot-v0.9.43#2d131f31e3d405439a4a9bbb8824906eea3b9336" +source = "git+https://github.com/moonbeam-foundation/frontier?branch=cem-precompiles-moonbeam-polkadot-v0.9.43#cc79225df53ae247b69c52d5776ebc8d3fceb92c" dependencies = [ "fp-evm", ] @@ -7994,7 +7949,7 @@ dependencies = [ [[package]] name = "pallet-evm-precompile-bn128" version = "2.0.0-dev" -source = "git+https://github.com/moonbeam-foundation/frontier?branch=moonbeam-polkadot-v0.9.43#2d131f31e3d405439a4a9bbb8824906eea3b9336" +source = "git+https://github.com/moonbeam-foundation/frontier?branch=cem-precompiles-moonbeam-polkadot-v0.9.43#cc79225df53ae247b69c52d5776ebc8d3fceb92c" dependencies = [ "fp-evm", "sp-core", @@ -8150,7 +8105,7 @@ dependencies = [ [[package]] name = "pallet-evm-precompile-dispatch" version = "2.0.0-dev" -source = "git+https://github.com/moonbeam-foundation/frontier?branch=moonbeam-polkadot-v0.9.43#2d131f31e3d405439a4a9bbb8824906eea3b9336" +source = "git+https://github.com/moonbeam-foundation/frontier?branch=cem-precompiles-moonbeam-polkadot-v0.9.43#cc79225df53ae247b69c52d5776ebc8d3fceb92c" dependencies = [ "fp-evm", "frame-support", @@ -8197,7 +8152,7 @@ dependencies = [ [[package]] name = "pallet-evm-precompile-modexp" version = "2.0.0-dev" -source = "git+https://github.com/moonbeam-foundation/frontier?branch=moonbeam-polkadot-v0.9.43#2d131f31e3d405439a4a9bbb8824906eea3b9336" +source = "git+https://github.com/moonbeam-foundation/frontier?branch=cem-precompiles-moonbeam-polkadot-v0.9.43#cc79225df53ae247b69c52d5776ebc8d3fceb92c" dependencies = [ "fp-evm", "num", @@ -8400,7 +8355,7 @@ dependencies = [ [[package]] name = "pallet-evm-precompile-sha3fips" version = "2.0.0-dev" -source = "git+https://github.com/moonbeam-foundation/frontier?branch=moonbeam-polkadot-v0.9.43#2d131f31e3d405439a4a9bbb8824906eea3b9336" +source = "git+https://github.com/moonbeam-foundation/frontier?branch=cem-precompiles-moonbeam-polkadot-v0.9.43#cc79225df53ae247b69c52d5776ebc8d3fceb92c" dependencies = [ "fp-evm", "tiny-keccak", @@ -8409,7 +8364,7 @@ dependencies = [ [[package]] name = "pallet-evm-precompile-simple" version = "2.0.0-dev" -source = "git+https://github.com/moonbeam-foundation/frontier?branch=moonbeam-polkadot-v0.9.43#2d131f31e3d405439a4a9bbb8824906eea3b9336" +source = "git+https://github.com/moonbeam-foundation/frontier?branch=cem-precompiles-moonbeam-polkadot-v0.9.43#cc79225df53ae247b69c52d5776ebc8d3fceb92c" dependencies = [ "fp-evm", "ripemd", @@ -8436,6 +8391,7 @@ dependencies = [ "pallet-xcm-transactor", "parity-scale-codec", "precompile-utils", + "precompile-utils-xcm-codec", "rustc-hex", "scale-info", "serde", @@ -8468,6 +8424,7 @@ dependencies = [ "parity-scale-codec", "polkadot-parachain", "precompile-utils", + "precompile-utils-xcm-codec", "scale-info", "serde", "sha3", @@ -8500,6 +8457,7 @@ dependencies = [ "pallet-xcm", "parity-scale-codec", "precompile-utils", + "precompile-utils-xcm-codec", "rustc-hex", "scale-info", "serde", @@ -10945,8 +10903,8 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "precompile-utils" version = "0.1.0" +source = "git+https://github.com/moonbeam-foundation/frontier?branch=cem-precompiles-moonbeam-polkadot-v0.9.43#05015e6f2f66cc8a4f6b365dce948d831d6d7d0c" dependencies = [ - "affix", "derive_more", "environmental", "evm", @@ -10954,7 +10912,7 @@ dependencies = [ "frame-support", "frame-system", "hex", - "hex-literal 0.3.4", + "hex-literal 0.4.1", "impl-trait-for-tuples", "log", "num_enum 0.5.11", @@ -10970,51 +10928,33 @@ dependencies = [ "sp-io", "sp-runtime", "sp-std", - "xcm", ] [[package]] name = "precompile-utils-macro" version = "0.1.0" +source = "git+https://github.com/moonbeam-foundation/frontier?branch=cem-precompiles-moonbeam-polkadot-v0.9.43#05015e6f2f66cc8a4f6b365dce948d831d6d7d0c" dependencies = [ "case", - "fp-evm", - "frame-support", - "macrotest", "num_enum 0.5.11", - "precompile-utils", "prettyplease 0.1.25", "proc-macro2", "quote", "sha3", - "sp-core", - "sp-std", "syn 1.0.109", - "trybuild", ] [[package]] -name = "precompile-utils-tests-external" +name = "precompile-utils-xcm-codec" version = "0.1.0" dependencies = [ - "derive_more", - "evm", - "fp-evm", "frame-support", - "frame-system", "hex-literal 0.3.4", - "pallet-balances", "pallet-evm", - "pallet-timestamp", - "parity-scale-codec", "precompile-utils", - "scale-info", - "serde", - "sha3", "sp-core", - "sp-io", - "sp-runtime", "sp-std", + "xcm", ] [[package]] @@ -15653,21 +15593,6 @@ dependencies = [ "zstd 0.12.4", ] -[[package]] -name = "trybuild" -version = "1.0.82" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a84e0202ea606ba5ebee8507ab2bfbe89b98551ed9b8f0be198109275cff284b" -dependencies = [ - "basic-toml", - "glob", - "once_cell", - "serde", - "serde_derive", - "serde_json", - "termcolor", -] - [[package]] name = "tt-call" version = "1.0.9" diff --git a/Cargo.toml b/Cargo.toml index bf537de4c4..fa4cad2a96 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,9 +25,7 @@ members = [ "precompiles/proxy", "precompiles/referenda", "precompiles/relay-encoder", - "precompiles/utils", - "precompiles/utils/macro", - "precompiles/utils/tests-external", + "precompiles/utils/xcm-codec", "precompiles/xcm-transactor", "precompiles/xtokens", "runtime/moonbase", @@ -90,7 +88,7 @@ pallet-moonbeam-orbiters = { path = "pallets/moonbeam-orbiters", default-feature pallet-parachain-staking = { path = "pallets/parachain-staking", default-features = false } pallet-proxy-genesis-companion = { path = "pallets/proxy-genesis-companion", default-features = false } pallet-xcm-transactor = { path = "pallets/xcm-transactor", default-features = false } -precompile-utils = { path = "precompiles/utils", default-features = false } +precompile-utils-xcm-codec = { path = "precompiles/utils/xcm-codec", default-features = false } xcm-primitives = { path = "primitives/xcm", default-features = false } pallet-crowdloan-rewards = { git = "https://github.com/moonbeam-foundation/crowdloan-rewards", branch = "moonbeam-polkadot-v0.9.43", default-features = false } @@ -220,33 +218,34 @@ ethereum-types = { version = "0.14", default-features = false } evm = { git = "https://github.com/moonbeam-foundation/evm", branch = "tgm-record-external-cost", default-features = false } evm-gasometer = { git = "https://github.com/moonbeam-foundation/evm", branch = "tgm-record-external-cost", default-features = false } evm-runtime = { git = "https://github.com/moonbeam-foundation/evm", branch = "tgm-record-external-cost", default-features = false } -fp-ethereum = { git = "https://github.com/moonbeam-foundation/frontier", branch = "moonbeam-polkadot-v0.9.43", default-features = false } -fp-evm = { git = "https://github.com/moonbeam-foundation/frontier", branch = "moonbeam-polkadot-v0.9.43", default-features = false } -fp-rpc = { git = "https://github.com/moonbeam-foundation/frontier", branch = "moonbeam-polkadot-v0.9.43", default-features = false } -fp-self-contained = { git = "https://github.com/moonbeam-foundation/frontier", branch = "moonbeam-polkadot-v0.9.43", default-features = false } -pallet-base-fee = { git = "https://github.com/moonbeam-foundation/frontier", branch = "moonbeam-polkadot-v0.9.43", default-features = false } -pallet-ethereum = { git = "https://github.com/moonbeam-foundation/frontier", branch = "moonbeam-polkadot-v0.9.43", default-features = false, features = [ "forbid-evm-reentrancy" ] } -pallet-evm = { git = "https://github.com/moonbeam-foundation/frontier", branch = "moonbeam-polkadot-v0.9.43", default-features = false, features = [ +fp-ethereum = { git = "https://github.com/moonbeam-foundation/frontier", branch = "cem-precompiles-moonbeam-polkadot-v0.9.43", default-features = false } +fp-evm = { git = "https://github.com/moonbeam-foundation/frontier", branch = "cem-precompiles-moonbeam-polkadot-v0.9.43", default-features = false } +fp-rpc = { git = "https://github.com/moonbeam-foundation/frontier", branch = "cem-precompiles-moonbeam-polkadot-v0.9.43", default-features = false } +fp-self-contained = { git = "https://github.com/moonbeam-foundation/frontier", branch = "cem-precompiles-moonbeam-polkadot-v0.9.43", default-features = false } +pallet-base-fee = { git = "https://github.com/moonbeam-foundation/frontier", branch = "cem-precompiles-moonbeam-polkadot-v0.9.43", default-features = false } +pallet-ethereum = { git = "https://github.com/moonbeam-foundation/frontier", branch = "cem-precompiles-moonbeam-polkadot-v0.9.43", default-features = false, features = [ "forbid-evm-reentrancy" ] } +pallet-evm = { git = "https://github.com/moonbeam-foundation/frontier", branch = "cem-precompiles-moonbeam-polkadot-v0.9.43", default-features = false, features = [ "forbid-evm-reentrancy", ] } -pallet-evm-precompile-blake2 = { git = "https://github.com/moonbeam-foundation/frontier", branch = "moonbeam-polkadot-v0.9.43", default-features = false } -pallet-evm-precompile-bn128 = { git = "https://github.com/moonbeam-foundation/frontier", branch = "moonbeam-polkadot-v0.9.43", default-features = false } -pallet-evm-precompile-dispatch = { git = "https://github.com/moonbeam-foundation/frontier", branch = "moonbeam-polkadot-v0.9.43", default-features = false } -pallet-evm-precompile-modexp = { git = "https://github.com/moonbeam-foundation/frontier", branch = "moonbeam-polkadot-v0.9.43", default-features = false } -pallet-evm-precompile-sha3fips = { git = "https://github.com/moonbeam-foundation/frontier", branch = "moonbeam-polkadot-v0.9.43", default-features = false } -pallet-evm-precompile-simple = { git = "https://github.com/moonbeam-foundation/frontier", branch = "moonbeam-polkadot-v0.9.43", default-features = false } +pallet-evm-precompile-blake2 = { git = "https://github.com/moonbeam-foundation/frontier", branch = "cem-precompiles-moonbeam-polkadot-v0.9.43", default-features = false } +pallet-evm-precompile-bn128 = { git = "https://github.com/moonbeam-foundation/frontier", branch = "cem-precompiles-moonbeam-polkadot-v0.9.43", default-features = false } +pallet-evm-precompile-dispatch = { git = "https://github.com/moonbeam-foundation/frontier", branch = "cem-precompiles-moonbeam-polkadot-v0.9.43", default-features = false } +pallet-evm-precompile-modexp = { git = "https://github.com/moonbeam-foundation/frontier", branch = "cem-precompiles-moonbeam-polkadot-v0.9.43", default-features = false } +pallet-evm-precompile-sha3fips = { git = "https://github.com/moonbeam-foundation/frontier", branch = "cem-precompiles-moonbeam-polkadot-v0.9.43", default-features = false } +pallet-evm-precompile-simple = { git = "https://github.com/moonbeam-foundation/frontier", branch = "cem-precompiles-moonbeam-polkadot-v0.9.43", default-features = false } # Frontier (client) -fc-consensus = { git = "https://github.com/moonbeam-foundation/frontier", branch = "moonbeam-polkadot-v0.9.43" } -fc-db = { git = "https://github.com/moonbeam-foundation/frontier", branch = "moonbeam-polkadot-v0.9.43" } -fc-mapping-sync = { git = "https://github.com/moonbeam-foundation/frontier", branch = "moonbeam-polkadot-v0.9.43" } -fc-rpc = { git = "https://github.com/moonbeam-foundation/frontier", branch = "moonbeam-polkadot-v0.9.43", features = [ +fc-consensus = { git = "https://github.com/moonbeam-foundation/frontier", branch = "cem-precompiles-moonbeam-polkadot-v0.9.43" } +fc-db = { git = "https://github.com/moonbeam-foundation/frontier", branch = "cem-precompiles-moonbeam-polkadot-v0.9.43" } +fc-mapping-sync = { git = "https://github.com/moonbeam-foundation/frontier", branch = "cem-precompiles-moonbeam-polkadot-v0.9.43" } +fc-rpc = { git = "https://github.com/moonbeam-foundation/frontier", branch = "cem-precompiles-moonbeam-polkadot-v0.9.43", features = [ "rpc-binary-search-estimate", ] } -fc-rpc-core = { git = "https://github.com/moonbeam-foundation/frontier", branch = "moonbeam-polkadot-v0.9.43" } -fc-storage = { git = "https://github.com/moonbeam-foundation/frontier", branch = "moonbeam-polkadot-v0.9.43" } -fp-consensus = { git = "https://github.com/moonbeam-foundation/frontier", branch = "moonbeam-polkadot-v0.9.43" } -fp-storage = { git = "https://github.com/moonbeam-foundation/frontier", branch = "moonbeam-polkadot-v0.9.43" } +fc-rpc-core = { git = "https://github.com/moonbeam-foundation/frontier", branch = "cem-precompiles-moonbeam-polkadot-v0.9.43" } +fc-storage = { git = "https://github.com/moonbeam-foundation/frontier", branch = "cem-precompiles-moonbeam-polkadot-v0.9.43" } +fp-consensus = { git = "https://github.com/moonbeam-foundation/frontier", branch = "cem-precompiles-moonbeam-polkadot-v0.9.43" } +fp-storage = { git = "https://github.com/moonbeam-foundation/frontier", branch = "cem-precompiles-moonbeam-polkadot-v0.9.43" } +precompile-utils = { git = "https://github.com/moonbeam-foundation/frontier", branch = "cem-precompiles-moonbeam-polkadot-v0.9.43", default-features = false } # Cumulus (wasm) cumulus-pallet-dmp-queue = { git = "https://github.com/moonbeam-foundation/cumulus", branch = "moonbeam-polkadot-v0.9.43", default-features = false } @@ -311,7 +310,6 @@ session-keys-primitives = { git = "https://github.com/Moonsong-Labs/moonkit", br nimbus-consensus = { git = "https://github.com/Moonsong-Labs/moonkit", branch = "moonbeam-polkadot-v0.9.43" } # Other (wasm) -affix = "0.1.2" async-trait = { version = "0.1.42" } blake2-rfc = { version = "0.2.18", default-features = false } derive_more = "0.99" diff --git a/precompiles/utils/Cargo.toml b/precompiles/utils/Cargo.toml deleted file mode 100644 index 3cd798b80e..0000000000 --- a/precompiles/utils/Cargo.toml +++ /dev/null @@ -1,61 +0,0 @@ -[package] -name = "precompile-utils" -authors = { workspace = true } -description = "Utils to write EVM precompiles." -edition = "2021" -version = "0.1.0" - -[dependencies] -affix = { workspace = true } -derive_more = { workspace = true, optional = true } -environmental = { workspace = true } -hex = { workspace = true } -hex-literal = { workspace = true, optional = true } -impl-trait-for-tuples = { workspace = true } -log = { workspace = true } -num_enum = { workspace = true } -paste = { workspace = true } -scale-info = { workspace = true, optional = true, features = [ "derive" ] } -serde = { workspace = true, optional = true } -sha3 = { workspace = true } -similar-asserts = { workspace = true, optional = true } - -# Moonbeam -precompile-utils-macro = { path = "macro" } - -# Substrate -frame-support = { workspace = true } -frame-system = { workspace = true } -parity-scale-codec = { workspace = true } -sp-core = { workspace = true } -sp-io = { workspace = true } -sp-runtime = { workspace = true } -sp-std = { workspace = true } - -# Frontier -evm = { workspace = true, features = [ "with-codec" ] } -fp-evm = { workspace = true } -pallet-evm = { workspace = true, features = [ "forbid-evm-reentrancy" ] } - -# Polkadot / XCM -xcm = { workspace = true, optional = true } - -[dev-dependencies] -hex-literal = { workspace = true } -xcm = { workspace = true } - -[features] -default = [ "std" ] -std = [ - "environmental/std", - "fp-evm/std", - "frame-support/std", - "frame-system/std", - "pallet-evm/std", - "parity-scale-codec/std", - "sp-core/std", - "sp-io/std", - "sp-std/std", -] -codec-xcm = [ "xcm" ] -testing = [ "derive_more", "hex-literal", "scale-info", "serde", "similar-asserts", "std" ] diff --git a/precompiles/utils/macro/Cargo.toml b/precompiles/utils/macro/Cargo.toml deleted file mode 100644 index f27ee05bd8..0000000000 --- a/precompiles/utils/macro/Cargo.toml +++ /dev/null @@ -1,33 +0,0 @@ -[package] -name = "precompile-utils-macro" -authors = { workspace = true } -description = "" -edition = "2021" -version = "0.1.0" - -[lib] -proc-macro = true - -[[test]] -name = "tests" -path = "tests/tests.rs" - -[dependencies] -case = "1.0" -num_enum = { version = "0.5.3", default-features = false } -prettyplease = "0.1.18" -proc-macro2 = "1.0" -quote = "1.0" -sha3 = "0.10" -syn = { version = "1.0", features = [ "extra-traits", "fold", "full", "visit" ] } - -[dev-dependencies] -macrotest = "1.0.9" -trybuild = "1.0" - -precompile-utils = { path = "../", features = [ "testing" ] } - -fp-evm = { workspace = true } -frame-support = { workspace = true } -sp-core = { workspace = true } -sp-std = { workspace = true } diff --git a/precompiles/utils/macro/docs/precompile_macro.md b/precompiles/utils/macro/docs/precompile_macro.md deleted file mode 100644 index e72a4e002a..0000000000 --- a/precompiles/utils/macro/docs/precompile_macro.md +++ /dev/null @@ -1,199 +0,0 @@ -# `#[precompile]` procedural macro. - -This procedural macro allows to simplify the implementation of an EVM precompile or precompile set -using an `impl` block with annotations to automatically generate: - -- the implementation of the trait `Precompile` or `PrecompileSet` (exposed by the `fp_evm` crate) -- parsing of the method parameters from Solidity encoding into Rust type, based on the `solidity::Codec` - trait (exposed by the `precompile-utils` crate) -- a test to ensure the types expressed in the Solidity signature match the Rust types in the - implementation. - -## How to use - -Define your precompile type and write an `impl` block that will contain the precompile methods -implementation. This `impl` block can have type parameters and a `where` clause, which will be -reused to generate the `Precompile`/`PrecompileSet` trait implementation and the enum representing -each public function of precompile with its parsed arguments. - -```rust,ignore -pub struct ExemplePrecompile(PhantomData<(R,I)>); - -#[precomile_utils::precompile] -impl ExemplePrecompile -where - R: pallet_evm::Config -{ - #[precompile::public("example(uint32)")] - fn example(handle: &mut impl PrecompileHandle, arg: u32) -> EvmResult { - Ok(arg * 2) - } -} -``` - -The example code above will automatically generate an enum like - -```rust,ignore -#[allow(non_camel_case_types)] -pub enum ExemplePrecompileCall -where - R: pallet_evm::Config -{ - example { - arg: u32 - }, - // + an non constrible variant with a PhantomData<(R,I)> -} -``` - -This enum have the function `parse_call_data` that can parse the calldata, recognize the Solidity -4-bytes selector and parse the appropriate enum variant. - -It will also generate automatically an implementation of `Precompile`/`PrecompileSet` that calls -this function and the content of the variant to its associated function of the `impl` block. - -## Function attributes - -`#[precompile::public("signature")]` allows to declare a function as a public method of the -precompile with the provided Solidity signature. A function can have multiple `public` attributes to -support renamed functions with backward compatibility, however the arguments must have the same -type. It is not allowed to use the exact same signature multiple times. - -The function must take a `&mut impl PrecompileHandle` as parameter, followed by all the parameters -of the Solidity function in the same order. Those parameters types must implement `solidity::Codec`, and -their name should match the one used in the Solidity interface (.sol) while being in `snake_case`, -which will automatically be converted to `camelCase` in revert messages. The function must return an -`EvmResult`, which is an alias of `Result`. This `T` must implement the -`solidity::Codec` trait and must match the return type in the Solidity interface. The macro will -automatically encode it to Solidity format. - -By default those functions are considered non-payable and non-view (can cause state changes). This -can be changed using either `#[precompile::payable]` or `#[precompile::view]`. Only one can be used. - -It is also possible to declare a fallback function using `#[precompile::fallback]`. This function -will be called if the selector is unknown or if the input is less than 4-bytes long (no selector). -This function cannot have any parameter outside of the `PrecompileHandle`. A function can be both -`public` and `fallback`. - -In case some check must be performed before parsing the input, such as forbidding being called from -some address, a function can be annotated with `#[precompile::pre_check]`: - -```rust,ignore -#[precompile::pre_check] -fn pre_check(handle: &mut impl PrecompileHandle) -> EvmResult { - todo!("Perform your check here") -} -``` - -This function cannot have other attributes. - -## PrecompileSet - -By default the macro considers the `impl` block to represent a precompile and this will implement -the `Precompile` trait. If you want to instead implement a precompile set, you must add the -`#[precompile::precompile_set]` to the `impl` block. - -Then, it is necessary to have a function annotated with the `#[precompile::discriminant]` attribute. -This function is called with the **code address**, the address of the precompile. It must return -`None` if this address is not part of the precompile set, or `Some` if it is. The `Some` variants -contains a value of a type of your choice that represents which member of the set this address -corresponds to. For example for our XC20 precompile sets this function returns the asset id -corresponding to this address if it exists. - -Finally, every other function annotated with a `precompile::_` attribute must now take this -discriminant as first parameter, before the `PrecompileHandle`. - -```rust,ignore -pub struct ExemplePrecompileSet(PhantomData); - -#[precompile_utils::precompile] -#[precompile::precompile_set] -impl ExamplePrecompileSet -where - R: pallet_evm::Config -{ - #[precompile::discriminant] - fn discriminant(address: H160) -> Option { - // Replace with your discriminant logic. - Some(match address { - a if a == H160::from(42) => 1 - a if a == H160::from(43) => 2, - _ => return None, - }) - } - - #[precompile::public("example(uint32)")] - fn example(discriminant: u8, handle: &mut impl PrecompileHandle, arg: u32) -> EvmResult { - // Discriminant can be used here. - Ok(arg * discriminant) - } -} -``` - -## Solidity signatures test - -The macro will automatically generate a unit test to ensure that the types expressed in a `public` -attribute matches the Rust parameters of the function, thanks to the `solidity::Codec` trait having the -`solidity_type() -> String` function. - -If any **parsed** argument (discriminant is not concerned) depends on the type parameters of the -`impl` block, the macro will not be able to produce valid code and output an error like: - -```text -error[E0412]: cannot find type `R` in this scope - --> tests/precompile/compile-fail/test/generic-arg.rs:25:63 - | -23 | impl> Precompile { - | - help: you might be missing a type parameter: `` -24 | #[precompile::public("foo(bytes)")] -25 | fn foo(handle: &mut impl PrecompileHandle, arg: BoundedBytes) -> EvmResult { - | ^ not found in this scope -``` - -In this case you need to annotate the `impl` block with the `#[precompile::test_concrete_types(...)]` -attributes. The `...` should be replaced with concrete types for each type parameter, like a mock -runtime. Those types are only used to generate the test and only one set of types can be used. - -```rust,ignore -pub struct ExamplePrecompile(PhantomData<(R, I)>); - -pub struct GetMaxSize(PhantomData<(R, I)>); - -impl Get for GetMaxSize { - fn get() -> u32 { - >::SomeConstant::get() - } -} - -#[precompile_utils::precompile] -#[precompile::test_concrete_types(mock::Runtime, Instance1)] -impl ExamplePrecompile -where - R: pallet_evm::Config + SomeConfig -{ - #[precompile::public("example(bytes)")] - fn example( - handle: &mut impl PrecompileHandle, - data: BoundedBytes>, - ) -> EvmResult { - todo!("Method implementation") - } -} -``` - -## Enum functions - -The generated enums exposes the following public functions: - -- `parse_call_data`: take a `PrecompileHandle` and tries to parse the call data. Returns an - `EvmResult`. It **DOES NOT** execute the code of the annotated `impl` block. -- `supports_selector`: take a selector as a `u32` is returns if this selector is supported by the - precompile(set) as a `bool`. Note that the presence of a fallback function is not taken into - account. -- `selectors`: returns a static array (`&'static [u32]`) of all the supported selectors. -- For each variant/public function `foo`, there is a function `foo_selectors` which returns a static - array of all the supported selectors **for that function**. That can be used to ensure in tests - that some function have a selector that was computed by hand. -- `encode`: take `self` and encodes it in Solidity format. Additionally, `Vec` implements - `From` which simply call encodes. This is useful to write tests as you can construct the - variant you want and it will be encoded to Solidity format for you. diff --git a/precompiles/utils/macro/src/derive_codec.rs b/precompiles/utils/macro/src/derive_codec.rs deleted file mode 100644 index e988e380dc..0000000000 --- a/precompiles/utils/macro/src/derive_codec.rs +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -use proc_macro::TokenStream; -use proc_macro2::Span; -use quote::{quote, quote_spanned}; -use syn::{ - parse_macro_input, punctuated::Punctuated, spanned::Spanned, DeriveInput, Ident, LitStr, Path, - PathSegment, PredicateType, TraitBound, TraitBoundModifier, -}; - -pub fn main(input: TokenStream) -> TokenStream { - let DeriveInput { - ident, - mut generics, - data, - .. - } = parse_macro_input!(input as DeriveInput); - - let syn::Data::Struct (syn::DataStruct {fields: syn::Fields::Named(fields), ..}) = data else { - return quote_spanned! { ident.span() => - compile_error!("Codec can only be derived for structs with named fields"); - } - .into() - }; - let fields = fields.named; - - if fields.len() == 0 { - return quote_spanned! { ident.span() => - compile_error!("Codec can only be derived for structs with at least one field"); - } - .into(); - } - - if let Some(unamed_field) = fields.iter().find(|f| f.ident.is_none()) { - return quote_spanned! { unamed_field.ty.span() => - compile_error!("Codec can only be derived for structs with named fields"); - } - .into(); - } - - let fields_ty: Vec<_> = fields.iter().map(|f| &f.ty).collect(); - let fields_ident: Vec<_> = fields - .iter() - .map(|f| f.ident.as_ref().expect("None case checked above")) - .collect(); - let fields_name_lit: Vec<_> = fields_ident - .iter() - .map(|i| LitStr::new(&i.to_string(), i.span())) - .collect(); - - let evm_data_trait_path = { - let mut segments = Punctuated::::new(); - segments.push(Ident::new("precompile_utils", Span::call_site()).into()); - segments.push(Ident::new("solidity", Span::call_site()).into()); - segments.push(Ident::new("Codec", Span::call_site()).into()); - Path { - leading_colon: Some(Default::default()), - segments, - } - }; - let where_clause = generics.make_where_clause(); - - for ty in &fields_ty { - let mut bounds = Punctuated::new(); - bounds.push( - TraitBound { - paren_token: None, - modifier: TraitBoundModifier::None, - lifetimes: None, - path: evm_data_trait_path.clone(), - } - .into(), - ); - - where_clause.predicates.push( - PredicateType { - lifetimes: None, - bounded_ty: (*ty).clone(), - colon_token: Default::default(), - bounds, - } - .into(), - ); - } - - let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); - quote! { - impl #impl_generics ::precompile_utils::solidity::codec::Codec for #ident #ty_generics - #where_clause { - fn read( - reader: &mut ::precompile_utils::solidity::codec::Reader - ) -> ::precompile_utils::solidity::revert::MayRevert { - use ::precompile_utils::solidity::revert::BacktraceExt as _; - let (#(#fields_ident,)*): (#(#fields_ty,)*) = reader - .read() - .map_in_tuple_to_field(&[#(#fields_name_lit),*])?; - Ok(Self { - #(#fields_ident,)* - }) - } - - fn write(writer: &mut ::precompile_utils::solidity::codec::Writer, value: Self) { - ::precompile_utils::solidity::codec::Codec::write(writer, (#(value.#fields_ident,)*)); - } - - fn has_static_size() -> bool { - <(#(#fields_ty,)*)>::has_static_size() - } - - fn signature() -> String { - <(#(#fields_ty,)*)>::signature() - } - } - } - .into() -} diff --git a/precompiles/utils/macro/src/generate_function_selector.rs b/precompiles/utils/macro/src/generate_function_selector.rs deleted file mode 100644 index 405db1e0a2..0000000000 --- a/precompiles/utils/macro/src/generate_function_selector.rs +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -use super::*; - -pub fn main(_: TokenStream, input: TokenStream) -> TokenStream { - let item = parse_macro_input!(input as ItemEnum); - - let ItemEnum { - attrs, - vis, - enum_token, - ident, - variants, - .. - } = item; - - let mut ident_expressions: Vec = vec![]; - let mut variant_expressions: Vec = vec![]; - let mut variant_attrs: Vec> = vec![]; - for variant in variants { - match variant.discriminant { - Some((_, Expr::Lit(ExprLit { lit, .. }))) => { - if let Lit::Str(lit_str) = lit { - let digest = Keccak256::digest(lit_str.value().as_bytes()); - let selector = u32::from_be_bytes([digest[0], digest[1], digest[2], digest[3]]); - ident_expressions.push(variant.ident); - variant_expressions.push(Expr::Lit(ExprLit { - lit: Lit::Verbatim(Literal::u32_suffixed(selector)), - attrs: Default::default(), - })); - variant_attrs.push(variant.attrs); - } else { - return quote_spanned! { - lit.span() => compile_error!("Expected literal string"); - } - .into(); - } - } - Some((_eg, expr)) => { - return quote_spanned! { - expr.span() => compile_error!("Expected literal"); - } - .into() - } - None => { - return quote_spanned! { - variant.span() => compile_error!("Each variant must have a discriminant"); - } - .into() - } - } - } - - (quote! { - #(#attrs)* - #[derive(num_enum::TryFromPrimitive, num_enum::IntoPrimitive)] - #[repr(u32)] - #vis #enum_token #ident { - #( - #(#variant_attrs)* - #ident_expressions = #variant_expressions, - )* - } - }) - .into() -} diff --git a/precompiles/utils/macro/src/lib.rs b/precompiles/utils/macro/src/lib.rs deleted file mode 100644 index 9214482837..0000000000 --- a/precompiles/utils/macro/src/lib.rs +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -#![crate_type = "proc-macro"] -extern crate proc_macro; - -use proc_macro::TokenStream; -use quote::{quote, quote_spanned}; -use sha3::{Digest, Keccak256}; -use syn::{parse_macro_input, spanned::Spanned, Expr, Ident, ItemType, Lit, LitStr}; - -mod derive_codec; -mod precompile; -mod precompile_name_from_address; - -struct Bytes(Vec); - -impl ::std::fmt::Debug for Bytes { - #[inline] - fn fmt(&self, f: &mut std::fmt::Formatter) -> ::std::fmt::Result { - let data = &self.0; - write!(f, "[")?; - if !data.is_empty() { - write!(f, "{:#04x}u8", data[0])?; - for unit in data.iter().skip(1) { - write!(f, ", {:#04x}", unit)?; - } - } - write!(f, "]") - } -} - -#[proc_macro] -pub fn keccak256(input: TokenStream) -> TokenStream { - let lit_str = parse_macro_input!(input as LitStr); - - let hash = Keccak256::digest(lit_str.value().as_bytes()); - - let bytes = Bytes(hash.to_vec()); - let eval_str = format!("{:?}", bytes); - let eval_ts: proc_macro2::TokenStream = eval_str.parse().unwrap_or_else(|_| { - panic!( - "Failed to parse the string \"{}\" to TokenStream.", - eval_str - ); - }); - quote!(#eval_ts).into() -} - -#[proc_macro_attribute] -pub fn precompile(attr: TokenStream, input: TokenStream) -> TokenStream { - precompile::main(attr, input) -} - -#[proc_macro_attribute] -pub fn precompile_name_from_address(attr: TokenStream, input: TokenStream) -> TokenStream { - precompile_name_from_address::main(attr, input) -} - -#[proc_macro_derive(Codec)] -pub fn derive_codec(input: TokenStream) -> TokenStream { - derive_codec::main(input) -} diff --git a/precompiles/utils/macro/src/precompile/attr.rs b/precompiles/utils/macro/src/precompile/attr.rs deleted file mode 100644 index db29087be0..0000000000 --- a/precompiles/utils/macro/src/precompile/attr.rs +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -use proc_macro2::Span; -use quote::ToTokens; -use syn::spanned::Spanned; - -pub fn take_attributes(attributes: &mut Vec) -> syn::Result> -where - A: syn::parse::Parse, -{ - let mut output = vec![]; - let pred = |attr: &syn::Attribute| { - attr.path - .segments - .first() - .map_or(false, |segment| segment.ident == "precompile") - }; - - while let Some(index) = attributes.iter().position(pred) { - let attr = attributes.remove(index); - let attr = syn::parse2(attr.into_token_stream())?; - output.push(attr) - } - Ok(output) -} - -/// List of additional token to be used for parsing. -pub mod keyword { - syn::custom_keyword!(precompile); - syn::custom_keyword!(public); - syn::custom_keyword!(fallback); - syn::custom_keyword!(payable); - syn::custom_keyword!(view); - syn::custom_keyword!(discriminant); - syn::custom_keyword!(precompile_set); - syn::custom_keyword!(test_concrete_types); - syn::custom_keyword!(pre_check); -} - -/// Attributes for methods. -pub enum MethodAttr { - Public(Span, syn::LitStr), - Fallback(Span), - Payable(Span), - View(Span), - Discriminant(Span), - PreCheck(Span), -} - -impl syn::parse::Parse for MethodAttr { - fn parse(input: syn::parse::ParseStream) -> syn::Result { - input.parse::()?; - let content; - syn::bracketed!(content in input); - content.parse::()?; - content.parse::()?; - - let lookahead = content.lookahead1(); - - if lookahead.peek(keyword::public) { - let span = content.parse::()?.span(); - - let inner; - syn::parenthesized!(inner in content); - let signature = inner.parse::()?; - - Ok(MethodAttr::Public(span, signature)) - } else if lookahead.peek(keyword::fallback) { - Ok(MethodAttr::Fallback( - content.parse::()?.span(), - )) - } else if lookahead.peek(keyword::payable) { - Ok(MethodAttr::Payable( - content.parse::()?.span(), - )) - } else if lookahead.peek(keyword::view) { - Ok(MethodAttr::View(content.parse::()?.span())) - } else if lookahead.peek(keyword::discriminant) { - Ok(MethodAttr::Discriminant( - content.parse::()?.span(), - )) - } else if lookahead.peek(keyword::pre_check) { - Ok(MethodAttr::PreCheck( - content.parse::()?.span(), - )) - } else { - Err(lookahead.error()) - } - } -} - -/// Attributes for the main impl Block. -pub enum ImplAttr { - PrecompileSet(Span), - TestConcreteTypes(Span, Vec), -} - -impl syn::parse::Parse for ImplAttr { - fn parse(input: syn::parse::ParseStream) -> syn::Result { - input.parse::()?; - let content; - syn::bracketed!(content in input); - content.parse::()?; - content.parse::()?; - - let lookahead = content.lookahead1(); - - if lookahead.peek(keyword::precompile_set) { - Ok(ImplAttr::PrecompileSet( - content.parse::()?.span(), - )) - } else if lookahead.peek(keyword::test_concrete_types) { - let span = content.parse::()?.span(); - - let inner; - syn::parenthesized!(inner in content); - let types = inner.parse_terminated::<_, syn::Token![,]>(syn::Type::parse)?; - - Ok(ImplAttr::TestConcreteTypes( - span, - types.into_iter().collect(), - )) - } else { - Err(lookahead.error()) - } - } -} diff --git a/precompiles/utils/macro/src/precompile/expand.rs b/precompiles/utils/macro/src/precompile/expand.rs deleted file mode 100644 index e12eba6fe4..0000000000 --- a/precompiles/utils/macro/src/precompile/expand.rs +++ /dev/null @@ -1,524 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -use super::*; - -impl Precompile { - /// Main expand function, which expands everything else. - pub fn expand(&self) -> impl ToTokens { - let enum_ = self.expand_enum_decl(); - let enum_impl = self.expand_enum_impl(); - let precomp_impl = self.expand_precompile_impl(); - let test_signature = self.expand_test_solidity_signature(); - - quote! { - #enum_ - #enum_impl - #precomp_impl - #test_signature - } - } - - /// Expands the call enum declaration. - pub fn expand_enum_decl(&self) -> impl ToTokens { - let enum_ident = &self.enum_ident; - let (_impl_generics, ty_generics, where_clause) = self.generics.split_for_impl(); - - let type_parameters = self.generics.type_params().map(|p| &p.ident); - - let variants: Vec<_> = self.variants_content.keys().collect(); - let idents: Vec> = self - .variants_content - .values() - .map(|v| v.arguments.iter().map(|a| &a.ident).collect()) - .collect(); - let types: Vec> = self - .variants_content - .values() - .map(|v| v.arguments.iter().map(|a| &a.ty).collect()) - .collect(); - - quote!( - #[allow(non_camel_case_types)] - pub enum #enum_ident #ty_generics #where_clause { - #( - #variants { - #( - #idents: #types - ),* - }, - )* - - #[doc(hidden)] - __phantom( - ::core::marker::PhantomData<( #( #type_parameters ),* )>, - ::core::convert::Infallible - ), - } - ) - } - - /// Expands the parse function for each variants. - pub fn expand_variants_parse_fn(&self) -> impl ToTokens { - let span = Span::call_site(); - - let fn_parse = self - .variants_content - .keys() - .map(Self::variant_ident_to_parse_fn); - - let modifier_check = self.variants_content.values().map(|variant| { - let modifier = match variant.modifier { - Modifier::NonPayable => "NonPayable", - Modifier::Payable => "Payable", - Modifier::View => "View", - }; - - let modifier = syn::Ident::new(modifier, span); - - quote!( - use ::precompile_utils::solidity::modifier::FunctionModifier; - use ::precompile_utils::evm::handle::PrecompileHandleExt; - handle.check_function_modifier(FunctionModifier::#modifier)?; - ) - }); - - let variant_parsing = self - .variants_content - .iter() - .map(|(variant_ident, variant)| { - Self::expand_variant_parsing_from_handle(variant_ident, variant) - }); - - quote!( - #( - fn #fn_parse( - handle: &mut impl PrecompileHandle - ) -> ::precompile_utils::EvmResult { - use ::precompile_utils::solidity::revert::InjectBacktrace; - - #modifier_check - #variant_parsing - } - )* - ) - } - - /// Generates the parsing code for a variant, reading the input from the handle and - /// parsing it using Reader. - fn expand_variant_parsing_from_handle( - variant_ident: &syn::Ident, - variant: &Variant, - ) -> impl ToTokens { - if variant.arguments.is_empty() { - quote!( Ok(Self::#variant_ident {})).to_token_stream() - } else { - use case::CaseExt; - - let args_parse = variant.arguments.iter().map(|arg| { - let ident = &arg.ident; - let span = ident.span(); - let name = ident.to_string().to_camel_lowercase(); - - quote_spanned!(span=> #ident: input.read().in_field(#name)?,) - }); - let args_count = variant.arguments.len(); - - quote!( - let mut input = handle.read_after_selector()?; - input.expect_arguments(#args_count)?; - - Ok(Self::#variant_ident { - #(#args_parse)* - }) - ) - .to_token_stream() - } - } - - /// Expands the call enum impl block. - pub fn expand_enum_impl(&self) -> impl ToTokens { - let enum_ident = &self.enum_ident; - let (impl_generics, ty_generics, where_clause) = self.generics.split_for_impl(); - - let match_selectors = self.selector_to_variant.keys(); - let match_selectors2 = self.selector_to_variant.keys(); - - let variants_parsing = self.expand_variants_parse_fn(); - - let variants_ident2: Vec<_> = self.variants_content.keys().collect(); - let variants_selectors_fn: Vec<_> = self - .variants_content - .keys() - .map(|name| format_ident!("{}_selectors", name)) - .collect(); - let variants_selectors: Vec<_> = self - .variants_content - .values() - .map(|variant| &variant.selectors) - .collect(); - - let variants_list: Vec> = self - .variants_content - .values() - .map(|variant| variant.arguments.iter().map(|arg| &arg.ident).collect()) - .collect(); - - let variants_encode: Vec<_> = self - .variants_content - .values() - .map(Self::expand_variant_encoding) - .collect(); - - let parse_call_data_fn = self.expand_enum_parse_call_data(); - let execute_fn = self.expand_enum_execute_fn(); - - quote!( - impl #impl_generics #enum_ident #ty_generics #where_clause { - #parse_call_data_fn - - #variants_parsing - - #execute_fn - - pub fn supports_selector(selector: u32) -> bool { - match selector { - #( - #match_selectors => true, - )* - _ => false, - } - } - - pub fn selectors() -> &'static [u32] { - &[#( - #match_selectors2 - ),*] - } - - #( - pub fn #variants_selectors_fn() -> &'static [u32] { - &[#( - #variants_selectors - ),*] - } - )* - - pub fn encode(self) -> ::sp_std::vec::Vec { - use ::precompile_utils::solidity::codec::Writer; - match self { - #( - Self::#variants_ident2 { #(#variants_list),* } => { - #variants_encode - }, - )* - Self::__phantom(_, _) => panic!("__phantom variant should not be used"), - } - } - } - - impl #impl_generics From<#enum_ident #ty_generics> for ::sp_std::vec::Vec - #where_clause - { - fn from(a: #enum_ident #ty_generics) -> ::sp_std::vec::Vec { - a.encode() - } - } - ) - } - - /// Expand the execute fn of the enum. - fn expand_enum_execute_fn(&self) -> impl ToTokens { - let impl_type = &self.impl_type; - - let variants_ident: Vec<_> = self.variants_content.keys().collect(); - - let variants_arguments: Vec> = self - .variants_content - .values() - .map(|variant| variant.arguments.iter().map(|arg| &arg.ident).collect()) - .collect(); - - // If there is no precompile set there is no discriminant. - let opt_discriminant_arg = self - .precompile_set_discriminant_type - .as_ref() - .map(|ty| quote!( discriminant: #ty,)); - - let variants_call = self - .variants_content - .iter() - .map(|(variant_ident, variant)| { - let arguments = variant.arguments.iter().map(|arg| &arg.ident); - - let output_span = variant.fn_output.span(); - let opt_discriminant_arg = self - .precompile_set_discriminant_fn - .as_ref() - .map(|_| quote!(discriminant,)); - - let write_output = quote_spanned!(output_span=> - ::precompile_utils::solidity::encode_return_value(output?) - ); - - quote!( - let output = <#impl_type>::#variant_ident( - #opt_discriminant_arg - handle, - #(#arguments),* - ); - #write_output - ) - }); - - quote!( - pub fn execute( - self, - #opt_discriminant_arg - handle: &mut impl PrecompileHandle - ) -> ::precompile_utils::EvmResult<::fp_evm::PrecompileOutput> { - use ::precompile_utils::solidity::codec::Writer; - use ::fp_evm::{PrecompileOutput, ExitSucceed}; - - let output = match self { - #( - Self::#variants_ident { #(#variants_arguments),* } => { - #variants_call - }, - )* - Self::__phantom(_, _) => panic!("__phantom variant should not be used"), - }; - - Ok(PrecompileOutput { - exit_status: ExitSucceed::Returned, - output - }) - } - ) - } - - /// Expand how a variant can be Solidity encoded. - fn expand_variant_encoding(variant: &Variant) -> impl ToTokens { - match variant.selectors.first() { - Some(selector) => { - let write_arguments = variant.arguments.iter().map(|arg| { - let ident = &arg.ident; - let span = ident.span(); - quote_spanned!(span=> .write(#ident)) - }); - - quote!( - Writer::new_with_selector(#selector) - #(#write_arguments)* - .build() - ) - .to_token_stream() - } - None => quote!(Default::default()).to_token_stream(), - } - } - - /// Expand the main parsing function that, based on the selector in the - /// input, dispatch the decoding to one of the variants parsing function. - fn expand_enum_parse_call_data(&self) -> impl ToTokens { - let selectors = self.selector_to_variant.keys(); - let parse_fn = self - .selector_to_variant - .values() - .map(Self::variant_ident_to_parse_fn); - - let match_fallback = match &self.fallback_to_variant { - Some(variant) => { - let parse_fn = Self::variant_ident_to_parse_fn(variant); - quote!(_ => Self::#parse_fn(handle),).to_token_stream() - } - None => quote!( - Some(_) => Err(RevertReason::UnknownSelector.into()), - None => Err(RevertReason::read_out_of_bounds("selector").into()), - ) - .to_token_stream(), - }; - - quote!( - pub fn parse_call_data( - handle: &mut impl PrecompileHandle - ) -> ::precompile_utils::EvmResult { - use ::precompile_utils::solidity::revert::RevertReason; - - let input = handle.input(); - - let selector = input.get(0..4).map(|s| { - let mut buffer = [0u8; 4]; - buffer.copy_from_slice(s); - u32::from_be_bytes(buffer) - }); - - match selector { - #( - Some(#selectors) => Self::#parse_fn(handle), - )* - #match_fallback - } - } - ) - } - - fn variant_ident_to_parse_fn(ident: &syn::Ident) -> syn::Ident { - format_ident!("_parse_{}", ident) - } - - /// Expands the impl of the Precomile(Set) trait. - pub fn expand_precompile_impl(&self) -> impl ToTokens { - let impl_type = &self.impl_type; - let enum_ident = &self.enum_ident; - let (impl_generics, ty_generics, where_clause) = self.generics.split_for_impl(); - - if let Some(discriminant_fn) = &self.precompile_set_discriminant_fn { - let opt_pre_check = self.pre_check.as_ref().map(|ident| { - let span = ident.span(); - quote_spanned!(span=> - let _: () = <#impl_type>::#ident(discriminant, handle) - .map_err(|err| Some(err))?; - ) - }); - - quote!( - impl #impl_generics ::fp_evm::PrecompileSet for #impl_type #where_clause { - fn execute( - &self, - handle: &mut impl PrecompileHandle - ) -> Option<::precompile_utils::EvmResult<::fp_evm::PrecompileOutput>> { - use ::precompile_utils::precompile_set::DiscriminantResult; - - let discriminant = <#impl_type>::#discriminant_fn( - handle.code_address(), - handle.remaining_gas() - ); - - if let DiscriminantResult::Some(_, cost) | DiscriminantResult::None(cost) = discriminant { - let result = handle.record_cost(cost); - if let Err(e) = result { - return Some(Err(e.into())); - } - } - - let discriminant = match discriminant { - DiscriminantResult::Some(d, _) => d, - DiscriminantResult::None(cost) => return None, - DiscriminantResult::OutOfGas => return Some(Err(ExitError::OutOfGas.into())) - }; - - #opt_pre_check - - Some( - <#enum_ident #ty_generics>::parse_call_data(handle) - .and_then(|call| call.execute(discriminant, handle)) - ) - } - - fn is_precompile(&self, address: H160, gas: u64) -> ::fp_evm::IsPrecompileResult { - <#impl_type>::#discriminant_fn(address, gas).into() - } - } - ) - .to_token_stream() - } else { - let opt_pre_check = self.pre_check.as_ref().map(|ident| { - let span = ident.span(); - quote_spanned!(span=>let _: () = <#impl_type>::#ident(handle)?;) - }); - - quote!( - impl #impl_generics ::fp_evm::Precompile for #impl_type #where_clause { - fn execute( - handle: &mut impl PrecompileHandle - ) -> ::precompile_utils::EvmResult<::fp_evm::PrecompileOutput> { - #opt_pre_check - - <#enum_ident #ty_generics>::parse_call_data(handle)?.execute(handle) - } - } - ) - .to_token_stream() - } - } - - /// Expands the Solidity signature test. - /// The macro expands an "inner" function in all build profiles, which is - /// then called by a test in test profile. This allows to display errors that occurs in - /// the expansion of the test without having to build in test profile, which is usually - /// related to the use of a type parameter in one of the parsed parameters of a method. - pub fn expand_test_solidity_signature(&self) -> impl ToTokens { - let variant_test: Vec<_> = self - .variants_content - .iter() - .map(|(ident, variant)| { - let span = ident.span(); - - let solidity = &variant.solidity_arguments_type; - let name = ident.to_string(); - let types: Vec<_> = variant.arguments.iter().map(|arg| &arg.ty).collect(); - - quote_spanned!(span=> - assert_eq!( - #solidity, - <(#(#types,)*) as Codec>::signature(), - "{} function signature doesn't match (left: attribute, right: computed \ - from Rust types)", - #name - ); - ) - }) - .collect(); - - let test_name = format_ident!("__{}_test_solidity_signatures", self.impl_ident); - let inner_name = format_ident!("__{}_test_solidity_signatures_inner", self.impl_ident); - - if let Some(test_types) = &self.test_concrete_types { - let (impl_generics, _ty_generics, where_clause) = self.generics.split_for_impl(); - - quote!( - #[allow(non_snake_case)] - pub(crate) fn #inner_name #impl_generics () #where_clause { - use ::precompile_utils::solidity::Codec; - #(#variant_test)* - } - - #[test] - #[allow(non_snake_case)] - fn #test_name() { - #inner_name::< #(#test_types),* >(); - } - ) - .to_token_stream() - } else { - quote!( - #[allow(non_snake_case)] - pub(crate) fn #inner_name() { - use ::precompile_utils::solidity::Codec; - #(#variant_test)* - } - - #[test] - #[allow(non_snake_case)] - fn #test_name() { - #inner_name(); - } - ) - .to_token_stream() - } - } -} diff --git a/precompiles/utils/macro/src/precompile/mod.rs b/precompiles/utils/macro/src/precompile/mod.rs deleted file mode 100644 index 4cd63ed287..0000000000 --- a/precompiles/utils/macro/src/precompile/mod.rs +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -#![doc = include_str!("../../docs/precompile_macro.md")] - -use proc_macro::TokenStream; -use proc_macro2::Span; -use quote::{format_ident, quote, quote_spanned, ToTokens}; -use sha3::{Digest, Keccak256}; -use std::collections::BTreeMap; -use syn::{parse_macro_input, spanned::Spanned}; - -pub mod attr; -pub mod expand; -pub mod parse; - -pub fn main(_attr: TokenStream, item: TokenStream) -> TokenStream { - // Macro must be used on `impl` block. - let mut impl_item = parse_macro_input!(item as syn::ItemImpl); - - // We inspect the block to collect all the data we need for the - // expansion, and make various checks. - let precompile = match Precompile::try_from(&mut impl_item) { - Ok(p) => p, - Err(e) => return e.into_compile_error().into(), - }; - - // We generate additional code based on the collected data. - let new_items = precompile.expand(); - let output = quote!( - #impl_item - #new_items - ); - - output.into() -} - -struct Precompile { - /// Impl struct type. - impl_type: syn::Type, - - /// Impl struct ident. - impl_ident: syn::Ident, - - /// New parsing enum ident. - enum_ident: syn::Ident, - - /// Generic part that needs to also be used by the input enum. - generics: syn::Generics, - - /// Which selector corresponds to which variant of the input enum. - selector_to_variant: BTreeMap, - - /// Optional fallback function if no selector matches. - fallback_to_variant: Option, - - /// Describes the content of each variant based on the precompile methods. - variants_content: BTreeMap, - - /// Since being a precompile set implies lots of changes, we must know it early - /// in the form of an attribute on the impl block itself. - tagged_as_precompile_set: bool, - - /// Ident of the function returning the PrecompileSet discriminant. - precompile_set_discriminant_fn: Option, - - /// Type of the PrecompileSet discriminant. - precompile_set_discriminant_type: Option, - - /// When generating the selector test the data types might depend on type parameters. - /// The test thus need to be written using concrete types. - test_concrete_types: Option>, - - /// Ident of a function that performs a check before the call is dispatched to the proper - /// function. - pre_check: Option, -} - -#[derive(Debug, PartialEq, Eq)] -enum Modifier { - NonPayable, - Payable, - View, -} - -#[derive(Debug)] -struct Variant { - /// Description of the arguments of this method, which will also - /// be members of a struct variant. - arguments: Vec, - - /// String extracted from the selector attribute. - /// A unit test will be generated to check that this selector matches - /// the Rust arguments. - /// - /// > solidity::Codec trait allows to generate this string at runtime only. Thus - /// > it is required to write it manually in the selector attribute, and - /// > a unit test is generated to check it matches. - solidity_arguments_type: String, - - /// Modifier of the function. They are all exclusive and defaults to - /// `NonPayable`. - modifier: Modifier, - - /// Selectors of this function to be able to encode back the data. - /// Empty if it only the fallback function. - selectors: Vec, - - /// Output of the variant fn (for better error messages). - fn_output: syn::Type, -} - -#[derive(Debug)] -struct Argument { - /// Identifier of the argument, which will be used in the struct variant. - ident: syn::Ident, - - /// Type of the argument, which will be used in the struct variant and - /// to parse the input. - ty: syn::Type, -} diff --git a/precompiles/utils/macro/src/precompile/parse.rs b/precompiles/utils/macro/src/precompile/parse.rs deleted file mode 100644 index 3a6449127e..0000000000 --- a/precompiles/utils/macro/src/precompile/parse.rs +++ /dev/null @@ -1,619 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -use super::*; - -impl Precompile { - /// Try to extract information out of an annotated `impl` block. - pub fn try_from(impl_: &mut syn::ItemImpl) -> syn::Result { - // Extract the name of the type used in the `impl` block. - let impl_ident = Self::extract_impl_ident(impl_)?; - let enum_ident = format_ident!("{}Call", impl_ident); - - // We setup the data collection struct. - let mut precompile = Precompile { - impl_type: impl_.self_ty.as_ref().clone(), - impl_ident, - enum_ident, - generics: impl_.generics.clone(), - selector_to_variant: BTreeMap::new(), - variants_content: BTreeMap::new(), - fallback_to_variant: None, - tagged_as_precompile_set: false, - precompile_set_discriminant_fn: None, - precompile_set_discriminant_type: None, - test_concrete_types: None, - pre_check: None, - }; - - precompile.process_impl_attr(impl_)?; - for mut item in &mut impl_.items { - // We only interact with methods and leave the rest as-is. - if let syn::ImplItem::Method(ref mut method) = &mut item { - precompile.process_method(method)?; - } - } - - // Check constraint of PrecompileSet. - if precompile.tagged_as_precompile_set - && precompile.precompile_set_discriminant_fn.is_none() - { - let msg = "A PrecompileSet must have exactly one function tagged with \ - `#[precompile::discriminant]`"; - return Err(syn::Error::new(Span::call_site(), msg)); - } - - Ok(precompile) - } - - /// Process the attributes used on the `impl` block, which allows to declare - /// if it is a PrecompileSet or not, and to provide concrete types for tests if necessary. - fn process_impl_attr(&mut self, impl_: &mut syn::ItemImpl) -> syn::Result<()> { - let attrs = attr::take_attributes::(&mut impl_.attrs)?; - - for attr in attrs { - match attr { - attr::ImplAttr::PrecompileSet(_) => { - self.tagged_as_precompile_set = true; - } - attr::ImplAttr::TestConcreteTypes(span, types) => { - if types.len() != self.generics.params.len() { - let msg = "The amount of types should match the amount of type parameters \ - of the impl block"; - return Err(syn::Error::new(span, msg)); - } - - if self.test_concrete_types.is_some() { - let msg = "Only one set of types can be provided to generate tests"; - return Err(syn::Error::new(span, msg)); - } - - self.test_concrete_types = Some(types); - } - } - } - - Ok(()) - } - - /// Extract the ident of the type of the `impl` block. - /// This ident is used to generate new idents such as the name of the Call enum and - /// the Solidity selector test. - fn extract_impl_ident(impl_: &syn::ItemImpl) -> syn::Result { - let type_path = match impl_.self_ty.as_ref() { - syn::Type::Path(p) => p, - _ => { - let msg = "The type in the impl block must be a path, like `Precompile` or - `example::Precompile`"; - return Err(syn::Error::new(impl_.self_ty.span(), msg)); - } - }; - - let final_path = type_path.path.segments.last().ok_or_else(|| { - let msg = "The type path must be non empty."; - syn::Error::new(impl_.self_ty.span(), msg) - })?; - - Ok(final_path.ident.clone()) - } - - /// Process a single method, looking for attributes and checking mandatory parameters. - fn process_method(&mut self, method: &mut syn::ImplItemMethod) -> syn::Result<()> { - // Take (remove) all attributes related to this macro. - let attrs = attr::take_attributes::(&mut method.attrs)?; - - // If there are no attributes it is a private function and we ignore it. - if attrs.is_empty() { - return Ok(()); - } - - // A method cannot have modifiers if it isn't a fallback and/or doesn't have a selector. - let mut used = false; - - let method_name = method.sig.ident.clone(); - let mut modifier = Modifier::NonPayable; - let mut solidity_arguments_type: Option = None; - let mut arguments = vec![]; - let mut is_fallback = false; - let mut selectors = vec![]; - let initial_arguments = if self.tagged_as_precompile_set { 2 } else { 1 }; - - // We first look for unique attributes. - if let Some(attr::MethodAttr::Discriminant(span)) = attrs.first() { - let span = *span; - - if attrs.len() != 1 { - let msg = "The discriminant attribute must be the only precompile attribute of \ - a function"; - return Err(syn::Error::new(span, msg)); - } - - return self.parse_discriminant_fn(span, method); - } - - if let Some(attr::MethodAttr::PreCheck(span)) = attrs.first() { - let span = *span; - - if attrs.len() != 1 { - let msg = "The pre_check attribute must be the only precompile attribute of \ - a function"; - return Err(syn::Error::new(span, msg)); - } - - return self.parse_pre_check_fn(span, method); - } - - // We iterate over all attributes of the method. - for attr in attrs { - match attr { - attr::MethodAttr::Discriminant(span) => { - let msg = "The discriminant attribute must be the only precompile \ - attribute of the function"; - return Err(syn::Error::new(span, msg)); - } - attr::MethodAttr::PreCheck(span) => { - let msg = "The pre_check attribute must be the only precompile \ - attribute of the function"; - return Err(syn::Error::new(span, msg)); - } - attr::MethodAttr::Fallback(span) => { - if self.fallback_to_variant.is_some() { - let msg = "A precompile can only have 1 fallback function"; - return Err(syn::Error::new(span, msg)); - } - - self.fallback_to_variant = Some(method_name.clone()); - used = true; - is_fallback = true; - } - attr::MethodAttr::Payable(span) => { - if modifier != Modifier::NonPayable { - let msg = - "A precompile method can have at most one modifier (payable, view)"; - return Err(syn::Error::new(span, msg)); - } - - modifier = Modifier::Payable; - } - attr::MethodAttr::View(span) => { - if modifier != Modifier::NonPayable { - let msg = - "A precompile method can have at most one modifier (payable, view)"; - return Err(syn::Error::new(span, msg)); - } - - modifier = Modifier::View; - } - attr::MethodAttr::Public(_, signature_lit) => { - used = true; - - let selector = self.parse_public_attr( - signature_lit, - &method_name, - &mut solidity_arguments_type, - )?; - selectors.push(selector); - } - } - } - - // A method cannot have attributes without being public or fallback. - if !used { - let msg = - "A precompile method cannot have modifiers without being a fallback or having\ - a `public` attribute"; - return Err(syn::Error::new(method.span(), msg)); - } - - // We forbid type parameters. - if let Some(param) = method.sig.generics.params.first() { - let msg = "Exposed precompile methods cannot have type parameters"; - return Err(syn::Error::new(param.span(), msg)); - } - - // Fallback method cannot have custom parameters. - if is_fallback { - if let Some(input) = method.sig.inputs.iter().skip(initial_arguments).next() { - let msg = if self.tagged_as_precompile_set { - "Fallback methods cannot take any parameter outside of the discriminant and \ - PrecompileHandle" - } else { - "Fallback methods cannot take any parameter outside of the PrecompileHandle" - }; - - return Err(syn::Error::new(input.span(), msg)); - } - } - - let mut method_inputs = method.sig.inputs.iter(); - - // We check the first parameters of the method. - // If this is a PrecompileSet it will look for a discriminant. - // Then for all precompile(set)s it will look for the PrecompileHandle. - // We take them from the iterator such that we are only left with the - // custom arguments. - self.check_initial_parameters(&mut method_inputs, method.sig.span())?; - - // We go through each parameter to collect each name and type that will be used to - // generate the input enum and parse the call data. - for input in method_inputs { - let input = match input { - syn::FnArg::Typed(t) => t, - _ => { - // I don't think it is possible to encounter this error since a self receiver - // seems to only be possible in the first position which is checked in - // `check_initial_parameters`. - let msg = "Exposed precompile methods cannot have a `self` parameter"; - return Err(syn::Error::new(input.span(), msg)); - } - }; - - let msg = "Parameter must be of the form `name: Type`, optionally prefixed by `mut`"; - let ident = match input.pat.as_ref() { - syn::Pat::Ident(pat) => { - if pat.by_ref.is_some() || pat.subpat.is_some() { - return Err(syn::Error::new(pat.span(), msg)); - } - - pat.ident.clone() - } - _ => { - return Err(syn::Error::new(input.pat.span(), msg)); - } - }; - let ty = input.ty.as_ref().clone(); - self.check_type_parameter_usage(&ty)?; - - arguments.push(Argument { ident, ty }) - } - - // Function output. - let output_type = match &method.sig.output { - syn::ReturnType::Type(_, t) => t, - _ => { - let msg = "A precompile method must have a return type of `EvmResult<_>` (exposed \ - by `precompile_utils`)"; - return Err(syn::Error::new(method.sig.span(), msg)); - } - }; - - // We insert the collected data in self. - if let Some(_) = self.variants_content.insert( - method_name.clone(), - Variant { - arguments, - solidity_arguments_type: solidity_arguments_type.unwrap_or(String::from("()")), - modifier, - selectors, - fn_output: output_type.as_ref().clone(), - }, - ) { - let msg = "Duplicate method name"; - return Err(syn::Error::new(method_name.span(), msg)); - } - - Ok(()) - } - - /// Check the initial parameters of most methods of a Precompile(Set). - fn check_initial_parameters<'a>( - &mut self, - method_inputs: &mut impl Iterator, - method_span: Span, - ) -> syn::Result<()> { - // Discriminant input - if self.tagged_as_precompile_set { - let input = match method_inputs.next() { - Some(a) => a, - None => { - let msg = "PrecompileSet methods must have at least 2 parameters (the \ - precompile instance discriminant and the PrecompileHandle)"; - return Err(syn::Error::new(method_span, msg)); - } - }; - - let input = match input { - syn::FnArg::Typed(a) => a, - _ => { - let msg = "self is not allowed in precompile methods"; - return Err(syn::Error::new(input.span(), msg)); - } - }; - - let input_type = input.ty.as_ref(); - - self.try_register_discriminant_type(&input_type)?; - } - - // Precompile handle input - { - let input = match method_inputs.next() { - Some(a) => a, - None => { - let msg = if self.tagged_as_precompile_set { - "PrecompileSet methods must have at least 2 parameters (the precompile \ - instance discriminant and the PrecompileHandle)" - } else { - "Precompile methods must have at least 1 parameter (the PrecompileHandle)" - }; - - return Err(syn::Error::new(method_span, msg)); - } - }; - - let input = match input { - syn::FnArg::Typed(a) => a, - _ => { - let msg = "self is not allowed in precompile methods"; - return Err(syn::Error::new(input.span(), msg)); - } - }; - - let input_type = input.ty.as_ref(); - - if !is_same_type(&input_type, &syn::parse_quote! {&mut impl PrecompileHandle}) { - let msg = "This parameter must have type `&mut impl PrecompileHandle`"; - return Err(syn::Error::new(input_type.span(), msg)); - } - } - - Ok(()) - } - - /// Records the type of the discriminant and ensure they all have the same type. - fn try_register_discriminant_type(&mut self, ty: &syn::Type) -> syn::Result<()> { - if let Some(known_type) = &self.precompile_set_discriminant_type { - if !is_same_type(&known_type, &ty) { - let msg = format!( - "All discriminants must have the same type (found {} before)", - known_type.to_token_stream() - ); - return Err(syn::Error::new(ty.span(), msg)); - } - } else { - self.precompile_set_discriminant_type = Some(ty.clone()); - } - - Ok(()) - } - - /// Process the discriminant function. - fn parse_discriminant_fn( - &mut self, - span: Span, - method: &syn::ImplItemMethod, - ) -> syn::Result<()> { - if !self.tagged_as_precompile_set { - let msg = "The impl block must be tagged with `#[precompile::precompile_set]` for - the discriminant attribute to be used"; - return Err(syn::Error::new(span, msg)); - } - - if self.precompile_set_discriminant_fn.is_some() { - let msg = "A PrecompileSet can only have 1 discriminant function"; - return Err(syn::Error::new(span, msg)); - } - - let span = method.sig.span(); - - if method.sig.inputs.len() != 2 { - let msg = "The discriminant function must only take code address (H160) and \ - remaining gas (u64) as parameters."; - return Err(syn::Error::new(span, msg)); - } - - let msg = "The discriminant function must return an DiscriminantResult<_> (no type alias)"; - - let return_type = match &method.sig.output { - syn::ReturnType::Type(_, t) => t.as_ref(), - _ => return Err(syn::Error::new(span, msg)), - }; - - let return_path = match return_type { - syn::Type::Path(p) => p, - _ => return Err(syn::Error::new(span, msg)), - }; - - if return_path.qself.is_some() { - return Err(syn::Error::new(span, msg)); - } - - let return_path = &return_path.path; - - if return_path.leading_colon.is_some() || return_path.segments.len() != 1 { - return Err(syn::Error::new(span, msg)); - } - - let return_segment = &return_path.segments[0]; - - if return_segment.ident.to_string() != "DiscriminantResult" { - return Err(syn::Error::new(return_segment.ident.span(), msg)); - } - - let result_arguments = match &return_segment.arguments { - syn::PathArguments::AngleBracketed(args) => args, - _ => return Err(syn::Error::new(return_segment.ident.span(), msg)), - }; - - if result_arguments.args.len() != 1 { - let msg = "DiscriminantResult type should only have 1 type argument"; - return Err(syn::Error::new(result_arguments.args.span(), msg)); - } - - let discriminant_type: &syn::Type = match &result_arguments.args[0] { - syn::GenericArgument::Type(t) => t, - _ => return Err(syn::Error::new(result_arguments.args.span(), msg)), - }; - - self.try_register_discriminant_type(&discriminant_type)?; - - self.precompile_set_discriminant_fn = Some(method.sig.ident.clone()); - - Ok(()) - } - - /// Process the pre_check function. - fn parse_pre_check_fn(&mut self, span: Span, method: &syn::ImplItemMethod) -> syn::Result<()> { - if self.pre_check.is_some() { - let msg = "A Precompile can only have 1 pre_check function"; - return Err(syn::Error::new(span, msg)); - } - - let span = method.sig.span(); - - let mut method_inputs = method.sig.inputs.iter(); - - self.check_initial_parameters(&mut method_inputs, span)?; - - if method_inputs.next().is_some() { - let msg = if self.tagged_as_precompile_set { - "PrecompileSet pre_check method must have exactly 2 parameters (the precompile \ - instance discriminant and the PrecompileHandle)" - } else { - "Precompile pre_check method must have exactly 1 parameter (the \ - PrecompileHandle)" - }; - - return Err(syn::Error::new(span, msg)); - } - - self.pre_check = Some(method.sig.ident.clone()); - - Ok(()) - } - - /// Process a `public` attribute on a method. - fn parse_public_attr( - &mut self, - signature_lit: syn::LitStr, - method_name: &syn::Ident, - solidity_arguments_type: &mut Option, - ) -> syn::Result { - let signature = signature_lit.value(); - // Split signature to get arguments type. - let split: Vec<_> = signature.splitn(2, "(").collect(); - if split.len() != 2 { - let msg = "Selector must have form \"foo(arg1,arg2,...)\""; - return Err(syn::Error::new(signature_lit.span(), msg)); - } - - let local_args_type = format!("({}", split[1]); // add back initial parenthesis - - // If there are multiple public attributes we check that they all have - // the same type. - if let Some(ref args_type) = solidity_arguments_type { - if args_type != &local_args_type { - let msg = "Method cannot have selectors with different types."; - return Err(syn::Error::new(signature_lit.span(), msg)); - } - } else { - *solidity_arguments_type = Some(local_args_type); - } - - // Compute the 4-bytes selector. - let digest = Keccak256::digest(signature.as_bytes()); - let selector = u32::from_be_bytes([digest[0], digest[1], digest[2], digest[3]]); - - if let Some(previous) = self - .selector_to_variant - .insert(selector, method_name.clone()) - { - let msg = format!("Selector collision with method {}", previous.to_string()); - return Err(syn::Error::new(signature_lit.span(), msg)); - } - - Ok(selector) - } - - /// Check that the provided type doesn't depend on one of the type parameters of the - /// precompile. Check is skipped if `test_concrete_types` attribute is used. - fn check_type_parameter_usage(&self, ty: &syn::Type) -> syn::Result<()> { - if self.test_concrete_types.is_some() { - return Ok(()); - } - - const ERR_MESSAGE: &'static str = - "impl type parameter is used in functions arguments. Arguments should not have a type -depending on a type parameter, unless it is a length bound for BoundedBytes, -BoundedString or alike, which doesn't affect the Solidity type. - -In that case, you must add a #[precompile::test_concrete_types(...)] attribute on the impl -block to provide concrete types that will be used to run the automatically generated tests -ensuring the Solidity function signatures are correct."; - - match ty { - syn::Type::Array(syn::TypeArray { elem, .. }) - | syn::Type::Group(syn::TypeGroup { elem, .. }) - | syn::Type::Paren(syn::TypeParen { elem, .. }) - | syn::Type::Reference(syn::TypeReference { elem, .. }) - | syn::Type::Ptr(syn::TypePtr { elem, .. }) - | syn::Type::Slice(syn::TypeSlice { elem, .. }) => self.check_type_parameter_usage(&elem)?, - - syn::Type::Path(syn::TypePath { - path: syn::Path { segments, .. }, - .. - }) => { - let impl_params: Vec<_> = self - .generics - .params - .iter() - .filter_map(|param| match param { - syn::GenericParam::Type(syn::TypeParam { ident, .. }) => Some(ident), - _ => None, - }) - .collect(); - - for segment in segments { - if impl_params.contains(&&segment.ident) { - return Err(syn::Error::new(segment.ident.span(), ERR_MESSAGE)); - } - - if let syn::PathArguments::AngleBracketed(args) = &segment.arguments { - let types = args.args.iter().filter_map(|arg| match arg { - syn::GenericArgument::Type(ty) - | syn::GenericArgument::Binding(syn::Binding { ty, .. }) => Some(ty), - _ => None, - }); - - for ty in types { - self.check_type_parameter_usage(&ty)?; - } - } - } - } - syn::Type::Tuple(tuple) => { - for ty in tuple.elems.iter() { - self.check_type_parameter_usage(ty)?; - } - } - // BareFn => very unlikely this appear as parameter - // ImplTrait => will cause other errors, it must be a concrete type - // TypeInfer => it must be explicit concrete types since it ends up in enum fields - // Macro => Cannot check easily - // Never => Function will not be callable. - ty => println!("Skipping type parameter check for non supported kind of type: {ty:?}"), - } - - Ok(()) - } -} - -/// Helper to check 2 types are equal. -/// Having a function with explicit type annotation helps type inference at callsite, -/// which have trouble if `==` is used inline. -fn is_same_type(a: &syn::Type, b: &syn::Type) -> bool { - a == b -} diff --git a/precompiles/utils/macro/src/precompile_name_from_address.rs b/precompiles/utils/macro/src/precompile_name_from_address.rs deleted file mode 100644 index 27ce5f1147..0000000000 --- a/precompiles/utils/macro/src/precompile_name_from_address.rs +++ /dev/null @@ -1,143 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -use super::*; -use syn::{GenericArgument, Type}; - -pub fn main(_: TokenStream, input: TokenStream) -> TokenStream { - let item = parse_macro_input!(input as ItemType); - - let ItemType { - attrs, - vis, - type_token, - ident, - generics, - eq_token, - ty, - semi_token, - } = item; - - if let Type::Tuple(ref type_tuple) = *ty { - let variants: Vec<(Ident, u64)> = type_tuple - .elems - .iter() - .filter_map(extract_precompile_name_and_prefix) - .collect(); - - let ident_expressions: Vec<&Ident> = variants.iter().map(|(ident, _)| ident).collect(); - let variant_expressions: Vec<&u64> = variants.iter().map(|(_, id)| id).collect(); - - (quote! { - #(#attrs)* - #vis #type_token #ident #generics #eq_token #ty #semi_token - - #[derive(num_enum::TryFromPrimitive, num_enum::IntoPrimitive, Debug)] - #[repr(u64)] - pub enum PrecompileName { - #( - #ident_expressions = #variant_expressions, - )* - } - - impl PrecompileName { - pub fn from_address(address: sp_core::H160) -> Option { - let _u64 = address.to_low_u64_be(); - if address == sp_core::H160::from_low_u64_be(_u64) { - use num_enum::TryFromPrimitive; - Self::try_from_primitive(_u64).ok() - } else { - None - } - } - } - }) - .into() - } else { - return quote_spanned! { - ty.span() => compile_error!("Expected tuple"); - } - .into(); - } -} - -fn extract_precompile_name_and_prefix(type_: &Type) -> Option<(Ident, u64)> { - match type_ { - Type::Path(type_path) => { - if let Some(path_segment) = type_path.path.segments.last() { - match path_segment.ident.to_string().as_ref() { - "PrecompileAt" => { - extract_precompile_name_and_prefix_for_precompile_at(path_segment) - } - _ => None, - } - } else { - None - } - } - _ => None, - } -} - -fn extract_precompile_name_and_prefix_for_precompile_at( - path_segment: &syn::PathSegment, -) -> Option<(Ident, u64)> { - if let syn::PathArguments::AngleBracketed(generics) = &path_segment.arguments { - let mut iter = generics.args.iter(); - if let ( - Some(GenericArgument::Type(Type::Path(type_path_1))), - Some(GenericArgument::Type(Type::Path(type_path_2))), - ) = (iter.next(), iter.next()) - { - if let (Some(path_segment_1), Some(path_segment_2)) = ( - type_path_1.path.segments.last(), - type_path_2.path.segments.last(), - ) { - if let syn::PathArguments::AngleBracketed(generics_) = &path_segment_1.arguments { - if let Some(GenericArgument::Const(Expr::Lit(lit))) = generics_.args.first() { - if let Lit::Int(int) = &lit.lit { - if let Ok(precompile_id) = int.base10_parse() { - if &path_segment_2.ident.to_string() == "CollectivePrecompile" { - if let Some(instance_ident) = - precompile_instance_ident(&path_segment_2) - { - return Some((instance_ident, precompile_id)); - } - } else { - return Some((path_segment_2.ident.clone(), precompile_id)); - } - } - } - } - } - } - } - } - - None -} - -fn precompile_instance_ident(path_segment: &syn::PathSegment) -> Option { - if let syn::PathArguments::AngleBracketed(generics_) = &path_segment.arguments { - if let Some(GenericArgument::Type(Type::Path(instance_type_path))) = generics_.args.last() { - if let Some(instance_type) = instance_type_path.path.segments.last() { - return Some(instance_type.ident.clone()); - } - } - } - - None -} diff --git a/precompiles/utils/macro/tests/compile-fail/derive_codec/empty_struct.rs b/precompiles/utils/macro/tests/compile-fail/derive_codec/empty_struct.rs deleted file mode 100644 index ea2cd4621a..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/derive_codec/empty_struct.rs +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -use precompile_utils::prelude::*; - -#[derive(solidity::Codec)] -struct Empty1; - -#[derive(solidity::Codec)] -struct Empty2 {} - -#[derive(solidity::Codec)] -struct Empty3 (); - -fn main() {} \ No newline at end of file diff --git a/precompiles/utils/macro/tests/compile-fail/derive_codec/empty_struct.stderr b/precompiles/utils/macro/tests/compile-fail/derive_codec/empty_struct.stderr deleted file mode 100644 index 8c0a9d8bae..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/derive_codec/empty_struct.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error: Codec can only be derived for structs with named fields - --> tests/compile-fail/derive_codec/empty_struct.rs:20:8 - | -20 | struct Empty1; - | ^^^^^^ - -error: Codec can only be derived for structs with at least one field - --> tests/compile-fail/derive_codec/empty_struct.rs:23:8 - | -23 | struct Empty2 {} - | ^^^^^^ - -error: Codec can only be derived for structs with named fields - --> tests/compile-fail/derive_codec/empty_struct.rs:26:8 - | -26 | struct Empty3 (); - | ^^^^^^ diff --git a/precompiles/utils/macro/tests/compile-fail/derive_codec/enum.rs b/precompiles/utils/macro/tests/compile-fail/derive_codec/enum.rs deleted file mode 100644 index de0a7a6123..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/derive_codec/enum.rs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -use precompile_utils::prelude::*; - -#[derive(solidity::Codec)] -enum Test { - One, - Two(u8), - Three { test: u16 } -} - -fn main() {} \ No newline at end of file diff --git a/precompiles/utils/macro/tests/compile-fail/derive_codec/enum.stderr b/precompiles/utils/macro/tests/compile-fail/derive_codec/enum.stderr deleted file mode 100644 index 42a65d4a17..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/derive_codec/enum.stderr +++ /dev/null @@ -1,5 +0,0 @@ -error: Codec can only be derived for structs with named fields - --> tests/compile-fail/derive_codec/enum.rs:20:6 - | -20 | enum Test { - | ^^^^ diff --git a/precompiles/utils/macro/tests/compile-fail/precompile/codec/arg-dont-impl-codec.rs b/precompiles/utils/macro/tests/compile-fail/precompile/codec/arg-dont-impl-codec.rs deleted file mode 100644 index d37fda0e7f..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/precompile/codec/arg-dont-impl-codec.rs +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -use core::marker::PhantomData; -use fp_evm::PrecompileHandle; -use precompile_utils::EvmResult; - -pub struct Precompile(PhantomData); - -#[precompile_utils_macro::precompile] -impl Precompile { - #[precompile::public("foo()")] - fn foo(test: &mut impl PrecompileHandle, arg: String) -> EvmResult { - todo!() - } -} - -fn main() { } \ No newline at end of file diff --git a/precompiles/utils/macro/tests/compile-fail/precompile/codec/arg-dont-impl-codec.stderr b/precompiles/utils/macro/tests/compile-fail/precompile/codec/arg-dont-impl-codec.stderr deleted file mode 100644 index 1e87e3c771..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/precompile/codec/arg-dont-impl-codec.stderr +++ /dev/null @@ -1,61 +0,0 @@ -error[E0277]: the trait bound `String: Codec` is not satisfied - --> tests/compile-fail/precompile/codec/arg-dont-impl-codec.rs:26:43 - | -26 | fn foo(test: &mut impl PrecompileHandle, arg: String) -> EvmResult { - | ^^^ the trait `Codec` is not implemented for `String` - | - = help: the following other types implement trait `Codec`: - () - (TupleElement0, TupleElement1) - (TupleElement0, TupleElement1, TupleElement2) - (TupleElement0, TupleElement1, TupleElement2, TupleElement3) - (TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4) - (TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4, TupleElement5) - (TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4, TupleElement5, TupleElement6) - (TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4, TupleElement5, TupleElement6, TupleElement7) - and $N others -note: required by a bound in `Reader::<'inner>::read` - --> $WORKSPACE/precompiles/utils/src/solidity/codec/mod.rs - | - | pub fn read(&mut self) -> MayRevert { - | ^^^^^ required by this bound in `Reader::<'inner>::read` - -error[E0277]: the trait bound `String: Codec` is not satisfied - --> tests/compile-fail/precompile/codec/arg-dont-impl-codec.rs:26:43 - | -26 | fn foo(test: &mut impl PrecompileHandle, arg: String) -> EvmResult { - | ^^^ the trait `Codec` is not implemented for `String` - | - = help: the following other types implement trait `Codec`: - () - (TupleElement0, TupleElement1) - (TupleElement0, TupleElement1, TupleElement2) - (TupleElement0, TupleElement1, TupleElement2, TupleElement3) - (TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4) - (TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4, TupleElement5) - (TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4, TupleElement5, TupleElement6) - (TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4, TupleElement5, TupleElement6, TupleElement7) - and $N others -note: required by a bound in `precompile_utils::solidity::codec::Writer::write` - --> $WORKSPACE/precompiles/utils/src/solidity/codec/mod.rs - | - | pub fn write(mut self, value: T) -> Self { - | ^^^^^ required by this bound in `Writer::write` - -error[E0277]: the trait bound `String: Codec` is not satisfied - --> tests/compile-fail/precompile/codec/arg-dont-impl-codec.rs:26:5 - | -26 | fn foo(test: &mut impl PrecompileHandle, arg: String) -> EvmResult { - | ^^^ the trait `Codec` is not implemented for `String` - | - = help: the following other types implement trait `Codec`: - () - (TupleElement0, TupleElement1) - (TupleElement0, TupleElement1, TupleElement2) - (TupleElement0, TupleElement1, TupleElement2, TupleElement3) - (TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4) - (TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4, TupleElement5) - (TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4, TupleElement5, TupleElement6) - (TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4, TupleElement5, TupleElement6, TupleElement7) - and $N others - = note: required for `(String,)` to implement `Codec` diff --git a/precompiles/utils/macro/tests/compile-fail/precompile/codec/no-output.rs b/precompiles/utils/macro/tests/compile-fail/precompile/codec/no-output.rs deleted file mode 100644 index 1f0ab2aebc..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/precompile/codec/no-output.rs +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -use core::marker::PhantomData; - -pub struct Precompile(PhantomData); - -#[precompile_utils_macro::precompile] -impl Precompile { - #[precompile::public("foo()")] - fn foo(test: &mut impl PrecompileHandle) { - todo!() - } -} - -fn main() { } \ No newline at end of file diff --git a/precompiles/utils/macro/tests/compile-fail/precompile/codec/no-output.stderr b/precompiles/utils/macro/tests/compile-fail/precompile/codec/no-output.stderr deleted file mode 100644 index 7a2758d0f5..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/precompile/codec/no-output.stderr +++ /dev/null @@ -1,5 +0,0 @@ -error: A precompile method must have a return type of `EvmResult<_>` (exposed by `precompile_utils`) - --> tests/compile-fail/precompile/codec/no-output.rs:24:2 - | -24 | fn foo(test: &mut impl PrecompileHandle) { - | ^^ diff --git a/precompiles/utils/macro/tests/compile-fail/precompile/codec/output-dont-impl-codec.rs b/precompiles/utils/macro/tests/compile-fail/precompile/codec/output-dont-impl-codec.rs deleted file mode 100644 index bb7ffb7233..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/precompile/codec/output-dont-impl-codec.rs +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -use core::marker::PhantomData; -use fp_evm::PrecompileHandle; -use precompile_utils::EvmResult; - -pub struct Precompile(PhantomData); - -#[precompile_utils_macro::precompile] -impl Precompile { - #[precompile::public("foo()")] - fn foo(test: &mut impl PrecompileHandle) -> EvmResult { - todo!() - } -} - -fn main() { } \ No newline at end of file diff --git a/precompiles/utils/macro/tests/compile-fail/precompile/codec/output-dont-impl-codec.stderr b/precompiles/utils/macro/tests/compile-fail/precompile/codec/output-dont-impl-codec.stderr deleted file mode 100644 index 52ba67e654..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/precompile/codec/output-dont-impl-codec.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error[E0277]: the trait bound `String: Codec` is not satisfied - --> tests/compile-fail/precompile/codec/output-dont-impl-codec.rs:26:46 - | -26 | fn foo(test: &mut impl PrecompileHandle) -> EvmResult { - | ^^^^^^^^^ the trait `Codec` is not implemented for `String` - | - = help: the following other types implement trait `Codec`: - () - (TupleElement0, TupleElement1) - (TupleElement0, TupleElement1, TupleElement2) - (TupleElement0, TupleElement1, TupleElement2, TupleElement3) - (TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4) - (TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4, TupleElement5) - (TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4, TupleElement5, TupleElement6) - (TupleElement0, TupleElement1, TupleElement2, TupleElement3, TupleElement4, TupleElement5, TupleElement6, TupleElement7) - and $N others -note: required by a bound in `encode_arguments` - --> $WORKSPACE/precompiles/utils/src/solidity/codec/mod.rs - | - | pub fn encode_arguments(value: T) -> Vec { - | ^^^^^ required by this bound in `encode_arguments` diff --git a/precompiles/utils/macro/tests/compile-fail/precompile/codec/output-not-result.rs b/precompiles/utils/macro/tests/compile-fail/precompile/codec/output-not-result.rs deleted file mode 100644 index 686f3bd044..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/precompile/codec/output-not-result.rs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -use core::marker::PhantomData; -use fp_evm::PrecompileHandle; - -pub struct Precompile(PhantomData); - -#[precompile_utils_macro::precompile] -impl Precompile { - #[precompile::public("foo()")] - fn foo(test: &mut impl PrecompileHandle) -> String { - todo!() - } -} - -fn main() { } \ No newline at end of file diff --git a/precompiles/utils/macro/tests/compile-fail/precompile/codec/output-not-result.stderr b/precompiles/utils/macro/tests/compile-fail/precompile/codec/output-not-result.stderr deleted file mode 100644 index c104ae8fb3..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/precompile/codec/output-not-result.stderr +++ /dev/null @@ -1,7 +0,0 @@ -error[E0277]: the `?` operator can only be applied to values that implement `Try` - --> tests/compile-fail/precompile/codec/output-not-result.rs:25:46 - | -25 | fn foo(test: &mut impl PrecompileHandle) -> String { - | ^^^^^^ the `?` operator cannot be applied to type `String` - | - = help: the trait `Try` is not implemented for `String` diff --git a/precompiles/utils/macro/tests/compile-fail/precompile/codec/output-wrong-error-result.rs b/precompiles/utils/macro/tests/compile-fail/precompile/codec/output-wrong-error-result.rs deleted file mode 100644 index df90aadd77..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/precompile/codec/output-wrong-error-result.rs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -use core::marker::PhantomData; -use fp_evm::PrecompileHandle; - -pub struct Precompile(PhantomData); - -#[precompile_utils_macro::precompile] -impl Precompile { - #[precompile::public("foo()")] - fn foo(test: &mut impl PrecompileHandle) -> Result<(), String> { - todo!() - } -} - -fn main() { } \ No newline at end of file diff --git a/precompiles/utils/macro/tests/compile-fail/precompile/codec/output-wrong-error-result.stderr b/precompiles/utils/macro/tests/compile-fail/precompile/codec/output-wrong-error-result.stderr deleted file mode 100644 index fa1fc8f71c..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/precompile/codec/output-wrong-error-result.stderr +++ /dev/null @@ -1,13 +0,0 @@ -error[E0277]: `?` couldn't convert the error to `PrecompileFailure` - --> tests/compile-fail/precompile/codec/output-wrong-error-result.rs:25:51 - | -25 | fn foo(test: &mut impl PrecompileHandle) -> Result<(), String> { - | ^ the trait `From` is not implemented for `PrecompileFailure` - | - = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait - = help: the following other types implement trait `From`: - > - > - > - > - = note: required for `Result` to implement `FromResidual>` diff --git a/precompiles/utils/macro/tests/compile-fail/precompile/discriminant/dont-return-option.rs b/precompiles/utils/macro/tests/compile-fail/precompile/discriminant/dont-return-option.rs deleted file mode 100644 index ca9faeaf10..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/precompile/discriminant/dont-return-option.rs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -use core::marker::PhantomData; - -pub struct Precompile(PhantomData); - -#[precompile_utils_macro::precompile] -#[precompile::precompile_set] -impl Precompile { - #[precompile::discriminant] - fn discriminant(address: H160) -> u32 { - 42 - } - - #[precompile::public("foo()")] - fn foo(_discriminant: u32, test: &mut impl PrecompileHandle) -> EvmResult { - todo!() - } -} - -fn main() { } \ No newline at end of file diff --git a/precompiles/utils/macro/tests/compile-fail/precompile/discriminant/dont-return-option.stderr b/precompiles/utils/macro/tests/compile-fail/precompile/discriminant/dont-return-option.stderr deleted file mode 100644 index 66d90708f0..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/precompile/discriminant/dont-return-option.stderr +++ /dev/null @@ -1,5 +0,0 @@ -error: The discriminant function must return an Option<_> (no type alias) - --> tests/compile-fail/precompile/discriminant/dont-return-option.rs:25:36 - | -25 | fn discriminant(address: H160) -> u32 { - | ^^^ diff --git a/precompiles/utils/macro/tests/compile-fail/precompile/discriminant/missing-fn.rs b/precompiles/utils/macro/tests/compile-fail/precompile/discriminant/missing-fn.rs deleted file mode 100644 index 9eb81c8d20..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/precompile/discriminant/missing-fn.rs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -use core::marker::PhantomData; - -pub struct Precompile(PhantomData); - -#[precompile_utils_macro::precompile] -#[precompile::precompile_set] -impl Precompile { - #[precompile::public("foo()")] - fn foo(_discriminant: u32, handle: &mut impl PrecompileHandle) -> EvmResult { - todo!() - } -} - -fn main() { } \ No newline at end of file diff --git a/precompiles/utils/macro/tests/compile-fail/precompile/discriminant/missing-fn.stderr b/precompiles/utils/macro/tests/compile-fail/precompile/discriminant/missing-fn.stderr deleted file mode 100644 index b24b8dddcb..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/precompile/discriminant/missing-fn.stderr +++ /dev/null @@ -1,7 +0,0 @@ -error: A PrecompileSet must have exactly one function tagged with `#[precompile::discriminant]` - --> tests/compile-fail/precompile/discriminant/missing-fn.rs:21:1 - | -21 | #[precompile_utils_macro::precompile] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: this error originates in the attribute macro `precompile_utils_macro::precompile` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/precompiles/utils/macro/tests/compile-fail/precompile/discriminant/missing-param.rs b/precompiles/utils/macro/tests/compile-fail/precompile/discriminant/missing-param.rs deleted file mode 100644 index 534c9b2a22..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/precompile/discriminant/missing-param.rs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -use core::marker::PhantomData; - -pub struct Precompile(PhantomData); - -#[precompile_utils_macro::precompile] -#[precompile::precompile_set] -impl Precompile { - #[precompile::discriminant] - fn discriminant() -> Option { - Some(42) - } - - #[precompile::public("foo()")] - fn foo(_discriminant: u32, test: &mut impl PrecompileHandle) -> EvmResult { - todo!() - } -} - -fn main() { } \ No newline at end of file diff --git a/precompiles/utils/macro/tests/compile-fail/precompile/discriminant/missing-param.stderr b/precompiles/utils/macro/tests/compile-fail/precompile/discriminant/missing-param.stderr deleted file mode 100644 index 3026b5ce42..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/precompile/discriminant/missing-param.stderr +++ /dev/null @@ -1,5 +0,0 @@ -error: The discriminant function must only take the code address (H160) as parameter. - --> tests/compile-fail/precompile/discriminant/missing-param.rs:25:2 - | -25 | fn discriminant() -> Option { - | ^^ diff --git a/precompiles/utils/macro/tests/compile-fail/precompile/discriminant/return-incomplete-option.rs b/precompiles/utils/macro/tests/compile-fail/precompile/discriminant/return-incomplete-option.rs deleted file mode 100644 index 8d08a6afb9..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/precompile/discriminant/return-incomplete-option.rs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -use core::marker::PhantomData; - -pub struct Precompile(PhantomData); - -#[precompile_utils_macro::precompile] -#[precompile::precompile_set] -impl Precompile { - #[precompile::discriminant] - fn discriminant(address: H160) -> Option { - None - } - - #[precompile::public("foo()")] - fn foo(_discriminant: u32, test: &mut impl PrecompileHandle) -> EvmResult { - todo!() - } -} - -fn main() { } \ No newline at end of file diff --git a/precompiles/utils/macro/tests/compile-fail/precompile/discriminant/return-incomplete-option.stderr b/precompiles/utils/macro/tests/compile-fail/precompile/discriminant/return-incomplete-option.stderr deleted file mode 100644 index dc6db9f600..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/precompile/discriminant/return-incomplete-option.stderr +++ /dev/null @@ -1,5 +0,0 @@ -error: The discriminant function must return an Option<_> (no type alias) - --> tests/compile-fail/precompile/discriminant/return-incomplete-option.rs:25:36 - | -25 | fn discriminant(address: H160) -> Option { - | ^^^^^^ diff --git a/precompiles/utils/macro/tests/compile-fail/precompile/discriminant/too-many-arguments.rs b/precompiles/utils/macro/tests/compile-fail/precompile/discriminant/too-many-arguments.rs deleted file mode 100644 index 63281a7a25..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/precompile/discriminant/too-many-arguments.rs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -use core::marker::PhantomData; - -pub struct Precompile(PhantomData); - -#[precompile_utils_macro::precompile] -#[precompile::precompile_set] -impl Precompile { - #[precompile::discriminant] - fn discriminant(address: H160, other: u32) -> Option { - Some(42) - } - - #[precompile::public("foo()")] - fn foo(_discriminant: u32, test: &mut impl PrecompileHandle) -> EvmResult { - todo!() - } -} - -fn main() { } \ No newline at end of file diff --git a/precompiles/utils/macro/tests/compile-fail/precompile/discriminant/too-many-arguments.stderr b/precompiles/utils/macro/tests/compile-fail/precompile/discriminant/too-many-arguments.stderr deleted file mode 100644 index a1b6e87865..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/precompile/discriminant/too-many-arguments.stderr +++ /dev/null @@ -1,5 +0,0 @@ -error: The discriminant function must only take the code address (H160) as parameter. - --> tests/compile-fail/precompile/discriminant/too-many-arguments.rs:25:2 - | -25 | fn discriminant(address: H160, other: u32) -> Option { - | ^^ diff --git a/precompiles/utils/macro/tests/compile-fail/precompile/discriminant/type-mismatch-1.rs b/precompiles/utils/macro/tests/compile-fail/precompile/discriminant/type-mismatch-1.rs deleted file mode 100644 index 9a392560b8..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/precompile/discriminant/type-mismatch-1.rs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -use core::marker::PhantomData; - -pub struct Precompile(PhantomData); - -#[precompile_utils_macro::precompile] -#[precompile::precompile_set] -impl Precompile { - #[precompile::discriminant] - fn discriminant(address: H160) -> Option { - Some(42) - } - - #[precompile::public("foo()")] - fn foo(_discriminant: u32, test: &mut impl PrecompileHandle) -> EvmResult { - todo!() - } -} - -fn main() { } \ No newline at end of file diff --git a/precompiles/utils/macro/tests/compile-fail/precompile/discriminant/type-mismatch-1.stderr b/precompiles/utils/macro/tests/compile-fail/precompile/discriminant/type-mismatch-1.stderr deleted file mode 100644 index 8d999769e4..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/precompile/discriminant/type-mismatch-1.stderr +++ /dev/null @@ -1,5 +0,0 @@ -error: All discriminants must have the same type (found u64 before) - --> tests/compile-fail/precompile/discriminant/type-mismatch-1.rs:30:24 - | -30 | fn foo(_discriminant: u32, test: &mut impl PrecompileHandle) -> EvmResult { - | ^^^ diff --git a/precompiles/utils/macro/tests/compile-fail/precompile/discriminant/type-mismatch-2.rs b/precompiles/utils/macro/tests/compile-fail/precompile/discriminant/type-mismatch-2.rs deleted file mode 100644 index 4ebfdd84a9..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/precompile/discriminant/type-mismatch-2.rs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -use core::marker::PhantomData; - -pub struct Precompile(PhantomData); - -#[precompile_utils_macro::precompile] -#[precompile::precompile_set] -impl Precompile { - #[precompile::public("foo()")] - fn foo(_discriminant: u32, test: &mut impl PrecompileHandle) -> EvmResult { - todo!() - } - - #[precompile::discriminant] - fn discriminant(address: H160) -> Option { - Some(42) - } -} - -fn main() { } \ No newline at end of file diff --git a/precompiles/utils/macro/tests/compile-fail/precompile/discriminant/type-mismatch-2.stderr b/precompiles/utils/macro/tests/compile-fail/precompile/discriminant/type-mismatch-2.stderr deleted file mode 100644 index d5ed6750af..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/precompile/discriminant/type-mismatch-2.stderr +++ /dev/null @@ -1,5 +0,0 @@ -error: All discriminants must have the same type (found u32 before) - --> tests/compile-fail/precompile/discriminant/type-mismatch-2.rs:30:43 - | -30 | fn discriminant(address: H160) -> Option { - | ^^^ diff --git a/precompiles/utils/macro/tests/compile-fail/precompile/fn-modifiers/discriminant-multiple.rs b/precompiles/utils/macro/tests/compile-fail/precompile/fn-modifiers/discriminant-multiple.rs deleted file mode 100644 index 6aac2cd214..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/precompile/fn-modifiers/discriminant-multiple.rs +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -use core::marker::PhantomData; - -pub struct PrecompileSet(PhantomData); - -#[precompile_utils_macro::precompile] -#[precompile::precompile_set] -impl PrecompileSet { - #[precompile::discriminant] - #[precompile::view] - fn foo(address: H160) -> Option { - None - } -} - -fn main() { } \ No newline at end of file diff --git a/precompiles/utils/macro/tests/compile-fail/precompile/fn-modifiers/discriminant-multiple.stderr b/precompiles/utils/macro/tests/compile-fail/precompile/fn-modifiers/discriminant-multiple.stderr deleted file mode 100644 index 93f4fb2617..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/precompile/fn-modifiers/discriminant-multiple.stderr +++ /dev/null @@ -1,5 +0,0 @@ -error: The discriminant attribute must be the only precompile attribute of a function - --> tests/compile-fail/precompile/fn-modifiers/discriminant-multiple.rs:24:16 - | -24 | #[precompile::discriminant] - | ^^^^^^^^^^^^ diff --git a/precompiles/utils/macro/tests/compile-fail/precompile/fn-modifiers/multiple-modifiers.rs b/precompiles/utils/macro/tests/compile-fail/precompile/fn-modifiers/multiple-modifiers.rs deleted file mode 100644 index 70d5ea920c..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/precompile/fn-modifiers/multiple-modifiers.rs +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -use core::marker::PhantomData; - -pub struct Precompile(PhantomData); - -#[precompile_utils_macro::precompile] -impl Precompile { - #[precompile::public("foo()")] - #[precompile::view] - #[precompile::payable] - fn foo(_handle: &mut impl PrecompileHandle) -> EvmResult { - Ok(()) - } -} - -fn main() { } \ No newline at end of file diff --git a/precompiles/utils/macro/tests/compile-fail/precompile/fn-modifiers/multiple-modifiers.stderr b/precompiles/utils/macro/tests/compile-fail/precompile/fn-modifiers/multiple-modifiers.stderr deleted file mode 100644 index 678199ab8b..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/precompile/fn-modifiers/multiple-modifiers.stderr +++ /dev/null @@ -1,5 +0,0 @@ -error: A precompile method can have at most one modifier (payable, view) - --> tests/compile-fail/precompile/fn-modifiers/multiple-modifiers.rs:25:16 - | -25 | #[precompile::payable] - | ^^^^^^^ diff --git a/precompiles/utils/macro/tests/compile-fail/precompile/fn-modifiers/pre-check-multiple.rs b/precompiles/utils/macro/tests/compile-fail/precompile/fn-modifiers/pre-check-multiple.rs deleted file mode 100644 index f80194ee33..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/precompile/fn-modifiers/pre-check-multiple.rs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -use core::marker::PhantomData; - -pub struct Precompile(PhantomData); - -#[precompile_utils_macro::precompile] -impl Precompile { - #[precompile::pre_check] - #[precompile::view] - fn foo(handle: &mut impl PrecompileHandle) -> EvmResult { - Ok(()) - } -} - -fn main() { } \ No newline at end of file diff --git a/precompiles/utils/macro/tests/compile-fail/precompile/fn-modifiers/pre-check-multiple.stderr b/precompiles/utils/macro/tests/compile-fail/precompile/fn-modifiers/pre-check-multiple.stderr deleted file mode 100644 index 7f96f8b568..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/precompile/fn-modifiers/pre-check-multiple.stderr +++ /dev/null @@ -1,5 +0,0 @@ -error: The pre_check attribute must be the only precompile attribute of a function - --> tests/compile-fail/precompile/fn-modifiers/pre-check-multiple.rs:23:16 - | -23 | #[precompile::pre_check] - | ^^^^^^^^^ diff --git a/precompiles/utils/macro/tests/compile-fail/precompile/handle/missing.rs b/precompiles/utils/macro/tests/compile-fail/precompile/handle/missing.rs deleted file mode 100644 index 50bee5b976..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/precompile/handle/missing.rs +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -use core::marker::PhantomData; - -pub struct Precompile(PhantomData); - -#[precompile_utils_macro::precompile] -impl Precompile { - #[precompile::public("foo()")] - fn foo() { - todo!() - } -} - -fn main() { } \ No newline at end of file diff --git a/precompiles/utils/macro/tests/compile-fail/precompile/handle/missing.stderr b/precompiles/utils/macro/tests/compile-fail/precompile/handle/missing.stderr deleted file mode 100644 index 2760a71988..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/precompile/handle/missing.stderr +++ /dev/null @@ -1,5 +0,0 @@ -error: Precompile methods must have at least 1 parameter (the PrecompileHandle) - --> tests/compile-fail/precompile/handle/missing.rs:24:2 - | -24 | fn foo() { - | ^^ diff --git a/precompiles/utils/macro/tests/compile-fail/precompile/handle/set-missing.rs b/precompiles/utils/macro/tests/compile-fail/precompile/handle/set-missing.rs deleted file mode 100644 index 14477da6b8..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/precompile/handle/set-missing.rs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -use core::marker::PhantomData; - -pub struct Precompile(PhantomData); - -#[precompile_utils_macro::precompile] -#[precompile::precompile_set] -impl Precompile { - #[precompile::public("foo()")] - fn foo(_: u32) { - todo!() - } -} - -fn main() { } \ No newline at end of file diff --git a/precompiles/utils/macro/tests/compile-fail/precompile/handle/set-missing.stderr b/precompiles/utils/macro/tests/compile-fail/precompile/handle/set-missing.stderr deleted file mode 100644 index 8f0a10d8ff..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/precompile/handle/set-missing.stderr +++ /dev/null @@ -1,5 +0,0 @@ -error: PrecompileSet methods must have at least 2 parameters (the precompile instance discriminant and the PrecompileHandle) - --> tests/compile-fail/precompile/handle/set-missing.rs:25:2 - | -25 | fn foo(_: u32) { - | ^^ diff --git a/precompiles/utils/macro/tests/compile-fail/precompile/handle/set-wrong-type.rs b/precompiles/utils/macro/tests/compile-fail/precompile/handle/set-wrong-type.rs deleted file mode 100644 index 0c33d1507d..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/precompile/handle/set-wrong-type.rs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -use core::marker::PhantomData; - -pub struct Precompile(PhantomData); - -#[precompile_utils_macro::precompile] -#[precompile::precompile_set] -impl Precompile { - #[precompile::public("foo()")] - fn foo(_discriminant: u32, _handle: u32) { - todo!() - } -} - -fn main() { } \ No newline at end of file diff --git a/precompiles/utils/macro/tests/compile-fail/precompile/handle/set-wrong-type.stderr b/precompiles/utils/macro/tests/compile-fail/precompile/handle/set-wrong-type.stderr deleted file mode 100644 index bf62c1381c..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/precompile/handle/set-wrong-type.stderr +++ /dev/null @@ -1,5 +0,0 @@ -error: This parameter must have type `&mut impl PrecompileHandle` - --> tests/compile-fail/precompile/handle/set-wrong-type.rs:25:38 - | -25 | fn foo(_discriminant: u32, _handle: u32) { - | ^^^ diff --git a/precompiles/utils/macro/tests/compile-fail/precompile/handle/wrong-type.rs b/precompiles/utils/macro/tests/compile-fail/precompile/handle/wrong-type.rs deleted file mode 100644 index 39efe0521d..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/precompile/handle/wrong-type.rs +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -use core::marker::PhantomData; - -pub struct Precompile(PhantomData); - -#[precompile_utils_macro::precompile] -impl Precompile { - #[precompile::public("foo()")] - fn foo(_handle: u32) { - todo!() - } -} - -fn main() { } \ No newline at end of file diff --git a/precompiles/utils/macro/tests/compile-fail/precompile/handle/wrong-type.stderr b/precompiles/utils/macro/tests/compile-fail/precompile/handle/wrong-type.stderr deleted file mode 100644 index 12e06e4889..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/precompile/handle/wrong-type.stderr +++ /dev/null @@ -1,5 +0,0 @@ -error: This parameter must have type `&mut impl PrecompileHandle` - --> tests/compile-fail/precompile/handle/wrong-type.rs:24:18 - | -24 | fn foo(_handle: u32) { - | ^^^ diff --git a/precompiles/utils/macro/tests/compile-fail/precompile/pre-check/no-parameter.rs b/precompiles/utils/macro/tests/compile-fail/precompile/pre-check/no-parameter.rs deleted file mode 100644 index 0c40d7158b..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/precompile/pre-check/no-parameter.rs +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -use core::marker::PhantomData; - -pub struct Precompile(PhantomData); - -#[precompile_utils_macro::precompile] -impl Precompile { - #[precompile::pre_check] - fn pre_check() { - todo!() - } - - #[precompile::public("foo()")] - fn foo(_handle: &mut impl PrecompileHandle) { - todo!() - } -} - -fn main() { } \ No newline at end of file diff --git a/precompiles/utils/macro/tests/compile-fail/precompile/pre-check/no-parameter.stderr b/precompiles/utils/macro/tests/compile-fail/precompile/pre-check/no-parameter.stderr deleted file mode 100644 index 406806c51c..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/precompile/pre-check/no-parameter.stderr +++ /dev/null @@ -1,5 +0,0 @@ -error: Precompile methods must have at least 1 parameter (the PrecompileHandle) - --> tests/compile-fail/precompile/pre-check/no-parameter.rs:24:2 - | -24 | fn pre_check() { - | ^^ diff --git a/precompiles/utils/macro/tests/compile-fail/precompile/pre-check/too-many-parameters.rs b/precompiles/utils/macro/tests/compile-fail/precompile/pre-check/too-many-parameters.rs deleted file mode 100644 index 1ad09c62fd..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/precompile/pre-check/too-many-parameters.rs +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -use core::marker::PhantomData; - -pub struct Precompile(PhantomData); - -#[precompile_utils_macro::precompile] -impl Precompile { - #[precompile::pre_check] - fn pre_check(_: &mut impl PrecompileHandle, _: u32) { - todo!() - } - - #[precompile::public("foo()")] - fn foo(_handle: &mut impl PrecompileHandle) { - todo!() - } -} - -fn main() { } \ No newline at end of file diff --git a/precompiles/utils/macro/tests/compile-fail/precompile/pre-check/too-many-parameters.stderr b/precompiles/utils/macro/tests/compile-fail/precompile/pre-check/too-many-parameters.stderr deleted file mode 100644 index 474b5c9dcd..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/precompile/pre-check/too-many-parameters.stderr +++ /dev/null @@ -1,5 +0,0 @@ -error: Precompile pre_check method must have exactly 1 parameter (the PrecompileHandle) - --> tests/compile-fail/precompile/pre-check/too-many-parameters.rs:24:2 - | -24 | fn pre_check(_: &mut impl PrecompileHandle, _: u32) { - | ^^ diff --git a/precompiles/utils/macro/tests/compile-fail/precompile/pre-check/wrong-parameter.rs b/precompiles/utils/macro/tests/compile-fail/precompile/pre-check/wrong-parameter.rs deleted file mode 100644 index d081415b13..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/precompile/pre-check/wrong-parameter.rs +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -use core::marker::PhantomData; - -pub struct Precompile(PhantomData); - -#[precompile_utils_macro::precompile] -impl Precompile { - #[precompile::pre_check] - fn pre_check(_: u32) { - todo!() - } - - #[precompile::public("foo()")] - fn foo(_handle: &mut impl PrecompileHandle) { - todo!() - } -} - -fn main() { } \ No newline at end of file diff --git a/precompiles/utils/macro/tests/compile-fail/precompile/pre-check/wrong-parameter.stderr b/precompiles/utils/macro/tests/compile-fail/precompile/pre-check/wrong-parameter.stderr deleted file mode 100644 index ea95fb0de8..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/precompile/pre-check/wrong-parameter.stderr +++ /dev/null @@ -1,5 +0,0 @@ -error: This parameter must have type `&mut impl PrecompileHandle` - --> tests/compile-fail/precompile/pre-check/wrong-parameter.rs:24:18 - | -24 | fn pre_check(_: u32) { - | ^^^ diff --git a/precompiles/utils/macro/tests/compile-fail/precompile/test-gen/generic-arg.rs b/precompiles/utils/macro/tests/compile-fail/precompile/test-gen/generic-arg.rs deleted file mode 100644 index c5670db2e9..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/precompile/test-gen/generic-arg.rs +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -use core::marker::PhantomData; - -pub struct Precompile(PhantomData); - -#[precompile_utils_macro::precompile] -impl> Precompile { - #[precompile::public("foo(bytes)")] - fn foo(handle: &mut impl PrecompileHandle, arg: BoundedBytes) -> EvmResult { - Ok(()) - } -} - -fn main() {} diff --git a/precompiles/utils/macro/tests/compile-fail/precompile/test-gen/generic-arg.stderr b/precompiles/utils/macro/tests/compile-fail/precompile/test-gen/generic-arg.stderr deleted file mode 100644 index 8b4daeb35f..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/precompile/test-gen/generic-arg.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error: impl type parameter is used in functions arguments. Arguments should not have a type - depending on a type parameter, unless it is a length bound for BoundedBytes, - BoundedString or alike, which doesn't affect the Solidity type. - - In that case, you must add a #[precompile::test_concrete_types(...)] attribute on the impl - block to provide concrete types that will be used to run the automatically generated tests - ensuring the Solidity function signatures are correct. - --> tests/compile-fail/precompile/test-gen/generic-arg.rs:24:63 - | -24 | fn foo(handle: &mut impl PrecompileHandle, arg: BoundedBytes) -> EvmResult { - | ^ diff --git a/precompiles/utils/macro/tests/compile-fail/precompile_name/not_tuple.stderr b/precompiles/utils/macro/tests/compile-fail/precompile_name/not_tuple.stderr deleted file mode 100644 index 343443a248..0000000000 --- a/precompiles/utils/macro/tests/compile-fail/precompile_name/not_tuple.stderr +++ /dev/null @@ -1,5 +0,0 @@ -error: Expected tuple - --> tests/compile-fail/precompile_name/not_tuple.rs:20:20 - | -20 | type Precompiles = Dummy; - | ^^^^^ diff --git a/precompiles/utils/macro/tests/expand/precompile.expanded.rs b/precompiles/utils/macro/tests/expand/precompile.expanded.rs deleted file mode 100644 index c5c5d5f45e..0000000000 --- a/precompiles/utils/macro/tests/expand/precompile.expanded.rs +++ /dev/null @@ -1,383 +0,0 @@ -use { - core::marker::PhantomData, precompile_utils::{EvmResult, prelude::*}, - sp_core::{H160, U256}, - frame_support::pallet_prelude::{Get, ConstU32}, -}; -struct BatchPrecompile(PhantomData); -type GetCallDataLimit = ConstU32<42>; -type GetArrayLimit = ConstU32<42>; -impl BatchPrecompile -where - Runtime: Get, -{ - fn pre_check(handle: &mut impl PrecompileHandle) -> EvmResult { - ::core::panicking::panic_fmt( - format_args!("not yet implemented: {0}", format_args!("pre_check")), - ) - } - fn batch_some( - handle: &mut impl PrecompileHandle, - to: BoundedVec, - value: BoundedVec, - call_data: BoundedVec, GetArrayLimit>, - gas_limit: BoundedVec, - ) -> EvmResult { - ::core::panicking::panic_fmt( - format_args!("not yet implemented: {0}", format_args!("batch_some")), - ) - } - fn batch_some_until_failure( - handle: &mut impl PrecompileHandle, - to: BoundedVec, - value: BoundedVec, - call_data: BoundedVec, GetArrayLimit>, - gas_limit: BoundedVec, - ) -> EvmResult { - ::core::panicking::panic_fmt( - format_args!( - "not yet implemented: {0}", format_args!("batch_some_until_failure") - ), - ) - } - fn batch_all( - handle: &mut impl PrecompileHandle, - to: BoundedVec, - value: BoundedVec, - call_data: BoundedVec, GetArrayLimit>, - gas_limit: BoundedVec, - ) -> EvmResult { - ::core::panicking::panic_fmt( - format_args!("not yet implemented: {0}", format_args!("batch_all")), - ) - } - fn fallback(handle: &mut impl PrecompileHandle) -> EvmResult { - ::core::panicking::panic_fmt( - format_args!("not yet implemented: {0}", format_args!("fallback")), - ) - } -} -#[allow(non_camel_case_types)] -pub enum BatchPrecompileCall -where - Runtime: Get, -{ - batch_all { - to: BoundedVec, - value: BoundedVec, - call_data: BoundedVec, GetArrayLimit>, - gas_limit: BoundedVec, - }, - batch_some { - to: BoundedVec, - value: BoundedVec, - call_data: BoundedVec, GetArrayLimit>, - gas_limit: BoundedVec, - }, - batch_some_until_failure { - to: BoundedVec, - value: BoundedVec, - call_data: BoundedVec, GetArrayLimit>, - gas_limit: BoundedVec, - }, - fallback {}, - #[doc(hidden)] - __phantom(::core::marker::PhantomData<(Runtime)>, ::core::convert::Infallible), -} -impl BatchPrecompileCall -where - Runtime: Get, -{ - pub fn parse_call_data( - handle: &mut impl PrecompileHandle, - ) -> ::precompile_utils::EvmResult { - use ::precompile_utils::solidity::revert::RevertReason; - let input = handle.input(); - let selector = input - .get(0..4) - .map(|s| { - let mut buffer = [0u8; 4]; - buffer.copy_from_slice(s); - u32::from_be_bytes(buffer) - }); - match selector { - Some(2044677020u32) => Self::_parse_batch_some(handle), - Some(2531431096u32) => Self::_parse_batch_all(handle), - Some(3473183175u32) => Self::_parse_batch_some_until_failure(handle), - _ => Self::_parse_fallback(handle), - } - } - fn _parse_batch_all( - handle: &mut impl PrecompileHandle, - ) -> ::precompile_utils::EvmResult { - use ::precompile_utils::solidity::revert::InjectBacktrace; - use ::precompile_utils::solidity::modifier::FunctionModifier; - use ::precompile_utils::evm::handle::PrecompileHandleExt; - handle.check_function_modifier(FunctionModifier::NonPayable)?; - let mut input = handle.read_after_selector()?; - input.expect_arguments(4usize)?; - Ok(Self::batch_all { - to: input.read().in_field("to")?, - value: input.read().in_field("value")?, - call_data: input.read().in_field("callData")?, - gas_limit: input.read().in_field("gasLimit")?, - }) - } - fn _parse_batch_some( - handle: &mut impl PrecompileHandle, - ) -> ::precompile_utils::EvmResult { - use ::precompile_utils::solidity::revert::InjectBacktrace; - use ::precompile_utils::solidity::modifier::FunctionModifier; - use ::precompile_utils::evm::handle::PrecompileHandleExt; - handle.check_function_modifier(FunctionModifier::NonPayable)?; - let mut input = handle.read_after_selector()?; - input.expect_arguments(4usize)?; - Ok(Self::batch_some { - to: input.read().in_field("to")?, - value: input.read().in_field("value")?, - call_data: input.read().in_field("callData")?, - gas_limit: input.read().in_field("gasLimit")?, - }) - } - fn _parse_batch_some_until_failure( - handle: &mut impl PrecompileHandle, - ) -> ::precompile_utils::EvmResult { - use ::precompile_utils::solidity::revert::InjectBacktrace; - use ::precompile_utils::solidity::modifier::FunctionModifier; - use ::precompile_utils::evm::handle::PrecompileHandleExt; - handle.check_function_modifier(FunctionModifier::NonPayable)?; - let mut input = handle.read_after_selector()?; - input.expect_arguments(4usize)?; - Ok(Self::batch_some_until_failure { - to: input.read().in_field("to")?, - value: input.read().in_field("value")?, - call_data: input.read().in_field("callData")?, - gas_limit: input.read().in_field("gasLimit")?, - }) - } - fn _parse_fallback( - handle: &mut impl PrecompileHandle, - ) -> ::precompile_utils::EvmResult { - use ::precompile_utils::solidity::revert::InjectBacktrace; - use ::precompile_utils::solidity::modifier::FunctionModifier; - use ::precompile_utils::evm::handle::PrecompileHandleExt; - handle.check_function_modifier(FunctionModifier::NonPayable)?; - Ok(Self::fallback {}) - } - pub fn execute( - self, - handle: &mut impl PrecompileHandle, - ) -> ::precompile_utils::EvmResult<::fp_evm::PrecompileOutput> { - use ::precompile_utils::solidity::codec::Writer; - use ::fp_evm::{PrecompileOutput, ExitSucceed}; - let output = match self { - Self::batch_all { to, value, call_data, gas_limit } => { - let output = >::batch_all(handle, to, value, call_data, gas_limit); - ::precompile_utils::solidity::encode_return_value(output?) - } - Self::batch_some { to, value, call_data, gas_limit } => { - let output = >::batch_some(handle, to, value, call_data, gas_limit); - ::precompile_utils::solidity::encode_return_value(output?) - } - Self::batch_some_until_failure { to, value, call_data, gas_limit } => { - let output = >::batch_some_until_failure(handle, to, value, call_data, gas_limit); - ::precompile_utils::solidity::encode_return_value(output?) - } - Self::fallback {} => { - let output = >::fallback(handle); - ::precompile_utils::solidity::encode_return_value(output?) - } - Self::__phantom(_, _) => { - ::core::panicking::panic_fmt( - format_args!("__phantom variant should not be used"), - ) - } - }; - Ok(PrecompileOutput { - exit_status: ExitSucceed::Returned, - output, - }) - } - pub fn supports_selector(selector: u32) -> bool { - match selector { - 2044677020u32 => true, - 2531431096u32 => true, - 3473183175u32 => true, - _ => false, - } - } - pub fn selectors() -> &'static [u32] { - &[2044677020u32, 2531431096u32, 3473183175u32] - } - pub fn batch_all_selectors() -> &'static [u32] { - &[2531431096u32] - } - pub fn batch_some_selectors() -> &'static [u32] { - &[2044677020u32] - } - pub fn batch_some_until_failure_selectors() -> &'static [u32] { - &[3473183175u32] - } - pub fn fallback_selectors() -> &'static [u32] { - &[] - } - pub fn encode(self) -> ::sp_std::vec::Vec { - use ::precompile_utils::solidity::codec::Writer; - match self { - Self::batch_all { to, value, call_data, gas_limit } => { - Writer::new_with_selector(2531431096u32) - .write(to) - .write(value) - .write(call_data) - .write(gas_limit) - .build() - } - Self::batch_some { to, value, call_data, gas_limit } => { - Writer::new_with_selector(2044677020u32) - .write(to) - .write(value) - .write(call_data) - .write(gas_limit) - .build() - } - Self::batch_some_until_failure { to, value, call_data, gas_limit } => { - Writer::new_with_selector(3473183175u32) - .write(to) - .write(value) - .write(call_data) - .write(gas_limit) - .build() - } - Self::fallback {} => Default::default(), - Self::__phantom(_, _) => { - ::core::panicking::panic_fmt( - format_args!("__phantom variant should not be used"), - ) - } - } - } -} -impl From> for ::sp_std::vec::Vec -where - Runtime: Get, -{ - fn from(a: BatchPrecompileCall) -> ::sp_std::vec::Vec { - a.encode() - } -} -impl ::fp_evm::Precompile for BatchPrecompile -where - Runtime: Get, -{ - fn execute( - handle: &mut impl PrecompileHandle, - ) -> ::precompile_utils::EvmResult<::fp_evm::PrecompileOutput> { - let _: () = >::pre_check(handle)?; - >::parse_call_data(handle)?.execute(handle) - } -} -#[allow(non_snake_case)] -pub(crate) fn __BatchPrecompile_test_solidity_signatures_inner() { - use ::precompile_utils::solidity::Codec; - match ( - &"(address[],uint256[],bytes[],uint64[])", - &<( - BoundedVec, - BoundedVec, - BoundedVec, GetArrayLimit>, - BoundedVec, - ) as Codec>::signature(), - ) { - (left_val, right_val) => { - if !(*left_val == *right_val) { - let kind = ::core::panicking::AssertKind::Eq; - ::core::panicking::assert_failed( - kind, - &*left_val, - &*right_val, - ::core::option::Option::Some( - format_args!( - "{0} function signature doesn\'t match (left: attribute, right: computed from Rust types)", - "batch_all" - ), - ), - ); - } - } - }; - match ( - &"(address[],uint256[],bytes[],uint64[])", - &<( - BoundedVec, - BoundedVec, - BoundedVec, GetArrayLimit>, - BoundedVec, - ) as Codec>::signature(), - ) { - (left_val, right_val) => { - if !(*left_val == *right_val) { - let kind = ::core::panicking::AssertKind::Eq; - ::core::panicking::assert_failed( - kind, - &*left_val, - &*right_val, - ::core::option::Option::Some( - format_args!( - "{0} function signature doesn\'t match (left: attribute, right: computed from Rust types)", - "batch_some" - ), - ), - ); - } - } - }; - match ( - &"(address[],uint256[],bytes[],uint64[])", - &<( - BoundedVec, - BoundedVec, - BoundedVec, GetArrayLimit>, - BoundedVec, - ) as Codec>::signature(), - ) { - (left_val, right_val) => { - if !(*left_val == *right_val) { - let kind = ::core::panicking::AssertKind::Eq; - ::core::panicking::assert_failed( - kind, - &*left_val, - &*right_val, - ::core::option::Option::Some( - format_args!( - "{0} function signature doesn\'t match (left: attribute, right: computed from Rust types)", - "batch_some_until_failure" - ), - ), - ); - } - } - }; - match (&"()", &<() as Codec>::signature()) { - (left_val, right_val) => { - if !(*left_val == *right_val) { - let kind = ::core::panicking::AssertKind::Eq; - ::core::panicking::assert_failed( - kind, - &*left_val, - &*right_val, - ::core::option::Option::Some( - format_args!( - "{0} function signature doesn\'t match (left: attribute, right: computed from Rust types)", - "fallback" - ), - ), - ); - } - } - }; -} diff --git a/precompiles/utils/macro/tests/expand/precompile.rs b/precompiles/utils/macro/tests/expand/precompile.rs deleted file mode 100644 index fc1d76e787..0000000000 --- a/precompiles/utils/macro/tests/expand/precompile.rs +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -use { - core::marker::PhantomData, - precompile_utils::{EvmResult, prelude::*}, - sp_core::{H160, U256}, - frame_support::pallet_prelude::{Get, ConstU32}, -}; - -// Based on Batch with stripped code. - -struct BatchPrecompile(PhantomData); - -type GetCallDataLimit = ConstU32<42>; -type GetArrayLimit = ConstU32<42>; - - -#[precompile_utils_macro::precompile] -impl BatchPrecompile -where - Runtime: Get, -{ - #[precompile::pre_check] - fn pre_check(handle: &mut impl PrecompileHandle) -> EvmResult { - todo!("pre_check") - } - - #[precompile::public("batchSome(address[],uint256[],bytes[],uint64[])")] - fn batch_some( - handle: &mut impl PrecompileHandle, - to: BoundedVec, - value: BoundedVec, - call_data: BoundedVec, GetArrayLimit>, - gas_limit: BoundedVec, - ) -> EvmResult { - todo!("batch_some") - } - - #[precompile::public("batchSomeUntilFailure(address[],uint256[],bytes[],uint64[])")] - fn batch_some_until_failure( - handle: &mut impl PrecompileHandle, - to: BoundedVec, - value: BoundedVec, - call_data: BoundedVec, GetArrayLimit>, - gas_limit: BoundedVec, - ) -> EvmResult { - todo!("batch_some_until_failure") - } - - #[precompile::public("batchAll(address[],uint256[],bytes[],uint64[])")] - fn batch_all( - handle: &mut impl PrecompileHandle, - to: BoundedVec, - value: BoundedVec, - call_data: BoundedVec, GetArrayLimit>, - gas_limit: BoundedVec, - ) -> EvmResult { - todo!("batch_all") - } - - // additional function to check fallback - #[precompile::fallback] - fn fallback( - handle: &mut impl PrecompileHandle, - ) -> EvmResult { - todo!("fallback") - } -} \ No newline at end of file diff --git a/precompiles/utils/macro/tests/expand/precompile_name.expanded.rs b/precompiles/utils/macro/tests/expand/precompile_name.expanded.rs deleted file mode 100644 index 1d04b9ed77..0000000000 --- a/precompiles/utils/macro/tests/expand/precompile_name.expanded.rs +++ /dev/null @@ -1,37 +0,0 @@ -struct PrecompileAt(PhantomData<(T, U, V)>); -struct AddressU64; -struct FooPrecompile(PhantomData); -struct BarPrecompile(PhantomData<(R, S)>); -struct MockCheck; -type Precompiles = ( - PrecompileAt, FooPrecompile>, - PrecompileAt, BarPrecompile, (MockCheck, MockCheck)>, -); -#[repr(u64)] -pub enum PrecompileName { - FooPrecompile = 1u64, - BarPrecompile = 2u64, -} -#[automatically_derived] -impl ::core::fmt::Debug for PrecompileName { - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::write_str( - f, - match self { - PrecompileName::FooPrecompile => "FooPrecompile", - PrecompileName::BarPrecompile => "BarPrecompile", - }, - ) - } -} -impl PrecompileName { - pub fn from_address(address: sp_core::H160) -> Option { - let _u64 = address.to_low_u64_be(); - if address == sp_core::H160::from_low_u64_be(_u64) { - use num_enum::TryFromPrimitive; - Self::try_from_primitive(_u64).ok() - } else { - None - } - } -} diff --git a/precompiles/utils/macro/tests/expand/precompile_name.rs b/precompiles/utils/macro/tests/expand/precompile_name.rs deleted file mode 100644 index 3e14f9fb01..0000000000 --- a/precompiles/utils/macro/tests/expand/precompile_name.rs +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -// Few mock structs to check the macro. -struct PrecompileAt(PhantomData<(T, U, V)>); -struct AddressU64; -struct FooPrecompile(PhantomData); -struct BarPrecompile(PhantomData<(R, S)>); -struct MockCheck; - -#[precompile_utils_macro::precompile_name_from_address] -type Precompiles = ( - PrecompileAt, FooPrecompile>, - PrecompileAt, BarPrecompile, (MockCheck, MockCheck)>, -); diff --git a/precompiles/utils/macro/tests/expand/precompileset.expanded.rs b/precompiles/utils/macro/tests/expand/precompileset.expanded.rs deleted file mode 100644 index 59163757ac..0000000000 --- a/precompiles/utils/macro/tests/expand/precompileset.expanded.rs +++ /dev/null @@ -1,1426 +0,0 @@ -use { - core::marker::PhantomData, - precompile_utils::{EvmResult, prelude::*, testing::PrecompileTesterExt}, - sp_core::H160, -}; -struct PrecompileSet(PhantomData); -type Discriminant = u32; -type GetAssetsStringLimit = R; -type MockRuntime = ConstU32<42>; -impl PrecompileSet -where - Runtime: Get, -{ - /// PrecompileSet discrimiant. Allows to knows if the address maps to an asset id, - /// and if this is the case which one. - fn discriminant(address: H160) -> Option { - ::core::panicking::panic_fmt( - format_args!("not yet implemented: {0}", format_args!("discriminant")), - ) - } - fn total_supply( - asset_id: Discriminant, - handle: &mut impl PrecompileHandle, - ) -> EvmResult { - ::core::panicking::panic_fmt( - format_args!("not yet implemented: {0}", format_args!("total_supply")), - ) - } - fn balance_of( - asset_id: Discriminant, - handle: &mut impl PrecompileHandle, - who: Address, - ) -> EvmResult { - ::core::panicking::panic_fmt( - format_args!("not yet implemented: {0}", format_args!("balance_of")), - ) - } - fn allowance( - asset_id: Discriminant, - handle: &mut impl PrecompileHandle, - owner: Address, - spender: Address, - ) -> EvmResult { - ::core::panicking::panic_fmt( - format_args!("not yet implemented: {0}", format_args!("allowance")), - ) - } - fn approve( - asset_id: Discriminant, - handle: &mut impl PrecompileHandle, - spender: Address, - value: U256, - ) -> EvmResult { - ::core::panicking::panic_fmt( - format_args!("not yet implemented: {0}", format_args!("approve")), - ) - } - fn approve_inner( - asset_id: Discriminant, - handle: &mut impl PrecompileHandle, - owner: H160, - spender: H160, - value: U256, - ) -> EvmResult { - ::core::panicking::panic_fmt( - format_args!("not yet implemented: {0}", format_args!("approve_inner")), - ) - } - fn transfer( - asset_id: Discriminant, - handle: &mut impl PrecompileHandle, - to: Address, - value: U256, - ) -> EvmResult { - ::core::panicking::panic_fmt( - format_args!("not yet implemented: {0}", format_args!("transfer")), - ) - } - fn transfer_from( - asset_id: Discriminant, - handle: &mut impl PrecompileHandle, - from: Address, - to: Address, - value: U256, - ) -> EvmResult { - ::core::panicking::panic_fmt( - format_args!("not yet implemented: {0}", format_args!("transfer_from")), - ) - } - fn name( - asset_id: Discriminant, - handle: &mut impl PrecompileHandle, - ) -> EvmResult { - ::core::panicking::panic_fmt( - format_args!("not yet implemented: {0}", format_args!("name")), - ) - } - fn symbol( - asset_id: Discriminant, - handle: &mut impl PrecompileHandle, - ) -> EvmResult { - ::core::panicking::panic_fmt( - format_args!("not yet implemented: {0}", format_args!("symbol")), - ) - } - fn decimals( - asset_id: Discriminant, - handle: &mut impl PrecompileHandle, - ) -> EvmResult { - ::core::panicking::panic_fmt( - format_args!("not yet implemented: {0}", format_args!("decimals")), - ) - } - fn mint( - asset_id: Discriminant, - handle: &mut impl PrecompileHandle, - to: Address, - value: U256, - ) -> EvmResult { - ::core::panicking::panic_fmt( - format_args!("not yet implemented: {0}", format_args!("mint")), - ) - } - fn burn( - asset_id: Discriminant, - handle: &mut impl PrecompileHandle, - from: Address, - value: U256, - ) -> EvmResult { - ::core::panicking::panic_fmt( - format_args!("not yet implemented: {0}", format_args!("burn")), - ) - } - fn freeze( - asset_id: Discriminant, - handle: &mut impl PrecompileHandle, - account: Address, - ) -> EvmResult { - ::core::panicking::panic_fmt( - format_args!("not yet implemented: {0}", format_args!("freeze")), - ) - } - fn thaw( - asset_id: Discriminant, - handle: &mut impl PrecompileHandle, - account: Address, - ) -> EvmResult { - ::core::panicking::panic_fmt( - format_args!("not yet implemented: {0}", format_args!("thaw")), - ) - } - fn freeze_asset( - asset_id: Discriminant, - handle: &mut impl PrecompileHandle, - ) -> EvmResult { - ::core::panicking::panic_fmt( - format_args!("not yet implemented: {0}", format_args!("freeze_asset")), - ) - } - fn thaw_asset( - asset_id: Discriminant, - handle: &mut impl PrecompileHandle, - ) -> EvmResult { - ::core::panicking::panic_fmt( - format_args!("not yet implemented: {0}", format_args!("thaw_asset")), - ) - } - fn transfer_ownership( - asset_id: Discriminant, - handle: &mut impl PrecompileHandle, - owner: Address, - ) -> EvmResult { - ::core::panicking::panic_fmt( - format_args!("not yet implemented: {0}", format_args!("transfer_ownership")), - ) - } - fn set_team( - asset_id: Discriminant, - handle: &mut impl PrecompileHandle, - issuer: Address, - admin: Address, - freezer: Address, - ) -> EvmResult { - ::core::panicking::panic_fmt( - format_args!("not yet implemented: {0}", format_args!("set_team")), - ) - } - fn set_metadata( - asset_id: Discriminant, - handle: &mut impl PrecompileHandle, - name: BoundedString>, - symbol: BoundedString>, - decimals: u8, - ) -> EvmResult { - ::core::panicking::panic_fmt( - format_args!("not yet implemented: {0}", format_args!("set_metadata")), - ) - } - fn clear_metadata( - asset_id: Discriminant, - handle: &mut impl PrecompileHandle, - ) -> EvmResult { - ::core::panicking::panic_fmt( - format_args!("not yet implemented: {0}", format_args!("clear_metadata")), - ) - } - fn eip2612_permit( - asset_id: Discriminant, - handle: &mut impl PrecompileHandle, - owner: Address, - spender: Address, - value: U256, - deadline: U256, - v: u8, - r: H256, - s: H256, - ) -> EvmResult { - ::core::panicking::panic_fmt( - format_args!("not yet implemented: {0}", format_args!("eip2612_permit")), - ) - } - fn eip2612_nonces( - asset_id: Discriminant, - handle: &mut impl PrecompileHandle, - owner: Address, - ) -> EvmResult { - ::core::panicking::panic_fmt( - format_args!("not yet implemented: {0}", format_args!("eip2612_nonces")), - ) - } - fn eip2612_domain_separator( - asset_id: Discriminant, - handle: &mut impl PrecompileHandle, - ) -> EvmResult { - ::core::panicking::panic_fmt( - format_args!( - "not yet implemented: {0}", format_args!("eip2612_domain_separator") - ), - ) - } -} -#[allow(non_camel_case_types)] -pub enum PrecompileSetCall -where - Runtime: Get, -{ - allowance { owner: Address, spender: Address }, - approve { spender: Address, value: U256 }, - balance_of { who: Address }, - burn { from: Address, value: U256 }, - clear_metadata {}, - decimals {}, - eip2612_domain_separator {}, - eip2612_nonces { owner: Address }, - eip2612_permit { - owner: Address, - spender: Address, - value: U256, - deadline: U256, - v: u8, - r: H256, - s: H256, - }, - freeze { account: Address }, - freeze_asset {}, - mint { to: Address, value: U256 }, - name {}, - set_metadata { - name: BoundedString>, - symbol: BoundedString>, - decimals: u8, - }, - set_team { issuer: Address, admin: Address, freezer: Address }, - symbol {}, - thaw { account: Address }, - thaw_asset {}, - total_supply {}, - transfer { to: Address, value: U256 }, - transfer_from { from: Address, to: Address, value: U256 }, - transfer_ownership { owner: Address }, - #[doc(hidden)] - __phantom(::core::marker::PhantomData<(Runtime)>, ::core::convert::Infallible), -} -impl PrecompileSetCall -where - Runtime: Get, -{ - pub fn parse_call_data( - handle: &mut impl PrecompileHandle, - ) -> ::precompile_utils::EvmResult { - use ::precompile_utils::solidity::revert::RevertReason; - let input = handle.input(); - let selector = input - .get(0..4) - .map(|s| { - let mut buffer = [0u8; 4]; - buffer.copy_from_slice(s); - u32::from_be_bytes(buffer) - }); - match selector { - Some(117300739u32) => Self::_parse_name(handle), - Some(157198259u32) => Self::_parse_approve(handle), - Some(404098525u32) => Self::_parse_total_supply(handle), - Some(484305945u32) => Self::_parse_thaw_asset(handle), - Some(599290589u32) => Self::_parse_transfer_from(handle), - Some(826074471u32) => Self::_parse_decimals(handle), - Some(910484757u32) => Self::_parse_eip2612_domain_separator(handle), - Some(936559348u32) => Self::_parse_set_metadata(handle), - Some(1086394137u32) => Self::_parse_mint(handle), - Some(1374431959u32) => Self::_parse_thaw_asset(handle), - Some(1587675670u32) => Self::_parse_thaw(handle), - Some(1804030401u32) => Self::_parse_freeze_asset(handle), - Some(1889567281u32) => Self::_parse_balance_of(handle), - Some(2127478272u32) => Self::_parse_eip2612_nonces(handle), - Some(2367676207u32) => Self::_parse_freeze(handle), - Some(2514000705u32) => Self::_parse_symbol(handle), - Some(2646777772u32) => Self::_parse_burn(handle), - Some(2835717307u32) => Self::_parse_transfer(handle), - Some(3352902745u32) => Self::_parse_set_team(handle), - Some(3552201630u32) => Self::_parse_clear_metadata(handle), - Some(3566436177u32) => Self::_parse_freeze_asset(handle), - Some(3573918927u32) => Self::_parse_eip2612_permit(handle), - Some(3714247998u32) => Self::_parse_allowance(handle), - Some(3999121892u32) => Self::_parse_set_metadata(handle), - Some(4021736498u32) => Self::_parse_clear_metadata(handle), - Some(4030008324u32) => Self::_parse_transfer_ownership(handle), - Some(4076725131u32) => Self::_parse_transfer_ownership(handle), - Some(4173303445u32) => Self::_parse_set_team(handle), - Some(_) => Err(RevertReason::UnknownSelector.into()), - None => Err(RevertReason::read_out_of_bounds("selector").into()), - } - } - fn _parse_allowance( - handle: &mut impl PrecompileHandle, - ) -> ::precompile_utils::EvmResult { - use ::precompile_utils::solidity::revert::InjectBacktrace; - use ::precompile_utils::solidity::modifier::FunctionModifier; - use ::precompile_utils::evm::handle::PrecompileHandleExt; - handle.check_function_modifier(FunctionModifier::NonPayable)?; - let mut input = handle.read_after_selector()?; - input.expect_arguments(2usize)?; - Ok(Self::allowance { - owner: input.read().in_field("owner")?, - spender: input.read().in_field("spender")?, - }) - } - fn _parse_approve( - handle: &mut impl PrecompileHandle, - ) -> ::precompile_utils::EvmResult { - use ::precompile_utils::solidity::revert::InjectBacktrace; - use ::precompile_utils::solidity::modifier::FunctionModifier; - use ::precompile_utils::evm::handle::PrecompileHandleExt; - handle.check_function_modifier(FunctionModifier::NonPayable)?; - let mut input = handle.read_after_selector()?; - input.expect_arguments(2usize)?; - Ok(Self::approve { - spender: input.read().in_field("spender")?, - value: input.read().in_field("value")?, - }) - } - fn _parse_balance_of( - handle: &mut impl PrecompileHandle, - ) -> ::precompile_utils::EvmResult { - use ::precompile_utils::solidity::revert::InjectBacktrace; - use ::precompile_utils::solidity::modifier::FunctionModifier; - use ::precompile_utils::evm::handle::PrecompileHandleExt; - handle.check_function_modifier(FunctionModifier::NonPayable)?; - let mut input = handle.read_after_selector()?; - input.expect_arguments(1usize)?; - Ok(Self::balance_of { - who: input.read().in_field("who")?, - }) - } - fn _parse_burn( - handle: &mut impl PrecompileHandle, - ) -> ::precompile_utils::EvmResult { - use ::precompile_utils::solidity::revert::InjectBacktrace; - use ::precompile_utils::solidity::modifier::FunctionModifier; - use ::precompile_utils::evm::handle::PrecompileHandleExt; - handle.check_function_modifier(FunctionModifier::NonPayable)?; - let mut input = handle.read_after_selector()?; - input.expect_arguments(2usize)?; - Ok(Self::burn { - from: input.read().in_field("from")?, - value: input.read().in_field("value")?, - }) - } - fn _parse_clear_metadata( - handle: &mut impl PrecompileHandle, - ) -> ::precompile_utils::EvmResult { - use ::precompile_utils::solidity::revert::InjectBacktrace; - use ::precompile_utils::solidity::modifier::FunctionModifier; - use ::precompile_utils::evm::handle::PrecompileHandleExt; - handle.check_function_modifier(FunctionModifier::NonPayable)?; - Ok(Self::clear_metadata {}) - } - fn _parse_decimals( - handle: &mut impl PrecompileHandle, - ) -> ::precompile_utils::EvmResult { - use ::precompile_utils::solidity::revert::InjectBacktrace; - use ::precompile_utils::solidity::modifier::FunctionModifier; - use ::precompile_utils::evm::handle::PrecompileHandleExt; - handle.check_function_modifier(FunctionModifier::NonPayable)?; - Ok(Self::decimals {}) - } - fn _parse_eip2612_domain_separator( - handle: &mut impl PrecompileHandle, - ) -> ::precompile_utils::EvmResult { - use ::precompile_utils::solidity::revert::InjectBacktrace; - use ::precompile_utils::solidity::modifier::FunctionModifier; - use ::precompile_utils::evm::handle::PrecompileHandleExt; - handle.check_function_modifier(FunctionModifier::View)?; - Ok(Self::eip2612_domain_separator {}) - } - fn _parse_eip2612_nonces( - handle: &mut impl PrecompileHandle, - ) -> ::precompile_utils::EvmResult { - use ::precompile_utils::solidity::revert::InjectBacktrace; - use ::precompile_utils::solidity::modifier::FunctionModifier; - use ::precompile_utils::evm::handle::PrecompileHandleExt; - handle.check_function_modifier(FunctionModifier::View)?; - let mut input = handle.read_after_selector()?; - input.expect_arguments(1usize)?; - Ok(Self::eip2612_nonces { - owner: input.read().in_field("owner")?, - }) - } - fn _parse_eip2612_permit( - handle: &mut impl PrecompileHandle, - ) -> ::precompile_utils::EvmResult { - use ::precompile_utils::solidity::revert::InjectBacktrace; - use ::precompile_utils::solidity::modifier::FunctionModifier; - use ::precompile_utils::evm::handle::PrecompileHandleExt; - handle.check_function_modifier(FunctionModifier::NonPayable)?; - let mut input = handle.read_after_selector()?; - input.expect_arguments(7usize)?; - Ok(Self::eip2612_permit { - owner: input.read().in_field("owner")?, - spender: input.read().in_field("spender")?, - value: input.read().in_field("value")?, - deadline: input.read().in_field("deadline")?, - v: input.read().in_field("v")?, - r: input.read().in_field("r")?, - s: input.read().in_field("s")?, - }) - } - fn _parse_freeze( - handle: &mut impl PrecompileHandle, - ) -> ::precompile_utils::EvmResult { - use ::precompile_utils::solidity::revert::InjectBacktrace; - use ::precompile_utils::solidity::modifier::FunctionModifier; - use ::precompile_utils::evm::handle::PrecompileHandleExt; - handle.check_function_modifier(FunctionModifier::NonPayable)?; - let mut input = handle.read_after_selector()?; - input.expect_arguments(1usize)?; - Ok(Self::freeze { - account: input.read().in_field("account")?, - }) - } - fn _parse_freeze_asset( - handle: &mut impl PrecompileHandle, - ) -> ::precompile_utils::EvmResult { - use ::precompile_utils::solidity::revert::InjectBacktrace; - use ::precompile_utils::solidity::modifier::FunctionModifier; - use ::precompile_utils::evm::handle::PrecompileHandleExt; - handle.check_function_modifier(FunctionModifier::NonPayable)?; - Ok(Self::freeze_asset {}) - } - fn _parse_mint( - handle: &mut impl PrecompileHandle, - ) -> ::precompile_utils::EvmResult { - use ::precompile_utils::solidity::revert::InjectBacktrace; - use ::precompile_utils::solidity::modifier::FunctionModifier; - use ::precompile_utils::evm::handle::PrecompileHandleExt; - handle.check_function_modifier(FunctionModifier::NonPayable)?; - let mut input = handle.read_after_selector()?; - input.expect_arguments(2usize)?; - Ok(Self::mint { - to: input.read().in_field("to")?, - value: input.read().in_field("value")?, - }) - } - fn _parse_name( - handle: &mut impl PrecompileHandle, - ) -> ::precompile_utils::EvmResult { - use ::precompile_utils::solidity::revert::InjectBacktrace; - use ::precompile_utils::solidity::modifier::FunctionModifier; - use ::precompile_utils::evm::handle::PrecompileHandleExt; - handle.check_function_modifier(FunctionModifier::NonPayable)?; - Ok(Self::name {}) - } - fn _parse_set_metadata( - handle: &mut impl PrecompileHandle, - ) -> ::precompile_utils::EvmResult { - use ::precompile_utils::solidity::revert::InjectBacktrace; - use ::precompile_utils::solidity::modifier::FunctionModifier; - use ::precompile_utils::evm::handle::PrecompileHandleExt; - handle.check_function_modifier(FunctionModifier::NonPayable)?; - let mut input = handle.read_after_selector()?; - input.expect_arguments(3usize)?; - Ok(Self::set_metadata { - name: input.read().in_field("name")?, - symbol: input.read().in_field("symbol")?, - decimals: input.read().in_field("decimals")?, - }) - } - fn _parse_set_team( - handle: &mut impl PrecompileHandle, - ) -> ::precompile_utils::EvmResult { - use ::precompile_utils::solidity::revert::InjectBacktrace; - use ::precompile_utils::solidity::modifier::FunctionModifier; - use ::precompile_utils::evm::handle::PrecompileHandleExt; - handle.check_function_modifier(FunctionModifier::NonPayable)?; - let mut input = handle.read_after_selector()?; - input.expect_arguments(3usize)?; - Ok(Self::set_team { - issuer: input.read().in_field("issuer")?, - admin: input.read().in_field("admin")?, - freezer: input.read().in_field("freezer")?, - }) - } - fn _parse_symbol( - handle: &mut impl PrecompileHandle, - ) -> ::precompile_utils::EvmResult { - use ::precompile_utils::solidity::revert::InjectBacktrace; - use ::precompile_utils::solidity::modifier::FunctionModifier; - use ::precompile_utils::evm::handle::PrecompileHandleExt; - handle.check_function_modifier(FunctionModifier::NonPayable)?; - Ok(Self::symbol {}) - } - fn _parse_thaw( - handle: &mut impl PrecompileHandle, - ) -> ::precompile_utils::EvmResult { - use ::precompile_utils::solidity::revert::InjectBacktrace; - use ::precompile_utils::solidity::modifier::FunctionModifier; - use ::precompile_utils::evm::handle::PrecompileHandleExt; - handle.check_function_modifier(FunctionModifier::NonPayable)?; - let mut input = handle.read_after_selector()?; - input.expect_arguments(1usize)?; - Ok(Self::thaw { - account: input.read().in_field("account")?, - }) - } - fn _parse_thaw_asset( - handle: &mut impl PrecompileHandle, - ) -> ::precompile_utils::EvmResult { - use ::precompile_utils::solidity::revert::InjectBacktrace; - use ::precompile_utils::solidity::modifier::FunctionModifier; - use ::precompile_utils::evm::handle::PrecompileHandleExt; - handle.check_function_modifier(FunctionModifier::NonPayable)?; - Ok(Self::thaw_asset {}) - } - fn _parse_total_supply( - handle: &mut impl PrecompileHandle, - ) -> ::precompile_utils::EvmResult { - use ::precompile_utils::solidity::revert::InjectBacktrace; - use ::precompile_utils::solidity::modifier::FunctionModifier; - use ::precompile_utils::evm::handle::PrecompileHandleExt; - handle.check_function_modifier(FunctionModifier::NonPayable)?; - Ok(Self::total_supply {}) - } - fn _parse_transfer( - handle: &mut impl PrecompileHandle, - ) -> ::precompile_utils::EvmResult { - use ::precompile_utils::solidity::revert::InjectBacktrace; - use ::precompile_utils::solidity::modifier::FunctionModifier; - use ::precompile_utils::evm::handle::PrecompileHandleExt; - handle.check_function_modifier(FunctionModifier::NonPayable)?; - let mut input = handle.read_after_selector()?; - input.expect_arguments(2usize)?; - Ok(Self::transfer { - to: input.read().in_field("to")?, - value: input.read().in_field("value")?, - }) - } - fn _parse_transfer_from( - handle: &mut impl PrecompileHandle, - ) -> ::precompile_utils::EvmResult { - use ::precompile_utils::solidity::revert::InjectBacktrace; - use ::precompile_utils::solidity::modifier::FunctionModifier; - use ::precompile_utils::evm::handle::PrecompileHandleExt; - handle.check_function_modifier(FunctionModifier::NonPayable)?; - let mut input = handle.read_after_selector()?; - input.expect_arguments(3usize)?; - Ok(Self::transfer_from { - from: input.read().in_field("from")?, - to: input.read().in_field("to")?, - value: input.read().in_field("value")?, - }) - } - fn _parse_transfer_ownership( - handle: &mut impl PrecompileHandle, - ) -> ::precompile_utils::EvmResult { - use ::precompile_utils::solidity::revert::InjectBacktrace; - use ::precompile_utils::solidity::modifier::FunctionModifier; - use ::precompile_utils::evm::handle::PrecompileHandleExt; - handle.check_function_modifier(FunctionModifier::NonPayable)?; - let mut input = handle.read_after_selector()?; - input.expect_arguments(1usize)?; - Ok(Self::transfer_ownership { - owner: input.read().in_field("owner")?, - }) - } - pub fn execute( - self, - discriminant: Discriminant, - handle: &mut impl PrecompileHandle, - ) -> ::precompile_utils::EvmResult<::fp_evm::PrecompileOutput> { - use ::precompile_utils::solidity::codec::Writer; - use ::fp_evm::{PrecompileOutput, ExitSucceed}; - let output = match self { - Self::allowance { owner, spender } => { - let output = >::allowance(discriminant, handle, owner, spender); - ::precompile_utils::solidity::encode_return_value(output?) - } - Self::approve { spender, value } => { - let output = >::approve(discriminant, handle, spender, value); - ::precompile_utils::solidity::encode_return_value(output?) - } - Self::balance_of { who } => { - let output = >::balance_of(discriminant, handle, who); - ::precompile_utils::solidity::encode_return_value(output?) - } - Self::burn { from, value } => { - let output = >::burn(discriminant, handle, from, value); - ::precompile_utils::solidity::encode_return_value(output?) - } - Self::clear_metadata {} => { - let output = >::clear_metadata(discriminant, handle); - ::precompile_utils::solidity::encode_return_value(output?) - } - Self::decimals {} => { - let output = >::decimals(discriminant, handle); - ::precompile_utils::solidity::encode_return_value(output?) - } - Self::eip2612_domain_separator {} => { - let output = >::eip2612_domain_separator(discriminant, handle); - ::precompile_utils::solidity::encode_return_value(output?) - } - Self::eip2612_nonces { owner } => { - let output = >::eip2612_nonces(discriminant, handle, owner); - ::precompile_utils::solidity::encode_return_value(output?) - } - Self::eip2612_permit { owner, spender, value, deadline, v, r, s } => { - let output = >::eip2612_permit( - discriminant, - handle, - owner, - spender, - value, - deadline, - v, - r, - s, - ); - ::precompile_utils::solidity::encode_return_value(output?) - } - Self::freeze { account } => { - let output = >::freeze(discriminant, handle, account); - ::precompile_utils::solidity::encode_return_value(output?) - } - Self::freeze_asset {} => { - let output = >::freeze_asset(discriminant, handle); - ::precompile_utils::solidity::encode_return_value(output?) - } - Self::mint { to, value } => { - let output = >::mint(discriminant, handle, to, value); - ::precompile_utils::solidity::encode_return_value(output?) - } - Self::name {} => { - let output = >::name(discriminant, handle); - ::precompile_utils::solidity::encode_return_value(output?) - } - Self::set_metadata { name, symbol, decimals } => { - let output = >::set_metadata(discriminant, handle, name, symbol, decimals); - ::precompile_utils::solidity::encode_return_value(output?) - } - Self::set_team { issuer, admin, freezer } => { - let output = >::set_team(discriminant, handle, issuer, admin, freezer); - ::precompile_utils::solidity::encode_return_value(output?) - } - Self::symbol {} => { - let output = >::symbol(discriminant, handle); - ::precompile_utils::solidity::encode_return_value(output?) - } - Self::thaw { account } => { - let output = >::thaw(discriminant, handle, account); - ::precompile_utils::solidity::encode_return_value(output?) - } - Self::thaw_asset {} => { - let output = >::thaw_asset(discriminant, handle); - ::precompile_utils::solidity::encode_return_value(output?) - } - Self::total_supply {} => { - let output = >::total_supply(discriminant, handle); - ::precompile_utils::solidity::encode_return_value(output?) - } - Self::transfer { to, value } => { - let output = >::transfer(discriminant, handle, to, value); - ::precompile_utils::solidity::encode_return_value(output?) - } - Self::transfer_from { from, to, value } => { - let output = >::transfer_from(discriminant, handle, from, to, value); - ::precompile_utils::solidity::encode_return_value(output?) - } - Self::transfer_ownership { owner } => { - let output = >::transfer_ownership(discriminant, handle, owner); - ::precompile_utils::solidity::encode_return_value(output?) - } - Self::__phantom(_, _) => { - ::core::panicking::panic_fmt( - format_args!("__phantom variant should not be used"), - ) - } - }; - Ok(PrecompileOutput { - exit_status: ExitSucceed::Returned, - output, - }) - } - pub fn supports_selector(selector: u32) -> bool { - match selector { - 117300739u32 => true, - 157198259u32 => true, - 404098525u32 => true, - 484305945u32 => true, - 599290589u32 => true, - 826074471u32 => true, - 910484757u32 => true, - 936559348u32 => true, - 1086394137u32 => true, - 1374431959u32 => true, - 1587675670u32 => true, - 1804030401u32 => true, - 1889567281u32 => true, - 2127478272u32 => true, - 2367676207u32 => true, - 2514000705u32 => true, - 2646777772u32 => true, - 2835717307u32 => true, - 3352902745u32 => true, - 3552201630u32 => true, - 3566436177u32 => true, - 3573918927u32 => true, - 3714247998u32 => true, - 3999121892u32 => true, - 4021736498u32 => true, - 4030008324u32 => true, - 4076725131u32 => true, - 4173303445u32 => true, - _ => false, - } - } - pub fn selectors() -> &'static [u32] { - &[ - 117300739u32, - 157198259u32, - 404098525u32, - 484305945u32, - 599290589u32, - 826074471u32, - 910484757u32, - 936559348u32, - 1086394137u32, - 1374431959u32, - 1587675670u32, - 1804030401u32, - 1889567281u32, - 2127478272u32, - 2367676207u32, - 2514000705u32, - 2646777772u32, - 2835717307u32, - 3352902745u32, - 3552201630u32, - 3566436177u32, - 3573918927u32, - 3714247998u32, - 3999121892u32, - 4021736498u32, - 4030008324u32, - 4076725131u32, - 4173303445u32, - ] - } - pub fn allowance_selectors() -> &'static [u32] { - &[3714247998u32] - } - pub fn approve_selectors() -> &'static [u32] { - &[157198259u32] - } - pub fn balance_of_selectors() -> &'static [u32] { - &[1889567281u32] - } - pub fn burn_selectors() -> &'static [u32] { - &[2646777772u32] - } - pub fn clear_metadata_selectors() -> &'static [u32] { - &[4021736498u32, 3552201630u32] - } - pub fn decimals_selectors() -> &'static [u32] { - &[826074471u32] - } - pub fn eip2612_domain_separator_selectors() -> &'static [u32] { - &[910484757u32] - } - pub fn eip2612_nonces_selectors() -> &'static [u32] { - &[2127478272u32] - } - pub fn eip2612_permit_selectors() -> &'static [u32] { - &[3573918927u32] - } - pub fn freeze_selectors() -> &'static [u32] { - &[2367676207u32] - } - pub fn freeze_asset_selectors() -> &'static [u32] { - &[3566436177u32, 1804030401u32] - } - pub fn mint_selectors() -> &'static [u32] { - &[1086394137u32] - } - pub fn name_selectors() -> &'static [u32] { - &[117300739u32] - } - pub fn set_metadata_selectors() -> &'static [u32] { - &[936559348u32, 3999121892u32] - } - pub fn set_team_selectors() -> &'static [u32] { - &[3352902745u32, 4173303445u32] - } - pub fn symbol_selectors() -> &'static [u32] { - &[2514000705u32] - } - pub fn thaw_selectors() -> &'static [u32] { - &[1587675670u32] - } - pub fn thaw_asset_selectors() -> &'static [u32] { - &[1374431959u32, 484305945u32] - } - pub fn total_supply_selectors() -> &'static [u32] { - &[404098525u32] - } - pub fn transfer_selectors() -> &'static [u32] { - &[2835717307u32] - } - pub fn transfer_from_selectors() -> &'static [u32] { - &[599290589u32] - } - pub fn transfer_ownership_selectors() -> &'static [u32] { - &[4076725131u32, 4030008324u32] - } - pub fn encode(self) -> ::sp_std::vec::Vec { - use ::precompile_utils::solidity::codec::Writer; - match self { - Self::allowance { owner, spender } => { - Writer::new_with_selector(3714247998u32) - .write(owner) - .write(spender) - .build() - } - Self::approve { spender, value } => { - Writer::new_with_selector(157198259u32) - .write(spender) - .write(value) - .build() - } - Self::balance_of { who } => { - Writer::new_with_selector(1889567281u32).write(who).build() - } - Self::burn { from, value } => { - Writer::new_with_selector(2646777772u32).write(from).write(value).build() - } - Self::clear_metadata {} => Writer::new_with_selector(4021736498u32).build(), - Self::decimals {} => Writer::new_with_selector(826074471u32).build(), - Self::eip2612_domain_separator {} => { - Writer::new_with_selector(910484757u32).build() - } - Self::eip2612_nonces { owner } => { - Writer::new_with_selector(2127478272u32).write(owner).build() - } - Self::eip2612_permit { owner, spender, value, deadline, v, r, s } => { - Writer::new_with_selector(3573918927u32) - .write(owner) - .write(spender) - .write(value) - .write(deadline) - .write(v) - .write(r) - .write(s) - .build() - } - Self::freeze { account } => { - Writer::new_with_selector(2367676207u32).write(account).build() - } - Self::freeze_asset {} => Writer::new_with_selector(3566436177u32).build(), - Self::mint { to, value } => { - Writer::new_with_selector(1086394137u32).write(to).write(value).build() - } - Self::name {} => Writer::new_with_selector(117300739u32).build(), - Self::set_metadata { name, symbol, decimals } => { - Writer::new_with_selector(936559348u32) - .write(name) - .write(symbol) - .write(decimals) - .build() - } - Self::set_team { issuer, admin, freezer } => { - Writer::new_with_selector(3352902745u32) - .write(issuer) - .write(admin) - .write(freezer) - .build() - } - Self::symbol {} => Writer::new_with_selector(2514000705u32).build(), - Self::thaw { account } => { - Writer::new_with_selector(1587675670u32).write(account).build() - } - Self::thaw_asset {} => Writer::new_with_selector(1374431959u32).build(), - Self::total_supply {} => Writer::new_with_selector(404098525u32).build(), - Self::transfer { to, value } => { - Writer::new_with_selector(2835717307u32).write(to).write(value).build() - } - Self::transfer_from { from, to, value } => { - Writer::new_with_selector(599290589u32) - .write(from) - .write(to) - .write(value) - .build() - } - Self::transfer_ownership { owner } => { - Writer::new_with_selector(4076725131u32).write(owner).build() - } - Self::__phantom(_, _) => { - ::core::panicking::panic_fmt( - format_args!("__phantom variant should not be used"), - ) - } - } - } -} -impl From> for ::sp_std::vec::Vec -where - Runtime: Get, -{ - fn from(a: PrecompileSetCall) -> ::sp_std::vec::Vec { - a.encode() - } -} -impl ::fp_evm::PrecompileSet for PrecompileSet -where - Runtime: Get, -{ - fn execute( - &self, - handle: &mut impl PrecompileHandle, - ) -> Option<::precompile_utils::EvmResult<::fp_evm::PrecompileOutput>> { - let discriminant = match >::discriminant(handle.code_address()) { - Some(d) => d, - None => return None, - }; - Some( - >::parse_call_data(handle) - .and_then(|call| call.execute(discriminant, handle)), - ) - } - fn is_precompile(&self, address: H160, gas: u64) -> ::fp_evm::IsPrecompileResult { - >::discriminant(address, gas).is_some() - } -} -#[allow(non_snake_case)] -pub(crate) fn __PrecompileSet_test_solidity_signatures_inner() -where - Runtime: Get, -{ - use ::precompile_utils::solidity::Codec; - match (&"(address,address)", &<(Address, Address) as Codec>::signature()) { - (left_val, right_val) => { - if !(*left_val == *right_val) { - let kind = ::core::panicking::AssertKind::Eq; - ::core::panicking::assert_failed( - kind, - &*left_val, - &*right_val, - ::core::option::Option::Some( - format_args!( - "{0} function signature doesn\'t match (left: attribute, right: computed from Rust types)", - "allowance" - ), - ), - ); - } - } - }; - match (&"(address,uint256)", &<(Address, U256) as Codec>::signature()) { - (left_val, right_val) => { - if !(*left_val == *right_val) { - let kind = ::core::panicking::AssertKind::Eq; - ::core::panicking::assert_failed( - kind, - &*left_val, - &*right_val, - ::core::option::Option::Some( - format_args!( - "{0} function signature doesn\'t match (left: attribute, right: computed from Rust types)", - "approve" - ), - ), - ); - } - } - }; - match (&"(address)", &<(Address,) as Codec>::signature()) { - (left_val, right_val) => { - if !(*left_val == *right_val) { - let kind = ::core::panicking::AssertKind::Eq; - ::core::panicking::assert_failed( - kind, - &*left_val, - &*right_val, - ::core::option::Option::Some( - format_args!( - "{0} function signature doesn\'t match (left: attribute, right: computed from Rust types)", - "balance_of" - ), - ), - ); - } - } - }; - match (&"(address,uint256)", &<(Address, U256) as Codec>::signature()) { - (left_val, right_val) => { - if !(*left_val == *right_val) { - let kind = ::core::panicking::AssertKind::Eq; - ::core::panicking::assert_failed( - kind, - &*left_val, - &*right_val, - ::core::option::Option::Some( - format_args!( - "{0} function signature doesn\'t match (left: attribute, right: computed from Rust types)", - "burn" - ), - ), - ); - } - } - }; - match (&"()", &<() as Codec>::signature()) { - (left_val, right_val) => { - if !(*left_val == *right_val) { - let kind = ::core::panicking::AssertKind::Eq; - ::core::panicking::assert_failed( - kind, - &*left_val, - &*right_val, - ::core::option::Option::Some( - format_args!( - "{0} function signature doesn\'t match (left: attribute, right: computed from Rust types)", - "clear_metadata" - ), - ), - ); - } - } - }; - match (&"()", &<() as Codec>::signature()) { - (left_val, right_val) => { - if !(*left_val == *right_val) { - let kind = ::core::panicking::AssertKind::Eq; - ::core::panicking::assert_failed( - kind, - &*left_val, - &*right_val, - ::core::option::Option::Some( - format_args!( - "{0} function signature doesn\'t match (left: attribute, right: computed from Rust types)", - "decimals" - ), - ), - ); - } - } - }; - match (&"()", &<() as Codec>::signature()) { - (left_val, right_val) => { - if !(*left_val == *right_val) { - let kind = ::core::panicking::AssertKind::Eq; - ::core::panicking::assert_failed( - kind, - &*left_val, - &*right_val, - ::core::option::Option::Some( - format_args!( - "{0} function signature doesn\'t match (left: attribute, right: computed from Rust types)", - "eip2612_domain_separator" - ), - ), - ); - } - } - }; - match (&"(address)", &<(Address,) as Codec>::signature()) { - (left_val, right_val) => { - if !(*left_val == *right_val) { - let kind = ::core::panicking::AssertKind::Eq; - ::core::panicking::assert_failed( - kind, - &*left_val, - &*right_val, - ::core::option::Option::Some( - format_args!( - "{0} function signature doesn\'t match (left: attribute, right: computed from Rust types)", - "eip2612_nonces" - ), - ), - ); - } - } - }; - match ( - &"(address,address,uint256,uint256,uint8,bytes32,bytes32)", - &<(Address, Address, U256, U256, u8, H256, H256) as Codec>::signature(), - ) { - (left_val, right_val) => { - if !(*left_val == *right_val) { - let kind = ::core::panicking::AssertKind::Eq; - ::core::panicking::assert_failed( - kind, - &*left_val, - &*right_val, - ::core::option::Option::Some( - format_args!( - "{0} function signature doesn\'t match (left: attribute, right: computed from Rust types)", - "eip2612_permit" - ), - ), - ); - } - } - }; - match (&"(address)", &<(Address,) as Codec>::signature()) { - (left_val, right_val) => { - if !(*left_val == *right_val) { - let kind = ::core::panicking::AssertKind::Eq; - ::core::panicking::assert_failed( - kind, - &*left_val, - &*right_val, - ::core::option::Option::Some( - format_args!( - "{0} function signature doesn\'t match (left: attribute, right: computed from Rust types)", - "freeze" - ), - ), - ); - } - } - }; - match (&"()", &<() as Codec>::signature()) { - (left_val, right_val) => { - if !(*left_val == *right_val) { - let kind = ::core::panicking::AssertKind::Eq; - ::core::panicking::assert_failed( - kind, - &*left_val, - &*right_val, - ::core::option::Option::Some( - format_args!( - "{0} function signature doesn\'t match (left: attribute, right: computed from Rust types)", - "freeze_asset" - ), - ), - ); - } - } - }; - match (&"(address,uint256)", &<(Address, U256) as Codec>::signature()) { - (left_val, right_val) => { - if !(*left_val == *right_val) { - let kind = ::core::panicking::AssertKind::Eq; - ::core::panicking::assert_failed( - kind, - &*left_val, - &*right_val, - ::core::option::Option::Some( - format_args!( - "{0} function signature doesn\'t match (left: attribute, right: computed from Rust types)", - "mint" - ), - ), - ); - } - } - }; - match (&"()", &<() as Codec>::signature()) { - (left_val, right_val) => { - if !(*left_val == *right_val) { - let kind = ::core::panicking::AssertKind::Eq; - ::core::panicking::assert_failed( - kind, - &*left_val, - &*right_val, - ::core::option::Option::Some( - format_args!( - "{0} function signature doesn\'t match (left: attribute, right: computed from Rust types)", - "name" - ), - ), - ); - } - } - }; - match ( - &"(string,string,uint8)", - &<( - BoundedString>, - BoundedString>, - u8, - ) as Codec>::signature(), - ) { - (left_val, right_val) => { - if !(*left_val == *right_val) { - let kind = ::core::panicking::AssertKind::Eq; - ::core::panicking::assert_failed( - kind, - &*left_val, - &*right_val, - ::core::option::Option::Some( - format_args!( - "{0} function signature doesn\'t match (left: attribute, right: computed from Rust types)", - "set_metadata" - ), - ), - ); - } - } - }; - match ( - &"(address,address,address)", - &<(Address, Address, Address) as Codec>::signature(), - ) { - (left_val, right_val) => { - if !(*left_val == *right_val) { - let kind = ::core::panicking::AssertKind::Eq; - ::core::panicking::assert_failed( - kind, - &*left_val, - &*right_val, - ::core::option::Option::Some( - format_args!( - "{0} function signature doesn\'t match (left: attribute, right: computed from Rust types)", - "set_team" - ), - ), - ); - } - } - }; - match (&"()", &<() as Codec>::signature()) { - (left_val, right_val) => { - if !(*left_val == *right_val) { - let kind = ::core::panicking::AssertKind::Eq; - ::core::panicking::assert_failed( - kind, - &*left_val, - &*right_val, - ::core::option::Option::Some( - format_args!( - "{0} function signature doesn\'t match (left: attribute, right: computed from Rust types)", - "symbol" - ), - ), - ); - } - } - }; - match (&"(address)", &<(Address,) as Codec>::signature()) { - (left_val, right_val) => { - if !(*left_val == *right_val) { - let kind = ::core::panicking::AssertKind::Eq; - ::core::panicking::assert_failed( - kind, - &*left_val, - &*right_val, - ::core::option::Option::Some( - format_args!( - "{0} function signature doesn\'t match (left: attribute, right: computed from Rust types)", - "thaw" - ), - ), - ); - } - } - }; - match (&"()", &<() as Codec>::signature()) { - (left_val, right_val) => { - if !(*left_val == *right_val) { - let kind = ::core::panicking::AssertKind::Eq; - ::core::panicking::assert_failed( - kind, - &*left_val, - &*right_val, - ::core::option::Option::Some( - format_args!( - "{0} function signature doesn\'t match (left: attribute, right: computed from Rust types)", - "thaw_asset" - ), - ), - ); - } - } - }; - match (&"()", &<() as Codec>::signature()) { - (left_val, right_val) => { - if !(*left_val == *right_val) { - let kind = ::core::panicking::AssertKind::Eq; - ::core::panicking::assert_failed( - kind, - &*left_val, - &*right_val, - ::core::option::Option::Some( - format_args!( - "{0} function signature doesn\'t match (left: attribute, right: computed from Rust types)", - "total_supply" - ), - ), - ); - } - } - }; - match (&"(address,uint256)", &<(Address, U256) as Codec>::signature()) { - (left_val, right_val) => { - if !(*left_val == *right_val) { - let kind = ::core::panicking::AssertKind::Eq; - ::core::panicking::assert_failed( - kind, - &*left_val, - &*right_val, - ::core::option::Option::Some( - format_args!( - "{0} function signature doesn\'t match (left: attribute, right: computed from Rust types)", - "transfer" - ), - ), - ); - } - } - }; - match ( - &"(address,address,uint256)", - &<(Address, Address, U256) as Codec>::signature(), - ) { - (left_val, right_val) => { - if !(*left_val == *right_val) { - let kind = ::core::panicking::AssertKind::Eq; - ::core::panicking::assert_failed( - kind, - &*left_val, - &*right_val, - ::core::option::Option::Some( - format_args!( - "{0} function signature doesn\'t match (left: attribute, right: computed from Rust types)", - "transfer_from" - ), - ), - ); - } - } - }; - match (&"(address)", &<(Address,) as Codec>::signature()) { - (left_val, right_val) => { - if !(*left_val == *right_val) { - let kind = ::core::panicking::AssertKind::Eq; - ::core::panicking::assert_failed( - kind, - &*left_val, - &*right_val, - ::core::option::Option::Some( - format_args!( - "{0} function signature doesn\'t match (left: attribute, right: computed from Rust types)", - "transfer_ownership" - ), - ), - ); - } - } - }; -} diff --git a/precompiles/utils/macro/tests/expand/precompileset.rs b/precompiles/utils/macro/tests/expand/precompileset.rs deleted file mode 100644 index 8edb5edd81..0000000000 --- a/precompiles/utils/macro/tests/expand/precompileset.rs +++ /dev/null @@ -1,270 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -use { - core::marker::PhantomData, - precompile_utils::{EvmResult, prelude::*, testing::PrecompileTesterExt}, - sp_core::H160 -}; - -// Based on Erc20AssetsPrecompileSet with stripped code. - -struct PrecompileSet(PhantomData); - -type Discriminant = u32; -type GetAssetsStringLimit = R; -type MockRuntime = ConstU32<42>; - -#[precompile_utils_macro::precompile] -#[precompile::precompile_set] -#[precompile::test_concrete_types(MockRuntime)] -impl PrecompileSet -where - Runtime: Get -{ - /// PrecompileSet discrimiant. Allows to knows if the address maps to an asset id, - /// and if this is the case which one. - #[precompile::discriminant] - fn discriminant(address: H160) -> Option { - todo!("discriminant") - } - - #[precompile::public("totalSupply()")] - fn total_supply( - asset_id: Discriminant, - handle: &mut impl PrecompileHandle, - ) -> EvmResult { - todo!("total_supply") - } - - #[precompile::public("balanceOf(address)")] - fn balance_of( - asset_id: Discriminant, - handle: &mut impl PrecompileHandle, - who: Address, - ) -> EvmResult { - todo!("balance_of") - } - - #[precompile::public("allowance(address,address)")] - fn allowance( - asset_id: Discriminant, - handle: &mut impl PrecompileHandle, - owner: Address, - spender: Address, - ) -> EvmResult { - todo!("allowance") - } - - #[precompile::public("approve(address,uint256)")] - fn approve( - asset_id: Discriminant, - handle: &mut impl PrecompileHandle, - spender: Address, - value: U256, - ) -> EvmResult { - todo!("approve") - } - - fn approve_inner( - asset_id: Discriminant, - handle: &mut impl PrecompileHandle, - owner: H160, - spender: H160, - value: U256, - ) -> EvmResult { - todo!("approve_inner") - } - - #[precompile::public("transfer(address,uint256)")] - fn transfer( - asset_id: Discriminant, - handle: &mut impl PrecompileHandle, - to: Address, - value: U256, - ) -> EvmResult { - todo!("transfer") - } - - #[precompile::public("transferFrom(address,address,uint256)")] - fn transfer_from( - asset_id: Discriminant, - handle: &mut impl PrecompileHandle, - from: Address, - to: Address, - value: U256, - ) -> EvmResult { - todo!("transfer_from") - } - - #[precompile::public("name()")] - fn name( - asset_id: Discriminant, - handle: &mut impl PrecompileHandle, - ) -> EvmResult { - todo!("name") - } - - #[precompile::public("symbol()")] - fn symbol( - asset_id: Discriminant, - handle: &mut impl PrecompileHandle, - ) -> EvmResult { - todo!("symbol") - } - - #[precompile::public("decimals()")] - fn decimals( - asset_id: Discriminant, - handle: &mut impl PrecompileHandle, - ) -> EvmResult { - todo!("decimals") - } - - // From here: only for locals, we need to check whether we are in local assets otherwise fail - #[precompile::public("mint(address,uint256)")] - fn mint( - asset_id: Discriminant, - handle: &mut impl PrecompileHandle, - to: Address, - value: U256, - ) -> EvmResult { - todo!("mint") - } - - #[precompile::public("burn(address,uint256)")] - fn burn( - asset_id: Discriminant, - handle: &mut impl PrecompileHandle, - from: Address, - value: U256, - ) -> EvmResult { - todo!("burn") - } - - #[precompile::public("freeze(address)")] - fn freeze( - asset_id: Discriminant, - handle: &mut impl PrecompileHandle, - account: Address, - ) -> EvmResult { - todo!("freeze") - } - - #[precompile::public("thaw(address)")] - fn thaw( - asset_id: Discriminant, - handle: &mut impl PrecompileHandle, - account: Address, - ) -> EvmResult { - todo!("thaw") - } - - #[precompile::public("freezeAsset()")] - #[precompile::public("freeze_asset()")] - fn freeze_asset( - asset_id: Discriminant, - handle: &mut impl PrecompileHandle, - ) -> EvmResult { - todo!("freeze_asset") - } - - #[precompile::public("thawAsset()")] - #[precompile::public("thaw_asset()")] - fn thaw_asset( - asset_id: Discriminant, - handle: &mut impl PrecompileHandle, - ) -> EvmResult { - todo!("thaw_asset") - } - - #[precompile::public("transferOwnership(address)")] - #[precompile::public("transfer_ownership(address)")] - fn transfer_ownership( - asset_id: Discriminant, - handle: &mut impl PrecompileHandle, - owner: Address, - ) -> EvmResult { - todo!("transfer_ownership") - } - - #[precompile::public("setTeam(address,address,address)")] - #[precompile::public("set_team(address,address,address)")] - fn set_team( - asset_id: Discriminant, - handle: &mut impl PrecompileHandle, - issuer: Address, - admin: Address, - freezer: Address, - ) -> EvmResult { - todo!("set_team") - } - - #[precompile::public("setMetadata(string,string,uint8)")] - #[precompile::public("set_metadata(string,string,uint8)")] - fn set_metadata( - asset_id: Discriminant, - handle: &mut impl PrecompileHandle, - name: BoundedString>, - symbol: BoundedString>, - decimals: u8, - ) -> EvmResult { - todo!("set_metadata") - } - - #[precompile::public("clearMetadata()")] - #[precompile::public("clear_metadata()")] - fn clear_metadata( - asset_id: Discriminant, - handle: &mut impl PrecompileHandle, - ) -> EvmResult { - todo!("clear_metadata") - } - - #[precompile::public("permit(address,address,uint256,uint256,uint8,bytes32,bytes32)")] - fn eip2612_permit( - asset_id: Discriminant, - handle: &mut impl PrecompileHandle, - owner: Address, - spender: Address, - value: U256, - deadline: U256, - v: u8, - r: H256, - s: H256, - ) -> EvmResult { - todo!("eip2612_permit") - } - - #[precompile::public("nonces(address)")] - #[precompile::view] - fn eip2612_nonces( - asset_id: Discriminant, - handle: &mut impl PrecompileHandle, - owner: Address, - ) -> EvmResult { - todo!("eip2612_nonces") - } - - #[precompile::public("DOMAIN_SEPARATOR()")] - #[precompile::view] - fn eip2612_domain_separator( - asset_id: Discriminant, - handle: &mut impl PrecompileHandle, - ) -> EvmResult { - todo!("eip2612_domain_separator") - } -} \ No newline at end of file diff --git a/precompiles/utils/macro/tests/expand/returns_tuple.expanded.rs b/precompiles/utils/macro/tests/expand/returns_tuple.expanded.rs deleted file mode 100644 index 1f4f46425e..0000000000 --- a/precompiles/utils/macro/tests/expand/returns_tuple.expanded.rs +++ /dev/null @@ -1,128 +0,0 @@ -use { - precompile_utils::{EvmResult, prelude::*}, - sp_core::{H160, U256}, -}; -struct ExamplePrecompile; -impl ExamplePrecompile { - fn example( - handle: &mut impl PrecompileHandle, - ) -> EvmResult<(Address, U256, UnboundedBytes)> { - ::core::panicking::panic_fmt( - format_args!("not yet implemented: {0}", format_args!("example")), - ) - } -} -#[allow(non_camel_case_types)] -pub enum ExamplePrecompileCall { - example {}, - #[doc(hidden)] - __phantom(::core::marker::PhantomData<()>, ::core::convert::Infallible), -} -impl ExamplePrecompileCall { - pub fn parse_call_data( - handle: &mut impl PrecompileHandle, - ) -> ::precompile_utils::EvmResult { - use ::precompile_utils::solidity::revert::RevertReason; - let input = handle.input(); - let selector = input - .get(0..4) - .map(|s| { - let mut buffer = [0u8; 4]; - buffer.copy_from_slice(s); - u32::from_be_bytes(buffer) - }); - match selector { - Some(1412775727u32) => Self::_parse_example(handle), - Some(_) => Err(RevertReason::UnknownSelector.into()), - None => Err(RevertReason::read_out_of_bounds("selector").into()), - } - } - fn _parse_example( - handle: &mut impl PrecompileHandle, - ) -> ::precompile_utils::EvmResult { - use ::precompile_utils::solidity::revert::InjectBacktrace; - use ::precompile_utils::solidity::modifier::FunctionModifier; - use ::precompile_utils::evm::handle::PrecompileHandleExt; - handle.check_function_modifier(FunctionModifier::NonPayable)?; - Ok(Self::example {}) - } - pub fn execute( - self, - handle: &mut impl PrecompileHandle, - ) -> ::precompile_utils::EvmResult<::fp_evm::PrecompileOutput> { - use ::precompile_utils::solidity::codec::Writer; - use ::fp_evm::{PrecompileOutput, ExitSucceed}; - let output = match self { - Self::example {} => { - let output = ::example(handle); - ::precompile_utils::solidity::encode_return_value(output?) - } - Self::__phantom(_, _) => { - ::core::panicking::panic_fmt( - format_args!("__phantom variant should not be used"), - ) - } - }; - Ok(PrecompileOutput { - exit_status: ExitSucceed::Returned, - output, - }) - } - pub fn supports_selector(selector: u32) -> bool { - match selector { - 1412775727u32 => true, - _ => false, - } - } - pub fn selectors() -> &'static [u32] { - &[1412775727u32] - } - pub fn example_selectors() -> &'static [u32] { - &[1412775727u32] - } - pub fn encode(self) -> ::sp_std::vec::Vec { - use ::precompile_utils::solidity::codec::Writer; - match self { - Self::example {} => Writer::new_with_selector(1412775727u32).build(), - Self::__phantom(_, _) => { - ::core::panicking::panic_fmt( - format_args!("__phantom variant should not be used"), - ) - } - } - } -} -impl From for ::sp_std::vec::Vec { - fn from(a: ExamplePrecompileCall) -> ::sp_std::vec::Vec { - a.encode() - } -} -impl ::fp_evm::Precompile for ExamplePrecompile { - fn execute( - handle: &mut impl PrecompileHandle, - ) -> ::precompile_utils::EvmResult<::fp_evm::PrecompileOutput> { - ::parse_call_data(handle)?.execute(handle) - } -} -#[allow(non_snake_case)] -pub(crate) fn __ExamplePrecompile_test_solidity_signatures_inner() { - use ::precompile_utils::solidity::Codec; - match (&"()", &<() as Codec>::signature()) { - (left_val, right_val) => { - if !(*left_val == *right_val) { - let kind = ::core::panicking::AssertKind::Eq; - ::core::panicking::assert_failed( - kind, - &*left_val, - &*right_val, - ::core::option::Option::Some( - format_args!( - "{0} function signature doesn\'t match (left: attribute, right: computed from Rust types)", - "example" - ), - ), - ); - } - } - }; -} diff --git a/precompiles/utils/macro/tests/expand/returns_tuple.rs b/precompiles/utils/macro/tests/expand/returns_tuple.rs deleted file mode 100644 index b87fe1220f..0000000000 --- a/precompiles/utils/macro/tests/expand/returns_tuple.rs +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -use { - precompile_utils::{EvmResult, prelude::*}, - sp_core::{H160, U256}, -}; - -struct ExamplePrecompile; - -#[precompile_utils_macro::precompile] -impl ExamplePrecompile -{ - #[precompile::public("example()")] - fn example( - handle: &mut impl PrecompileHandle, - ) -> EvmResult<(Address, U256, UnboundedBytes)> { - todo!("example") - } -} \ No newline at end of file diff --git a/precompiles/utils/macro/tests/pass/derive_codec.rs b/precompiles/utils/macro/tests/pass/derive_codec.rs deleted file mode 100644 index c23f5611da..0000000000 --- a/precompiles/utils/macro/tests/pass/derive_codec.rs +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -use precompile_utils::solidity::codec::{Address, Codec, Reader, Writer}; -use sp_core::H160; - -#[derive(Debug, Clone, PartialEq, Eq, Codec)] -struct StaticSize { - id: u32, - address: Address, -} - -#[derive(Debug, Clone, PartialEq, Eq, Codec)] -struct DynamicSize { - id: u32, - array: Vec, -} - -fn main() { - // static - let static_size = StaticSize { - id: 5, - address: H160::repeat_byte(0x42).into(), - }; - - assert!(StaticSize::has_static_size()); - assert_eq!(&StaticSize::signature(), "(uint32,address)"); - - let bytes = Writer::new().write(static_size.clone()).build(); - assert_eq!( - bytes, - Writer::new() - .write(5u32) - .write(Address::from(H160::repeat_byte(0x42))) - .build() - ); - - let mut reader = Reader::new(&bytes); - let static_size_2: StaticSize = reader.read().expect("to decode properly"); - assert_eq!(static_size_2, static_size); - - // dynamic - let dynamic_size = DynamicSize { - id: 6, - array: vec![10u32, 15u32], - }; - assert!(!DynamicSize::::has_static_size()); - assert_eq!(DynamicSize::::signature(), "(uint32,uint32[])"); - - let bytes = Writer::new().write(dynamic_size.clone()).build(); - assert_eq!( - bytes, - Writer::new() - .write(0x20u32) // offset of struct - .write(6u32) // id - .write(0x40u32) // array offset - .write(2u32) // array size - .write(10u32) // array[0] - .write(15u32) // array[1] - .build() - ); - - let mut reader = Reader::new(&bytes); - let dynamic_size_2: DynamicSize = reader.read().expect("to decode properly"); - assert_eq!(dynamic_size_2, dynamic_size); -} diff --git a/precompiles/utils/macro/tests/pass/precompile_fn_modifiers.rs b/precompiles/utils/macro/tests/pass/precompile_fn_modifiers.rs deleted file mode 100644 index 7437a11ea9..0000000000 --- a/precompiles/utils/macro/tests/pass/precompile_fn_modifiers.rs +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -use { - precompile_utils::{EvmResult, prelude::*, testing::PrecompileTesterExt}, - sp_core::H160 -}; - -pub struct PrecompileSet; - -#[precompile_utils_macro::precompile] -#[precompile::precompile_set] -impl PrecompileSet { - #[precompile::discriminant] - fn discriminant(_: H160) -> Option<()> { - Some(()) - } - - #[precompile::public("default()")] - fn default(_: (), _: &mut impl PrecompileHandle) -> EvmResult { - Ok(()) - } - - #[precompile::public("view()")] - #[precompile::view] - fn view(_: (), _: &mut impl PrecompileHandle) -> EvmResult { - Ok(()) - } - - #[precompile::public("payable()")] - #[precompile::payable] - fn payable(_: (), _: &mut impl PrecompileHandle) -> EvmResult { - Ok(()) - } -} - -fn main() { - PrecompileSet.prepare_test( - [0u8;20], - [0u8;20], - PrecompileSetCall::default {} - ).with_value(1) - .execute_reverts(|output| output == b"Function is not payable"); - - PrecompileSet.prepare_test( - [0u8;20], - [0u8;20], - PrecompileSetCall::default {} - ).with_static_call(true) - .execute_reverts(|output| output == b"Can't call non-static function in static context"); - - PrecompileSet.prepare_test( - [0u8;20], - [0u8;20], - PrecompileSetCall::view {} - ).with_value(1) - .execute_reverts(|output| output == b"Function is not payable"); - - PrecompileSet.prepare_test( - [0u8;20], - [0u8;20], - PrecompileSetCall::view {} - ).with_static_call(true) - .execute_returns(()); - - PrecompileSet.prepare_test( - [0u8;20], - [0u8;20], - PrecompileSetCall::payable {} - ).with_value(1) - .execute_returns(()); - - PrecompileSet.prepare_test( - [0u8;20], - [0u8;20], - PrecompileSetCall::payable {} - ).with_static_call(true) - .execute_reverts(|output| output == b"Can't call non-static function in static context"); -} \ No newline at end of file diff --git a/precompiles/utils/macro/tests/tests.rs b/precompiles/utils/macro/tests/tests.rs deleted file mode 100644 index b392fd027f..0000000000 --- a/precompiles/utils/macro/tests/tests.rs +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -use sha3::{Digest, Keccak256}; - -#[test] -fn test_keccak256() { - assert_eq!( - &precompile_utils_macro::keccak256!(""), - Keccak256::digest(b"").as_slice(), - ); - assert_eq!( - &precompile_utils_macro::keccak256!("toto()"), - Keccak256::digest(b"toto()").as_slice(), - ); - assert_ne!( - &precompile_utils_macro::keccak256!("toto()"), - Keccak256::digest(b"tata()").as_slice(), - ); -} - -#[test] -#[ignore] -fn ui() { - let t = trybuild::TestCases::new(); - t.compile_fail("tests/compile-fail/**/*.rs"); - t.pass("tests/pass/**/*.rs"); -} - -// Cargo expand is not supported on stable rust -#[test] -#[ignore] -fn expand() { - // Use `expand` to update the expansions - // Replace it with `expand_without_refresh` afterward so that - // CI checks the expension don't change - - // macrotest::expand("tests/expand/**/*.rs"); - macrotest::expand_without_refresh("tests/expand/**/*.rs"); -} diff --git a/precompiles/utils/src/evm/costs.rs b/precompiles/utils/src/evm/costs.rs deleted file mode 100644 index 5f2abd2541..0000000000 --- a/precompiles/utils/src/evm/costs.rs +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -//! Cost calculations. -//! TODO: PR EVM to make those cost calculations public. - -use { - crate::EvmResult, - fp_evm::{ExitError, PrecompileFailure}, - sp_core::U256, -}; - -pub fn log_costs(topics: usize, data_len: usize) -> EvmResult { - // Cost calculation is copied from EVM code that is not publicly exposed by the crates. - // https://github.com/rust-blockchain/evm/blob/master/gasometer/src/costs.rs#L148 - - const G_LOG: u64 = 375; - const G_LOGDATA: u64 = 8; - const G_LOGTOPIC: u64 = 375; - - let topic_cost = G_LOGTOPIC - .checked_mul(topics as u64) - .ok_or(PrecompileFailure::Error { - exit_status: ExitError::OutOfGas, - })?; - - let data_cost = G_LOGDATA - .checked_mul(data_len as u64) - .ok_or(PrecompileFailure::Error { - exit_status: ExitError::OutOfGas, - })?; - - G_LOG - .checked_add(topic_cost) - .ok_or(PrecompileFailure::Error { - exit_status: ExitError::OutOfGas, - })? - .checked_add(data_cost) - .ok_or(PrecompileFailure::Error { - exit_status: ExitError::OutOfGas, - }) -} - -// Compute the cost of doing a subcall. -// Some parameters cannot be known in advance, so we estimate the worst possible cost. -pub fn call_cost(value: U256, config: &evm::Config) -> u64 { - // Copied from EVM code since not public. - pub const G_CALLVALUE: u64 = 9000; - pub const G_NEWACCOUNT: u64 = 25000; - - fn address_access_cost(is_cold: bool, regular_value: u64, config: &evm::Config) -> u64 { - if config.increase_state_access_gas { - if is_cold { - config.gas_account_access_cold - } else { - config.gas_storage_read_warm - } - } else { - regular_value - } - } - - fn xfer_cost(is_call_or_callcode: bool, transfers_value: bool) -> u64 { - if is_call_or_callcode && transfers_value { - G_CALLVALUE - } else { - 0 - } - } - - fn new_cost( - is_call_or_staticcall: bool, - new_account: bool, - transfers_value: bool, - config: &evm::Config, - ) -> u64 { - let eip161 = !config.empty_considered_exists; - if is_call_or_staticcall { - if eip161 { - if transfers_value && new_account { - G_NEWACCOUNT - } else { - 0 - } - } else if new_account { - G_NEWACCOUNT - } else { - 0 - } - } else { - 0 - } - } - - let transfers_value = value != U256::default(); - let is_cold = true; - let is_call_or_callcode = true; - let is_call_or_staticcall = true; - let new_account = true; - - address_access_cost(is_cold, config.gas_call, config) - + xfer_cost(is_call_or_callcode, transfers_value) - + new_cost(is_call_or_staticcall, new_account, transfers_value, config) -} diff --git a/precompiles/utils/src/evm/handle.rs b/precompiles/utils/src/evm/handle.rs deleted file mode 100644 index 2ae7c77282..0000000000 --- a/precompiles/utils/src/evm/handle.rs +++ /dev/null @@ -1,227 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -use { - crate::{ - solidity::{ - codec::Reader, - modifier::FunctionModifier, - revert::{MayRevert, RevertReason}, - }, - EvmResult, - }, - fp_evm::{Log, PrecompileHandle}, -}; - -pub trait PrecompileHandleExt: PrecompileHandle { - /// Record cost of one DB read manually. - /// The max encoded lenght of the data that will be read should be provided. - #[must_use] - fn record_db_read( - &mut self, - data_max_encoded_len: usize, - ) -> Result<(), evm::ExitError>; - - /// Record cost of a log manually. - /// This can be useful to record log costs early when their content have static size. - #[must_use] - fn record_log_costs_manual(&mut self, topics: usize, data_len: usize) -> EvmResult; - - /// Record cost of logs. - #[must_use] - fn record_log_costs(&mut self, logs: &[&Log]) -> EvmResult; - - #[must_use] - /// Check that a function call is compatible with the context it is - /// called into. - fn check_function_modifier(&self, modifier: FunctionModifier) -> MayRevert; - - #[must_use] - /// Read the selector from the input data. - fn read_u32_selector(&self) -> MayRevert; - - #[must_use] - /// Returns a reader of the input, skipping the selector. - fn read_after_selector(&self) -> MayRevert; -} - -impl PrecompileHandleExt for T { - #[must_use] - fn record_db_read( - &mut self, - data_max_encoded_len: usize, - ) -> Result<(), evm::ExitError> { - self.record_cost(crate::prelude::RuntimeHelper::::db_read_gas_cost())?; - // TODO: record ref time when precompile will be benchmarked - self.record_external_cost(None, Some(data_max_encoded_len as u64)) - } - - /// Record cost of a log manualy. - /// This can be useful to record log costs early when their content have static size. - #[must_use] - fn record_log_costs_manual(&mut self, topics: usize, data_len: usize) -> EvmResult { - self.record_cost(crate::evm::costs::log_costs(topics, data_len)?)?; - - Ok(()) - } - - /// Record cost of logs. - #[must_use] - fn record_log_costs(&mut self, logs: &[&Log]) -> EvmResult { - for log in logs { - self.record_log_costs_manual(log.topics.len(), log.data.len())?; - } - - Ok(()) - } - - #[must_use] - /// Check that a function call is compatible with the context it is - /// called into. - fn check_function_modifier(&self, modifier: FunctionModifier) -> MayRevert { - crate::solidity::modifier::check_function_modifier( - self.context(), - self.is_static(), - modifier, - ) - } - - #[must_use] - /// Read the selector from the input data as u32. - fn read_u32_selector(&self) -> MayRevert { - crate::solidity::codec::selector(self.input()) - .ok_or(RevertReason::read_out_of_bounds("selector").into()) - } - - #[must_use] - /// Returns a reader of the input, skipping the selector. - fn read_after_selector(&self) -> MayRevert { - Reader::new_skip_selector(self.input()) - } -} - -environmental::environmental!(EVM_CONTEXT: trait PrecompileHandle); - -pub fn using_precompile_handle<'a, R, F: FnOnce() -> R>( - precompile_handle: &'a mut dyn PrecompileHandle, - mutator: F, -) -> R { - // # Safety - // - // unsafe rust does not mean unsafe, but "the compiler cannot guarantee the safety of the - // memory". - // - // The only risk here is that the lifetime 'a comes to its end while the global variable - // `EVM_CONTEXT` still contains the reference to the precompile handle. - // The `using` method guarantee that it can't happen because the global variable is freed right - // after the execution of the `mutator` closure (whatever the result of the execution). - unsafe { - EVM_CONTEXT::using( - core::mem::transmute::<&'a mut dyn PrecompileHandle, &'static mut dyn PrecompileHandle>( - precompile_handle, - ), - mutator, - ) - } -} - -pub fn with_precompile_handle R>(f: F) -> Option { - EVM_CONTEXT::with(|precompile_handle| f(precompile_handle)) -} - -#[cfg(test)] -mod tests { - use super::*; - - struct MockPrecompileHandle; - impl PrecompileHandle for MockPrecompileHandle { - fn call( - &mut self, - _: sp_core::H160, - _: Option, - _: Vec, - _: Option, - _: bool, - _: &evm::Context, - ) -> (evm::ExitReason, Vec) { - unimplemented!() - } - - fn record_cost(&mut self, _: u64) -> Result<(), evm::ExitError> { - unimplemented!() - } - - fn remaining_gas(&self) -> u64 { - unimplemented!() - } - - fn log( - &mut self, - _: sp_core::H160, - _: Vec, - _: Vec, - ) -> Result<(), evm::ExitError> { - unimplemented!() - } - - fn code_address(&self) -> sp_core::H160 { - unimplemented!() - } - - fn input(&self) -> &[u8] { - unimplemented!() - } - - fn context(&self) -> &evm::Context { - unimplemented!() - } - - fn is_static(&self) -> bool { - true - } - - fn gas_limit(&self) -> Option { - unimplemented!() - } - - fn record_external_cost( - &mut self, - _ref_time: Option, - _proof_size: Option, - ) -> Result<(), fp_evm::ExitError> { - Ok(()) - } - - fn refund_external_cost(&mut self, _ref_time: Option, _proof_size: Option) {} - } - - #[test] - fn with_precompile_handle_without_context() { - assert_eq!(with_precompile_handle(|_| {}), None); - } - - #[test] - fn with_precompile_handle_with_context() { - let mut precompile_handle = MockPrecompileHandle; - - assert_eq!( - using_precompile_handle(&mut precompile_handle, || with_precompile_handle( - |handle| handle.is_static() - )), - Some(true) - ); - } -} diff --git a/precompiles/utils/src/evm/logs.rs b/precompiles/utils/src/evm/logs.rs deleted file mode 100644 index 2dde6ff126..0000000000 --- a/precompiles/utils/src/evm/logs.rs +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -use { - crate::EvmResult, - pallet_evm::{Log, PrecompileHandle}, - sp_core::{H160, H256}, - sp_std::{vec, vec::Vec}, -}; - -/// Create a 0-topic log. -#[must_use] -pub fn log0(address: impl Into, data: impl Into>) -> Log { - Log { - address: address.into(), - topics: vec![], - data: data.into(), - } -} - -/// Create a 1-topic log. -#[must_use] -pub fn log1(address: impl Into, topic0: impl Into, data: impl Into>) -> Log { - Log { - address: address.into(), - topics: vec![topic0.into()], - data: data.into(), - } -} - -/// Create a 2-topics log. -#[must_use] -pub fn log2( - address: impl Into, - topic0: impl Into, - topic1: impl Into, - data: impl Into>, -) -> Log { - Log { - address: address.into(), - topics: vec![topic0.into(), topic1.into()], - data: data.into(), - } -} - -/// Create a 3-topics log. -#[must_use] -pub fn log3( - address: impl Into, - topic0: impl Into, - topic1: impl Into, - topic2: impl Into, - data: impl Into>, -) -> Log { - Log { - address: address.into(), - topics: vec![topic0.into(), topic1.into(), topic2.into()], - data: data.into(), - } -} - -/// Create a 4-topics log. -#[must_use] -pub fn log4( - address: impl Into, - topic0: impl Into, - topic1: impl Into, - topic2: impl Into, - topic3: impl Into, - data: impl Into>, -) -> Log { - Log { - address: address.into(), - topics: vec![topic0.into(), topic1.into(), topic2.into(), topic3.into()], - data: data.into(), - } -} - -/// Extension trait allowing to record logs into a PrecompileHandle. -pub trait LogExt { - fn record(self, handle: &mut impl PrecompileHandle) -> EvmResult; - - fn compute_cost(&self) -> EvmResult; -} - -impl LogExt for Log { - fn record(self, handle: &mut impl PrecompileHandle) -> EvmResult { - handle.log(self.address, self.topics, self.data)?; - Ok(()) - } - - fn compute_cost(&self) -> EvmResult { - crate::evm::costs::log_costs(self.topics.len(), self.data.len()) - } -} diff --git a/precompiles/utils/src/evm/mod.rs b/precompiles/utils/src/evm/mod.rs deleted file mode 100644 index 6b4cc27f82..0000000000 --- a/precompiles/utils/src/evm/mod.rs +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2019-2023 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -pub mod costs; -pub mod handle; -pub mod logs; diff --git a/precompiles/utils/src/lib.rs b/precompiles/utils/src/lib.rs deleted file mode 100644 index 7c84765450..0000000000 --- a/precompiles/utils/src/lib.rs +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -#![cfg_attr(not(feature = "std"), no_std)] - -extern crate alloc; - -// Allows to use inside this crate `solidity::Codec` derive macro,which depends on -// `precompile_utils` being in the list of imported crates. -extern crate self as precompile_utils; - -pub mod evm; -pub mod precompile_set; -pub mod substrate; - -pub mod solidity; - -#[cfg(feature = "testing")] -pub mod testing; - -#[cfg(test)] -mod tests; - -use fp_evm::PrecompileFailure; - -// pub mod data; - -// pub use data::{solidity::Codec, Reader, Writer}; -pub use fp_evm::Precompile; -pub use precompile_utils_macro::{keccak256, precompile, precompile_name_from_address}; - -/// Alias for Result returning an EVM precompile error. -pub type EvmResult = Result; - -pub mod prelude { - pub use { - crate::{ - evm::{ - handle::PrecompileHandleExt, - logs::{log0, log1, log2, log3, log4, LogExt}, - }, - precompile_set::DiscriminantResult, - solidity::{ - // We export solidity itself to encourage using `solidity::Codec` to avoid confusion - // with parity_scale_codec, - self, - codec::{ - Address, - BoundedBytes, - BoundedString, - BoundedVec, - // Allow usage of Codec methods while not exporting the name directly. - Codec as _, - Convert, - UnboundedBytes, - UnboundedString, - }, - revert::{ - revert, BacktraceExt, InjectBacktrace, MayRevert, Revert, RevertExt, - RevertReason, - }, - }, - substrate::{RuntimeHelper, TryDispatchError}, - EvmResult, - }, - alloc::string::String, - pallet_evm::{PrecompileHandle, PrecompileOutput}, - precompile_utils_macro::{keccak256, precompile}, - }; -} diff --git a/precompiles/utils/src/precompile_set.rs b/precompiles/utils/src/precompile_set.rs deleted file mode 100644 index 8be669151e..0000000000 --- a/precompiles/utils/src/precompile_set.rs +++ /dev/null @@ -1,1100 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -//! Provide utils to assemble precompiles and precompilesets into a -//! final precompile set with security checks. All security checks are enabled by -//! default and must be disabled explicely throught type annotations. - -use crate::{ - evm::handle::PrecompileHandleExt, - solidity::{codec::String, revert::revert}, - EvmResult, -}; -use fp_evm::{ - ExitError, IsPrecompileResult, Precompile, PrecompileFailure, PrecompileHandle, - PrecompileResult, PrecompileSet, -}; -use frame_support::pallet_prelude::Get; -use impl_trait_for_tuples::impl_for_tuples; -use pallet_evm::AddressMapping; -use sp_core::{H160, H256}; -use sp_std::{ - cell::RefCell, collections::btree_map::BTreeMap, marker::PhantomData, ops::RangeInclusive, vec, - vec::Vec, -}; - -/// Trait representing checks that can be made on a precompile call. -/// Types implementing this trait are made to be chained in a tuple. -/// -/// For that reason every method returns an Option, None meaning that -/// the implementor have no constraint and the decision is left to -/// latter elements in the chain. If None is returned by all elements of -/// the chain then sensible defaults are used. -/// -/// Both `PrecompileAt` and `PrecompileSetStartingWith` have a type parameter that must -/// implement this trait to configure the checks of the precompile(set) it represents. -pub trait PrecompileChecks { - #[inline(always)] - /// Is there a limit to the amount of recursions this precompile - /// can make using subcalls? 0 means this specific precompile will not - /// be callable as a subcall of itself, 1 will allow one level of recursion, - /// etc... - /// - /// If all checks return None, defaults to `Some(0)` (no recursion allowed). - fn recursion_limit() -> Option> { - None - } - - #[inline(always)] - /// Does this precompile supports being called with DELEGATECALL or CALLCODE? - /// - /// If all checks return None, defaults to `false`. - fn accept_delegate_call() -> Option { - None - } - - #[inline(always)] - /// Is this precompile callable by a smart contract? - /// - /// If all checks return None, defaults to `false`. - fn callable_by_smart_contract(_caller: H160, _called_selector: Option) -> Option { - None - } - - #[inline(always)] - /// Is this precompile callable by a precompile? - /// - /// If all checks return None, defaults to `false`. - fn callable_by_precompile(_caller: H160, _called_selector: Option) -> Option { - None - } - - #[inline(always)] - /// Is this precompile able to do subcalls? - /// - /// If all checks return None, defaults to `false`. - fn allow_subcalls() -> Option { - None - } - - /// Summarize the checks when being called by a smart contract. - fn callable_by_smart_contract_summary() -> Option { - None - } - - /// Summarize the checks when being called by a precompile. - fn callable_by_precompile_summary() -> Option { - None - } -} - -#[derive(Debug, Clone)] -pub enum DiscriminantResult { - Some(T, u64), - None(u64), - OutOfGas, -} - -impl Into for DiscriminantResult { - fn into(self) -> IsPrecompileResult { - match self { - Self::Some(_, extra_cost) => IsPrecompileResult::Answer { - is_precompile: true, - extra_cost, - }, - Self::None(extra_cost) => IsPrecompileResult::Answer { - is_precompile: false, - extra_cost, - }, - Self::OutOfGas => IsPrecompileResult::OutOfGas, - } - } -} - -#[derive(Debug, Clone)] -#[cfg_attr(feature = "testing", derive(serde::Serialize, serde::Deserialize))] -pub enum PrecompileKind { - Single(H160), - Prefixed(Vec), -} - -#[derive(Debug, Clone)] -#[cfg_attr(feature = "testing", derive(serde::Serialize, serde::Deserialize))] -pub struct PrecompileCheckSummary { - pub name: Option, - pub precompile_kind: PrecompileKind, - pub recursion_limit: Option, - pub accept_delegate_call: bool, - pub callable_by_smart_contract: String, - pub callable_by_precompile: String, -} - -#[impl_for_tuples(0, 20)] -impl PrecompileChecks for Tuple { - #[inline(always)] - fn recursion_limit() -> Option> { - for_tuples!(#( - if let Some(check) = Tuple::recursion_limit() { - return Some(check); - } - )*); - - None - } - - #[inline(always)] - fn accept_delegate_call() -> Option { - for_tuples!(#( - if let Some(check) = Tuple::accept_delegate_call() { - return Some(check); - } - )*); - - None - } - - #[inline(always)] - fn callable_by_smart_contract(caller: H160, called_selector: Option) -> Option { - for_tuples!(#( - if let Some(check) = Tuple::callable_by_smart_contract(caller, called_selector) { - return Some(check); - } - )*); - - None - } - - #[inline(always)] - fn callable_by_precompile(caller: H160, called_selector: Option) -> Option { - for_tuples!(#( - if let Some(check) = Tuple::callable_by_precompile(caller, called_selector) { - return Some(check); - } - )*); - - None - } - - #[inline(always)] - fn allow_subcalls() -> Option { - for_tuples!(#( - if let Some(check) = Tuple::allow_subcalls() { - return Some(check); - } - )*); - - None - } - - fn callable_by_smart_contract_summary() -> Option { - for_tuples!(#( - if let Some(check) = Tuple::callable_by_smart_contract_summary() { - return Some(check); - } - )*); - - None - } - - fn callable_by_precompile_summary() -> Option { - for_tuples!(#( - if let Some(check) = Tuple::callable_by_precompile_summary() { - return Some(check); - } - )*); - - None - } -} - -/// Precompile can be called using DELEGATECALL/CALLCODE. -pub struct AcceptDelegateCall; - -impl PrecompileChecks for AcceptDelegateCall { - #[inline(always)] - fn accept_delegate_call() -> Option { - Some(true) - } -} - -/// Precompile is able to do subcalls with provided nesting limit. -pub struct SubcallWithMaxNesting; - -impl PrecompileChecks for SubcallWithMaxNesting { - #[inline(always)] - fn recursion_limit() -> Option> { - Some(Some(R)) - } - - #[inline(always)] - fn allow_subcalls() -> Option { - Some(true) - } -} - -pub trait SelectorFilter { - fn is_allowed(_caller: H160, _selector: Option) -> bool; - - fn description() -> String; -} -pub struct ForAllSelectors; -impl SelectorFilter for ForAllSelectors { - fn is_allowed(_caller: H160, _selector: Option) -> bool { - true - } - - fn description() -> String { - "Allowed for all selectors and callers".into() - } -} - -pub struct OnlyFrom(PhantomData); -impl> SelectorFilter for OnlyFrom { - fn is_allowed(caller: H160, _selector: Option) -> bool { - caller == T::get() - } - - fn description() -> String { - alloc::format!("Allowed for all selectors only if called from {}", T::get()) - } -} - -pub struct CallableByContract(PhantomData); - -impl PrecompileChecks for CallableByContract { - #[inline(always)] - fn callable_by_smart_contract(caller: H160, called_selector: Option) -> Option { - Some(T::is_allowed(caller, called_selector)) - } - - fn callable_by_smart_contract_summary() -> Option { - Some(T::description()) - } -} - -/// Precompiles are allowed to call this precompile. -pub struct CallableByPrecompile(PhantomData); - -impl PrecompileChecks for CallableByPrecompile { - #[inline(always)] - fn callable_by_precompile(caller: H160, called_selector: Option) -> Option { - Some(T::is_allowed(caller, called_selector)) - } - - fn callable_by_precompile_summary() -> Option { - Some(T::description()) - } -} - -/// The type of EVM address. -#[derive(PartialEq)] -#[cfg_attr(feature = "std", derive(Debug))] -pub enum AddressType { - /// The code stored at the address is less than 5 bytes, but not well known. - Unknown, - /// No code is stored at the address, therefore is EOA. - EOA, - /// The 5-byte magic constant for a precompile is stored at the address. - Precompile, - /// The code is greater than 5-bytes, potentially a Smart Contract. - Contract, -} - -/// Retrieves the type of address demarcated by `AddressType`. -pub fn get_address_type( - handle: &mut impl PrecompileHandle, - address: H160, -) -> Result { - // AccountCodesMetadata: - // Blake2128(16) + H160(20) + CodeMetadata(40) - handle.record_db_read::(76)?; - let code_len = pallet_evm::Pallet::::account_code_metadata(address).size; - - // 0 => either EOA or precompile without dummy code - if code_len == 0 { - return Ok(AddressType::EOA); - } - - // dummy code is 5 bytes long, so any other len means it is a contract. - if code_len != 5 { - return Ok(AddressType::Contract); - } - - // check code matches dummy code - handle.record_db_read::(code_len as usize)?; - let code = pallet_evm::AccountCodes::::get(address); - if &code == &[0x60, 0x00, 0x60, 0x00, 0xfd] { - return Ok(AddressType::Precompile); - } - - Ok(AddressType::Unknown) -} - -fn is_address_eoa_or_precompile( - handle: &mut impl PrecompileHandle, - address: H160, -) -> Result { - match get_address_type::(handle, address)? { - AddressType::EOA | AddressType::Precompile => Ok(true), - _ => Ok(false), - } -} - -/// Common checks for precompile and precompile sets. -/// Don't contain recursion check as precompile sets have recursion check for each member. -fn common_checks( - handle: &mut impl PrecompileHandle, -) -> EvmResult<()> { - let code_address = handle.code_address(); - let caller = handle.context().caller; - - // Check DELEGATECALL config. - let accept_delegate_call = C::accept_delegate_call().unwrap_or(false); - if !accept_delegate_call && code_address != handle.context().address { - return Err(revert("Cannot be called with DELEGATECALL or CALLCODE")); - } - - // Extract which selector is called. - let selector = handle.input().get(0..4).map(|bytes| { - let mut buffer = [0u8; 4]; - buffer.copy_from_slice(bytes); - u32::from_be_bytes(buffer) - }); - - // Is this selector callable from a smart contract? - let callable_by_smart_contract = - C::callable_by_smart_contract(caller, selector).unwrap_or(false); - if !callable_by_smart_contract { - if !is_address_eoa_or_precompile::(handle, caller)? { - return Err(revert("Function not callable by smart contracts")); - } - } - - // Is this selector callable from a precompile? - let callable_by_precompile = C::callable_by_precompile(caller, selector).unwrap_or(false); - if !callable_by_precompile && is_precompile_or_fail::(caller, handle.remaining_gas())? { - return Err(revert("Function not callable by precompiles")); - } - - Ok(()) -} - -pub fn is_precompile_or_fail(address: H160, gas: u64) -> EvmResult { - match ::PrecompilesValue::get().is_precompile(address, gas) { - IsPrecompileResult::Answer { is_precompile, .. } => Ok(is_precompile), - IsPrecompileResult::OutOfGas => Err(PrecompileFailure::Error { - exit_status: ExitError::OutOfGas, - }), - } -} - -pub struct AddressU64; -impl Get for AddressU64 { - #[inline(always)] - fn get() -> H160 { - H160::from_low_u64_be(N) - } -} - -pub struct RestrictiveHandle<'a, H> { - handle: &'a mut H, - allow_subcalls: bool, -} - -impl<'a, H: PrecompileHandle> PrecompileHandle for RestrictiveHandle<'a, H> { - fn call( - &mut self, - address: H160, - transfer: Option, - input: Vec, - target_gas: Option, - is_static: bool, - context: &evm::Context, - ) -> (evm::ExitReason, Vec) { - if !self.allow_subcalls { - return ( - evm::ExitReason::Revert(evm::ExitRevert::Reverted), - crate::solidity::revert::revert_as_bytes("subcalls disabled for this precompile"), - ); - } - - self.handle - .call(address, transfer, input, target_gas, is_static, context) - } - - fn record_cost(&mut self, cost: u64) -> Result<(), evm::ExitError> { - self.handle.record_cost(cost) - } - - fn remaining_gas(&self) -> u64 { - self.handle.remaining_gas() - } - - fn log( - &mut self, - address: H160, - topics: Vec, - data: Vec, - ) -> Result<(), evm::ExitError> { - self.handle.log(address, topics, data) - } - - fn code_address(&self) -> H160 { - self.handle.code_address() - } - - fn input(&self) -> &[u8] { - self.handle.input() - } - - fn context(&self) -> &evm::Context { - self.handle.context() - } - - fn is_static(&self) -> bool { - self.handle.is_static() - } - - fn gas_limit(&self) -> Option { - self.handle.gas_limit() - } - - fn record_external_cost( - &mut self, - ref_time: Option, - proof_size: Option, - ) -> Result<(), ExitError> { - self.handle.record_external_cost(ref_time, proof_size) - } - - fn refund_external_cost(&mut self, ref_time: Option, proof_size: Option) { - self.handle.refund_external_cost(ref_time, proof_size) - } -} - -/// Allows to know if a precompile is active or not. -/// This allows to detect deactivated precompile, that are still considered precompiles by -/// the EVM but that will always revert when called. -pub trait IsActivePrecompile { - /// Is the provided address an active precompile, a precompile that has - /// not be deactivated. Note that a deactivated precompile is still considered a precompile - /// for the EVM, but it will always revert when called. - fn is_active_precompile(&self, address: H160, gas: u64) -> IsPrecompileResult; -} - -// INDIVIDUAL PRECOMPILE(SET) - -/// A fragment of a PrecompileSet. Should be implemented as is it -/// was a PrecompileSet containing only the precompile(set) it wraps. -/// They can be combined into a real PrecompileSet using `PrecompileSetBuilder`. -pub trait PrecompileSetFragment { - /// Instanciate the fragment. - fn new() -> Self; - - /// Execute the fragment. - fn execute( - &self, - handle: &mut impl PrecompileHandle, - ) -> Option; - - /// Is the provided address a precompile in this fragment? - fn is_precompile(&self, address: H160, gas: u64) -> IsPrecompileResult; - - /// Return the list of addresses covered by this fragment. - fn used_addresses(&self) -> Vec; - - /// Summarize - fn summarize_checks(&self) -> Vec; -} - -/// Wraps a stateless precompile: a type implementing the `Precompile` trait. -/// Type parameters allow to define: -/// - A: The address of the precompile -/// - R: The recursion limit (defaults to 1) -/// - D: If DELEGATECALL is supported (default to no) -pub struct PrecompileAt { - current_recursion_level: RefCell, - _phantom: PhantomData<(A, P, C)>, -} - -impl PrecompileSetFragment for PrecompileAt -where - A: Get, - P: Precompile, - C: PrecompileChecks, -{ - #[inline(always)] - fn new() -> Self { - Self { - current_recursion_level: RefCell::new(0), - _phantom: PhantomData, - } - } - - #[inline(always)] - fn execute( - &self, - handle: &mut impl PrecompileHandle, - ) -> Option { - let code_address = handle.code_address(); - - // Check if this is the address of the precompile. - if A::get() != code_address { - return None; - } - - // Perform common checks. - if let Err(err) = common_checks::(handle) { - return Some(Err(err)); - } - - // Check and increase recursion level if needed. - let recursion_limit = C::recursion_limit().unwrap_or(Some(0)); - if let Some(max_recursion_level) = recursion_limit { - match self.current_recursion_level.try_borrow_mut() { - Ok(mut recursion_level) => { - if *recursion_level > max_recursion_level { - return Some(Err( - revert("Precompile is called with too high nesting").into() - )); - } - - *recursion_level += 1; - } - // We don't hold the borrow and are in single-threaded code, thus we should - // not be able to fail borrowing in nested calls. - Err(_) => return Some(Err(revert("Couldn't check precompile nesting").into())), - } - } - - // Subcall protection. - let allow_subcalls = C::allow_subcalls().unwrap_or(false); - let mut handle = RestrictiveHandle { - handle, - allow_subcalls, - }; - - let res = P::execute(&mut handle); - - // Decrease recursion level if needed. - if recursion_limit.is_some() { - match self.current_recursion_level.try_borrow_mut() { - Ok(mut recursion_level) => { - *recursion_level -= 1; - } - // We don't hold the borrow and are in single-threaded code, thus we should - // not be able to fail borrowing in nested calls. - Err(_) => return Some(Err(revert("Couldn't check precompile nesting").into())), - } - } - - Some(res) - } - - #[inline(always)] - fn is_precompile(&self, address: H160, _gas: u64) -> IsPrecompileResult { - IsPrecompileResult::Answer { - is_precompile: address == A::get(), - extra_cost: 0, - } - } - - #[inline(always)] - fn used_addresses(&self) -> Vec { - vec![A::get()] - } - - fn summarize_checks(&self) -> Vec { - vec![PrecompileCheckSummary { - name: None, - precompile_kind: PrecompileKind::Single(A::get()), - recursion_limit: C::recursion_limit().unwrap_or(Some(0)), - accept_delegate_call: C::accept_delegate_call().unwrap_or(false), - callable_by_smart_contract: C::callable_by_smart_contract_summary() - .unwrap_or_else(|| "Not callable".into()), - callable_by_precompile: C::callable_by_precompile_summary() - .unwrap_or_else(|| "Not callable".into()), - }] - } -} - -impl IsActivePrecompile for PrecompileAt -where - A: Get, -{ - #[inline(always)] - fn is_active_precompile(&self, address: H160, _gas: u64) -> IsPrecompileResult { - IsPrecompileResult::Answer { - is_precompile: address == A::get(), - extra_cost: 0, - } - } -} - -/// Wraps an inner PrecompileSet with all its addresses starting with -/// a common prefix. -/// Type parameters allow to define: -/// - A: The common prefix -/// - D: If DELEGATECALL is supported (default to no) -pub struct PrecompileSetStartingWith { - precompile_set: P, - current_recursion_level: RefCell>, - _phantom: PhantomData<(A, C)>, -} - -impl PrecompileSetFragment for PrecompileSetStartingWith -where - A: Get<&'static [u8]>, - P: PrecompileSet + Default, - C: PrecompileChecks, -{ - #[inline(always)] - fn new() -> Self { - Self { - precompile_set: P::default(), - current_recursion_level: RefCell::new(BTreeMap::new()), - _phantom: PhantomData, - } - } - - #[inline(always)] - fn execute( - &self, - handle: &mut impl PrecompileHandle, - ) -> Option { - let code_address = handle.code_address(); - if !is_precompile_or_fail::(code_address, handle.remaining_gas()).ok()? { - return None; - } - // Perform common checks. - if let Err(err) = common_checks::(handle) { - return Some(Err(err)); - } - - // Check and increase recursion level if needed. - let recursion_limit = C::recursion_limit().unwrap_or(Some(0)); - if let Some(max_recursion_level) = recursion_limit { - match self.current_recursion_level.try_borrow_mut() { - Ok(mut recursion_level_map) => { - let recursion_level = recursion_level_map.entry(code_address).or_insert(0); - - if *recursion_level > max_recursion_level { - return Some(Err(revert("Precompile is called with too high nesting"))); - } - - *recursion_level += 1; - } - // We don't hold the borrow and are in single-threaded code, thus we should - // not be able to fail borrowing in nested calls. - Err(_) => return Some(Err(revert("Couldn't check precompile nesting"))), - } - } - - // Subcall protection. - let allow_subcalls = C::allow_subcalls().unwrap_or(false); - let mut handle = RestrictiveHandle { - handle, - allow_subcalls, - }; - - let res = self.precompile_set.execute(&mut handle); - - // Decrease recursion level if needed. - if recursion_limit.is_some() { - match self.current_recursion_level.try_borrow_mut() { - Ok(mut recursion_level_map) => { - let recursion_level = match recursion_level_map.get_mut(&code_address) { - Some(recursion_level) => recursion_level, - None => return Some(Err(revert("Couldn't retreive precompile nesting"))), - }; - - *recursion_level -= 1; - } - // We don't hold the borrow and are in single-threaded code, thus we should - // not be able to fail borrowing in nested calls. - Err(_) => return Some(Err(revert("Couldn't check precompile nesting"))), - } - } - - res - } - - #[inline(always)] - fn is_precompile(&self, address: H160, gas: u64) -> IsPrecompileResult { - if address.as_bytes().starts_with(A::get()) { - return self.precompile_set.is_precompile(address, gas); - } - IsPrecompileResult::Answer { - is_precompile: false, - extra_cost: 0, - } - } - - #[inline(always)] - fn used_addresses(&self) -> Vec { - // TODO: We currently can't get the list of used addresses. - vec![] - } - - fn summarize_checks(&self) -> Vec { - let prefix = A::get(); - - vec![PrecompileCheckSummary { - name: None, - precompile_kind: PrecompileKind::Prefixed(prefix.to_vec()), - recursion_limit: C::recursion_limit().unwrap_or(Some(0)), - accept_delegate_call: C::accept_delegate_call().unwrap_or(false), - callable_by_smart_contract: C::callable_by_smart_contract_summary() - .unwrap_or_else(|| "Not callable".into()), - callable_by_precompile: C::callable_by_precompile_summary() - .unwrap_or_else(|| "Not callable".into()), - }] - } -} - -impl IsActivePrecompile for PrecompileSetStartingWith -where - Self: PrecompileSetFragment, -{ - #[inline(always)] - fn is_active_precompile(&self, address: H160, gas: u64) -> IsPrecompileResult { - self.is_precompile(address, gas) - } -} - -/// Make a precompile that always revert. -/// Can be useful when writing tests. -pub struct RevertPrecompile(PhantomData); - -impl PrecompileSetFragment for RevertPrecompile -where - A: Get, -{ - #[inline(always)] - fn new() -> Self { - Self(PhantomData) - } - - #[inline(always)] - fn execute( - &self, - handle: &mut impl PrecompileHandle, - ) -> Option { - if A::get() == handle.code_address() { - Some(Err(revert("revert"))) - } else { - None - } - } - - #[inline(always)] - fn is_precompile(&self, address: H160, _gas: u64) -> IsPrecompileResult { - IsPrecompileResult::Answer { - is_precompile: address == A::get(), - extra_cost: 0, - } - } - - #[inline(always)] - fn used_addresses(&self) -> Vec { - vec![A::get()] - } - - fn summarize_checks(&self) -> Vec { - vec![PrecompileCheckSummary { - name: None, - precompile_kind: PrecompileKind::Single(A::get()), - recursion_limit: Some(0), - accept_delegate_call: true, - callable_by_smart_contract: "Reverts in all cases".into(), - callable_by_precompile: "Reverts in all cases".into(), - }] - } -} - -impl IsActivePrecompile for RevertPrecompile { - #[inline(always)] - fn is_active_precompile(&self, _address: H160, _gas: u64) -> IsPrecompileResult { - IsPrecompileResult::Answer { - is_precompile: true, - extra_cost: 0, - } - } -} - -/// A precompile that was removed from a precompile set. -/// Still considered a precompile but is inactive and always revert. -pub struct RemovedPrecompileAt(PhantomData); -impl PrecompileSetFragment for RemovedPrecompileAt -where - A: Get, -{ - #[inline(always)] - fn new() -> Self { - Self(PhantomData) - } - - #[inline(always)] - fn execute( - &self, - handle: &mut impl PrecompileHandle, - ) -> Option { - if A::get() == handle.code_address() { - Some(Err(revert("Removed precompile"))) - } else { - None - } - } - - #[inline(always)] - fn is_precompile(&self, address: H160, _gas: u64) -> IsPrecompileResult { - IsPrecompileResult::Answer { - is_precompile: address == A::get(), - extra_cost: 0, - } - } - - #[inline(always)] - fn used_addresses(&self) -> Vec { - vec![A::get()] - } - - fn summarize_checks(&self) -> Vec { - vec![PrecompileCheckSummary { - name: None, - precompile_kind: PrecompileKind::Single(A::get()), - recursion_limit: Some(0), - accept_delegate_call: true, - callable_by_smart_contract: "Reverts in all cases".into(), - callable_by_precompile: "Reverts in all cases".into(), - }] - } -} - -impl IsActivePrecompile for RemovedPrecompileAt { - #[inline(always)] - fn is_active_precompile(&self, _address: H160, _gas: u64) -> IsPrecompileResult { - IsPrecompileResult::Answer { - is_precompile: false, - extra_cost: 0, - } - } -} - -// COMPOSITION OF PARTS -#[impl_for_tuples(1, 100)] -impl PrecompileSetFragment for Tuple { - #[inline(always)] - fn new() -> Self { - (for_tuples!(#( - Tuple::new() - ),*)) - } - - #[inline(always)] - fn execute( - &self, - handle: &mut impl PrecompileHandle, - ) -> Option { - for_tuples!(#( - if let Some(res) = self.Tuple.execute::(handle) { - return Some(res); - } - )*); - - None - } - - #[inline(always)] - fn is_precompile(&self, address: H160, gas: u64) -> IsPrecompileResult { - for_tuples!(#( - match self.Tuple.is_precompile(address, gas) { - IsPrecompileResult::Answer { - is_precompile: true, - .. - } => return IsPrecompileResult::Answer { - is_precompile: true, - extra_cost: 0, - }, - _ => {} - }; - )*); - IsPrecompileResult::Answer { - is_precompile: false, - extra_cost: 0, - } - } - - #[inline(always)] - fn used_addresses(&self) -> Vec { - let mut used_addresses = vec![]; - - for_tuples!(#( - let mut inner = self.Tuple.used_addresses(); - used_addresses.append(&mut inner); - )*); - - used_addresses - } - - fn summarize_checks(&self) -> Vec { - let mut checks = Vec::new(); - - for_tuples!(#( - let mut inner = self.Tuple.summarize_checks(); - checks.append(&mut inner); - )*); - - checks - } -} - -#[impl_for_tuples(1, 100)] -impl IsActivePrecompile for Tuple { - #[inline(always)] - fn is_active_precompile(&self, address: H160, gas: u64) -> IsPrecompileResult { - for_tuples!(#( - match self.Tuple.is_active_precompile(address, gas) { - IsPrecompileResult::Answer { - is_precompile: true, - .. - } => return IsPrecompileResult::Answer { - is_precompile: true, - extra_cost: 0, - }, - _ => {} - }; - )*); - IsPrecompileResult::Answer { - is_precompile: false, - extra_cost: 0, - } - } -} - -/// Wraps a precompileset fragment into a range, and will skip processing it if the address -/// is out of the range. -pub struct PrecompilesInRangeInclusive { - inner: P, - range: RangeInclusive, - _phantom: PhantomData, -} - -impl PrecompileSetFragment for PrecompilesInRangeInclusive<(S, E), P> -where - S: Get, - E: Get, - P: PrecompileSetFragment, -{ - fn new() -> Self { - Self { - inner: P::new(), - range: RangeInclusive::new(S::get(), E::get()), - _phantom: PhantomData, - } - } - - fn execute( - &self, - handle: &mut impl PrecompileHandle, - ) -> Option { - if self.range.contains(&handle.code_address()) { - self.inner.execute::(handle) - } else { - None - } - } - - fn is_precompile(&self, address: H160, gas: u64) -> IsPrecompileResult { - if self.range.contains(&address) { - self.inner.is_precompile(address, gas) - } else { - IsPrecompileResult::Answer { - is_precompile: false, - extra_cost: 0, - } - } - } - - fn used_addresses(&self) -> Vec { - self.inner.used_addresses() - } - - fn summarize_checks(&self) -> Vec { - self.inner.summarize_checks() - } -} - -impl IsActivePrecompile for PrecompilesInRangeInclusive<(S, E), P> -where - P: IsActivePrecompile, -{ - fn is_active_precompile(&self, address: H160, gas: u64) -> IsPrecompileResult { - if self.range.contains(&address) { - self.inner.is_active_precompile(address, gas) - } else { - IsPrecompileResult::Answer { - is_precompile: false, - extra_cost: 0, - } - } - } -} - -/// Wraps a tuple of `PrecompileSetFragment` to make a real `PrecompileSet`. -pub struct PrecompileSetBuilder { - inner: P, - _phantom: PhantomData, -} - -impl PrecompileSet for PrecompileSetBuilder { - fn execute(&self, handle: &mut impl PrecompileHandle) -> Option { - self.inner.execute::(handle) - } - - fn is_precompile(&self, address: H160, gas: u64) -> IsPrecompileResult { - self.inner.is_precompile(address, gas) - } -} - -impl IsActivePrecompile for PrecompileSetBuilder { - fn is_active_precompile(&self, address: H160, gas: u64) -> IsPrecompileResult { - self.inner.is_active_precompile(address, gas) - } -} - -impl PrecompileSetBuilder { - /// Create a new instance of the PrecompileSet. - pub fn new() -> Self { - Self { - inner: P::new(), - _phantom: PhantomData, - } - } - - /// Return the list of addresses contained in this PrecompileSet. - pub fn used_addresses() -> impl Iterator { - Self::new() - .inner - .used_addresses() - .into_iter() - .map(|x| R::AddressMapping::into_account_id(x)) - } - - pub fn summarize_checks(&self) -> Vec { - self.inner.summarize_checks() - } -} diff --git a/precompiles/utils/src/solidity/codec/bytes.rs b/precompiles/utils/src/solidity/codec/bytes.rs deleted file mode 100644 index c3c72b8fb0..0000000000 --- a/precompiles/utils/src/solidity/codec/bytes.rs +++ /dev/null @@ -1,221 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -use super::*; -use alloc::borrow::ToOwned; -use sp_core::{ConstU32, Get}; - -type ConstU32Max = ConstU32<{ u32::MAX }>; - -pub type UnboundedBytes = BoundedBytesString; -pub type BoundedBytes = BoundedBytesString; - -pub type UnboundedString = BoundedBytesString; -pub type BoundedString = BoundedBytesString; - -trait Kind { - fn signature() -> String; -} - -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct BytesKind; - -impl Kind for BytesKind { - fn signature() -> String { - String::from("bytes") - } -} - -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct StringKind; - -impl Kind for StringKind { - fn signature() -> String { - String::from("string") - } -} - -/// The `bytes/string` type of Solidity. -/// It is different from `Vec` which will be serialized with padding for each `u8` element -/// of the array, while `Bytes` is tightly packed. -#[derive(Debug)] -pub struct BoundedBytesString { - data: Vec, - _phantom: PhantomData<(K, S)>, -} - -impl> Clone for BoundedBytesString { - fn clone(&self) -> Self { - Self { - data: self.data.clone(), - _phantom: PhantomData, - } - } -} - -impl PartialEq> for BoundedBytesString { - fn eq(&self, other: &BoundedBytesString) -> bool { - self.data.eq(&other.data) - } -} - -impl Eq for BoundedBytesString {} - -impl> BoundedBytesString { - pub fn as_bytes(&self) -> &[u8] { - &self.data - } - - pub fn as_str(&self) -> Result<&str, sp_std::str::Utf8Error> { - sp_std::str::from_utf8(&self.data) - } -} - -impl> Codec for BoundedBytesString { - fn read(reader: &mut Reader) -> MayRevert { - let mut inner_reader = reader.read_pointer()?; - - // Read bytes/string size. - let array_size: usize = inner_reader - .read::() - .map_err(|_| RevertReason::read_out_of_bounds("length"))? - .try_into() - .map_err(|_| RevertReason::value_is_too_large("length"))?; - - if array_size > S::get() as usize { - return Err(RevertReason::value_is_too_large("length").into()); - } - - // Get valid range over the bytes data. - let range = inner_reader.move_cursor(array_size)?; - - let data = inner_reader - .input - .get(range) - .ok_or_else(|| RevertReason::read_out_of_bounds(K::signature()))?; - - let bytes = Self { - data: data.to_owned(), - _phantom: PhantomData, - }; - - Ok(bytes) - } - - fn write(writer: &mut Writer, value: Self) { - let value: Vec<_> = value.into(); - let length = value.len(); - - // Pad the data. - // Leave it as is if a multiple of 32, otherwise pad to next - // multiple or 32. - let chunks = length / 32; - let padded_size = match length % 32 { - 0 => chunks * 32, - _ => (chunks + 1) * 32, - }; - - let mut value = value.to_vec(); - value.resize(padded_size, 0); - - writer.write_pointer( - Writer::new() - .write(U256::from(length)) - .write_raw_bytes(&value) - .build(), - ); - } - - fn has_static_size() -> bool { - false - } - - fn signature() -> String { - K::signature() - } -} - -// BytesString <=> Vec/&[u8] - -impl From> for Vec { - fn from(value: BoundedBytesString) -> Self { - value.data - } -} - -impl From> for BoundedBytesString { - fn from(value: Vec) -> Self { - Self { - data: value, - _phantom: PhantomData, - } - } -} - -impl From<&[u8]> for BoundedBytesString { - fn from(value: &[u8]) -> Self { - Self { - data: value.to_vec(), - _phantom: PhantomData, - } - } -} - -impl From<[u8; N]> for BoundedBytesString { - fn from(value: [u8; N]) -> Self { - Self { - data: value.to_vec(), - _phantom: PhantomData, - } - } -} - -impl From<&[u8; N]> for BoundedBytesString { - fn from(value: &[u8; N]) -> Self { - Self { - data: value.to_vec(), - _phantom: PhantomData, - } - } -} - -// BytesString <=> String/str - -impl TryFrom> for String { - type Error = alloc::string::FromUtf8Error; - - fn try_from(value: BoundedBytesString) -> Result { - alloc::string::String::from_utf8(value.data) - } -} - -impl From<&str> for BoundedBytesString { - fn from(value: &str) -> Self { - Self { - data: value.as_bytes().into(), - _phantom: PhantomData, - } - } -} - -impl From for BoundedBytesString { - fn from(value: String) -> Self { - Self { - data: value.as_bytes().into(), - _phantom: PhantomData, - } - } -} diff --git a/precompiles/utils/src/solidity/codec/mod.rs b/precompiles/utils/src/solidity/codec/mod.rs deleted file mode 100644 index ea27fb6330..0000000000 --- a/precompiles/utils/src/solidity/codec/mod.rs +++ /dev/null @@ -1,369 +0,0 @@ -// Copyright 2019-2023 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -//! Solidity encoding following the -//! [Contract ABI Specification](https://docs.soliditylang.org/en/v0.8.19/abi-spec.html#abi) - -pub mod bytes; -pub mod native; - -#[cfg(any(feature = "codec-xcm", test))] -pub mod xcm; - -use crate::solidity::revert::{MayRevert, RevertReason}; -use core::{marker::PhantomData, ops::Range}; -use sp_core::{H256, U256}; -use sp_std::{convert::TryInto, vec, vec::Vec}; - -pub use alloc::string::String; -pub use bytes::{BoundedBytes, BoundedString, UnboundedBytes, UnboundedString}; -pub use native::{Address, BoundedVec}; - -// derive macro -pub use precompile_utils_macro::Codec; - -/// Data that can be encoded/encoded followiong the Solidity ABI Specification. -pub trait Codec: Sized { - fn read(reader: &mut Reader) -> MayRevert; - fn write(writer: &mut Writer, value: Self); - fn has_static_size() -> bool; - fn signature() -> String; - fn is_explicit_tuple() -> bool { - false - } -} - -/// Encode the value into its Solidity ABI format. -/// If `T` is a tuple it is encoded as a Solidity tuple with dynamic-size offset. -fn encode(value: T) -> Vec { - Writer::new().write(value).build() -} - -/// Encode the value into its Solidity ABI format. -/// If `T` is a tuple every element is encoded without a prefixed offset. -/// It matches the encoding of Solidity function arguments and return value, or event data. -pub fn encode_arguments(value: T) -> Vec { - let output = encode(value); - if T::is_explicit_tuple() && !T::has_static_size() { - output[32..].to_vec() - } else { - output - } -} - -pub use self::encode_arguments as encode_return_value; -pub use self::encode_arguments as encode_event_data; - -/// Encode the value as the arguments of a Solidity function with given selector. -/// If `T` is a tuple each member represents an argument of the function. -pub fn encode_with_selector(selector: u32, value: T) -> Vec { - Writer::new_with_selector(selector) - .write_raw_bytes(&encode_arguments(value)) - .build() -} - -/// Decode the value from its Solidity ABI format. -/// If `T` is a tuple it is decoded as a Solidity tuple with dynamic-size offset. -fn decode(input: &[u8]) -> MayRevert { - Reader::new(input).read() -} - -/// Decode the value from its Solidity ABI format. -/// If `T` is a tuple every element is decoded without a prefixed offset. -/// It matches the encoding of Solidity function arguments and return value, or event data. -pub fn decode_arguments(input: &[u8]) -> MayRevert { - if T::is_explicit_tuple() && !T::has_static_size() { - let writer = Writer::new(); - let mut writer = writer.write(U256::from(32)); - writer.write_pointer(input.to_vec()); - let input = writer.build(); - decode(&input) - } else { - decode(&input) - } -} - -pub use self::decode_arguments as decode_return_value; -pub use self::decode_arguments as decode_event_data; - -/// Extracts the selector from the start of the input, or returns `None` if the input is too short. -pub fn selector(input: &[u8]) -> Option { - input.get(0..4).map(|s| { - let mut buffer = [0u8; 4]; - buffer.copy_from_slice(s); - u32::from_be_bytes(buffer) - }) -} - -/// Wrapper around an EVM input slice. -#[derive(Clone, Copy, Debug)] -pub struct Reader<'inner> { - input: &'inner [u8], - cursor: usize, -} - -impl<'inner> Reader<'inner> { - /// Create a Reader. - pub fn new(input: &'inner [u8]) -> Self { - Self { input, cursor: 0 } - } - - /// Create a Reader while skipping an initial selector. - pub fn new_skip_selector(input: &'inner [u8]) -> MayRevert { - if input.len() < 4 { - return Err(RevertReason::read_out_of_bounds("selector").into()); - } - - Ok(Self::new(&input[4..])) - } - - /// Check the input has at least the correct amount of arguments before the end (32 bytes values). - pub fn expect_arguments(&self, args: usize) -> MayRevert { - if self.input.len() >= self.cursor + args * 32 { - Ok(()) - } else { - Err(RevertReason::ExpectedAtLeastNArguments(args).into()) - } - } - - /// Read data from the input. - pub fn read(&mut self) -> MayRevert { - T::read(self) - } - - /// Read raw bytes from the input. - /// Doesn't handle any alignment checks, prefer using `read` instead of possible. - /// Returns an error if trying to parse out of bounds. - pub fn read_raw_bytes(&mut self, len: usize) -> MayRevert<&[u8]> { - let range = self.move_cursor(len)?; - - let data = self - .input - .get(range) - .ok_or_else(|| RevertReason::read_out_of_bounds("raw bytes"))?; - - Ok(data) - } - - /// Reads a pointer, returning a reader targetting the pointed location. - pub fn read_pointer(&mut self) -> MayRevert { - let offset: usize = self - .read::() - .map_err(|_| RevertReason::read_out_of_bounds("pointer"))? - .try_into() - .map_err(|_| RevertReason::value_is_too_large("pointer"))?; - - if offset >= self.input.len() { - return Err(RevertReason::PointerToOutofBound.into()); - } - - Ok(Self { - input: &self.input[offset..], - cursor: 0, - }) - } - - /// Read remaining bytes - pub fn read_till_end(&mut self) -> MayRevert<&[u8]> { - let range = self.move_cursor(self.input.len() - self.cursor)?; - - let data = self - .input - .get(range) - .ok_or_else(|| RevertReason::read_out_of_bounds("raw bytes"))?; - - Ok(data) - } - - /// Move the reading cursor with provided length, and return a range from the previous cursor - /// location to the new one. - /// Checks cursor overflows. - fn move_cursor(&mut self, len: usize) -> MayRevert> { - let start = self.cursor; - let end = self - .cursor - .checked_add(len) - .ok_or_else(|| RevertReason::CursorOverflow)?; - - self.cursor = end; - - Ok(start..end) - } -} - -/// Help build an EVM input/output data. -/// -/// Functions takes `self` to allow chaining all calls like -/// `Writer::new().write(...).write(...).build()`. -/// While it could be more ergonomic to take &mut self, this would -/// prevent to have a `build` function that don't clone the output. -#[derive(Clone, Debug)] -pub struct Writer { - pub(crate) data: Vec, - offset_data: Vec, - selector: Option, -} - -#[derive(Clone, Debug)] -struct OffsetChunk { - // Offset location in the container data. - offset_position: usize, - // Data pointed by the offset that must be inserted at the end of container data. - data: Vec, - // Inside of arrays, the offset is not from the start of array data (length), but from the start - // of the item. This shift allow to correct this. - offset_shift: usize, -} - -impl Writer { - /// Creates a new empty output builder (without selector). - pub fn new() -> Self { - Self { - data: vec![], - offset_data: vec![], - selector: None, - } - } - - /// Creates a new empty output builder with provided selector. - /// Selector will only be appended before the data when calling - /// `build` to not mess with the offsets. - pub fn new_with_selector(selector: impl Into) -> Self { - Self { - data: vec![], - offset_data: vec![], - selector: Some(selector.into()), - } - } - - // Return the built data. - pub fn build(mut self) -> Vec { - Self::bake_offsets(&mut self.data, self.offset_data); - - if let Some(selector) = self.selector { - let mut output = selector.to_be_bytes().to_vec(); - output.append(&mut self.data); - output - } else { - self.data - } - } - - /// Add offseted data at the end of this writer's data, updating the offsets. - fn bake_offsets(output: &mut Vec, offsets: Vec) { - for mut offset_chunk in offsets { - let offset_position = offset_chunk.offset_position; - let offset_position_end = offset_position + 32; - - // The offset is the distance between the start of the data and the - // start of the pointed data (start of a struct, length of an array). - // Offsets in inner data are relative to the start of their respective "container". - // However in arrays the "container" is actually the item itself instead of the whole - // array, which is corrected by `offset_shift`. - let free_space_offset = output.len() - offset_chunk.offset_shift; - - // Override dummy offset to the offset it will be in the final output. - U256::from(free_space_offset) - .to_big_endian(&mut output[offset_position..offset_position_end]); - - // Append this data at the end of the current output. - output.append(&mut offset_chunk.data); - } - } - - /// Write arbitrary bytes. - /// Doesn't handle any alignement checks, prefer using `write` instead if possible. - fn write_raw_bytes(mut self, value: &[u8]) -> Self { - self.data.extend_from_slice(value); - self - } - - /// Write data of requested type. - pub fn write(mut self, value: T) -> Self { - T::write(&mut self, value); - self - } - - /// Writes a pointer to given data. - /// The data will be appended when calling `build`. - /// Initially write a dummy value as offset in this writer's data, which will be replaced by - /// the correct offset once the pointed data is appended. - /// - /// Takes `&mut self` since its goal is to be used inside `solidity::Codec` impl and not in chains. - pub fn write_pointer(&mut self, data: Vec) { - let offset_position = self.data.len(); - H256::write(self, H256::repeat_byte(0xff)); - - self.offset_data.push(OffsetChunk { - offset_position, - data, - offset_shift: 0, - }); - } -} - -/// Adapter to parse data as a first type then convert it to another one. -/// Useful for old precompiles in which Solidity arguments where set larger than -/// the needed Rust type. -#[derive(Clone, Copy, Debug)] -pub struct Convert { - inner: C, - _phantom: PhantomData

, -} - -impl From for Convert { - fn from(value: C) -> Self { - Self { - inner: value, - _phantom: PhantomData, - } - } -} - -impl Convert { - pub fn converted(self) -> C { - self.inner - } -} - -impl Codec for Convert -where - P: Codec + TryInto, - C: Codec + Into

, -{ - fn read(reader: &mut Reader) -> MayRevert { - let c = P::read(reader)? - .try_into() - .map_err(|_| RevertReason::value_is_too_large(C::signature()))?; - - Ok(Self { - inner: c, - _phantom: PhantomData, - }) - } - - fn write(writer: &mut Writer, value: Self) { - P::write(writer, value.inner.into()) - } - - fn has_static_size() -> bool { - P::has_static_size() - } - - fn signature() -> String { - P::signature() - } -} diff --git a/precompiles/utils/src/solidity/codec/native.rs b/precompiles/utils/src/solidity/codec/native.rs deleted file mode 100644 index 1ad1d1ebb9..0000000000 --- a/precompiles/utils/src/solidity/codec/native.rs +++ /dev/null @@ -1,380 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -use super::*; -use crate::solidity::revert::InjectBacktrace; -use impl_trait_for_tuples::impl_for_tuples; -use sp_core::{ConstU32, Get, H160}; - -impl Codec for () { - fn read(_reader: &mut Reader) -> MayRevert { - Ok(()) - } - - fn write(_writer: &mut Writer, _value: Self) {} - - fn has_static_size() -> bool { - true - } - - fn signature() -> String { - String::from("()") - } -} - -#[impl_for_tuples(1, 18)] -impl Codec for Tuple { - fn has_static_size() -> bool { - for_tuples!(#( Tuple::has_static_size() )&*) - } - - fn read(reader: &mut Reader) -> MayRevert { - if Self::has_static_size() { - let mut index = 0; - Ok(for_tuples!( ( #( { - let elem = reader.read::().in_tuple(index)?; - index +=1; - elem - } ),* ) )) - } else { - let reader = &mut reader.read_pointer()?; - let mut index = 0; - Ok(for_tuples!( ( #( { - let elem = reader.read::().in_tuple(index)?; - index +=1; - elem - } ),* ) )) - } - } - - fn write(writer: &mut Writer, value: Self) { - if Self::has_static_size() { - for_tuples!( #( Tuple::write(writer, value.Tuple); )* ); - } else { - let mut inner_writer = Writer::new(); - for_tuples!( #( Tuple::write(&mut inner_writer, value.Tuple); )* ); - writer.write_pointer(inner_writer.build()); - } - } - - fn signature() -> String { - let mut subtypes = Vec::new(); - for_tuples!( #( subtypes.push(Tuple::signature()); )* ); - alloc::format!("({})", subtypes.join(",")) - } - - fn is_explicit_tuple() -> bool { - true - } -} - -impl Codec for H256 { - fn read(reader: &mut Reader) -> MayRevert { - let range = reader.move_cursor(32)?; - - let data = reader - .input - .get(range) - .ok_or_else(|| RevertReason::read_out_of_bounds("bytes32"))?; - - Ok(H256::from_slice(data)) - } - - fn write(writer: &mut Writer, value: Self) { - writer.data.extend_from_slice(value.as_bytes()); - } - - fn has_static_size() -> bool { - true - } - - fn signature() -> String { - String::from("bytes32") - } -} - -/// The `address` type of Solidity. -/// H160 could represent 2 types of data (bytes20 and address) that are not encoded the same way. -/// To avoid issues writing H160 is thus not supported. -#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] -pub struct Address(pub H160); - -impl From for Address { - fn from(a: H160) -> Address { - Address(a) - } -} - -impl From

for H160 { - fn from(a: Address) -> H160 { - a.0 - } -} - -impl Address { - pub fn as_u64(&self) -> Option { - let _u64 = self.0.to_low_u64_be(); - if self.0 == H160::from_low_u64_be(_u64) { - Some(_u64) - } else { - None - } - } -} - -impl Codec for Address { - fn read(reader: &mut Reader) -> MayRevert { - let range = reader.move_cursor(32)?; - - let data = reader - .input - .get(range) - .ok_or_else(|| RevertReason::read_out_of_bounds("address"))?; - - Ok(H160::from_slice(&data[12..32]).into()) - } - - fn write(writer: &mut Writer, value: Self) { - H256::write(writer, value.0.into()); - } - - fn has_static_size() -> bool { - true - } - - fn signature() -> String { - String::from("address") - } -} - -impl Codec for U256 { - fn read(reader: &mut Reader) -> MayRevert { - let range = reader.move_cursor(32)?; - - let data = reader - .input - .get(range) - .ok_or_else(|| RevertReason::read_out_of_bounds("uint256"))?; - - Ok(U256::from_big_endian(data)) - } - - fn write(writer: &mut Writer, value: Self) { - let mut buffer = [0u8; 32]; - value.to_big_endian(&mut buffer); - writer.data.extend_from_slice(&buffer); - } - - fn has_static_size() -> bool { - true - } - - fn signature() -> String { - String::from("uint256") - } -} - -macro_rules! impl_evmdata_for_uints { - ($($uint:ty, )*) => { - $( - impl Codec for $uint { - fn read(reader: &mut Reader) -> MayRevert { - let value256: U256 = reader.read() - .map_err(|_| RevertReason::read_out_of_bounds( - Self::signature() - ))?; - - value256 - .try_into() - .map_err(|_| RevertReason::value_is_too_large( - Self::signature() - ).into()) - } - - fn write(writer: &mut Writer, value: Self) { - U256::write(writer, value.into()); - } - - fn has_static_size() -> bool { - true - } - - fn signature() -> String { - alloc::format!("uint{}", core::mem::size_of::() * 8) - } - } - )* - }; -} - -impl_evmdata_for_uints!(u8, u16, u32, u64, u128,); - -impl Codec for bool { - fn read(reader: &mut Reader) -> MayRevert { - let h256 = H256::read(reader).map_err(|_| RevertReason::read_out_of_bounds("bool"))?; - - Ok(!h256.is_zero()) - } - - fn write(writer: &mut Writer, value: Self) { - let mut buffer = [0u8; 32]; - if value { - buffer[31] = 1; - } - - writer.data.extend_from_slice(&buffer); - } - - fn has_static_size() -> bool { - true - } - - fn signature() -> String { - String::from("bool") - } -} - -type ConstU32Max = ConstU32<{ u32::MAX }>; - -impl Codec for Vec { - fn read(reader: &mut Reader) -> MayRevert { - BoundedVec::::read(reader).map(|x| x.into()) - } - - fn write(writer: &mut Writer, value: Self) { - BoundedVec::::write( - writer, - BoundedVec { - inner: value, - _phantom: PhantomData, - }, - ) - } - - fn has_static_size() -> bool { - false - } - - fn signature() -> String { - alloc::format!("{}[]", T::signature()) - } -} - -/// Wrapper around a Vec that provides a max length bound on read. -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct BoundedVec { - inner: Vec, - _phantom: PhantomData, -} - -impl> Codec for BoundedVec { - fn read(reader: &mut Reader) -> MayRevert { - let mut inner_reader = reader.read_pointer()?; - - let array_size: usize = inner_reader - .read::() - .map_err(|_| RevertReason::read_out_of_bounds("length"))? - .try_into() - .map_err(|_| RevertReason::value_is_too_large("length"))?; - - if array_size > S::get() as usize { - return Err(RevertReason::value_is_too_large("length").into()); - } - - let mut array = vec![]; - - let mut item_reader = Reader { - input: inner_reader - .input - .get(32..) - .ok_or_else(|| RevertReason::read_out_of_bounds("array content"))?, - cursor: 0, - }; - - for i in 0..array_size { - array.push(item_reader.read().in_array(i)?); - } - - Ok(BoundedVec { - inner: array, - _phantom: PhantomData, - }) - } - - fn write(writer: &mut Writer, value: Self) { - let value: Vec<_> = value.into(); - let mut inner_writer = Writer::new().write(U256::from(value.len())); - - for inner in value { - // Any offset in items are relative to the start of the item instead of the - // start of the array. However if there is offseted data it must but appended after - // all items (offsets) are written. We thus need to rely on `compute_offsets` to do - // that, and must store a "shift" to correct the offsets. - let shift = inner_writer.data.len(); - let item_writer = Writer::new().write(inner); - - inner_writer = inner_writer.write_raw_bytes(&item_writer.data); - for mut offset_datum in item_writer.offset_data { - offset_datum.offset_shift += 32; - offset_datum.offset_position += shift; - inner_writer.offset_data.push(offset_datum); - } - } - - writer.write_pointer(inner_writer.build()); - } - - fn has_static_size() -> bool { - false - } - - fn signature() -> String { - alloc::format!("{}[]", T::signature()) - } -} - -impl From> for BoundedVec { - fn from(value: Vec) -> Self { - BoundedVec { - inner: value, - _phantom: PhantomData, - } - } -} - -impl From<&[T]> for BoundedVec { - fn from(value: &[T]) -> Self { - BoundedVec { - inner: value.to_vec(), - _phantom: PhantomData, - } - } -} - -impl From<[T; N]> for BoundedVec { - fn from(value: [T; N]) -> Self { - BoundedVec { - inner: value.to_vec(), - _phantom: PhantomData, - } - } -} - -impl From> for Vec { - fn from(value: BoundedVec) -> Self { - value.inner - } -} diff --git a/precompiles/utils/src/solidity/mod.rs b/precompiles/utils/src/solidity/mod.rs deleted file mode 100644 index 13d6d65686..0000000000 --- a/precompiles/utils/src/solidity/mod.rs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2019-2023 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -//! Provides utilities for compatibility with Solidity tooling. - -pub mod codec; -pub mod modifier; -pub mod revert; - -pub use codec::{ - decode_arguments, decode_event_data, decode_return_value, encode_arguments, encode_event_data, - encode_return_value, encode_with_selector, Codec, -}; diff --git a/precompiles/utils/src/solidity/modifier.rs b/precompiles/utils/src/solidity/modifier.rs deleted file mode 100644 index 80e4d33e89..0000000000 --- a/precompiles/utils/src/solidity/modifier.rs +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -//! Provide checks related to function modifiers (view/payable). - -use { - crate::solidity::revert::{MayRevert, RevertReason}, - fp_evm::Context, - sp_core::U256, -}; - -/// Represents modifiers a Solidity function can be annotated with. -#[derive(Copy, Clone, PartialEq, Eq)] -pub enum FunctionModifier { - /// Function that doesn't modify the state. - View, - /// Function that modifies the state but refuse receiving funds. - /// Correspond to a Solidity function with no modifiers. - NonPayable, - /// Function that modifies the state and accept funds. - Payable, -} - -#[must_use] -/// Check that a function call is compatible with the context it is -/// called into. -pub fn check_function_modifier( - context: &Context, - is_static: bool, - modifier: FunctionModifier, -) -> MayRevert { - if is_static && modifier != FunctionModifier::View { - return Err( - RevertReason::custom("Can't call non-static function in static context").into(), - ); - } - - if modifier != FunctionModifier::Payable && context.apparent_value > U256::zero() { - return Err(RevertReason::custom("Function is not payable").into()); - } - - Ok(()) -} diff --git a/precompiles/utils/src/solidity/revert.rs b/precompiles/utils/src/solidity/revert.rs deleted file mode 100644 index 0b7aa8f5b5..0000000000 --- a/precompiles/utils/src/solidity/revert.rs +++ /dev/null @@ -1,382 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -//! Utilities to work with revert messages with support for backtraces and -//! consistent formatting. - -use crate::solidity::{self, codec::bytes::UnboundedBytes}; -use alloc::string::{String, ToString}; -use fp_evm::{ExitRevert, PrecompileFailure}; -use sp_std::vec::Vec; - -/// Represent the result of a computation that can revert. -pub type MayRevert = Result; - -/// Generate an encoded revert from a simple String. -/// Returns a `PrecompileFailure` that fits in an `EvmResult::Err`. -pub fn revert(msg: impl Into) -> PrecompileFailure { - RevertReason::custom(msg).into() -} - -/// Generate an encoded revert from a simple String. -/// Returns a `Vec` in case `PrecompileFailure` is too high level. -pub fn revert_as_bytes(msg: impl Into) -> Vec { - Revert::new(RevertReason::custom(msg)).to_encoded_bytes() -} - -/// Generic error to build abi-encoded revert output. -/// See: https://docs.soliditylang.org/en/latest/control-structures.html?highlight=revert#revert -pub const ERROR_SELECTOR: u32 = 0x08c379a0; - -#[derive(Clone, PartialEq, Eq)] -enum BacktracePart { - Field(String), - Tuple(usize), - Array(usize), -} - -/// Backtrace of an revert. -/// Built depth-first. -/// Implement `Display` to render the backtrace as a string. -#[derive(Default, PartialEq, Eq)] -pub struct Backtrace(Vec); - -impl Backtrace { - /// Create a new empty backtrace. - pub fn new() -> Self { - Self(Vec::new()) - } - - /// Check if the backtrace is empty. - pub fn is_empty(&self) -> bool { - self.0.is_empty() - } -} - -impl core::fmt::Display for Backtrace { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { - for (i, part) in self.0.iter().rev().enumerate() { - match (i, part) { - (0, BacktracePart::Field(field)) => write!(f, "{field}")?, - (_, BacktracePart::Field(field)) => write!(f, ".{field}")?, - (_, BacktracePart::Tuple(index)) => write!(f, ".{index}")?, - (_, BacktracePart::Array(index)) => write!(f, "[{index}]")?, - } - } - Ok(()) - } -} - -/// Possible revert reasons. -#[non_exhaustive] -#[derive(PartialEq, Eq)] -pub enum RevertReason { - /// A custom revert reason if other variants are not appropriate. - Custom(String), - /// Tried to read data out of bounds. - ReadOutOfBounds { - /// What was being read? - what: String, - }, - /// An unknown selector has been provided. - UnknownSelector, - /// A value is too large to fit in the wanted type. - /// For security reasons integers are always parsed as `uint256` then - /// casted to the wanted type. If the value overflows this type then this - /// revert is used. - ValueIsTooLarge { - /// What was being read? - what: String, - }, - /// A pointer (used for structs and arrays) points out of bounds. - PointerToOutofBound, - /// The reading cursor overflowed. - /// This should realistically never happen as it would require an input - /// of length larger than 2^64, which would cost too much to be included - /// in a block. - CursorOverflow, - /// Used by a check that the input contains at least N static arguments. - /// Often use to return early if the input is too short. - ExpectedAtLeastNArguments(usize), -} - -impl RevertReason { - /// Create a `RevertReason::Custom` from anything that can be converted to a `String`. - /// Argument is the custom revert message. - pub fn custom(s: impl Into) -> Self { - RevertReason::Custom(s.into()) - } - - /// Create a `RevertReason::ReadOutOfBounds` from anything that can be converted to a `String`. - /// Argument names what was expected to be read. - pub fn read_out_of_bounds(what: impl Into) -> Self { - RevertReason::ReadOutOfBounds { what: what.into() } - } - - /// Create a `RevertReason::ValueIsTooLarge` from anything that can be converted to a `String`. - /// Argument names what was expected to be read. - pub fn value_is_too_large(what: impl Into) -> Self { - RevertReason::ValueIsTooLarge { what: what.into() } - } -} - -impl core::fmt::Display for RevertReason { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { - match self { - RevertReason::Custom(s) => write!(f, "{s}"), - RevertReason::ReadOutOfBounds { what } => { - write!(f, "Tried to read {what} out of bounds") - } - RevertReason::UnknownSelector => write!(f, "Unknown selector"), - RevertReason::ValueIsTooLarge { what } => write!(f, "Value is too large for {what}"), - RevertReason::PointerToOutofBound => write!(f, "Pointer points to out of bound"), - RevertReason::CursorOverflow => write!(f, "Reading cursor overflowed"), - RevertReason::ExpectedAtLeastNArguments(n) => { - write!(f, "Expected at least {n} arguments") - } - } - } -} - -/// An revert returned by various functions in precompile-utils. -/// Allows to dynamically construct the backtrace (backtrace) of the revert -/// and manage it in a typed way. -/// Can be transformed into a `PrecompileFailure::Revert` and `String`, and -/// implement `Display` and `Debug`. -#[derive(PartialEq, Eq)] -pub struct Revert { - reason: RevertReason, - backtrace: Backtrace, -} - -impl Revert { - /// Create a new `Revert` with a `RevertReason` and - /// an empty backtrace. - pub fn new(reason: RevertReason) -> Self { - Self { - reason, - backtrace: Backtrace::new(), - } - } - - /// For all `RevertReason` variants that have a `what` field, change its value. - /// Otherwise do nothing. - /// It is useful when writing custom types `solidity::Codec` implementations using - /// simpler types. - pub fn change_what(mut self, what: impl Into) -> Self { - let what = what.into(); - - self.reason = match self.reason { - RevertReason::ReadOutOfBounds { .. } => RevertReason::ReadOutOfBounds { what }, - RevertReason::ValueIsTooLarge { .. } => RevertReason::ValueIsTooLarge { what }, - other => other, - }; - - self - } - - /// Transforms the revert into its bytes representation (from a String). - pub fn to_encoded_bytes(self) -> Vec { - let bytes: Vec = self.into(); - solidity::encode_with_selector(ERROR_SELECTOR, UnboundedBytes::from(bytes)) - } -} - -impl From for Revert { - fn from(a: RevertReason) -> Revert { - Revert::new(a) - } -} - -impl core::fmt::Display for Revert { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { - if !self.backtrace.is_empty() { - write!(f, "{}: ", self.backtrace)?; - } - - write!(f, "{}", self.reason) - } -} - -impl core::fmt::Debug for Revert { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { - write!(f, "{}", self) - } -} - -impl Into> for Revert { - fn into(self) -> Vec { - self.to_string().into() - } -} - -/// Allows to inject backtrace data. -pub trait InjectBacktrace { - /// Output type of the injection. - /// Should be a type that can hold a backtrace. - type Output; - - /// Occurs in a field. - fn in_field(self, field: impl Into) -> Self::Output; - - /// Occurs in a tuple. - fn in_tuple(self, index: usize) -> Self::Output; - - /// Occurs in an array at provided index. - fn in_array(self, index: usize) -> Self::Output; -} - -/// Additional function for everything having a Backtrace. -pub trait BacktraceExt { - /// Map last tuple entry into a field. - /// Does nothing if last entry is not a tuple. - /// As in Solidity structs are equivalent to tuples and are tricky to parse correctly, - /// it allows to parse any struct as a tuple (with the correct implementation in this crate) and - /// then map tuple indices to struct fields. - fn map_in_tuple_to_field(self, fields: &[&'static str]) -> Self; -} - -/// Additional functions for Revert and MayRevert. -pub trait RevertExt { - /// Map the reason while keeping the same backtrace. - fn map_reason(self, f: impl FnOnce(RevertReason) -> RevertReason) -> Self; -} - -impl InjectBacktrace for RevertReason { - // `RevertReason` cannot hold a backtrace, thus it wraps - // it into a `Revert`. - type Output = Revert; - - fn in_field(self, field: impl Into) -> Revert { - Revert::new(self).in_field(field) - } - - fn in_array(self, index: usize) -> Revert { - Revert::new(self).in_array(index) - } - - fn in_tuple(self, index: usize) -> Revert { - Revert::new(self).in_tuple(index) - } -} - -impl InjectBacktrace for Backtrace { - type Output = Self; - - fn in_field(mut self, field: impl Into) -> Self { - self.0.push(BacktracePart::Field(field.into())); - self - } - - fn in_array(mut self, index: usize) -> Self { - self.0.push(BacktracePart::Array(index)); - self - } - - fn in_tuple(mut self, index: usize) -> Self { - self.0.push(BacktracePart::Tuple(index)); - self - } -} - -impl BacktraceExt for Backtrace { - fn map_in_tuple_to_field(mut self, fields: &[&'static str]) -> Self { - if let Some(entry) = self.0.last_mut() { - if let BacktracePart::Tuple(index) = *entry { - if let Some(field) = fields.get(index) { - *entry = BacktracePart::Field(field.to_string()) - } - } - } - self - } -} - -impl InjectBacktrace for Revert { - type Output = Self; - - fn in_field(mut self, field: impl Into) -> Self { - self.backtrace = self.backtrace.in_field(field); - self - } - - fn in_array(mut self, index: usize) -> Self { - self.backtrace = self.backtrace.in_array(index); - self - } - - fn in_tuple(mut self, index: usize) -> Self { - self.backtrace = self.backtrace.in_tuple(index); - self - } -} - -impl RevertExt for Revert { - fn map_reason(mut self, f: impl FnOnce(RevertReason) -> RevertReason) -> Self { - self.reason = f(self.reason); - self - } -} - -impl BacktraceExt for Revert { - fn map_in_tuple_to_field(mut self, fields: &[&'static str]) -> Self { - self.backtrace = self.backtrace.map_in_tuple_to_field(fields); - self - } -} - -impl InjectBacktrace for MayRevert { - type Output = Self; - - fn in_field(self, field: impl Into) -> Self { - self.map_err(|e| e.in_field(field)) - } - - fn in_array(self, index: usize) -> Self { - self.map_err(|e| e.in_array(index)) - } - - fn in_tuple(self, index: usize) -> Self { - self.map_err(|e| e.in_tuple(index)) - } -} - -impl RevertExt for MayRevert { - fn map_reason(self, f: impl FnOnce(RevertReason) -> RevertReason) -> Self { - self.map_err(|e| e.map_reason(f)) - } -} - -impl BacktraceExt for MayRevert { - fn map_in_tuple_to_field(self, fields: &[&'static str]) -> Self { - self.map_err(|e| e.map_in_tuple_to_field(fields)) - } -} - -impl From for PrecompileFailure { - fn from(err: Revert) -> Self { - PrecompileFailure::Revert { - exit_status: ExitRevert::Reverted, - output: err.to_encoded_bytes(), - } - } -} - -impl From for PrecompileFailure { - fn from(err: RevertReason) -> Self { - Revert::new(err).into() - } -} diff --git a/precompiles/utils/src/substrate.rs b/precompiles/utils/src/substrate.rs deleted file mode 100644 index 9d7940c2ba..0000000000 --- a/precompiles/utils/src/substrate.rs +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -//! Utils related to Substrate features: -//! - Substrate call dispatch. -//! - Substrate DB read and write costs - -use { - crate::{evm::handle::using_precompile_handle, solidity::revert::revert}, - core::marker::PhantomData, - fp_evm::{ExitError, PrecompileFailure, PrecompileHandle}, - frame_support::{ - dispatch::{Dispatchable, GetDispatchInfo, PostDispatchInfo}, - pallet_prelude::*, - traits::Get, - }, - pallet_evm::GasWeightMapping, -}; - -#[derive(Debug)] -pub enum TryDispatchError { - Evm(ExitError), - Substrate(DispatchError), -} - -impl From for PrecompileFailure { - fn from(f: TryDispatchError) -> PrecompileFailure { - match f { - TryDispatchError::Evm(e) => PrecompileFailure::Error { exit_status: e }, - TryDispatchError::Substrate(e) => { - revert(alloc::format!("Dispatched call failed with error: {e:?}")) - } - } - } -} - -/// Helper functions requiring a Substrate runtime. -/// This runtime must of course implement `pallet_evm::Config`. -#[derive(Clone, Copy, Debug)] -pub struct RuntimeHelper(PhantomData); - -impl RuntimeHelper -where - Runtime: pallet_evm::Config, - Runtime::RuntimeCall: Dispatchable + GetDispatchInfo, -{ - #[inline(always)] - pub fn record_weight_v2_cost( - handle: &mut impl PrecompileHandle, - weight: Weight, - ) -> Result<(), ExitError> { - // Make sure there is enough gas. - let remaining_gas = handle.remaining_gas(); - let required_gas = Runtime::GasWeightMapping::weight_to_gas(weight); - if required_gas > remaining_gas { - return Err(ExitError::OutOfGas); - } - - // Make sure there is enough remaining weight - // TODO: record ref time when precompile will be benchmarked - handle.record_external_cost(None, Some(weight.proof_size())) - } - - #[inline(always)] - pub fn refund_weight_v2_cost( - handle: &mut impl PrecompileHandle, - weight: Weight, - maybe_actual_weight: Option, - ) -> Result { - // Refund weights and compute used weight them record used gas - // TODO: refund ref time when precompile will be benchmarked - let used_weight = if let Some(actual_weight) = maybe_actual_weight { - let refund_weight = weight.checked_sub(&actual_weight).unwrap_or_default(); - handle.refund_external_cost(None, Some(refund_weight.proof_size())); - actual_weight - } else { - weight - }; - let used_gas = Runtime::GasWeightMapping::weight_to_gas(used_weight); - handle.record_cost(used_gas)?; - Ok(used_gas) - } - - /// Try to dispatch a Substrate call. - /// Return an error if there are not enough gas, or if the call fails. - /// If successful returns the used gas using the Runtime GasWeightMapping. - pub fn try_dispatch( - handle: &mut impl PrecompileHandle, - origin: ::RuntimeOrigin, - call: Call, - ) -> Result - where - Runtime::RuntimeCall: From, - { - let call = Runtime::RuntimeCall::from(call); - let dispatch_info = call.get_dispatch_info(); - - Self::record_weight_v2_cost(handle, dispatch_info.weight) - .map_err(|e| TryDispatchError::Evm(e))?; - - // Dispatch call. - // It may be possible to not record gas cost if the call returns Pays::No. - // However while Substrate handle checking weight while not making the sender pay for it, - // the EVM doesn't. It seems this safer to always record the costs to avoid unmetered - // computations. - let post_dispatch_info = using_precompile_handle(handle, || call.dispatch(origin)) - .map_err(|e| TryDispatchError::Substrate(e.error))?; - - Self::refund_weight_v2_cost( - handle, - dispatch_info.weight, - post_dispatch_info.actual_weight, - ) - .map_err(|e| TryDispatchError::Evm(e))?; - - Ok(post_dispatch_info) - } -} - -impl RuntimeHelper -where - Runtime: pallet_evm::Config, -{ - /// Cost of a Substrate DB write in gas. - pub fn db_write_gas_cost() -> u64 { - ::GasWeightMapping::weight_to_gas( - ::DbWeight::get().writes(1), - ) - } - - /// Cost of a Substrate DB read in gas. - pub fn db_read_gas_cost() -> u64 { - ::GasWeightMapping::weight_to_gas( - ::DbWeight::get().reads(1), - ) - } -} diff --git a/precompiles/utils/src/testing/account.rs b/precompiles/utils/src/testing/account.rs deleted file mode 100644 index b4062ecd75..0000000000 --- a/precompiles/utils/src/testing/account.rs +++ /dev/null @@ -1,187 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -use { - pallet_evm::AddressMapping, - scale_info::TypeInfo, - serde::{Deserialize, Serialize}, - sp_core::{Decode, Encode, MaxEncodedLen, H160, H256}, -}; - -#[derive( - Eq, - PartialEq, - Ord, - PartialOrd, - Clone, - Encode, - Decode, - Debug, - MaxEncodedLen, - TypeInfo, - Serialize, - Deserialize, - derive_more::Display, -)] -pub struct MockAccount(pub H160); - -impl MockAccount { - pub fn from_u64(v: u64) -> Self { - H160::from_low_u64_be(v).into() - } - - pub fn zero() -> Self { - H160::zero().into() - } - - pub fn has_prefix(&self, prefix: &[u8]) -> bool { - &self.0[0..4] == prefix - } - - pub fn has_prefix_u32(&self, prefix: u32) -> bool { - self.0[0..4] == prefix.to_be_bytes() - } - - pub fn without_prefix(&self) -> u128 { - u128::from_be_bytes(<[u8; 16]>::try_from(&self.0[4..20]).expect("slice have len 16")) - } -} - -impl From for H160 { - fn from(account: MockAccount) -> H160 { - account.0 - } -} - -impl From for [u8; 20] { - fn from(account: MockAccount) -> [u8; 20] { - let x: H160 = account.into(); - x.into() - } -} - -impl From for H256 { - fn from(x: MockAccount) -> H256 { - let x: H160 = x.into(); - x.into() - } -} - -impl From for MockAccount { - fn from(address: H160) -> MockAccount { - MockAccount(address) - } -} - -impl From<[u8; 20]> for MockAccount { - fn from(address: [u8; 20]) -> MockAccount { - let x: H160 = address.into(); - MockAccount(x) - } -} - -impl AddressMapping for MockAccount { - fn into_account_id(address: H160) -> MockAccount { - address.into() - } -} - -impl sp_runtime::traits::Convert for MockAccount { - fn convert(address: H160) -> MockAccount { - address.into() - } -} - -#[macro_export] -macro_rules! mock_account { - ($name:ident, $convert:expr) => { - pub struct $name; - mock_account!(# $name, $convert); - }; - ($name:ident ( $($field:ty),* ), $convert:expr) => { - pub struct $name($(pub $field),*); - mock_account!(# $name, $convert); - }; - (# $name:ident, $convert:expr) => { - impl From<$name> for MockAccount { - fn from(value: $name) -> MockAccount { - $convert(value) - } - } - - impl From<$name> for sp_core::H160 { - fn from(value: $name) -> sp_core::H160 { - MockAccount::from(value).into() - } - } - - impl From<$name> for sp_core::H256 { - fn from(value: $name) -> sp_core::H256 { - MockAccount::from(value).into() - } - } - }; -} - -mock_account!(Zero, |_| MockAccount::zero()); -mock_account!(Alice, |_| H160::repeat_byte(0xAA).into()); -mock_account!(Bob, |_| H160::repeat_byte(0xBB).into()); -mock_account!(Charlie, |_| H160::repeat_byte(0xCC).into()); -mock_account!(David, |_| H160::repeat_byte(0xDD).into()); - -mock_account!(Precompile1, |_| MockAccount::from_u64(1)); - -mock_account!(CryptoAlith, |_| H160::from(hex_literal::hex!( - "f24FF3a9CF04c71Dbc94D0b566f7A27B94566cac" -)) -.into()); -mock_account!(CryptoBaltathar, |_| H160::from(hex_literal::hex!( - "3Cd0A705a2DC65e5b1E1205896BaA2be8A07c6e0" -)) -.into()); -mock_account!(CryptoCarleth, |_| H160::from(hex_literal::hex!( - "798d4Ba9baf0064Ec19eB4F0a1a45785ae9D6DFc" -)) -.into()); - -mock_account!( - AddressInPrefixedSet(u32, u128), - |value: AddressInPrefixedSet| { - let prefix: u32 = value.0; - let index: u128 = value.1; - - let mut buffer = Vec::with_capacity(20); // 160 bits - - buffer.extend_from_slice(&prefix.to_be_bytes()); - buffer.extend_from_slice(&index.to_be_bytes()); - - assert_eq!(buffer.len(), 20, "address buffer should have len of 20"); - - H160::from_slice(&buffer).into() - } -); - -pub fn alith_secret_key() -> [u8; 32] { - hex_literal::hex!("5fb92d6e98884f76de468fa3f6278f8807c48bebc13595d45af5bdc4da702133") -} - -pub fn baltathar_secret_key() -> [u8; 32] { - hex_literal::hex!("8075991ce870b93a8870eca0c0f91913d12f47948ca0fd25b49c6fa7cdbeee8b") -} - -pub fn charleth_secret_key() -> [u8; 32] { - hex_literal::hex!("0b6e18cafb6ed99687ec547bd28139cafdd2bffe70e6b688025de6b445aa5c5b") -} diff --git a/precompiles/utils/src/testing/execution.rs b/precompiles/utils/src/testing/execution.rs deleted file mode 100644 index 8e45aaa772..0000000000 --- a/precompiles/utils/src/testing/execution.rs +++ /dev/null @@ -1,254 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -use { - crate::{ - solidity::codec::Codec, - testing::{decode_revert_message, MockHandle, PrettyLog, SubcallHandle, SubcallTrait}, - }, - fp_evm::{ - Context, ExitError, ExitSucceed, Log, PrecompileFailure, PrecompileOutput, - PrecompileResult, PrecompileSet, - }, - sp_core::{H160, U256}, - sp_std::boxed::Box, -}; - -#[must_use] -pub struct PrecompilesTester<'p, P> { - precompiles: &'p P, - handle: MockHandle, - - target_gas: Option, - subcall_handle: Option, - - expected_cost: Option, - expected_logs: Option>, - static_call: bool, -} - -impl<'p, P: PrecompileSet> PrecompilesTester<'p, P> { - pub fn new( - precompiles: &'p P, - from: impl Into, - to: impl Into, - data: Vec, - ) -> Self { - let to = to.into(); - let mut handle = MockHandle::new( - to.clone(), - Context { - address: to, - caller: from.into(), - apparent_value: U256::zero(), - }, - ); - - handle.input = data; - - Self { - precompiles, - handle, - - target_gas: None, - subcall_handle: None, - - expected_cost: None, - expected_logs: None, - static_call: false, - } - } - - pub fn with_value(mut self, value: impl Into) -> Self { - self.handle.context.apparent_value = value.into(); - self - } - - pub fn with_subcall_handle(mut self, subcall_handle: impl SubcallTrait) -> Self { - self.subcall_handle = Some(Box::new(subcall_handle)); - self - } - - pub fn with_target_gas(mut self, target_gas: Option) -> Self { - self.target_gas = target_gas; - self - } - - pub fn with_static_call(mut self, static_call: bool) -> Self { - self.static_call = static_call; - self - } - - pub fn expect_cost(mut self, cost: u64) -> Self { - self.expected_cost = Some(cost); - self - } - - pub fn expect_no_logs(mut self) -> Self { - self.expected_logs = Some(vec![]); - self - } - - pub fn expect_log(mut self, log: Log) -> Self { - self.expected_logs = Some({ - let mut logs = self.expected_logs.unwrap_or_else(Vec::new); - logs.push(PrettyLog(log)); - logs - }); - self - } - - fn assert_optionals(&self) { - if let Some(cost) = &self.expected_cost { - assert_eq!(&self.handle.gas_used, cost); - } - - if let Some(logs) = &self.expected_logs { - similar_asserts::assert_eq!(&self.handle.logs, logs); - } - } - - fn execute(&mut self) -> Option { - let handle = &mut self.handle; - handle.subcall_handle = self.subcall_handle.take(); - handle.is_static = self.static_call; - - if let Some(gas_limit) = self.target_gas { - handle.gas_limit = gas_limit; - } - - let res = self.precompiles.execute(handle); - - self.subcall_handle = handle.subcall_handle.take(); - - res - } - - /// Execute the precompile set and expect some precompile to have been executed, regardless of the - /// result. - pub fn execute_some(mut self) { - let res = self.execute(); - assert!(res.is_some()); - self.assert_optionals(); - } - - /// Execute the precompile set and expect no precompile to have been executed. - pub fn execute_none(mut self) { - let res = self.execute(); - assert!(res.is_some()); - self.assert_optionals(); - } - - /// Execute the precompile set and check it returns provided output. - pub fn execute_returns_raw(mut self, output: Vec) { - let res = self.execute(); - - match res { - Some(Err(PrecompileFailure::Revert { output, .. })) => { - let decoded = decode_revert_message(&output); - eprintln!( - "Revert message (bytes): {:?}", - sp_core::hexdisplay::HexDisplay::from(&decoded) - ); - eprintln!( - "Revert message (string): {:?}", - core::str::from_utf8(decoded).ok() - ); - panic!("Shouldn't have reverted"); - } - Some(Ok(PrecompileOutput { - exit_status: ExitSucceed::Returned, - output: execution_output, - })) => { - if execution_output != output { - eprintln!( - "Output (bytes): {:?}", - sp_core::hexdisplay::HexDisplay::from(&execution_output) - ); - eprintln!( - "Output (string): {:?}", - core::str::from_utf8(&execution_output).ok() - ); - panic!("Output doesn't match"); - } - } - other => panic!("Unexpected result: {:?}", other), - } - - self.assert_optionals(); - } - - /// Execute the precompile set and check it returns provided Solidity encoded output. - pub fn execute_returns(self, output: impl Codec) { - self.execute_returns_raw(crate::solidity::encode_return_value(output)) - } - - /// Execute the precompile set and check if it reverts. - /// Take a closure allowing to perform custom matching on the output. - pub fn execute_reverts(mut self, check: impl Fn(&[u8]) -> bool) { - let res = self.execute(); - - match res { - Some(Err(PrecompileFailure::Revert { output, .. })) => { - let decoded = decode_revert_message(&output); - if !check(decoded) { - eprintln!( - "Revert message (bytes): {:?}", - sp_core::hexdisplay::HexDisplay::from(&decoded) - ); - eprintln!( - "Revert message (string): {:?}", - core::str::from_utf8(decoded).ok() - ); - panic!("Revert reason doesn't match !"); - } - } - other => panic!("Didn't revert, instead returned {:?}", other), - } - - self.assert_optionals(); - } - - /// Execute the precompile set and check it returns provided output. - pub fn execute_error(mut self, error: ExitError) { - let res = self.execute(); - assert_eq!( - res, - Some(Err(PrecompileFailure::Error { exit_status: error })) - ); - self.assert_optionals(); - } -} - -pub trait PrecompileTesterExt: PrecompileSet + Sized { - fn prepare_test( - &self, - from: impl Into, - to: impl Into, - data: impl Into>, - ) -> PrecompilesTester; -} - -impl PrecompileTesterExt for T { - fn prepare_test( - &self, - from: impl Into, - to: impl Into, - data: impl Into>, - ) -> PrecompilesTester { - PrecompilesTester::new(self, from, to, data.into()) - } -} diff --git a/precompiles/utils/src/testing/handle.rs b/precompiles/utils/src/testing/handle.rs deleted file mode 100644 index 4529141033..0000000000 --- a/precompiles/utils/src/testing/handle.rs +++ /dev/null @@ -1,215 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -use { - crate::testing::PrettyLog, - evm::{ExitRevert, ExitSucceed}, - fp_evm::{Context, ExitError, ExitReason, Log, PrecompileHandle, Transfer}, - sp_core::{H160, H256}, - sp_std::boxed::Box, -}; - -#[derive(Debug, Clone)] -pub struct Subcall { - pub address: H160, - pub transfer: Option, - pub input: Vec, - pub target_gas: Option, - pub is_static: bool, - pub context: Context, -} - -#[derive(Debug, Clone)] -pub struct SubcallOutput { - pub reason: ExitReason, - pub output: Vec, - pub cost: u64, - pub logs: Vec, -} - -impl SubcallOutput { - pub fn revert() -> Self { - Self { - reason: ExitReason::Revert(ExitRevert::Reverted), - output: Vec::new(), - cost: 0, - logs: Vec::new(), - } - } - - pub fn succeed() -> Self { - Self { - reason: ExitReason::Succeed(ExitSucceed::Returned), - output: Vec::new(), - cost: 0, - logs: Vec::new(), - } - } - - pub fn out_of_gas() -> Self { - Self { - reason: ExitReason::Error(ExitError::OutOfGas), - output: Vec::new(), - cost: 0, - logs: Vec::new(), - } - } -} - -pub trait SubcallTrait: FnMut(Subcall) -> SubcallOutput + 'static {} - -impl SubcallOutput + 'static> SubcallTrait for T {} - -pub type SubcallHandle = Box; - -/// Mock handle to write tests for precompiles. -pub struct MockHandle { - pub gas_limit: u64, - pub gas_used: u64, - pub logs: Vec, - pub subcall_handle: Option, - pub code_address: H160, - pub input: Vec, - pub context: Context, - pub is_static: bool, -} - -impl MockHandle { - pub fn new(code_address: H160, context: Context) -> Self { - Self { - gas_limit: u64::MAX, - gas_used: 0, - logs: vec![], - subcall_handle: None, - code_address, - input: Vec::new(), - context, - is_static: false, - } - } -} - -impl PrecompileHandle for MockHandle { - /// Perform subcall in provided context. - /// Precompile specifies in which context the subcall is executed. - fn call( - &mut self, - address: H160, - transfer: Option, - input: Vec, - target_gas: Option, - is_static: bool, - context: &Context, - ) -> (ExitReason, Vec) { - if self - .record_cost(crate::evm::costs::call_cost( - context.apparent_value, - &evm::Config::london(), - )) - .is_err() - { - return (ExitReason::Error(ExitError::OutOfGas), vec![]); - } - - match &mut self.subcall_handle { - Some(handle) => { - let SubcallOutput { - reason, - output, - cost, - logs, - } = handle(Subcall { - address, - transfer, - input, - target_gas, - is_static, - context: context.clone(), - }); - - if self.record_cost(cost).is_err() { - return (ExitReason::Error(ExitError::OutOfGas), vec![]); - } - - for log in logs { - self.log(log.address, log.topics, log.data) - .expect("cannot fail"); - } - - (reason, output) - } - None => panic!("no subcall handle registered"), - } - } - - fn record_cost(&mut self, cost: u64) -> Result<(), ExitError> { - self.gas_used += cost; - - if self.gas_used > self.gas_limit { - Err(ExitError::OutOfGas) - } else { - Ok(()) - } - } - - fn remaining_gas(&self) -> u64 { - self.gas_limit - self.gas_used - } - - fn log(&mut self, address: H160, topics: Vec, data: Vec) -> Result<(), ExitError> { - self.logs.push(PrettyLog(Log { - address, - topics, - data, - })); - Ok(()) - } - - /// Retreive the code address (what is the address of the precompile being called). - fn code_address(&self) -> H160 { - self.code_address - } - - /// Retreive the input data the precompile is called with. - fn input(&self) -> &[u8] { - &self.input - } - - /// Retreive the context in which the precompile is executed. - fn context(&self) -> &Context { - &self.context - } - - /// Is the precompile call is done statically. - fn is_static(&self) -> bool { - self.is_static - } - - /// Retreive the gas limit of this call. - fn gas_limit(&self) -> Option { - Some(self.gas_limit) - } - - fn record_external_cost( - &mut self, - _ref_time: Option, - _proof_size: Option, - ) -> Result<(), ExitError> { - Ok(()) - } - - fn refund_external_cost(&mut self, _ref_time: Option, _proof_size: Option) {} -} diff --git a/precompiles/utils/src/testing/mod.rs b/precompiles/utils/src/testing/mod.rs deleted file mode 100644 index 89a10b6438..0000000000 --- a/precompiles/utils/src/testing/mod.rs +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -pub mod account; -pub mod execution; -pub mod handle; -pub mod modifier; -mod solidity; - -pub use { - account::*, - execution::*, - handle::*, - modifier::*, - solidity::{check_precompile_implements_solidity_interfaces, compute_selector}, -}; - -use fp_evm::Log; - -pub fn decode_revert_message(encoded: &[u8]) -> &[u8] { - let encoded_len = encoded.len(); - // selector 4 + offset 32 + string length 32 - if encoded_len > 68 { - let message_len = encoded[36..68].iter().sum::(); - if encoded_len >= 68 + message_len as usize { - return &encoded[68..68 + message_len as usize]; - } - } - b"decode_revert_message: error" -} - -#[derive(Clone, PartialEq, Eq)] -pub struct PrettyLog(Log); - -impl core::fmt::Debug for PrettyLog { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { - let bytes = self - .0 - .data - .iter() - .map(|b| format!("{:02X}", b)) - .collect::>() - .join(""); - - let message = String::from_utf8(self.0.data.clone()).ok(); - - f.debug_struct("Log") - .field("address", &self.0.address) - .field("topics", &self.0.topics) - .field("data", &bytes) - .field("data_utf8", &message) - .finish() - } -} - -/// Panics if an event is not found in the system log of events -#[macro_export] -macro_rules! assert_event_emitted { - ($event:expr) => { - match &$event { - e => { - assert!( - crate::mock::events().iter().find(|x| *x == e).is_some(), - "Event {:?} was not found in events: \n {:?}", - e, - crate::mock::events() - ); - } - } - }; -} - -// Panics if an event is found in the system log of events -#[macro_export] -macro_rules! assert_event_not_emitted { - ($event:expr) => { - match &$event { - e => { - assert!( - crate::mock::events().iter().find(|x| *x == e).is_none(), - "Event {:?} was found in events: \n {:?}", - e, - crate::mock::events() - ); - } - } - }; -} diff --git a/precompiles/utils/src/testing/modifier.rs b/precompiles/utils/src/testing/modifier.rs deleted file mode 100644 index 41e3c56feb..0000000000 --- a/precompiles/utils/src/testing/modifier.rs +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -use { - crate::{ - solidity::codec::Writer, - testing::{decode_revert_message, MockHandle}, - }, - fp_evm::{Context, PrecompileFailure, PrecompileSet}, - sp_core::{H160, U256}, -}; - -pub struct PrecompilesModifierTester

{ - precompiles: P, - handle: MockHandle, -} - -impl PrecompilesModifierTester

{ - pub fn new(precompiles: P, from: impl Into, to: impl Into) -> Self { - let to = to.into(); - let mut handle = MockHandle::new( - to.clone(), - Context { - address: to, - caller: from.into(), - apparent_value: U256::zero(), - }, - ); - - handle.gas_limit = u64::MAX; - - Self { - precompiles, - handle, - } - } - - fn is_view(&mut self, selector: u32) -> bool { - // View: calling with static should not revert with static-related message. - let handle = &mut self.handle; - handle.is_static = true; - handle.context.apparent_value = U256::zero(); - handle.input = Writer::new_with_selector(selector).build(); - - let res = self.precompiles.execute(handle); - - match res { - Some(Err(PrecompileFailure::Revert { output, .. })) => { - let decoded = decode_revert_message(&output); - - dbg!(decoded) != b"Can't call non-static function in static context" - } - Some(_) => true, - None => panic!("tried to check view modifier on unknown precompile"), - } - } - - fn is_payable(&mut self, selector: u32) -> bool { - // Payable: calling with value should not revert with payable-related message. - let handle = &mut self.handle; - handle.is_static = false; - handle.context.apparent_value = U256::one(); - handle.input = Writer::new_with_selector(selector).build(); - - let res = self.precompiles.execute(handle); - - match res { - Some(Err(PrecompileFailure::Revert { output, .. })) => { - let decoded = decode_revert_message(&output); - - decoded != b"Function is not payable" - } - Some(_) => true, - None => panic!("tried to check payable modifier on unknown precompile"), - } - } - - pub fn test_view_modifier(&mut self, selectors: &[u32]) { - for &s in selectors { - assert!( - self.is_view(s), - "Function doesn't behave like a view function." - ); - assert!( - !self.is_payable(s), - "Function doesn't behave like a non-payable function." - ) - } - } - - pub fn test_payable_modifier(&mut self, selectors: &[u32]) { - for &s in selectors { - assert!( - !self.is_view(s), - "Function doesn't behave like a non-view function." - ); - assert!( - self.is_payable(s), - "Function doesn't behave like a payable function." - ); - } - } - - pub fn test_default_modifier(&mut self, selectors: &[u32]) { - for &s in selectors { - assert!( - !self.is_view(s), - "Function doesn't behave like a non-view function." - ); - assert!( - !self.is_payable(s), - "Function doesn't behave like a non-payable function." - ); - } - } -} diff --git a/precompiles/utils/src/testing/solidity.rs b/precompiles/utils/src/testing/solidity.rs deleted file mode 100644 index fb3e24dd7a..0000000000 --- a/precompiles/utils/src/testing/solidity.rs +++ /dev/null @@ -1,372 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -//! Utility module to interact with solidity file. - -use sp_io::hashing::keccak_256; -use std::{ - collections::HashMap, - fs::File, - io::{BufRead, BufReader, Read}, -}; - -pub fn check_precompile_implements_solidity_interfaces( - files: &[&'static str], - supports_selector: F, -) where - F: Fn(u32) -> bool, -{ - for file in files { - for solidity_fn in get_selectors(file) { - assert_eq!( - solidity_fn.compute_selector_hex(), - solidity_fn.docs_selector, - "documented selector for '{}' did not match in file '{}'", - solidity_fn.signature(), - file, - ); - - let selector = solidity_fn.compute_selector(); - if !supports_selector(selector) { - panic!( - "precompile don't support selector {selector:x} for function '{}' listed in file\ - {file}", - solidity_fn.signature(), - ) - } - } - } -} - -/// Represents a declared custom type struct within a solidity file -#[derive(Clone, Default, Debug)] -pub struct SolidityStruct { - /// Struct name - pub name: String, - /// List of parameter types - pub params: Vec, - /// Is struct an enum - pub is_enum: bool, -} - -impl SolidityStruct { - /// Returns the representative signature for the solidity struct - pub fn signature(&self) -> String { - if self.is_enum { - "uint8".to_string() - } else { - format!("({})", self.params.join(",")) - } - } -} - -/// Represents a declared function within a solidity file -#[derive(Clone, Default)] -pub struct SolidityFunction { - /// Function name - pub name: String, - /// List of function parameter types - pub args: Vec, - /// The declared selector in the file - pub docs_selector: String, -} - -impl SolidityFunction { - /// Returns the representative signature for the solidity function - pub fn signature(&self) -> String { - format!("{}({})", self.name, self.args.join(",")) - } - - /// Computes the selector code for the solidity function - pub fn compute_selector(&self) -> u32 { - compute_selector(&self.signature()) - } - - /// Computes the selector code as a hex string for the solidity function - pub fn compute_selector_hex(&self) -> String { - format!("{:0>8x}", self.compute_selector()) - } -} - -/// Computes a solidity selector from a given string -pub fn compute_selector(v: &str) -> u32 { - let output = keccak_256(v.as_bytes()); - let mut buf = [0u8; 4]; - buf.clone_from_slice(&output[..4]); - u32::from_be_bytes(buf) -} - -/// Returns a list of [SolidityFunction] defined in a solidity file -pub fn get_selectors(filename: &str) -> Vec { - let file = File::open(filename) - .unwrap_or_else(|e| panic!("failed opening file '{}': {}", filename, e)); - get_selectors_from_reader(file) -} - -/// Attempts to lookup a custom struct and returns its primitive signature -fn try_lookup_custom_type(word: &str, custom_types: &HashMap) -> String { - match word.strip_suffix("[]") { - Some(word) => { - if let Some(t) = custom_types.get(word) { - return format!("{}[]", t.signature()); - } - } - None => { - if let Some(t) = custom_types.get(word) { - return t.signature(); - } - } - }; - - word.to_string() -} - -fn get_selectors_from_reader(reader: R) -> Vec { - #[derive(Clone, Copy)] - enum Stage { - Start, - Enum, - Struct, - StructParams, - FnName, - Args, - } - #[derive(Clone, Copy)] - enum Pair { - First, - Second, - } - impl Pair { - fn next(&mut self) { - *self = match self { - Pair::First => Pair::Second, - Pair::Second => Pair::First, - } - } - } - - let reader = BufReader::new(reader); - let mut functions = vec![]; - let mut custom_types = HashMap::new(); - let mut solidity_struct = SolidityStruct::default(); - - let mut stage = Stage::Start; - let mut pair = Pair::First; - let mut solidity_fn = SolidityFunction::default(); - for line in reader.lines() { - let line = line.expect("failed unwrapping line").trim().to_string(); - // identify declared selector - if line.starts_with("/// @custom:selector ") && matches!(stage, Stage::Start) { - solidity_fn.docs_selector = line.replace("/// @custom:selector ", "").to_string(); - } - - // skip comments - if line.starts_with("//") { - continue; - } - - for word in line.split(&[';', ',', '(', ')', ' ']) { - // skip whitespace - if word.trim().is_empty() { - continue; - } - match (stage, pair, word) { - // parse custom type enums - (Stage::Start, Pair::First, "enum") => { - stage = Stage::Enum; - pair.next(); - } - (Stage::Enum, Pair::Second, _) => { - custom_types.insert( - word.to_string(), - SolidityStruct { - name: word.to_string(), - is_enum: true, - params: vec![], - }, - ); - stage = Stage::Start; - pair = Pair::First; - } - - // parse custom type structs - (Stage::Start, Pair::First, "struct") => { - stage = Stage::Struct; - pair.next(); - } - (Stage::Struct, Pair::Second, _) => { - solidity_struct.name = word.to_string(); - stage = Stage::StructParams; - pair.next(); - } - (Stage::StructParams, Pair::First, "{") => (), - (Stage::StructParams, Pair::First, "}") => { - custom_types.insert(solidity_struct.name.clone(), solidity_struct); - stage = Stage::Start; - solidity_struct = SolidityStruct::default(); - } - (Stage::StructParams, Pair::First, _) => { - let param = try_lookup_custom_type(&word, &custom_types); - solidity_struct.params.push(param); - pair.next(); - } - (Stage::StructParams, Pair::Second, _) => { - pair.next(); - } - - // parse function - (Stage::Start, Pair::First, "function") => { - stage = Stage::FnName; - pair.next(); - } - (Stage::FnName, Pair::Second, _) => { - solidity_fn.name = word.to_string(); - stage = Stage::Args; - pair.next(); - } - (Stage::Args, Pair::First, "external") => { - functions.push(solidity_fn); - stage = Stage::Start; - pair = Pair::First; - solidity_fn = SolidityFunction::default() - } - (Stage::Args, Pair::First, _) => { - let mut arg = word.to_string(); - arg = try_lookup_custom_type(&arg, &custom_types); - - solidity_fn.args.push(arg); - pair.next(); - } - (Stage::Args, Pair::Second, "memory" | "calldata" | "storage") => (), - (Stage::Args, Pair::Second, _) => pair.next(), - _ => { - stage = Stage::Start; - pair = Pair::First; - solidity_fn = SolidityFunction::default() - } - } - } - } - - functions -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_selectors_are_parsed() { - let actual = get_selectors("tests/solidity_test.sol") - .into_iter() - .map(|sol_fn| { - ( - sol_fn.compute_selector_hex(), - sol_fn.docs_selector.clone(), - sol_fn.signature(), - ) - }) - .collect::>(); - let expected = vec![ - ( - String::from("f7af8d91"), - String::from(""), - String::from("fnNoArgs()"), - ), - ( - String::from("d43a9a43"), - String::from("c4921133"), - String::from("fnOneArg(address)"), - ), - ( - String::from("40d6a43d"), - String::from("67ea837e"), - String::from("fnTwoArgs(address,uint256)"), - ), - ( - String::from("cee150c8"), - String::from("d6b423d9"), - String::from("fnSameArgs(uint64,uint64)"), - ), - ( - String::from("c6024207"), - String::from("b9904a86"), - String::from("fnOneArgSameLine(uint64)"), - ), - ( - String::from("fcbc04c3"), - String::from("28f0c44e"), - String::from("fnTwoArgsSameLine(uint64,bytes32)"), - ), - ( - String::from("c590304c"), - String::from("06f0c1ce"), - String::from("fnTwoArgsSameLineExternalSplit(uint64,bytes32)"), - ), - ( - String::from("a19a07e1"), - String::from("18001a4e"), - String::from("fnMemoryArrayArgs(address[],uint256[],bytes[])"), - ), - ( - String::from("ec26cf1c"), - String::from("1ea61a4e"), - String::from("fnCalldataArgs(string,bytes[])"), - ), - ( - String::from("f29f96de"), - String::from("d8af1a4e"), - String::from("fnCustomArgs((uint8,bytes[]),bytes[],uint64)"), - ), - ( - String::from("d751d651"), - String::from("e8af1642"), - String::from("fnEnumArgs(uint8,uint64)"), - ), - ( - String::from("b2c9f1a3"), - String::from("550c1a4e"), - String::from( - "fnCustomArgsMultiple((uint8,bytes[]),(address[],uint256[],bytes[]),bytes[],\ - uint64)", - ), - ), - ( - String::from("d5363eee"), - String::from("77af1a40"), - String::from("fnCustomArrayArgs((uint8,bytes[])[],bytes[])"), - ), - ( - String::from("b82da727"), - String::from("80af0a40"), - String::from( - "fnCustomComposedArg(((uint8,bytes[]),\ - (address[],uint256[],bytes[])[]),uint64)", - ), - ), - ( - String::from("586a2193"), - String::from("97baa040"), - String::from( - "fnCustomComposedArrayArg(((uint8,bytes[]),\ - (address[],uint256[],bytes[])[])[],uint64)", - ), - ), - ]; - - assert_eq!(expected, actual); - } -} diff --git a/precompiles/utils/tests-external/Cargo.toml b/precompiles/utils/tests-external/Cargo.toml deleted file mode 100644 index c38753dc34..0000000000 --- a/precompiles/utils/tests-external/Cargo.toml +++ /dev/null @@ -1,30 +0,0 @@ -[package] -name = "precompile-utils-tests-external" -authors = { workspace = true } -edition = "2021" -version = "0.1.0" - -[lib] -path = "./lib.rs" - -[dependencies] -derive_more = { workspace = true } -hex-literal = { workspace = true } -precompile-utils = { workspace = true, features = [ "testing" ] } -serde = { workspace = true } -sha3 = { workspace = true } - -frame-support = { workspace = true } -frame-system = { workspace = true } -pallet-balances = { workspace = true, features = [ "insecure_zero_ed" ] } -pallet-timestamp = { workspace = true } -parity-scale-codec = { workspace = true, features = [ "max-encoded-len" ] } -scale-info = { workspace = true, features = [ "derive" ] } -sp-core = { workspace = true } -sp-io = { workspace = true } -sp-runtime = { workspace = true } -sp-std = { workspace = true } - -evm = { workspace = true, features = [ "with-codec" ] } -fp-evm = { workspace = true } -pallet-evm = { workspace = true, features = [ "forbid-evm-reentrancy" ] } diff --git a/precompiles/utils/tests-external/lib.rs b/precompiles/utils/tests-external/lib.rs deleted file mode 100644 index 2348abd273..0000000000 --- a/precompiles/utils/tests-external/lib.rs +++ /dev/null @@ -1,451 +0,0 @@ -// Copyright 2019-2022 PureStake Inc. -// This file is part of Moonbeam. - -// Moonbeam is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Moonbeam is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Moonbeam. If not, see . - -#[cfg(test)] -mod tests { - use std::cell::RefCell; - use std::rc::Rc; - - use evm::Context; - use fp_evm::{ExitReason, ExitRevert, PrecompileFailure, PrecompileHandle}; - use frame_support::traits::Everything; - use frame_support::{construct_runtime, parameter_types, weights::Weight}; - use pallet_evm::{EnsureAddressNever, EnsureAddressRoot}; - use precompile_utils::{ - precompile_set::*, - solidity::{codec::Writer, revert::revert}, - testing::*, - EvmResult, - }; - use sp_core::H160; - use sp_core::{H256, U256}; - use sp_runtime::{ - traits::{BlakeTwo256, IdentityLookup}, - Perbill, - }; - - pub type AccountId = MockAccount; - pub type Balance = u128; - pub type BlockNumber = u32; - - type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; - type Block = frame_system::mocking::MockBlock; - - construct_runtime!( - pub enum Runtime where - Block = Block, - NodeBlock = Block, - UncheckedExtrinsic = UncheckedExtrinsic, - { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Event}, - Evm: pallet_evm::{Pallet, Call, Storage, Event}, - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, - } - ); - - parameter_types! { - pub const BlockHashCount: u32 = 250; - pub const MaximumBlockWeight: Weight = Weight::from_parts(1024, 1); - pub const MaximumBlockLength: u32 = 2 * 1024; - pub const AvailableBlockRatio: Perbill = Perbill::one(); - pub const SS58Prefix: u8 = 42; - } - - impl frame_system::Config for Runtime { - type BaseCallFilter = Everything; - type DbWeight = (); - type RuntimeOrigin = RuntimeOrigin; - type Index = u64; - type BlockNumber = BlockNumber; - type RuntimeCall = RuntimeCall; - type Hash = H256; - type Hashing = BlakeTwo256; - type AccountId = AccountId; - type Lookup = IdentityLookup; - type Header = sp_runtime::generic::Header; - type RuntimeEvent = RuntimeEvent; - type BlockHashCount = BlockHashCount; - type Version = (); - type PalletInfo = PalletInfo; - type AccountData = pallet_balances::AccountData; - type OnNewAccount = (); - type OnKilledAccount = (); - type SystemWeightInfo = (); - type BlockWeights = (); - type BlockLength = (); - type SS58Prefix = SS58Prefix; - type OnSetCode = (); - type MaxConsumers = frame_support::traits::ConstU32<16>; - } - parameter_types! { - pub const ExistentialDeposit: u128 = 0; - } - impl pallet_balances::Config for Runtime { - type MaxReserves = (); - type ReserveIdentifier = [u8; 4]; - type MaxLocks = (); - type Balance = Balance; - type RuntimeEvent = RuntimeEvent; - type DustRemoval = (); - type ExistentialDeposit = ExistentialDeposit; - type AccountStore = System; - type WeightInfo = (); - type HoldIdentifier = (); - type FreezeIdentifier = (); - type MaxHolds = (); - type MaxFreezes = (); - } - - #[derive(Debug, Clone)] - pub struct MockPrecompile; - - #[precompile_utils::precompile] - impl MockPrecompile { - // a3cab0dd - #[precompile::public("subcall()")] - fn subcall(handle: &mut impl PrecompileHandle) -> EvmResult { - match handle.call( - handle.code_address(), - None, - // calls subcallLayer2() - Writer::new_with_selector(0x0b93381bu32).build(), - None, - false, - &Context { - caller: handle.code_address(), - address: handle.code_address(), - apparent_value: 0.into(), - }, - ) { - (ExitReason::Succeed(_), _) => Ok(()), - (ExitReason::Revert(_), v) => Err(PrecompileFailure::Revert { - exit_status: ExitRevert::Reverted, - output: v, - }), - _ => Err(revert("unexpected error")), - } - } - - // 0b93381b - #[precompile::public("success()")] - fn success(_: &mut impl PrecompileHandle) -> EvmResult { - Ok(()) - } - } - - struct MockPrecompileHandle; - impl PrecompileHandle for MockPrecompileHandle { - fn call( - &mut self, - _: sp_core::H160, - _: Option, - _: Vec, - _: Option, - _: bool, - _: &evm::Context, - ) -> (evm::ExitReason, Vec) { - unimplemented!() - } - - fn record_cost(&mut self, _: u64) -> Result<(), evm::ExitError> { - Ok(()) - } - - fn remaining_gas(&self) -> u64 { - unimplemented!() - } - - fn log( - &mut self, - _: sp_core::H160, - _: Vec, - _: Vec, - ) -> Result<(), evm::ExitError> { - unimplemented!() - } - - fn code_address(&self) -> sp_core::H160 { - unimplemented!() - } - - fn input(&self) -> &[u8] { - unimplemented!() - } - - fn context(&self) -> &evm::Context { - unimplemented!() - } - - fn is_static(&self) -> bool { - true - } - - fn gas_limit(&self) -> Option { - unimplemented!() - } - - fn record_external_cost( - &mut self, - _ref_time: Option, - _proof_size: Option, - ) -> Result<(), fp_evm::ExitError> { - Ok(()) - } - - fn refund_external_cost(&mut self, _ref_time: Option, _proof_size: Option) {} - } - - pub type Precompiles = PrecompileSetBuilder< - R, - ( - PrecompileAt, MockPrecompile>, - PrecompileAt, MockPrecompile, CallableByContract>, - PrecompileAt, MockPrecompile, CallableByPrecompile>, - PrecompileAt, MockPrecompile, SubcallWithMaxNesting<1>>, - ), - >; - - pub type PCall = MockPrecompileCall; - - const MAX_POV_SIZE: u64 = 5 * 1024 * 1024; - - parameter_types! { - pub BlockGasLimit: U256 = U256::from(u64::MAX); - pub PrecompilesValue: Precompiles = Precompiles::new(); - pub const WeightPerGas: Weight = Weight::from_parts(1, 0); - pub GasLimitPovSizeRatio: u64 = { - let block_gas_limit = BlockGasLimit::get().min(u64::MAX.into()).low_u64(); - block_gas_limit.saturating_div(MAX_POV_SIZE) - }; - } - - impl pallet_evm::Config for Runtime { - type FeeCalculator = (); - type GasWeightMapping = pallet_evm::FixedGasWeightMapping; - type WeightPerGas = WeightPerGas; - type CallOrigin = EnsureAddressRoot; - type WithdrawOrigin = EnsureAddressNever; - type AddressMapping = AccountId; - type Currency = Balances; - type RuntimeEvent = RuntimeEvent; - type Runner = pallet_evm::runner::stack::Runner; - type PrecompilesType = Precompiles; - type PrecompilesValue = PrecompilesValue; - type ChainId = (); - type OnChargeTransaction = (); - type BlockGasLimit = BlockGasLimit; - type BlockHashMapping = pallet_evm::SubstrateBlockHashMapping; - type FindAuthor = (); - type OnCreate = (); - type GasLimitPovSizeRatio = GasLimitPovSizeRatio; - type Timestamp = Timestamp; - type WeightInfo = pallet_evm::weights::SubstrateWeight; - } - - parameter_types! { - pub const MinimumPeriod: u64 = 5; - } - impl pallet_timestamp::Config for Runtime { - type Moment = u64; - type OnTimestampSet = (); - type MinimumPeriod = MinimumPeriod; - type WeightInfo = (); - } - - struct ExtBuilder; - - impl Default for ExtBuilder { - fn default() -> ExtBuilder { - ExtBuilder - } - } - - impl ExtBuilder { - #[cfg(test)] - fn build(self) -> sp_io::TestExternalities { - let t = frame_system::GenesisConfig::default() - .build_storage::() - .expect("Frame system builds valid default genesis config"); - - let mut ext = sp_io::TestExternalities::new(t); - ext.execute_with(|| { - System::set_block_number(1); - }); - ext - } - } - - #[cfg(test)] - fn precompiles() -> Precompiles { - PrecompilesValue::get() - } - - #[test] - fn default_checks_succeed_when_called_by_eoa() { - ExtBuilder::default().build().execute_with(|| { - precompiles() - .prepare_test(Alice, H160::from_low_u64_be(1), PCall::success {}) - .with_subcall_handle(|Subcall { .. }| panic!("there should be no subcall")) - .execute_returns(()) - }) - } - - #[test] - fn default_checks_revert_when_called_by_precompile() { - ExtBuilder::default().build().execute_with(|| { - precompiles() - .prepare_test( - H160::from_low_u64_be(1), - H160::from_low_u64_be(1), - PCall::success {}, - ) - .with_subcall_handle(|Subcall { .. }| panic!("there should be no subcall")) - .execute_reverts(|r| r == b"Function not callable by precompiles") - }) - } - - #[test] - fn default_checks_revert_when_called_by_contract() { - ExtBuilder::default().build().execute_with(|| { - pallet_evm::Pallet::::create_account( - Alice.into(), - hex_literal::hex!("1460006000fd").to_vec(), - ); - - precompiles() - .prepare_test(Alice, H160::from_low_u64_be(1), PCall::success {}) - .with_subcall_handle(|Subcall { .. }| panic!("there should be no subcall")) - .execute_reverts(|r| r == b"Function not callable by smart contracts") - }) - } - - #[test] - fn default_checks_revert_when_doing_subcall() { - ExtBuilder::default().build().execute_with(|| { - precompiles() - .prepare_test(Alice, H160::from_low_u64_be(1), PCall::subcall {}) - .with_subcall_handle(|Subcall { .. }| panic!("there should be no subcall")) - .execute_reverts(|r| r == b"subcalls disabled for this precompile") - }) - } - - #[test] - fn callable_by_contract_works() { - ExtBuilder::default().build().execute_with(|| { - pallet_evm::Pallet::::create_account( - Alice.into(), - hex_literal::hex!("1460006000fd").to_vec(), - ); - - precompiles() - .prepare_test(Alice, H160::from_low_u64_be(2), PCall::success {}) - .with_subcall_handle(|Subcall { .. }| panic!("there should be no subcall")) - .execute_returns(()) - }) - } - - #[test] - fn callable_by_precompile_works() { - ExtBuilder::default().build().execute_with(|| { - precompiles() - .prepare_test( - H160::from_low_u64_be(3), - H160::from_low_u64_be(3), - PCall::success {}, - ) - .with_subcall_handle(|Subcall { .. }| panic!("there should be no subcall")) - .execute_returns(()) - }) - } - - #[test] - fn subcalls_works_when_allowed() { - ExtBuilder::default().build().execute_with(|| { - let subcall_occured = Rc::new(RefCell::new(false)); - { - let subcall_occured = Rc::clone(&subcall_occured); - precompiles() - .prepare_test(Alice, H160::from_low_u64_be(4), PCall::subcall {}) - .with_subcall_handle(move |Subcall { .. }| { - *subcall_occured.borrow_mut() = true; - SubcallOutput::succeed() - }) - .execute_returns(()); - } - assert!(*subcall_occured.borrow()); - }) - } - - #[test] - fn get_address_type_works_for_eoa() { - ExtBuilder::default().build().execute_with(|| { - let addr = H160::repeat_byte(0x1d); - assert_eq!( - AddressType::EOA, - get_address_type::(&mut MockPrecompileHandle, addr).expect("OOG") - ); - }) - } - - #[test] - fn get_address_type_works_for_precompile() { - ExtBuilder::default().build().execute_with(|| { - let addr = H160::repeat_byte(0x1d); - pallet_evm::AccountCodes::::insert(addr, vec![0x60, 0x00, 0x60, 0x00, 0xfd]); - assert_eq!( - AddressType::Precompile, - get_address_type::(&mut MockPrecompileHandle, addr).expect("OOG") - ); - }) - } - - #[test] - fn get_address_type_works_for_smart_contract() { - ExtBuilder::default().build().execute_with(|| { - let addr = H160::repeat_byte(0x1d); - - // length > 5 - pallet_evm::AccountCodes::::insert( - addr, - vec![0x60, 0x00, 0x60, 0x00, 0xfd, 0xff, 0xff], - ); - assert_eq!( - AddressType::Contract, - get_address_type::(&mut MockPrecompileHandle, addr).expect("OOG") - ); - - // length < 5 - pallet_evm::AccountCodes::::insert(addr, vec![0x60, 0x00, 0x60]); - assert_eq!( - AddressType::Contract, - get_address_type::(&mut MockPrecompileHandle, addr).expect("OOG") - ); - }) - } - - #[test] - fn get_address_type_works_for_unknown() { - ExtBuilder::default().build().execute_with(|| { - let addr = H160::repeat_byte(0x1d); - pallet_evm::AccountCodes::::insert(addr, vec![0x11, 0x00, 0x60, 0x00, 0xfd]); - assert_eq!( - AddressType::Unknown, - get_address_type::(&mut MockPrecompileHandle, addr).expect("OOG") - ); - }) - } -} diff --git a/precompiles/utils/tests/solidity_test.sol b/precompiles/utils/tests/solidity_test.sol deleted file mode 100644 index bd16b8487c..0000000000 --- a/precompiles/utils/tests/solidity_test.sol +++ /dev/null @@ -1,123 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-only -pragma solidity >=0.8.3; - -/// @title Solidity test file with incorrectly defined selectors -interface SolidityTest { - /// A custom enum - enum CustomEnum0 { - A, - B, - C - } - - /// A custom type - struct CustomArg0 { - CustomEnum0 p0; - bytes[] p1; - } - - /// A custom type - struct CustomArg1 { - address[] p0; - uint256[] p1; - bytes[] p2; - } - - /// A composed custom type - struct CustomArg2 { - CustomArg0 p0; - CustomArg1[] p1; - } - - /// @dev Function without params and no selector - function fnNoArgs() external; - - /// @dev Function info - /// - /// @param arg0 Arg0 Description - /// @custom:selector c4921133 - function fnOneArg(address arg0) external; - - /// @param arg0 Arg0 Description - /// @param arg1 Arg1 Description - /// @custom:selector 67ea837e - function fnTwoArgs(address arg0, uint256 arg1) external; - - /// @param arg0 Arg0 Description - /// @param arg1 Arg1 Description - /// @custom:selector d6b423d9 - function fnSameArgs(uint64 arg0, uint64 arg1) external; - - /// @param arg0 Arg0 Description - /// @custom:selector b9904a86 - function fnOneArgSameLine(uint64 arg0) external; - - /// @param arg0 Arg0 Description - /// @param arg1 Arg1 Description - /// @custom:selector 28f0c44e - function fnTwoArgsSameLine(uint64 arg0, bytes32 arg1) external; - - /// @param arg0 Arg0 Description - /// @param arg1 Arg1 Description - /// @custom:selector 06f0c1ce - function fnTwoArgsSameLineExternalSplit(uint64 arg0, bytes32 arg1) external; - - /// @param arg0 Arg0 Description - /// @param arg1 Arg1 Description - /// @param arg2 Arg2 Description - /// @custom:selector 18001a4e - function fnMemoryArrayArgs( - address[] memory arg0, - uint256[] memory arg1, - bytes[] memory arg2 - ) external; - - /// @param arg0 Arg0 Description - /// @param arg1 Arg1 Description - /// @custom:selector 1ea61a4e - function fnCalldataArgs(string calldata arg0, bytes[] memory arg1) external; - - /// @param arg0 Arg0 Description - /// @param arg1 Arg1 Description - /// @param arg2 Arg2 Description - /// @custom:selector d8af1a4e - function fnCustomArgs( - CustomArg0 memory arg0, - bytes[] memory arg1, - uint64 arg2 - ) external; - - /// @param arg0 Arg0 Description - /// @param arg1 Arg1 Description - /// @custom:selector e8af1642 - function fnEnumArgs(CustomEnum0 arg0, uint64 arg1) external; - - /// @param arg0 Arg0 Description - /// @param arg1 Arg1 Description - /// @param arg2 Arg2 Description - /// @param arg3 Arg3 Description - /// @custom:selector 550c1a4e - function fnCustomArgsMultiple( - CustomArg0 memory arg0, - CustomArg1 memory arg1, - bytes[] memory arg2, - uint64 arg3 - ) external; - - /// @param arg0 Arg0 Description - /// @param arg1 Arg1 Description - /// @custom:selector 77af1a40 - function fnCustomArrayArgs(CustomArg0[] memory arg0, bytes[] memory arg1) - external; - - /// @param arg0 Arg0 Description - /// @param arg1 Arg1 Description - /// @custom:selector 80af0a40 - function fnCustomComposedArg(CustomArg2 memory arg0, uint64 arg1) external; - - /// @param arg0 Arg0 Description - /// @param arg1 Arg1 Description - /// @custom:selector 97baa040 - function fnCustomComposedArrayArg(CustomArg2[] memory arg0, uint64 arg1) - external; -} diff --git a/precompiles/utils/xcm-codec/Cargo.toml b/precompiles/utils/xcm-codec/Cargo.toml new file mode 100644 index 0000000000..445d49e752 --- /dev/null +++ b/precompiles/utils/xcm-codec/Cargo.toml @@ -0,0 +1,31 @@ +[package] +name = "precompile-utils-xcm-codec" +authors = { workspace = true } +description = "Utils to use xcm codec." +edition = "2021" +version = "0.1.0" + +[dependencies] +precompile-utils = { workspace = true } +# Polkadot / XCM (wasm) +xcm = { workspace = true } + +# Substrate FRAME +frame-support = { workspace = true } +# Substrate Primitive +sp-core = { workspace = true } +sp-std = { workspace = true } + +[dev-dependencies] +hex-literal = { workspace = true } +pallet-evm = { workspace = true, features = ["forbid-evm-reentrancy"] } + +[features] +default = ["std"] +std = [ + "xcm/std", + "frame-support/std", + "sp-core/std", + "sp-std/std", + "pallet-evm/std", +] diff --git a/precompiles/utils/macro/tests/compile-fail/precompile_name/not_tuple.rs b/precompiles/utils/xcm-codec/src/lib.rs similarity index 75% rename from precompiles/utils/macro/tests/compile-fail/precompile_name/not_tuple.rs rename to precompiles/utils/xcm-codec/src/lib.rs index 838e53d28a..16d6dc6ed3 100644 --- a/precompiles/utils/macro/tests/compile-fail/precompile_name/not_tuple.rs +++ b/precompiles/utils/xcm-codec/src/lib.rs @@ -14,9 +14,14 @@ // You should have received a copy of the GNU General Public License // along with Moonbeam. If not, see . -struct Dummy; +//! Solidity encoding following the +//! [Contract ABI Specification](https://docs.soliditylang.org/en/v0.8.19/abi-spec.html#abi) -#[precompile_utils_macro::precompile_name_from_address] -type Precompiles = Dummy; +#![cfg_attr(not(feature = "std"), no_std)] -fn main() {} +extern crate alloc; + +pub mod xcm; + +#[cfg(test)] +mod tests; diff --git a/precompiles/utils/src/tests.rs b/precompiles/utils/xcm-codec/src/tests.rs similarity index 95% rename from precompiles/utils/src/tests.rs rename to precompiles/utils/xcm-codec/src/tests.rs index 8f0739358a..4833f4c261 100644 --- a/precompiles/utils/src/tests.rs +++ b/precompiles/utils/xcm-codec/src/tests.rs @@ -14,21 +14,21 @@ // You should have received a copy of the GNU General Public License // along with Moonbeam. If not, see . +use crate::xcm::{XcmJunction, XcmJunctions}; + use { - crate::{ + crate::xcm::{network_id_from_bytes, network_id_to_bytes}, + frame_support::traits::ConstU32, + hex_literal::hex, + pallet_evm::Context, + precompile_utils::{ prelude::*, solidity::{ - codec::{ - xcm::{network_id_from_bytes, network_id_to_bytes}, - Reader, Writer, - }, + codec::{Reader, Writer}, modifier::{check_function_modifier, FunctionModifier}, revert::Backtrace, }, }, - frame_support::traits::ConstU32, - hex_literal::hex, - pallet_evm::Context, sp_core::{H160, H256, U256}, sp_std::convert::TryInto, xcm::latest::{Junction, Junctions, NetworkId}, @@ -733,45 +733,42 @@ fn read_complex_solidity_function() { #[test] fn junctions_decoder_works() { let writer_output = Writer::new() - .write(Junctions::X1(Junction::OnlyChild)) + .write(XcmJunctions(Junctions::X1(Junction::OnlyChild))) .build(); let mut reader = Reader::new(&writer_output); - let parsed: Junctions = reader - .read::() - .expect("to correctly parse Junctions"); + let parsed: XcmJunctions = reader.read().expect("to correctly parse Junctions"); - assert_eq!(parsed, Junctions::X1(Junction::OnlyChild)); + assert_eq!(parsed.0, Junctions::X1(Junction::OnlyChild)); let writer_output = Writer::new() - .write(Junctions::X2(Junction::OnlyChild, Junction::OnlyChild)) + .write(XcmJunctions(Junctions::X2( + Junction::OnlyChild, + Junction::OnlyChild, + ))) .build(); let mut reader = Reader::new(&writer_output); - let parsed: Junctions = reader - .read::() - .expect("to correctly parse Junctions"); + let parsed: XcmJunctions = reader.read().expect("to correctly parse Junctions"); assert_eq!( - parsed, + parsed.0, Junctions::X2(Junction::OnlyChild, Junction::OnlyChild) ); let writer_output = Writer::new() - .write(Junctions::X3( + .write(XcmJunctions(Junctions::X3( Junction::OnlyChild, Junction::OnlyChild, Junction::OnlyChild, - )) + ))) .build(); let mut reader = Reader::new(&writer_output); - let parsed: Junctions = reader - .read::() - .expect("to correctly parse Junctions"); + let parsed: XcmJunctions = reader.read().expect("to correctly parse Junctions"); assert_eq!( - parsed, + parsed.0, Junctions::X3( Junction::OnlyChild, Junction::OnlyChild, @@ -782,29 +779,27 @@ fn junctions_decoder_works() { #[test] fn junction_decoder_works() { - let writer_output = Writer::new().write(Junction::Parachain(0)).build(); + let writer_output = Writer::new() + .write(XcmJunction(Junction::Parachain(0))) + .build(); let mut reader = Reader::new(&writer_output); - let parsed: Junction = reader - .read::() - .expect("to correctly parse Junctions"); + let parsed: XcmJunction = reader.read().expect("to correctly parse Junctions"); - assert_eq!(parsed, Junction::Parachain(0)); + assert_eq!(parsed.0, Junction::Parachain(0)); let writer_output = Writer::new() - .write(Junction::AccountId32 { + .write(XcmJunction(Junction::AccountId32 { network: None, id: [1u8; 32], - }) + })) .build(); let mut reader = Reader::new(&writer_output); - let parsed: Junction = reader - .read::() - .expect("to correctly parse Junctions"); + let parsed: XcmJunction = reader.read().expect("to correctly parse Junctions"); assert_eq!( - parsed, + parsed.0, Junction::AccountId32 { network: None, id: [1u8; 32], @@ -812,19 +807,17 @@ fn junction_decoder_works() { ); let writer_output = Writer::new() - .write(Junction::AccountIndex64 { + .write(XcmJunction(Junction::AccountIndex64 { network: None, index: u64::from_be_bytes([1u8; 8]), - }) + })) .build(); let mut reader = Reader::new(&writer_output); - let parsed: Junction = reader - .read::() - .expect("to correctly parse Junctions"); + let parsed: XcmJunction = reader.read().expect("to correctly parse Junctions"); assert_eq!( - parsed, + parsed.0, Junction::AccountIndex64 { network: None, index: u64::from_be_bytes([1u8; 8]), @@ -832,19 +825,19 @@ fn junction_decoder_works() { ); let writer_output = Writer::new() - .write(Junction::AccountKey20 { + .write(XcmJunction(Junction::AccountKey20 { network: None, key: H160::repeat_byte(0xAA).as_bytes().try_into().unwrap(), - }) + })) .build(); let mut reader = Reader::new(&writer_output); - let parsed: Junction = reader - .read::() + let parsed: XcmJunction = reader + .read::() .expect("to correctly parse Junctions"); assert_eq!( - parsed, + parsed.0, Junction::AccountKey20 { network: None, key: H160::repeat_byte(0xAA).as_bytes().try_into().unwrap(), @@ -1079,7 +1072,7 @@ fn error_formatting() { #[test] fn evm_data_solidity_types() { - use crate::solidity::Codec; + use precompile_utils::solidity::Codec; // Simple types assert_eq!(bool::signature(), "bool"); assert_eq!(u8::signature(), "uint8"); diff --git a/precompiles/utils/src/solidity/codec/xcm.rs b/precompiles/utils/xcm-codec/src/xcm.rs similarity index 82% rename from precompiles/utils/src/solidity/codec/xcm.rs rename to precompiles/utils/xcm-codec/src/xcm.rs index e1c7a05814..a02d01db86 100644 --- a/precompiles/utils/src/solidity/codec/xcm.rs +++ b/precompiles/utils/xcm-codec/src/xcm.rs @@ -17,12 +17,12 @@ //! Encoding of XCM types for solidity use { - crate::solidity::{ + alloc::string::String, + frame_support::{ensure, traits::ConstU32}, + precompile_utils::solidity::{ codec::{bytes::*, Codec, Reader, Writer}, revert::{BacktraceExt, InjectBacktrace, MayRevert, RevertReason}, }, - alloc::string::String, - frame_support::{ensure, traits::ConstU32}, sp_core::H256, sp_std::vec::Vec, xcm::latest::{Junction, Junctions, MultiLocation, NetworkId}, @@ -44,7 +44,7 @@ pub const JUNCTION_SIZE_LIMIT: u32 = 2u32.pow(16); pub(crate) fn network_id_to_bytes(network_id: Option) -> Vec { let mut encoded: Vec = Vec::new(); - match network_id.clone() { + match network_id { None => { encoded.push(0u8); encoded @@ -111,7 +111,7 @@ pub(crate) fn network_id_to_bytes(network_id: Option) -> Vec { // Function to convert bytes to networkId pub(crate) fn network_id_from_bytes(encoded_bytes: Vec) -> MayRevert> { ensure!( - encoded_bytes.len() > 0, + !encoded_bytes.is_empty(), RevertReason::custom("Junctions cannot be empty") ); let mut encoded_network_id = Reader::new(&encoded_bytes); @@ -136,10 +136,10 @@ pub(crate) fn network_id_from_bytes(encoded_bytes: Vec) -> MayRevert Ok(Some(NetworkId::Kusama)), 4 => { let mut block_number: [u8; 8] = Default::default(); - block_number.copy_from_slice(&encoded_network_id.read_raw_bytes(8)?); + block_number.copy_from_slice(encoded_network_id.read_raw_bytes(8)?); let mut block_hash: [u8; 32] = Default::default(); - block_hash.copy_from_slice(&encoded_network_id.read_raw_bytes(32)?); + block_hash.copy_from_slice(encoded_network_id.read_raw_bytes(32)?); Ok(Some(NetworkId::ByFork { block_number: u64::from_be_bytes(block_number), block_hash, @@ -150,7 +150,7 @@ pub(crate) fn network_id_from_bytes(encoded_bytes: Vec) -> MayRevert Ok(Some(NetworkId::Wococo)), 8 => { let mut chain_id: [u8; 8] = Default::default(); - chain_id.copy_from_slice(&encoded_network_id.read_raw_bytes(8)?); + chain_id.copy_from_slice(encoded_network_id.read_raw_bytes(8)?); Ok(Some(NetworkId::Ethereum { chain_id: u64::from_be_bytes(chain_id), })) @@ -161,13 +161,15 @@ pub(crate) fn network_id_from_bytes(encoded_bytes: Vec) -> MayRevert MayRevert { let junction = reader.read::>>()?; let junction_bytes: Vec<_> = junction.into(); ensure!( - junction_bytes.len() > 0, + !junction_bytes.is_empty(), RevertReason::custom("Junctions cannot be empty") ); @@ -184,51 +186,53 @@ impl Codec for Junction { 0 => { // In the case of Junction::Parachain, we need 4 additional bytes let mut data: [u8; 4] = Default::default(); - data.copy_from_slice(&encoded_junction.read_raw_bytes(4)?); + data.copy_from_slice(encoded_junction.read_raw_bytes(4)?); let para_id = u32::from_be_bytes(data); - Ok(Junction::Parachain(para_id)) + Ok(XcmJunction(Junction::Parachain(para_id))) } 1 => { // In the case of Junction::AccountId32, we need 32 additional bytes plus NetworkId let mut account: [u8; 32] = Default::default(); - account.copy_from_slice(&encoded_junction.read_raw_bytes(32)?); + account.copy_from_slice(encoded_junction.read_raw_bytes(32)?); let network = encoded_junction.read_till_end()?.to_vec(); - Ok(Junction::AccountId32 { + Ok(XcmJunction(Junction::AccountId32 { network: network_id_from_bytes(network)?, id: account, - }) + })) } 2 => { // In the case of Junction::AccountIndex64, we need 8 additional bytes plus NetworkId let mut index: [u8; 8] = Default::default(); - index.copy_from_slice(&encoded_junction.read_raw_bytes(8)?); + index.copy_from_slice(encoded_junction.read_raw_bytes(8)?); // Now we read the network let network = encoded_junction.read_till_end()?.to_vec(); - Ok(Junction::AccountIndex64 { + Ok(XcmJunction(Junction::AccountIndex64 { network: network_id_from_bytes(network)?, index: u64::from_be_bytes(index), - }) + })) } 3 => { // In the case of Junction::AccountKey20, we need 20 additional bytes plus NetworkId let mut account: [u8; 20] = Default::default(); - account.copy_from_slice(&encoded_junction.read_raw_bytes(20)?); + account.copy_from_slice(encoded_junction.read_raw_bytes(20)?); let network = encoded_junction.read_till_end()?.to_vec(); - Ok(Junction::AccountKey20 { + Ok(XcmJunction(Junction::AccountKey20 { network: network_id_from_bytes(network)?, key: account, - }) + })) } - 4 => Ok(Junction::PalletInstance( + 4 => Ok(XcmJunction(Junction::PalletInstance( encoded_junction.read_raw_bytes(1)?[0], - )), + ))), 5 => { // In the case of Junction::GeneralIndex, we need 16 additional bytes let mut general_index: [u8; 16] = Default::default(); - general_index.copy_from_slice(&encoded_junction.read_raw_bytes(16)?); - Ok(Junction::GeneralIndex(u128::from_be_bytes(general_index))) + general_index.copy_from_slice(encoded_junction.read_raw_bytes(16)?); + Ok(XcmJunction(Junction::GeneralIndex(u128::from_be_bytes( + general_index, + )))) } 6 => { let length = encoded_junction @@ -237,14 +241,14 @@ impl Codec for Junction { let data = encoded_junction.read::().in_field("data")?.into(); - Ok(Junction::GeneralKey { length, data }) + Ok(XcmJunction(Junction::GeneralKey { length, data })) } - 7 => Ok(Junction::OnlyChild), + 7 => Ok(XcmJunction(Junction::OnlyChild)), 8 => Err(RevertReason::custom("Junction::Plurality not supported yet").into()), 9 => { let network = encoded_junction.read_till_end()?.to_vec(); if let Some(network_id) = network_id_from_bytes(network)? { - Ok(Junction::GlobalConsensus(network_id)) + Ok(XcmJunction(Junction::GlobalConsensus(network_id))) } else { Err(RevertReason::custom("Unknown NetworkId").into()) } @@ -255,7 +259,7 @@ impl Codec for Junction { fn write(writer: &mut Writer, value: Self) { let mut encoded: Vec = Vec::new(); - let encoded_bytes: UnboundedBytes = match value { + let encoded_bytes: UnboundedBytes = match value.0 { Junction::Parachain(para_id) => { encoded.push(0u8); encoded.append(&mut para_id.to_be_bytes().to_vec()); @@ -320,21 +324,27 @@ impl Codec for Junction { } } -impl Codec for Junctions { +pub struct XcmJunctions(pub Junctions); + +impl Codec for XcmJunctions { fn read(reader: &mut Reader) -> MayRevert { - let junctions_bytes: Vec = reader.read()?; + let junctions_bytes: Vec = reader.read()?; let mut junctions = Junctions::Here; for item in junctions_bytes { junctions - .push(item) + .push(item.0) .map_err(|_| RevertReason::custom("overflow when reading junctions"))?; } - Ok(junctions) + Ok(XcmJunctions(junctions)) } fn write(writer: &mut Writer, value: Self) { - let encoded: Vec = value.iter().map(|junction| junction.clone()).collect(); + let encoded: Vec = value + .0 + .iter() + .map(|junction| XcmJunction(*junction)) + .collect(); Codec::write(writer, encoded); } @@ -343,28 +353,36 @@ impl Codec for Junctions { } fn signature() -> String { - Vec::::signature() + Vec::::signature() } } +pub struct XcmMultiLocation(pub MultiLocation); + // Cannot used derive macro since it is a foreign struct. -impl Codec for MultiLocation { +impl Codec for XcmMultiLocation { fn read(reader: &mut Reader) -> MayRevert { - let (parents, interior) = reader + let (parents, XcmJunctions(interior)) = reader .read() .map_in_tuple_to_field(&["parents", "interior"])?; - Ok(MultiLocation { parents, interior }) + Ok(MultiLocation { parents, interior }.into()) } fn write(writer: &mut Writer, value: Self) { - Codec::write(writer, (value.parents, value.interior)); + Codec::write(writer, (value.0.parents, XcmJunctions(value.0.interior))); } fn has_static_size() -> bool { - <(u8, Junctions)>::has_static_size() + <(u8, XcmJunctions)>::has_static_size() } fn signature() -> String { - <(u8, Junctions)>::signature() + <(u8, XcmJunctions)>::signature() + } +} + +impl From for XcmMultiLocation { + fn from(multilocation: MultiLocation) -> Self { + XcmMultiLocation(multilocation) } } diff --git a/precompiles/xcm-transactor/Cargo.toml b/precompiles/xcm-transactor/Cargo.toml index fcccf736c9..09ed1516cb 100644 --- a/precompiles/xcm-transactor/Cargo.toml +++ b/precompiles/xcm-transactor/Cargo.toml @@ -13,6 +13,7 @@ rustc-hex = { workspace = true } # Moonbeam pallet-xcm-transactor = { workspace = true } precompile-utils = { workspace = true } +precompile-utils-xcm-codec = { workspace = true } xcm-primitives = { workspace = true } # Substrate diff --git a/precompiles/xcm-transactor/src/tests.rs b/precompiles/xcm-transactor/src/tests.rs index c6b4825078..f90a9fc45b 100644 --- a/precompiles/xcm-transactor/src/tests.rs +++ b/precompiles/xcm-transactor/src/tests.rs @@ -130,7 +130,7 @@ fn take_transact_info() { .build() .execute_with(|| { let input: Vec<_> = PCallV1::transact_info { - multilocation: MultiLocation::parent(), + multilocation: MultiLocation::parent().into(), } .into(); @@ -169,7 +169,7 @@ fn take_transact_info_with_signed() { .build() .execute_with(|| { let input: Vec<_> = PCallV1::transact_info_with_signed { - multilocation: MultiLocation::parent(), + multilocation: MultiLocation::parent().into(), } .into(); @@ -209,7 +209,7 @@ fn take_fee_per_second() { .build() .execute_with(|| { let input: Vec<_> = PCallV1::fee_per_second { - multilocation: MultiLocation::parent(), + multilocation: MultiLocation::parent().into(), } .into(); @@ -246,7 +246,7 @@ fn test_transact_derivative_multilocation_v2() { )); // we pay with our current self reserve. - let fee_payer_asset = MultiLocation::parent(); + let fee_payer_asset = MultiLocation::parent().into(); let bytes = vec![1u8, 2u8, 3u8]; @@ -302,7 +302,7 @@ fn test_transact_derivative_multilocation() { )); // we pay with our current self reserve. - let fee_payer_asset = MultiLocation::parent(); + let fee_payer_asset = MultiLocation::parent().into(); let bytes = vec![1u8, 2u8, 3u8]; @@ -436,7 +436,7 @@ fn test_transact_signed() { )); // Destination - let dest = MultiLocation::parent(); + let dest = MultiLocation::parent().into(); let bytes = vec![1u8, 2u8, 3u8]; @@ -465,7 +465,7 @@ fn test_transact_signed_v2() { .build() .execute_with(|| { // Destination - let dest = MultiLocation::parent(); + let dest = MultiLocation::parent().into(); let bytes = vec![1u8, 2u8, 3u8]; @@ -514,9 +514,9 @@ fn test_transact_signed_multilocation() { )); // Destination - let dest = MultiLocation::parent(); + let dest = MultiLocation::parent().into(); - let fee_payer_asset = MultiLocation::parent(); + let fee_payer_asset = MultiLocation::parent().into(); let bytes = vec![1u8, 2u8, 3u8]; @@ -545,9 +545,9 @@ fn test_transact_signed_multilocation_v2() { .build() .execute_with(|| { // Destination - let dest = MultiLocation::parent(); + let dest = MultiLocation::parent().into(); - let fee_payer_asset = MultiLocation::parent(); + let fee_payer_asset = MultiLocation::parent().into(); let bytes = vec![1u8, 2u8, 3u8]; diff --git a/precompiles/xcm-transactor/src/v1/mod.rs b/precompiles/xcm-transactor/src/v1/mod.rs index 370696ee26..ee6ff4281b 100644 --- a/precompiles/xcm-transactor/src/v1/mod.rs +++ b/precompiles/xcm-transactor/src/v1/mod.rs @@ -21,9 +21,9 @@ use frame_support::dispatch::{Dispatchable, GetDispatchInfo, PostDispatchInfo}; use crate::functions::{CurrencyIdOf, GetDataLimit, TransactorOf, XcmTransactorWrapper}; use precompile_utils::prelude::*; +use precompile_utils_xcm_codec::xcm::XcmMultiLocation; use sp_core::{H160, U256}; use sp_std::{convert::TryFrom, marker::PhantomData}; -use xcm::latest::MultiLocation; use xcm_primitives::AccountIdToCurrencyId; /// A precompile to wrap the functionality from xcm transactor @@ -52,9 +52,9 @@ where #[precompile::view] fn transact_info( handle: &mut impl PrecompileHandle, - multilocation: MultiLocation, + multilocation: XcmMultiLocation, ) -> EvmResult<(u64, U256, u64)> { - XcmTransactorWrapper::::transact_info(handle, multilocation) + XcmTransactorWrapper::::transact_info(handle, multilocation.0) } #[precompile::public("transactInfoWithSigned((uint8,bytes[]))")] @@ -62,9 +62,9 @@ where #[precompile::view] fn transact_info_with_signed( handle: &mut impl PrecompileHandle, - multilocation: MultiLocation, + multilocation: XcmMultiLocation, ) -> EvmResult<(u64, u64, u64)> { - XcmTransactorWrapper::::transact_info_with_signed(handle, multilocation) + XcmTransactorWrapper::::transact_info_with_signed(handle, multilocation.0) } #[precompile::public("feePerSecond((uint8,bytes[]))")] @@ -72,9 +72,9 @@ where #[precompile::view] fn fee_per_second( handle: &mut impl PrecompileHandle, - multilocation: MultiLocation, + multilocation: XcmMultiLocation, ) -> EvmResult { - XcmTransactorWrapper::::fee_per_second(handle, multilocation) + XcmTransactorWrapper::::fee_per_second(handle, multilocation.0) } #[precompile::public( @@ -97,12 +97,17 @@ where handle: &mut impl PrecompileHandle, transactor: u8, index: u16, - fee_asset: MultiLocation, + fee_asset: XcmMultiLocation, weight: u64, inner_call: BoundedBytes, ) -> EvmResult { XcmTransactorWrapper::::transact_through_derivative_multilocation( - handle, transactor, index, fee_asset, weight, inner_call, + handle, + transactor, + index, + fee_asset.0, + weight, + inner_call, ) } @@ -142,13 +147,17 @@ where )] fn transact_through_signed_multilocation( handle: &mut impl PrecompileHandle, - dest: MultiLocation, - fee_asset: MultiLocation, + dest: XcmMultiLocation, + fee_asset: XcmMultiLocation, weight: u64, call: BoundedBytes, ) -> EvmResult { XcmTransactorWrapper::::transact_through_signed_multilocation( - handle, dest, fee_asset, weight, call, + handle, + dest.0, + fee_asset.0, + weight, + call, ) } @@ -156,13 +165,13 @@ where #[precompile::public("transact_through_signed((uint8,bytes[]),address,uint64,bytes)")] fn transact_through_signed( handle: &mut impl PrecompileHandle, - dest: MultiLocation, + dest: XcmMultiLocation, fee_asset: Address, weight: u64, call: BoundedBytes, ) -> EvmResult { XcmTransactorWrapper::::transact_through_signed( - handle, dest, fee_asset, weight, call, + handle, dest.0, fee_asset, weight, call, ) } diff --git a/precompiles/xcm-transactor/src/v2/mod.rs b/precompiles/xcm-transactor/src/v2/mod.rs index 6f3e89cfdb..f70fbcb538 100644 --- a/precompiles/xcm-transactor/src/v2/mod.rs +++ b/precompiles/xcm-transactor/src/v2/mod.rs @@ -20,9 +20,9 @@ use crate::functions::{CurrencyIdOf, GetDataLimit, TransactorOf, XcmTransactorWr use fp_evm::PrecompileHandle; use frame_support::dispatch::{Dispatchable, GetDispatchInfo, PostDispatchInfo}; use precompile_utils::prelude::*; +use precompile_utils_xcm_codec::xcm::XcmMultiLocation; use sp_core::{H160, U256}; use sp_std::{convert::TryFrom, marker::PhantomData}; -use xcm::latest::MultiLocation; use xcm_primitives::AccountIdToCurrencyId; /// A precompile to wrap the functionality from xcm transactor @@ -49,18 +49,18 @@ where #[precompile::view] fn transact_info_with_signed( handle: &mut impl PrecompileHandle, - multilocation: MultiLocation, + multilocation: XcmMultiLocation, ) -> EvmResult<(u64, u64, u64)> { - XcmTransactorWrapper::::transact_info_with_signed(handle, multilocation) + XcmTransactorWrapper::::transact_info_with_signed(handle, multilocation.0) } #[precompile::public("feePerSecond((uint8,bytes[]))")] #[precompile::view] fn fee_per_second( handle: &mut impl PrecompileHandle, - multilocation: MultiLocation, + multilocation: XcmMultiLocation, ) -> EvmResult { - XcmTransactorWrapper::::fee_per_second(handle, multilocation) + XcmTransactorWrapper::::fee_per_second(handle, multilocation.0) } #[precompile::public( @@ -76,7 +76,7 @@ where handle: &mut impl PrecompileHandle, transactor: u8, index: u16, - fee_asset: MultiLocation, + fee_asset: XcmMultiLocation, weight: u64, inner_call: BoundedBytes, fee_amount: Convert, @@ -86,7 +86,7 @@ where handle, transactor, index, - fee_asset, + fee_asset.0, weight, inner_call, fee_amount.converted(), @@ -137,8 +137,8 @@ where )] fn transact_through_signed_multilocation( handle: &mut impl PrecompileHandle, - dest: MultiLocation, - fee_asset: MultiLocation, + dest: XcmMultiLocation, + fee_asset: XcmMultiLocation, weight: u64, call: BoundedBytes, fee_amount: Convert, @@ -146,8 +146,8 @@ where ) -> EvmResult { XcmTransactorWrapper::::transact_through_signed_multilocation_fee_weight( handle, - dest, - fee_asset, + dest.0, + fee_asset.0, weight, call, fee_amount.converted(), @@ -160,7 +160,7 @@ where )] fn transact_through_signed( handle: &mut impl PrecompileHandle, - dest: MultiLocation, + dest: XcmMultiLocation, fee_asset: Address, weight: u64, call: BoundedBytes, @@ -169,7 +169,7 @@ where ) -> EvmResult { XcmTransactorWrapper::::transact_through_signed_fee_weight( handle, - dest, + dest.0, fee_asset, weight, call, diff --git a/precompiles/xcm-utils/Cargo.toml b/precompiles/xcm-utils/Cargo.toml index 77fa9a9e1f..8c656dd468 100644 --- a/precompiles/xcm-utils/Cargo.toml +++ b/precompiles/xcm-utils/Cargo.toml @@ -10,6 +10,7 @@ num_enum = { workspace = true } # Moonbeam precompile-utils = { workspace = true } +precompile-utils-xcm-codec = { workspace = true } xcm-primitives = { workspace = true } # Substrate diff --git a/precompiles/xcm-utils/src/lib.rs b/precompiles/xcm-utils/src/lib.rs index 732966ac16..3f716f4bac 100644 --- a/precompiles/xcm-utils/src/lib.rs +++ b/precompiles/xcm-utils/src/lib.rs @@ -29,6 +29,7 @@ use pallet_evm::AddressMapping; use parity_scale_codec::{DecodeLimit, MaxEncodedLen}; use precompile_utils::precompile_set::SelectorFilter; use precompile_utils::prelude::*; +use precompile_utils_xcm_codec::xcm::XcmMultiLocation; use sp_core::{H160, U256}; use sp_std::boxed::Box; use sp_std::marker::PhantomData; @@ -104,18 +105,19 @@ where #[precompile::view] fn multilocation_to_address( handle: &mut impl PrecompileHandle, - multilocation: MultiLocation, + multilocation: XcmMultiLocation, ) -> EvmResult

{ // storage item: AssetTypeUnitsPerSecond // max encoded len: hash (16) + Multilocation + u128 (16) handle.record_db_read::(32 + MultiLocation::max_encoded_len())?; - let origin = - XcmConfig::OriginConverter::convert_origin(multilocation, OriginKind::SovereignAccount) - .map_err(|_| { - RevertReason::custom("Failed multilocation conversion") - .in_field("multilocation") - })?; + let origin = XcmConfig::OriginConverter::convert_origin( + multilocation.0, + OriginKind::SovereignAccount, + ) + .map_err(|_| { + RevertReason::custom("Failed multilocation conversion").in_field("multilocation") + })?; let account: H160 = origin .as_signed() @@ -130,7 +132,7 @@ where #[precompile::view] fn get_units_per_second( handle: &mut impl PrecompileHandle, - multilocation: MultiLocation, + multilocation: XcmMultiLocation, ) -> EvmResult { // storage item: AssetTypeUnitsPerSecond // max encoded len: hash (16) + Multilocation + u128 (16) @@ -138,7 +140,7 @@ where // We will construct an asset with the max amount, and check how much we // get in return to substract - let multiasset: xcm::latest::MultiAsset = (multilocation.clone(), u128::MAX).into(); + let multiasset: xcm::latest::MultiAsset = (multilocation.0.clone(), u128::MAX).into(); let weight_per_second = 1_000_000_000_000u64; let mut trader = ::Trader::new(); @@ -224,7 +226,7 @@ where #[precompile::public("xcmSend((uint8,bytes[]),bytes)")] fn xcm_send( handle: &mut impl PrecompileHandle, - dest: MultiLocation, + dest: XcmMultiLocation, message: BoundedBytes, ) -> EvmResult { let message: Vec = message.into(); @@ -239,7 +241,7 @@ where .map_err(|_e| RevertReason::custom("Failed xcm decoding").in_field("message"))?; let call = pallet_xcm::Call::::send { - dest: Box::new(dest.into()), + dest: Box::new(dest.0.into()), message: Box::new(xcm), }; diff --git a/precompiles/xcm-utils/src/tests.rs b/precompiles/xcm-utils/src/tests.rs index 05252addbe..74797b916e 100644 --- a/precompiles/xcm-utils/src/tests.rs +++ b/precompiles/xcm-utils/src/tests.rs @@ -50,7 +50,7 @@ fn modifiers() { fn test_get_account_parent() { ExtBuilder::default().build().execute_with(|| { let input = PCall::multilocation_to_address { - multilocation: MultiLocation::parent(), + multilocation: MultiLocation::parent().into(), }; let expected_address: H160 = ParentAccount.into(); @@ -70,7 +70,8 @@ fn test_get_account_sibling() { multilocation: MultiLocation { parents: 1, interior: Junctions::X1(Junction::Parachain(2000u32)), - }, + } + .into(), }; let expected_address: H160 = SiblingParachainAccount(2000u32).into(); @@ -104,7 +105,7 @@ fn test_weight_message() { fn test_get_units_per_second() { ExtBuilder::default().build().execute_with(|| { let input = PCall::get_units_per_second { - multilocation: MultiLocation::parent(), + multilocation: MultiLocation::parent().into(), }; precompiles() @@ -214,7 +215,7 @@ fn test_send_clear_origin() { let xcm_to_send = VersionedXcm::<()>::V3(Xcm(vec![ClearOrigin])).encode(); let input = PCall::xcm_send { - dest: MultiLocation::parent(), + dest: MultiLocation::parent().into(), message: xcm_to_send.into(), }; diff --git a/precompiles/xtokens/Cargo.toml b/precompiles/xtokens/Cargo.toml index 467df5bcb4..5da7e96233 100644 --- a/precompiles/xtokens/Cargo.toml +++ b/precompiles/xtokens/Cargo.toml @@ -11,7 +11,8 @@ num_enum = { workspace = true } rustc-hex = { workspace = true } # Moonbeam -precompile-utils = { workspace = true, features = [ "codec-xcm" ] } +precompile-utils = { workspace = true } +precompile-utils-xcm-codec = { workspace = true } xcm-primitives = { workspace = true } # Substrate diff --git a/precompiles/xtokens/src/lib.rs b/precompiles/xtokens/src/lib.rs index c4d3cdd4f4..2cf2acb61c 100644 --- a/precompiles/xtokens/src/lib.rs +++ b/precompiles/xtokens/src/lib.rs @@ -25,6 +25,7 @@ use frame_support::{ }; use pallet_evm::AddressMapping; use precompile_utils::prelude::*; +use precompile_utils_xcm_codec::xcm::XcmMultiLocation; use sp_core::{H160, U256}; use sp_std::{ boxed::Box, @@ -78,7 +79,7 @@ where handle: &mut impl PrecompileHandle, currency_address: Address, amount: U256, - destination: MultiLocation, + destination: XcmMultiLocation, weight: u64, ) -> EvmResult { let to_address: H160 = currency_address.into(); @@ -103,7 +104,7 @@ where let call = orml_xtokens::Call::::transfer { currency_id, amount, - dest: Box::new(VersionedMultiLocation::V3(destination)), + dest: Box::new(VersionedMultiLocation::V3(destination.0)), dest_weight_limit, }; @@ -119,7 +120,7 @@ where currency_address: Address, amount: U256, fee: U256, - destination: MultiLocation, + destination: XcmMultiLocation, weight: u64, ) -> EvmResult { let to_address: H160 = currency_address.into(); @@ -153,7 +154,7 @@ where currency_id, amount, fee, - dest: Box::new(VersionedMultiLocation::V3(destination)), + dest: Box::new(VersionedMultiLocation::V3(destination.0)), dest_weight_limit, }; @@ -166,9 +167,9 @@ where #[precompile::public("transfer_multiasset((uint8,bytes[]),uint256,(uint8,bytes[]),uint64)")] fn transfer_multiasset( handle: &mut impl PrecompileHandle, - asset: MultiLocation, + asset: XcmMultiLocation, amount: U256, - destination: MultiLocation, + destination: XcmMultiLocation, weight: u64, ) -> EvmResult { let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); @@ -184,10 +185,10 @@ where let call = orml_xtokens::Call::::transfer_multiasset { asset: Box::new(VersionedMultiAsset::V3(MultiAsset { - id: AssetId::Concrete(asset), + id: AssetId::Concrete(asset.0), fun: Fungibility::Fungible(to_balance), })), - dest: Box::new(VersionedMultiLocation::V3(destination)), + dest: Box::new(VersionedMultiLocation::V3(destination.0)), dest_weight_limit, }; @@ -204,10 +205,10 @@ where )] fn transfer_multiasset_with_fee( handle: &mut impl PrecompileHandle, - asset: MultiLocation, + asset: XcmMultiLocation, amount: U256, fee: U256, - destination: MultiLocation, + destination: XcmMultiLocation, weight: u64, ) -> EvmResult { let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); @@ -226,14 +227,14 @@ where let call = orml_xtokens::Call::::transfer_multiasset_with_fee { asset: Box::new(VersionedMultiAsset::V3(MultiAsset { - id: AssetId::Concrete(asset.clone()), + id: AssetId::Concrete(asset.0.clone()), fun: Fungibility::Fungible(amount), })), fee: Box::new(VersionedMultiAsset::V3(MultiAsset { - id: AssetId::Concrete(asset), + id: AssetId::Concrete(asset.0), fun: Fungibility::Fungible(fee), })), - dest: Box::new(VersionedMultiLocation::V3(destination)), + dest: Box::new(VersionedMultiLocation::V3(destination.0)), dest_weight_limit, }; @@ -252,7 +253,7 @@ where handle: &mut impl PrecompileHandle, currencies: BoundedVec>, fee_item: u32, - destination: MultiLocation, + destination: XcmMultiLocation, weight: u64, ) -> EvmResult { let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); @@ -293,7 +294,7 @@ where let call = orml_xtokens::Call::::transfer_multicurrencies { currencies, fee_item, - dest: Box::new(VersionedMultiLocation::V3(destination)), + dest: Box::new(VersionedMultiLocation::V3(destination.0)), dest_weight_limit, }; @@ -312,7 +313,7 @@ where handle: &mut impl PrecompileHandle, assets: BoundedVec>, fee_item: u32, - destination: MultiLocation, + destination: XcmMultiLocation, weight: u64, ) -> EvmResult { let origin = Runtime::AddressMapping::into_account_id(handle.context().caller); @@ -327,7 +328,7 @@ where .in_array(index) .in_field("assets") })?; - Ok((evm_multiasset.location, to_balance).into()) + Ok((evm_multiasset.location.0, to_balance).into()) }) .collect(); @@ -348,7 +349,7 @@ where let call = orml_xtokens::Call::::transfer_multiassets { assets: Box::new(VersionedMultiAssets::V3(multiassets)), fee_item, - dest: Box::new(VersionedMultiLocation::V3(destination)), + dest: Box::new(VersionedMultiLocation::V3(destination.0)), dest_weight_limit, }; @@ -376,14 +377,14 @@ impl From<(Address, U256)> for Currency { #[derive(solidity::Codec)] pub struct EvmMultiAsset { - location: MultiLocation, + location: XcmMultiLocation, amount: U256, } impl From<(MultiLocation, U256)> for EvmMultiAsset { fn from(tuple: (MultiLocation, U256)) -> Self { EvmMultiAsset { - location: tuple.0, + location: tuple.0.into(), amount: tuple.1, } } diff --git a/precompiles/xtokens/src/tests.rs b/precompiles/xtokens/src/tests.rs index 29bffdef3c..1db86805d9 100644 --- a/precompiles/xtokens/src/tests.rs +++ b/precompiles/xtokens/src/tests.rs @@ -92,7 +92,7 @@ fn transfer_self_reserve_works() { PCall::transfer { currency_address: Address(SelfReserveAccount.into()), amount: 500.into(), - destination: destination.clone(), + destination: destination.clone().into(), weight: 4_000_000, }, ) @@ -139,7 +139,7 @@ fn transfer_to_reserve_works() { PCall::transfer { currency_address: Address(AssetAccount(0u128).into()), amount: 500.into(), - destination: destination.clone(), + destination: destination.clone().into(), weight: 4_000_000, }, ) @@ -186,7 +186,7 @@ fn transfer_to_reserve_with_unlimited_weight_works() { PCall::transfer { currency_address: Address(AssetAccount(0u128).into()), amount: 500.into(), - destination: destination.clone(), + destination: destination.clone().into(), weight: u64::MAX, }, ) @@ -235,7 +235,7 @@ fn transfer_to_reserve_with_fee_works() { currency_address: Address(AssetAccount(0u128).into()), amount: 500.into(), fee: 50.into(), - destination: destination.clone(), + destination: destination.clone().into(), weight: 4_000_000, }, ) @@ -290,7 +290,7 @@ fn transfer_non_reserve_to_non_reserve_works() { PCall::transfer { currency_address: Address(AssetAccount(1u128).into()), amount: 500.into(), - destination: destination.clone(), + destination: destination.clone().into(), weight: 4_000_000, }, ) @@ -339,7 +339,7 @@ fn transfer_non_reserve_to_non_reserve_with_fee_works() { currency_address: Address(AssetAccount(1u128).into()), amount: 500.into(), fee: 50.into(), - destination: destination.clone(), + destination: destination.clone().into(), weight: 4_000_000, }, ) @@ -392,9 +392,9 @@ fn transfer_multi_asset_to_reserve_works() { Alice, Precompile1, PCall::transfer_multiasset { - asset: asset.clone(), + asset: asset.clone().into(), amount: 500.into(), - destination: destination.clone(), + destination: destination.clone().into(), weight: 4_000_000, }, ) @@ -440,9 +440,9 @@ fn transfer_multi_asset_self_reserve_works() { Alice, Precompile1, PCall::transfer_multiasset { - asset: self_reserve.clone(), + asset: self_reserve.clone().into(), amount: 500.into(), - destination: destination.clone(), + destination: destination.clone().into(), weight: 4_000_000, }, ) @@ -487,10 +487,10 @@ fn transfer_multi_asset_self_reserve_with_fee_works() { Alice, Precompile1, PCall::transfer_multiasset_with_fee { - asset: self_reserve.clone(), + asset: self_reserve.clone().into(), amount: 500.into(), fee: 50.into(), - destination: destination.clone(), + destination: destination.clone().into(), weight: 4_000_000, }, ) @@ -542,9 +542,9 @@ fn transfer_multi_asset_non_reserve_to_non_reserve() { Alice, Precompile1, PCall::transfer_multiasset { - asset: asset_location.clone(), + asset: asset_location.clone().into(), amount: 500.into(), - destination: destination.clone(), + destination: destination.clone().into(), weight: 4_000_000, }, ) @@ -592,10 +592,10 @@ fn transfer_multi_asset_non_reserve_to_non_reserve_with_fee() { Alice, Precompile1, PCall::transfer_multiasset_with_fee { - asset: asset_location.clone(), + asset: asset_location.clone().into(), amount: 500.into(), fee: 50.into(), - destination: destination.clone(), + destination: destination.clone().into(), weight: 4_000_000, }, ) @@ -649,7 +649,7 @@ fn transfer_multi_currencies() { PCall::transfer_multi_currencies { currencies: currencies.into(), fee_item: 0, - destination: destination.clone(), + destination: destination.clone().into(), weight: 4_000_000, }, ) @@ -726,7 +726,7 @@ fn transfer_multi_assets() { PCall::transfer_multi_assets { assets: assets.into(), fee_item: 0, - destination: destination.clone(), + destination: destination.clone().into(), weight: 4_000_000, }, ) @@ -775,7 +775,7 @@ fn transfer_multi_currencies_cannot_insert_more_than_max() { PCall::transfer_multi_currencies { currencies: currencies.into(), fee_item: 0, - destination: destination.clone(), + destination: destination.clone().into(), weight: 4_000_000, }, ) @@ -828,7 +828,7 @@ fn transfer_multi_assets_cannot_insert_more_than_max() { PCall::transfer_multi_assets { assets: assets.into(), fee_item: 0, - destination: destination.clone(), + destination: destination.clone().into(), weight: 4_000_000, }, ) @@ -876,7 +876,7 @@ fn transfer_multi_assets_is_not_sorted_error() { PCall::transfer_multi_assets { assets: assets.into(), fee_item: 0, - destination: destination.clone(), + destination: destination.clone().into(), weight: 4_000_000, }, ) diff --git a/runtime/moonbase/tests/integration_test.rs b/runtime/moonbase/tests/integration_test.rs index 90f5713936..d8c7f7582d 100644 --- a/runtime/moonbase/tests/integration_test.rs +++ b/runtime/moonbase/tests/integration_test.rs @@ -2040,7 +2040,7 @@ fn xtokens_precompiles_transfer() { XtokensPCall::transfer { currency_address: Address(asset_precompile_address.into()), amount: 500_000_000_000_000u128.into(), - destination, + destination: destination.into(), weight: 4_000_000, }, ) @@ -2090,9 +2090,9 @@ fn xtokens_precompiles_transfer_multiasset() { xtokens_precompile_address, XtokensPCall::transfer_multiasset { // We want to transfer the relay token - asset: MultiLocation::parent(), + asset: MultiLocation::parent().into(), amount: 500_000_000_000_000u128.into(), - destination, + destination: destination.into(), weight: 4_000_000, }, ) @@ -2134,7 +2134,7 @@ fn xtokens_precompiles_transfer_native() { XtokensPCall::transfer { currency_address: Address(asset_precompile_address), amount: { 500 * UNIT }.into(), - destination: destination.clone(), + destination: destination.clone().into(), weight: 4_000_000, }, ) @@ -2182,7 +2182,7 @@ fn xtokens_precompile_transfer_local_asset() { XtokensPCall::transfer { currency_address: Address(asset_precompile_address), amount: { 500 * UNIT }.into(), - destination: destination.clone(), + destination: destination.clone().into(), weight: 4_000_000, }, ) @@ -2681,9 +2681,9 @@ fn transact_through_signed_precompile_works_v1() { .build() .execute_with(|| { // Destination - let dest = MultiLocation::parent(); + let dest = MultiLocation::parent().into(); - let fee_payer_asset = MultiLocation::parent(); + let fee_payer_asset = MultiLocation::parent().into(); let bytes = vec![1u8, 2u8, 3u8]; @@ -2733,9 +2733,9 @@ fn transact_through_signed_precompile_works_v2() { .build() .execute_with(|| { // Destination - let dest = MultiLocation::parent(); + let dest = MultiLocation::parent().into(); - let fee_payer_asset = MultiLocation::parent(); + let fee_payer_asset = MultiLocation::parent().into(); let bytes = vec![1u8, 2u8, 3u8]; @@ -2773,9 +2773,9 @@ fn transact_through_signed_cannot_send_to_local_chain() { .build() .execute_with(|| { // Destination - let dest = MultiLocation::here(); + let dest = MultiLocation::here().into(); - let fee_payer_asset = MultiLocation::parent(); + let fee_payer_asset = MultiLocation::parent().into(); let bytes = vec![1u8, 2u8, 3u8]; @@ -2977,7 +2977,7 @@ fn test_xcm_utils_ml_tp_account() { ALICE, xcm_utils_precompile_address, XcmUtilsPCall::multilocation_to_address { - multilocation: MultiLocation::parent(), + multilocation: MultiLocation::parent().into(), }, ) .expect_cost(1000) @@ -2997,7 +2997,7 @@ fn test_xcm_utils_ml_tp_account() { ALICE, xcm_utils_precompile_address, XcmUtilsPCall::multilocation_to_address { - multilocation: parachain_2000_multilocation, + multilocation: parachain_2000_multilocation.into(), }, ) .expect_cost(1000) @@ -3026,7 +3026,7 @@ fn test_xcm_utils_ml_tp_account() { ALICE, xcm_utils_precompile_address, XcmUtilsPCall::multilocation_to_address { - multilocation: alice_in_parachain_2000_multilocation, + multilocation: alice_in_parachain_2000_multilocation.into(), }, ) .expect_cost(1000) @@ -3060,7 +3060,7 @@ fn test_xcm_utils_weight_message() { fn test_xcm_utils_get_units_per_second() { ExtBuilder::default().build().execute_with(|| { let xcm_utils_precompile_address = H160::from_low_u64_be(2060); - let multilocation = SelfReserve::get(); + let multilocation = SelfReserve::get().into(); let input = XcmUtilsPCall::get_units_per_second { multilocation }; diff --git a/runtime/moonbeam/tests/integration_test.rs b/runtime/moonbeam/tests/integration_test.rs index 9f85bded15..b762880f93 100644 --- a/runtime/moonbeam/tests/integration_test.rs +++ b/runtime/moonbeam/tests/integration_test.rs @@ -2449,7 +2449,7 @@ fn xtokens_precompile_transfer() { XtokensPCall::transfer { currency_address: Address(asset_precompile_address.into()), amount: 500_000_000_000_000u128.into(), - destination: destination.clone(), + destination: destination.clone().into(), weight: 4_000_000, }, ) @@ -2499,9 +2499,9 @@ fn xtokens_precompile_transfer_multiasset() { xtokens_precompile_address, XtokensPCall::transfer_multiasset { // We want to transfer the relay token - asset: MultiLocation::parent(), + asset: MultiLocation::parent().into(), amount: 500_000_000_000_000u128.into(), - destination: destination.clone(), + destination: destination.clone().into(), weight: 4_000_000, }, ) @@ -2630,9 +2630,9 @@ fn transact_through_signed_precompile_works_v2() { .build() .execute_with(|| { // Destination - let dest = MultiLocation::parent(); + let dest = MultiLocation::parent().into(); - let fee_payer_asset = MultiLocation::parent(); + let fee_payer_asset = MultiLocation::parent().into(); let bytes = vec![1u8, 2u8, 3u8]; @@ -2670,9 +2670,9 @@ fn transact_through_signed_cannot_send_to_local_chain() { .build() .execute_with(|| { // Destination - let dest = MultiLocation::here(); + let dest = MultiLocation::here().into(); - let fee_payer_asset = MultiLocation::parent(); + let fee_payer_asset = MultiLocation::parent().into(); let bytes = vec![1u8, 2u8, 3u8]; @@ -2851,7 +2851,7 @@ fn test_xcm_utils_ml_tp_account() { ALICE, xcm_utils_precompile_address, XcmUtilsPCall::multilocation_to_address { - multilocation: MultiLocation::parent(), + multilocation: MultiLocation::parent().into(), }, ) .expect_cost(1000) @@ -2871,7 +2871,7 @@ fn test_xcm_utils_ml_tp_account() { ALICE, xcm_utils_precompile_address, XcmUtilsPCall::multilocation_to_address { - multilocation: parachain_2000_multilocation, + multilocation: parachain_2000_multilocation.into(), }, ) .expect_cost(1000) @@ -2900,7 +2900,7 @@ fn test_xcm_utils_ml_tp_account() { ALICE, xcm_utils_precompile_address, XcmUtilsPCall::multilocation_to_address { - multilocation: alice_in_parachain_2000_multilocation, + multilocation: alice_in_parachain_2000_multilocation.into(), }, ) .expect_cost(1000) @@ -2934,7 +2934,7 @@ fn test_xcm_utils_weight_message() { fn test_xcm_utils_get_units_per_second() { ExtBuilder::default().build().execute_with(|| { let xcm_utils_precompile_address = H160::from_low_u64_be(2060); - let multilocation = SelfReserve::get(); + let multilocation = SelfReserve::get().into(); let input = XcmUtilsPCall::get_units_per_second { multilocation }; diff --git a/runtime/moonriver/tests/integration_test.rs b/runtime/moonriver/tests/integration_test.rs index 9f23dd0eb1..c9adb2e423 100644 --- a/runtime/moonriver/tests/integration_test.rs +++ b/runtime/moonriver/tests/integration_test.rs @@ -2424,7 +2424,7 @@ fn xtokens_precompiles_transfer() { XtokensPCall::transfer { currency_address: Address(asset_precompile_address.into()), amount: 500_000_000_000_000u128.into(), - destination: destination.clone(), + destination: destination.into(), weight: 4_000_000, }, ) @@ -2474,9 +2474,9 @@ fn xtokens_precompiles_transfer_multiasset() { xtokens_precompile_address, XtokensPCall::transfer_multiasset { // We want to transfer the relay token - asset: MultiLocation::parent(), + asset: MultiLocation::parent().into(), amount: 500_000_000_000_000u128.into(), - destination, + destination: destination.into(), weight: 4_000_000, }, ) @@ -2625,9 +2625,9 @@ fn transact_through_signed_precompile_works_v2() { .build() .execute_with(|| { // Destination - let dest = MultiLocation::parent(); + let dest = MultiLocation::parent().into(); - let fee_payer_asset = MultiLocation::parent(); + let fee_payer_asset = MultiLocation::parent().into(); let bytes = vec![1u8, 2u8, 3u8]; @@ -2665,9 +2665,9 @@ fn transact_through_signed_cannot_send_to_local_chain() { .build() .execute_with(|| { // Destination - let dest = MultiLocation::here(); + let dest = MultiLocation::here().into(); - let fee_payer_asset = MultiLocation::parent(); + let fee_payer_asset = MultiLocation::parent().into(); let bytes = vec![1u8, 2u8, 3u8]; @@ -2760,7 +2760,7 @@ fn test_xcm_utils_ml_tp_account() { ALICE, xcm_utils_precompile_address, XcmUtilsPCall::multilocation_to_address { - multilocation: MultiLocation::parent(), + multilocation: MultiLocation::parent().into(), }, ) .expect_cost(1000) @@ -2780,7 +2780,7 @@ fn test_xcm_utils_ml_tp_account() { ALICE, xcm_utils_precompile_address, XcmUtilsPCall::multilocation_to_address { - multilocation: parachain_2000_multilocation, + multilocation: parachain_2000_multilocation.into(), }, ) .expect_cost(1000) @@ -2809,7 +2809,7 @@ fn test_xcm_utils_ml_tp_account() { ALICE, xcm_utils_precompile_address, XcmUtilsPCall::multilocation_to_address { - multilocation: alice_in_parachain_2000_multilocation, + multilocation: alice_in_parachain_2000_multilocation.into(), }, ) .expect_cost(1000) @@ -2843,7 +2843,7 @@ fn test_xcm_utils_weight_message() { fn test_xcm_utils_get_units_per_second() { ExtBuilder::default().build().execute_with(|| { let xcm_utils_precompile_address = H160::from_low_u64_be(2060); - let multilocation = SelfReserve::get(); + let multilocation = SelfReserve::get().into(); let input = XcmUtilsPCall::get_units_per_second { multilocation }; diff --git a/runtime/summarize-precompile-checks/Cargo.toml b/runtime/summarize-precompile-checks/Cargo.toml index f7d96d9c8f..132934fabc 100644 --- a/runtime/summarize-precompile-checks/Cargo.toml +++ b/runtime/summarize-precompile-checks/Cargo.toml @@ -12,5 +12,5 @@ clap = "4.0.18" moonbase-runtime = { path = "../moonbase" } moonbeam-runtime = { path = "../moonbeam" } moonriver-runtime = { path = "../moonriver" } -precompile-utils = { path = "../../precompiles/utils", features = [ "testing" ] } +precompile-utils = { workspace = true, features = [ "testing" ] } serde_json = "1.0"