From d54fdd788efe07ee96b26946f805b54c983a7c0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Sat, 12 Jun 2021 19:21:46 +0100 Subject: [PATCH] Bring support for calling `check_inherents` (#490) * Start * More work * Add proc-macro for `validate_block` * Make everything compile * Add some test --- Cargo.lock | 232 +++++++++--------- Cargo.toml | 1 + pallets/aura-ext/src/lib.rs | 10 +- pallets/parachain-system/Cargo.toml | 8 +- .../parachain-system/proc-macro/Cargo.toml | 19 ++ .../parachain-system/proc-macro/src/lib.rs | 144 +++++++++++ pallets/parachain-system/src/lib.rs | 67 +++-- .../src/relay_state_snapshot.rs | 198 ++++++++------- .../src/validate_block/implementation.rs | 76 ++++-- .../src/validate_block/mod.rs | 61 ----- .../src/validate_block/tests.rs | 49 +++- polkadot-parachains/rococo-runtime/src/lib.rs | 20 +- polkadot-parachains/shell-runtime/src/lib.rs | 17 +- .../statemine-runtime/src/lib.rs | 20 +- .../statemint-runtime/src/lib.rs | 20 +- .../westmint-runtime/src/lib.rs | 20 +- .../parachain-inherent/src/client_side.rs | 7 +- primitives/parachain-inherent/src/lib.rs | 1 + test/relay-sproof-builder/src/lib.rs | 11 +- test/runtime/src/lib.rs | 27 +- 20 files changed, 683 insertions(+), 325 deletions(-) create mode 100644 pallets/parachain-system/proc-macro/Cargo.toml create mode 100644 pallets/parachain-system/proc-macro/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 6d34b3fca95..a4416fa1d1d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -204,7 +204,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3203e79f4dd9bdda415ed03cf14dae5a2bf775c683a00f94e9cd1faf0f596e5" dependencies = [ "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", ] [[package]] @@ -357,9 +357,9 @@ version = "0.1.50" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b98e84bbb4cbcdd97da190ba0c58a1bb0de2c1fdf67d159e192ed766aeca722" dependencies = [ - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", ] [[package]] @@ -557,7 +557,7 @@ dependencies = [ "lazy_static", "lazycell", "peeking_take_while", - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", "regex", "rustc-hash", @@ -1380,7 +1380,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8f45d9ad417bcef4817d614a501ab55cdd96a6fdb24f49aab89a54acfd66b19" dependencies = [ "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", ] [[package]] @@ -1651,6 +1651,7 @@ dependencies = [ name = "cumulus-pallet-parachain-system" version = "0.1.0" dependencies = [ + "cumulus-pallet-parachain-system-proc-macro", "cumulus-primitives-core", "cumulus-primitives-parachain-inherent", "cumulus-test-client", @@ -1659,11 +1660,9 @@ dependencies = [ "environmental", "frame-support", "frame-system", - "hash-db", "hex-literal 0.2.1", "lazy_static", "log", - "memory-db", "pallet-balances", "parity-scale-codec", "polkadot-parachain", @@ -1684,10 +1683,19 @@ dependencies = [ "sp-trie", "sp-version", "substrate-test-runtime-client", - "trie-db", "xcm", ] +[[package]] +name = "cumulus-pallet-parachain-system-proc-macro" +version = "0.1.0" +dependencies = [ + "proc-macro-crate 1.0.0", + "proc-macro2 1.0.27", + "quote 1.0.9", + "syn 1.0.73", +] + [[package]] name = "cumulus-pallet-xcm" version = "0.1.0" @@ -2088,7 +2096,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0f83e699727abca3c56e187945f303389590305ab2f0185ea445aa66e8d5f2a" dependencies = [ "data-encoding", - "syn 1.0.68", + "syn 1.0.73", ] [[package]] @@ -2097,9 +2105,9 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" dependencies = [ - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", ] [[package]] @@ -2122,9 +2130,9 @@ version = "0.99.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41cb0e6161ad61ed084a36ba71fbba9e3ac5aee3606fb607fe08da6acbcf3d8c" dependencies = [ - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", ] [[package]] @@ -2230,9 +2238,9 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "558e40ea573c374cf53507fd240b7ee2f5477df7cfebdb97323ec61c719399c5" dependencies = [ - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", ] [[package]] @@ -2277,9 +2285,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c5f0096a91d210159eceb2ff5e1c4da18388a170e1e3ce948aac9c8fdbbf595" dependencies = [ "heck", - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", ] [[package]] @@ -2297,9 +2305,9 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "946ee94e3dbf58fdd324f9ce245c7b238d46a66f00e86a020b71996349e46cce" dependencies = [ - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", ] [[package]] @@ -2308,9 +2316,9 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4e58b112d5099aa0857c5d05f0eacab86406dd8c0f85fe5d320a13256d29ecf4" dependencies = [ - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", ] [[package]] @@ -2455,9 +2463,9 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" dependencies = [ - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", "synstructure", ] @@ -2686,9 +2694,9 @@ source = "git+https://github.com/paritytech/substrate?branch=master#a2f48bf96eec dependencies = [ "Inflector", "frame-support-procedural-tools", - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", ] [[package]] @@ -2698,9 +2706,9 @@ source = "git+https://github.com/paritytech/substrate?branch=master#a2f48bf96eec dependencies = [ "frame-support-procedural-tools-derive", "proc-macro-crate 1.0.0", - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", ] [[package]] @@ -2708,9 +2716,9 @@ name = "frame-support-procedural-tools-derive" version = "3.0.0" source = "git+https://github.com/paritytech/substrate?branch=master#a2f48bf96eecbb5cd1f45bd5319ba814595eaaef" dependencies = [ - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", ] [[package]] @@ -2924,9 +2932,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "668c6733a182cd7deb4f1de7ba3bf2120823835b3bcfbeacf7d2c4a773c1bb8b" dependencies = [ "proc-macro-hack", - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", ] [[package]] @@ -3554,9 +3562,9 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5dacb10c5b3bb92d46ba347505a9041e676bb20ad220101326bffb0c93031ee" dependencies = [ - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", ] [[package]] @@ -3724,9 +3732,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99a847f9ec7bb52149b2786a17c9cb260d6effc6b8eeb8c16b343a487a7563a3" dependencies = [ "proc-macro-crate 0.1.5", - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", ] [[package]] @@ -3809,9 +3817,9 @@ checksum = "3b4c85cfa6767333f3e5f3b2f2f765dad2727b0033ee270ae07c599bf43ed5ae" dependencies = [ "Inflector", "proc-macro-crate 1.0.0", - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", ] [[package]] @@ -4412,7 +4420,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "365b0a699fea5168676840567582a012ea297b1ca02eee467e58301b9c9c5eed" dependencies = [ "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", ] [[package]] @@ -4684,9 +4692,9 @@ version = "3.0.0" source = "git+https://github.com/paritytech/substrate?branch=master#a2f48bf96eecbb5cd1f45bd5319ba814595eaaef" dependencies = [ "proc-macro-crate 1.0.0", - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", ] [[package]] @@ -4802,9 +4810,9 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19ce18b5423c573a13e80cb3046ea0af6379ef725dc3af4886bdb8f4e5093068" dependencies = [ - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", ] [[package]] @@ -4935,9 +4943,9 @@ checksum = "85ee3c48cb9d9b275ad967a0e96715badc13c6029adb92f34fa17b9ff28fd81f" dependencies = [ "proc-macro-crate 0.1.5", "proc-macro-error", - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", "synstructure", ] @@ -5791,9 +5799,9 @@ version = "3.0.0" source = "git+https://github.com/paritytech/substrate?branch=master#a2f48bf96eecbb5cd1f45bd5319ba814595eaaef" dependencies = [ "proc-macro-crate 1.0.0", - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", ] [[package]] @@ -6035,9 +6043,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f44c5f94427bd0b5076e8f7e15ca3f60a4d8ac0077e4793884e6fdfd8915344e" dependencies = [ "proc-macro-crate 0.1.5", - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", ] [[package]] @@ -6089,8 +6097,8 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f557c32c6d268a07c921471619c0295f5efad3a0e76d4f97a05c091a51d110b2" dependencies = [ - "proc-macro2 1.0.26", - "syn 1.0.68", + "proc-macro2 1.0.27", + "syn 1.0.73", "synstructure", ] @@ -6326,9 +6334,9 @@ checksum = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55" dependencies = [ "pest", "pest_meta", - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", ] [[package]] @@ -6376,9 +6384,9 @@ version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "65ad2ae56b6abe3a1ee25f15ee605bacadb9a764edaba9c2bf4103800d4a1895" dependencies = [ - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", ] [[package]] @@ -6387,9 +6395,9 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "caa25a6393f22ce819b0f50e0be89287292fda8d425be38ee0ca14c4931d9e71" dependencies = [ - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", ] [[package]] @@ -7116,9 +7124,9 @@ version = "0.1.0" source = "git+https://github.com/paritytech/polkadot?branch=master#a803f87252b82f66df3c3ec1c23b94b50090ef8d" dependencies = [ "assert_matches", - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", ] [[package]] @@ -7127,9 +7135,9 @@ version = "0.1.0" source = "git+https://github.com/paritytech/polkadot?branch=master#a803f87252b82f66df3c3ec1c23b94b50090ef8d" dependencies = [ "assert_matches", - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", ] [[package]] @@ -7685,9 +7693,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" dependencies = [ "proc-macro-error-attr", - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", "version_check", ] @@ -7697,7 +7705,7 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" dependencies = [ - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", "version_check", ] @@ -7725,9 +7733,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.26" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec" +checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038" dependencies = [ "unicode-xid 0.2.1", ] @@ -7782,9 +7790,9 @@ checksum = "169a15f3008ecb5160cba7d37bcd690a7601b6d30cfb87a117d45e59d52af5d4" dependencies = [ "anyhow", "itertools 0.9.0", - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", ] [[package]] @@ -7855,7 +7863,7 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" dependencies = [ - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", ] [[package]] @@ -8197,9 +8205,9 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c38e3aecd2b21cb3959637b883bb3714bc7e43f0268b9a29d3743ee3e55cdd2" dependencies = [ - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", ] [[package]] @@ -8646,9 +8654,9 @@ version = "3.0.0" source = "git+https://github.com/paritytech/substrate?branch=master#a2f48bf96eecbb5cd1f45bd5319ba814595eaaef" dependencies = [ "proc-macro-crate 1.0.0", - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", ] [[package]] @@ -9500,9 +9508,9 @@ version = "3.0.0" source = "git+https://github.com/paritytech/substrate?branch=master#a2f48bf96eecbb5cd1f45bd5319ba814595eaaef" dependencies = [ "proc-macro-crate 1.0.0", - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", ] [[package]] @@ -9615,9 +9623,9 @@ version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b12bd20b94c7cdfda8c7ba9b92ad0d9a56e3fa018c25fca83b51aa664c9b4c0d" dependencies = [ - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", ] [[package]] @@ -9743,9 +9751,9 @@ version = "1.0.126" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43" dependencies = [ - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", ] [[package]] @@ -10031,9 +10039,9 @@ source = "git+https://github.com/paritytech/substrate?branch=master#a2f48bf96eec dependencies = [ "blake2-rfc", "proc-macro-crate 1.0.0", - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", ] [[package]] @@ -10273,9 +10281,9 @@ name = "sp-debug-derive" version = "3.0.0" source = "git+https://github.com/paritytech/substrate?branch=master#a2f48bf96eecbb5cd1f45bd5319ba814595eaaef" dependencies = [ - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", ] [[package]] @@ -10401,9 +10409,9 @@ version = "3.0.0" source = "git+https://github.com/paritytech/substrate?branch=master#a2f48bf96eecbb5cd1f45bd5319ba814595eaaef" dependencies = [ "proc-macro-crate 1.0.0", - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", ] [[package]] @@ -10481,9 +10489,9 @@ source = "git+https://github.com/paritytech/substrate?branch=master#a2f48bf96eec dependencies = [ "Inflector", "proc-macro-crate 1.0.0", - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", ] [[package]] @@ -10697,9 +10705,9 @@ source = "git+https://github.com/paritytech/substrate?branch=master#a2f48bf96eec dependencies = [ "parity-scale-codec", "proc-macro-crate 1.0.0", - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", ] [[package]] @@ -10903,9 +10911,9 @@ checksum = "f2261c91034a1edc3fc4d1b80e89d82714faede0515c14a75da10cb941546bbf" dependencies = [ "cfg_aliases", "memchr", - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", ] [[package]] @@ -10973,9 +10981,9 @@ checksum = "5ba9cdfda491b814720b6b06e0cac513d922fc407582032e8706e9f137976f90" dependencies = [ "heck", "proc-macro-error", - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", ] [[package]] @@ -10994,9 +11002,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee8bc6b87a5112aeeab1f4a9f7ab634fe6cbefc4850006df31267f4cfb9e3149" dependencies = [ "heck", - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", ] [[package]] @@ -11165,7 +11173,7 @@ source = "git+https://github.com/paritytech/substrate?branch=master#5d89967d7cc1 dependencies = [ "proc-macro-crate 1.0.0", "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", ] [[package]] @@ -11225,11 +11233,11 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.68" +version = "1.0.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ce15dd3ed8aa2f8eeac4716d6ef5ab58b6b9256db41d7e1a0224c2788e8fd87" +checksum = "f71489ff30030d2ae598524f61326b902466f72a0fb1a8564c001cc63425bcc7" dependencies = [ - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", "unicode-xid 0.2.1", ] @@ -11240,9 +11248,9 @@ version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701" dependencies = [ - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", "unicode-xid 0.2.1", ] @@ -11311,9 +11319,9 @@ version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7765189610d8241a44529806d6fd1f2e0a08734313a35d5b3a556f92b381f3c0" dependencies = [ - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", ] [[package]] @@ -11527,9 +11535,9 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e44da00bfc73a25f814cd8d7e57a68a5c31b74b3152a0a1d1f590c97ed06265a" dependencies = [ - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", ] [[package]] @@ -11732,9 +11740,9 @@ version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c42e6fa53307c8a17e4ccd4dc81cf5ec38db9209f59b222210375b54ee40d1e2" dependencies = [ - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", ] [[package]] @@ -12179,9 +12187,9 @@ dependencies = [ "bumpalo", "lazy_static", "log", - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", "wasm-bindgen-shared", ] @@ -12213,9 +12221,9 @@ version = "0.2.73" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d53739ff08c8a68b0fdbcd54c372b8ab800b1449ab3c9d706503bc7dd1621b2c" dependencies = [ - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -12861,9 +12869,9 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3f369ddb18862aba61aa49bf31e74d29f0f162dec753063200e1dc084345d16" dependencies = [ - "proc-macro2 1.0.26", + "proc-macro2 1.0.27", "quote 1.0.9", - "syn 1.0.68", + "syn 1.0.73", "synstructure", ] diff --git a/Cargo.toml b/Cargo.toml index a1bbff9c537..ae32d360658 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ members = [ "pallets/collator-selection", "pallets/dmp-queue", "pallets/parachain-system", + "pallets/parachain-system/proc-macro", "pallets/session-benchmarking", "pallets/xcm", "pallets/xcmp-queue", diff --git a/pallets/aura-ext/src/lib.rs b/pallets/aura-ext/src/lib.rs index 3638f5d9181..3ea994f42cb 100644 --- a/pallets/aura-ext/src/lib.rs +++ b/pallets/aura-ext/src/lib.rs @@ -25,10 +25,12 @@ //! ``` //!# struct Runtime; //!# struct Executive; -//! cumulus_pallet_parachain_system::register_validate_block!( -//! Runtime, -//! cumulus_pallet_aura_ext::BlockExecutor::, -//! ); +//!# struct CheckInherents; +//! cumulus_pallet_parachain_system::register_validate_block! { +//! Runtime = Runtime, +//! BlockExecutor = cumulus_pallet_aura_ext::BlockExecutor::, +//! CheckInherents = CheckInherents, +//! } //! ``` #![cfg_attr(not(feature = "std"), no_std)] diff --git a/pallets/parachain-system/Cargo.toml b/pallets/parachain-system/Cargo.toml index 5202fd0518e..f265fcaf68c 100644 --- a/pallets/parachain-system/Cargo.toml +++ b/pallets/parachain-system/Cargo.toml @@ -9,6 +9,7 @@ description = "Base pallet for cumulus-based parachains" # Cumulus dependencies cumulus-primitives-core = { path = "../../primitives/core", default-features = false } cumulus-primitives-parachain-inherent = { path = "../../primitives/parachain-inherent", default-features = false } +cumulus-pallet-parachain-system-proc-macro = { path = "proc-macro", default-features = false } # Polkadot dependencies polkadot-parachain = { git = "https://github.com/paritytech/polkadot", default-features = false, features = [ "wasm-api" ], branch = "master" } @@ -31,10 +32,7 @@ sp-externalities = { git = "https://github.com/paritytech/substrate", default-fe # Other Dependencies codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false, features = ["derive"]} serde = { version = "1.0.101", optional = true, features = ["derive"] } -hash-db = { version = "0.15.2", default-features = false } log = { version = "0.4.14", default-features = false } -memory-db = { version = "0.26.0", default-features = false } -trie-db = { version = "0.22.0", default-features = false } environmental = { version = "1.1.2", default-features = false } [dev-dependencies] @@ -63,16 +61,14 @@ std = [ "sp-runtime/std", "sp-io/std", "sp-std/std", - "hash-db/std", "log/std", - "memory-db/std", - "trie-db/std", "sp-state-machine/std", "sp-trie/std", "sp-externalities/std", "frame-system/std", "cumulus-primitives-core/std", "cumulus-primitives-parachain-inherent/std", + "cumulus-pallet-parachain-system-proc-macro/std", "environmental/std", "xcm/std" ] diff --git a/pallets/parachain-system/proc-macro/Cargo.toml b/pallets/parachain-system/proc-macro/Cargo.toml new file mode 100644 index 00000000000..ea47cfdfc44 --- /dev/null +++ b/pallets/parachain-system/proc-macro/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "cumulus-pallet-parachain-system-proc-macro" +version = "0.1.0" +authors = ["Parity Technologies "] +edition = "2018" +description = "Proc macros provided by the parachain-system pallet" + +[lib] +proc-macro = true + +[dependencies] +syn = "1.0.73" +proc-macro2 = "1.0.27" +quote = "1.0.9" +proc-macro-crate = "1.0.0" + +[features] +default = [ "std" ] +std = [] diff --git a/pallets/parachain-system/proc-macro/src/lib.rs b/pallets/parachain-system/proc-macro/src/lib.rs new file mode 100644 index 00000000000..c56387707d9 --- /dev/null +++ b/pallets/parachain-system/proc-macro/src/lib.rs @@ -0,0 +1,144 @@ +// Copyright 2021 Parity Technologies (UK) Ltd. +// This file is part of Cumulus. + +// Cumulus 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. + +// Cumulus 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 Cumulus. If not, see . + +use proc_macro2::{Span, TokenStream}; +use proc_macro_crate::{crate_name, FoundCrate}; +use syn::{ + parse::{Parse, ParseStream}, + spanned::Spanned, + token, Error, Ident, Path, +}; + +mod keywords { + syn::custom_keyword!(Runtime); + syn::custom_keyword!(BlockExecutor); + syn::custom_keyword!(CheckInherents); +} + +struct Input { + runtime: Path, + block_executor: Path, + check_inherents: Path, +} + +impl Parse for Input { + fn parse(input: ParseStream) -> Result { + let mut runtime = None; + let mut block_executor = None; + let mut check_inherents = None; + + fn parse_inner( + input: ParseStream, + result: &mut Option, + ) -> Result<(), Error> { + let kw = input.parse::()?; + + if result.is_none() { + input.parse::()?; + *result = Some(input.parse::()?); + if input.peek(token::Comma) { + input.parse::()?; + } + + Ok(()) + } else { + Err(Error::new(kw.span(), "Is only allowed to be passed once")) + } + } + + while runtime.is_none() || block_executor.is_none() || check_inherents.is_none() { + let lookahead = input.lookahead1(); + + if lookahead.peek(keywords::Runtime) { + parse_inner::(input, &mut runtime)?; + } else if lookahead.peek(keywords::BlockExecutor) { + parse_inner::(input, &mut block_executor)?; + } else if lookahead.peek(keywords::CheckInherents) { + parse_inner::(input, &mut check_inherents)?; + } else { + return Err(lookahead.error()); + } + } + + let rest = input.parse::()?; + if !rest.is_empty() { + return Err(Error::new(rest.span(), "Unexpected input data")); + } + + Ok(Self { + runtime: runtime.expect("Everything is parsed before; qed"), + block_executor: block_executor.expect("Everything is parsed before; qed"), + check_inherents: check_inherents.expect("Everything is parsed before; qed"), + }) + } +} + +fn crate_() -> Result { + match crate_name("cumulus-pallet-parachain-system") { + Ok(FoundCrate::Itself) => Ok(syn::Ident::new( + "cumulus_pallet_parachain_system", + Span::call_site(), + )), + Ok(FoundCrate::Name(name)) => Ok(Ident::new(&name, Span::call_site())), + Err(e) => Err(Error::new(Span::call_site(), e)), + } +} + +#[proc_macro] +pub fn register_validate_block(input: proc_macro::TokenStream) -> proc_macro::TokenStream { + let Input { + runtime, + check_inherents, + block_executor, + } = match syn::parse(input) { + Ok(t) => t, + Err(e) => return e.into_compile_error().into(), + }; + + let crate_ = match crate_() { + Ok(c) => c, + Err(e) => return e.into_compile_error().into(), + }; + + if cfg!(not(feature = "std")) { + quote::quote! { + #[doc(hidden)] + mod parachain_validate_block { + use super::*; + + #[no_mangle] + unsafe fn validate_block(arguments: *const u8, arguments_len: usize) -> u64 { + let params = #crate_::validate_block::polkadot_parachain::load_params( + arguments, + arguments_len, + ); + + let res = #crate_::validate_block::implementation::validate_block::< + <#runtime as #crate_::validate_block::GetRuntimeBlockType>::RuntimeBlock, + #block_executor, + #runtime, + #check_inherents, + >(params); + + #crate_::validate_block::polkadot_parachain::write_result(&res) + } + } + } + } else { + quote::quote!() + } + .into() +} diff --git a/pallets/parachain-system/src/lib.rs b/pallets/parachain-system/src/lib.rs index eb03bb0feda..2e2a9b8e34f 100644 --- a/pallets/parachain-system/src/lib.rs +++ b/pallets/parachain-system/src/lib.rs @@ -30,8 +30,8 @@ use cumulus_primitives_core::{ relay_chain, AbridgedHostConfiguration, ChannelStatus, CollationInfo, DmpMessageHandler, GetChannelInfo, InboundDownwardMessage, InboundHrmpMessage, MessageSendError, OnValidationData, - OutboundHrmpMessage, ParaId, PersistedValidationData, UpwardMessage, UpwardMessageSender, - XcmpMessageHandler, XcmpMessageSource, + OutboundHrmpMessage, ParaId, UpwardMessage, UpwardMessageSender, XcmpMessageHandler, + XcmpMessageSource, PersistedValidationData, }; use cumulus_primitives_parachain_inherent::ParachainInherentData; use frame_support::{ @@ -46,7 +46,7 @@ use frame_system::{ensure_none, ensure_root}; use polkadot_parachain::primitives::RelayChainBlockNumber; use relay_state_snapshot::MessagingStateSnapshot; use sp_runtime::{ - traits::{BlakeTwo256, Hash}, + traits::{BlakeTwo256, Block as BlockT, Hash}, transaction_validity::{ InvalidTransaction, TransactionLongevity, TransactionSource, TransactionValidity, ValidTransaction, @@ -60,6 +60,31 @@ pub mod validate_block; #[cfg(test)] mod tests; +/// Register the `validate_block` function that is used by parachains to validate blocks on a +/// validator. +/// +/// Does *nothing* when `std` feature is enabled. +/// +/// Expects as parameters the runtime, a block executor and an inherent checker. +/// +/// # Example +/// +/// ``` +/// struct BlockExecutor; +/// struct Runtime; +/// struct CheckInherents; +/// +/// cumulus_pallet_parachain_system::register_validate_block! { +/// Runtime = Runtime, +/// BlockExecutor = Executive, +/// CheckInherents = CheckInherents, +/// } +/// +/// # fn main() {} +/// ``` +pub use cumulus_pallet_parachain_system_proc_macro::register_validate_block; +pub use relay_state_snapshot::RelayChainStateProof; + pub use pallet::*; #[frame_support::pallet] @@ -309,17 +334,19 @@ pub mod pallet { } } - let (host_config, relevant_messaging_state) = - match relay_state_snapshot::extract_from_proof( - T::SelfParaId::get(), - vfp.relay_parent_storage_root, - relay_chain_state, - ) { - Ok(r) => r, - Err(err) => { - panic!("invalid relay chain merkle proof: {:?}", err); - } - }; + let relay_state_proof = RelayChainStateProof::new( + T::SelfParaId::get(), + vfp.relay_parent_storage_root, + relay_chain_state, + ) + .expect("Invalid relay chain state proof"); + + let host_config = relay_state_proof + .read_abridged_host_configuration() + .expect("Invalid host configuration in relay chain state proof"); + let relevant_messaging_state = relay_state_proof + .read_messaging_state_snapshot() + .expect("Invalid messaging state in relay chain state proof"); >::put(&vfp); >::put(relevant_messaging_state.clone()); @@ -999,3 +1026,15 @@ impl UpwardMessageSender for Pallet { Self::send_upward_message(message) } } + +/// Something that can check the inherents of a block. +pub trait CheckInherents { + /// Check all inherents of the block. + /// + /// This function gets passed all the extrinsics of the block, so it is up to the callee to + /// identify the inherents. The `validation_data` can be used to access the + fn check_inherents( + extrinsics: &[Block::Extrinsic], + validation_data: &RelayChainStateProof, + ) -> frame_support::inherent::CheckInherentsResult; +} diff --git a/pallets/parachain-system/src/relay_state_snapshot.rs b/pallets/parachain-system/src/relay_state_snapshot.rs index 1bfe478e329..d2ad2c45a06 100644 --- a/pallets/parachain-system/src/relay_state_snapshot.rs +++ b/pallets/parachain-system/src/relay_state_snapshot.rs @@ -14,13 +14,15 @@ // You should have received a copy of the GNU General Public License // along with Cumulus. If not, see . -use codec::{Encode, Decode}; -use cumulus_primitives_core::{relay_chain, AbridgedHostConfiguration, AbridgedHrmpChannel, ParaId}; -use hash_db::{HashDB, EMPTY_PREFIX}; +use codec::{Decode, Encode}; +use cumulus_primitives_core::{ + relay_chain, AbridgedHostConfiguration, AbridgedHrmpChannel, ParaId, +}; +use sp_trie::{MemoryDB, HashDBT, EMPTY_PREFIX}; use sp_runtime::traits::HashFor; use sp_state_machine::{Backend, TrieBackend}; -use sp_trie::StorageProof; use sp_std::vec::Vec; +use sp_trie::StorageProof; /// A snapshot of some messaging related state of relay chain pertaining to the current parachain. /// @@ -61,6 +63,8 @@ pub struct MessagingStateSnapshot { pub enum Error { /// The provided proof was created against unexpected storage root. RootMismatch, + /// The slot cannot be extracted. + Slot(ReadEntryErr), /// The host configuration cannot be extracted. Config(ReadEntryErr), /// The DMQ MQC head cannot be extracted. @@ -105,94 +109,122 @@ where .ok_or(ReadEntryErr::Absent) } -/// Extract the relay chain state from the given storage proof. This function accepts the `para_id` -/// of the current parachain and the expected storage root the proof should stem from. -pub fn extract_from_proof( +/// A state proof extracted from the relay chain. +/// +/// This state proof is extracted from the relay chain block we are building on top of. +pub struct RelayChainStateProof { para_id: ParaId, - relay_parent_storage_root: relay_chain::v1::Hash, - proof: StorageProof, -) -> Result<(AbridgedHostConfiguration, MessagingStateSnapshot), Error> { - let db = proof.into_memory_db::>(); - if !db.contains(&relay_parent_storage_root, EMPTY_PREFIX) { - return Err(Error::RootMismatch); + trie_backend: TrieBackend>, HashFor>, +} + +impl RelayChainStateProof { + /// Create a new instance of `Self`. + /// + /// Returns an error if the given `relay_parent_storage_root` is not the root of the given + /// `proof`. + pub fn new( + para_id: ParaId, + relay_parent_storage_root: relay_chain::v1::Hash, + proof: StorageProof, + ) -> Result { + let db = proof.into_memory_db::>(); + if !db.contains(&relay_parent_storage_root, EMPTY_PREFIX) { + return Err(Error::RootMismatch); + } + let trie_backend = TrieBackend::new(db, relay_parent_storage_root); + + Ok(Self { + para_id, + trie_backend, + }) } - let backend = TrieBackend::new(db, relay_parent_storage_root); - - let host_config: AbridgedHostConfiguration = read_entry( - &backend, - relay_chain::well_known_keys::ACTIVE_CONFIG, - None, - ) - .map_err(Error::Config)?; - - let dmq_mqc_head: relay_chain::Hash = read_entry( - &backend, - &relay_chain::well_known_keys::dmq_mqc_head(para_id), - Some(Default::default()), - ) - .map_err(Error::DmqMqcHead)?; - - let relay_dispatch_queue_size: (u32, u32) = read_entry( - &backend, - &relay_chain::well_known_keys::relay_dispatch_queue_size(para_id), - Some((0, 0)), - ) - .map_err(Error::RelayDispatchQueueSize)?; - - let ingress_channel_index: Vec = read_entry( - &backend, - &relay_chain::well_known_keys::hrmp_ingress_channel_index(para_id), - Some(Vec::new()), - ) - .map_err(Error::HrmpIngressChannelIndex)?; - - let egress_channel_index: Vec = read_entry( - &backend, - &relay_chain::well_known_keys::hrmp_egress_channel_index(para_id), - Some(Vec::new()), - ) - .map_err(Error::HrmpEgressChannelIndex)?; - - let mut ingress_channels = Vec::with_capacity(ingress_channel_index.len()); - for sender in ingress_channel_index { - let channel_id = relay_chain::v1::HrmpChannelId { - sender, - recipient: para_id, - }; - let hrmp_channel: AbridgedHrmpChannel = read_entry( - &backend, - &relay_chain::well_known_keys::hrmp_channels(channel_id), - None, + + /// Read the [`MessagingStateSnapshot`] from the relay chain state proof. + /// + /// Returns an error if anything failed at reading or decoding. + pub fn read_messaging_state_snapshot(&self) -> Result { + let dmq_mqc_head: relay_chain::Hash = read_entry( + &self.trie_backend, + &relay_chain::well_known_keys::dmq_mqc_head(self.para_id), + Some(Default::default()), ) - .map_err(|read_err| Error::HrmpChannel(sender, para_id, read_err))?; - ingress_channels.push((sender, hrmp_channel)); - } + .map_err(Error::DmqMqcHead)?; - let mut egress_channels = Vec::with_capacity(egress_channel_index.len()); - for recipient in egress_channel_index { - let channel_id = relay_chain::v1::HrmpChannelId { - sender: para_id, - recipient, - }; - let hrmp_channel: AbridgedHrmpChannel = read_entry( - &backend, - &relay_chain::well_known_keys::hrmp_channels(channel_id), - None, + let relay_dispatch_queue_size: (u32, u32) = read_entry( + &self.trie_backend, + &relay_chain::well_known_keys::relay_dispatch_queue_size(self.para_id), + Some((0, 0)), ) - .map_err(|read_err| Error::HrmpChannel(para_id, recipient, read_err))?; - egress_channels.push((recipient, hrmp_channel)); - } + .map_err(Error::RelayDispatchQueueSize)?; - // NOTE that ingress_channels and egress_channels promise to be sorted. We satisfy this property - // by relying on the fact that `ingress_channel_index` and `egress_channel_index` are themselves sorted. + let ingress_channel_index: Vec = read_entry( + &self.trie_backend, + &relay_chain::well_known_keys::hrmp_ingress_channel_index(self.para_id), + Some(Vec::new()), + ) + .map_err(Error::HrmpIngressChannelIndex)?; - Ok(( - host_config, - MessagingStateSnapshot { + let egress_channel_index: Vec = read_entry( + &self.trie_backend, + &relay_chain::well_known_keys::hrmp_egress_channel_index(self.para_id), + Some(Vec::new()), + ) + .map_err(Error::HrmpEgressChannelIndex)?; + + let mut ingress_channels = Vec::with_capacity(ingress_channel_index.len()); + for sender in ingress_channel_index { + let channel_id = relay_chain::v1::HrmpChannelId { + sender, + recipient: self.para_id, + }; + let hrmp_channel: AbridgedHrmpChannel = read_entry( + &self.trie_backend, + &relay_chain::well_known_keys::hrmp_channels(channel_id), + None, + ) + .map_err(|read_err| Error::HrmpChannel(sender, self.para_id, read_err))?; + ingress_channels.push((sender, hrmp_channel)); + } + + let mut egress_channels = Vec::with_capacity(egress_channel_index.len()); + for recipient in egress_channel_index { + let channel_id = relay_chain::v1::HrmpChannelId { + sender: self.para_id, + recipient, + }; + let hrmp_channel: AbridgedHrmpChannel = read_entry( + &self.trie_backend, + &relay_chain::well_known_keys::hrmp_channels(channel_id), + None, + ) + .map_err(|read_err| Error::HrmpChannel(self.para_id, recipient, read_err))?; + egress_channels.push((recipient, hrmp_channel)); + } + + // NOTE that ingress_channels and egress_channels promise to be sorted. We satisfy this property + // by relying on the fact that `ingress_channel_index` and `egress_channel_index` are themselves sorted. + Ok(MessagingStateSnapshot { dmq_mqc_head, relay_dispatch_queue_size, ingress_channels, egress_channels, - }, - )) + }) + } + + /// Read the [`AbridgedHostConfiguration`] from the relay chain state proof. + /// + /// Returns an error if anything failed at reading or decoding. + pub fn read_abridged_host_configuration(&self) -> Result { + read_entry(&self.trie_backend, relay_chain::well_known_keys::ACTIVE_CONFIG, None) + .map_err(Error::Config) + } + + /// Read the [`Slot`](relay_chain::v1::Slot) from the relay chain state proof. + /// + /// The slot is slot of the relay chain block this state proof was extracted from. + /// + /// Returns an error if anything failed at reading or decoding. + pub fn read_slot(&self) -> Result { + read_entry(&self.trie_backend, relay_chain::well_known_keys::CURRENT_SLOT, None).map_err(Error::Slot) + } } diff --git a/pallets/parachain-system/src/validate_block/implementation.rs b/pallets/parachain-system/src/validate_block/implementation.rs index 2caacb97869..37643a8497e 100644 --- a/pallets/parachain-system/src/validate_block/implementation.rs +++ b/pallets/parachain-system/src/validate_block/implementation.rs @@ -16,14 +16,12 @@ //! The actual implementation of the validate block functionality. -use frame_support::traits::ExecuteBlock; -use sp_runtime::traits::{Block as BlockT, HashFor, Header as HeaderT, NumberFor}; +use frame_support::traits::{ExecuteBlock, ExtrinsicCall, IsSubType, Get}; +use sp_runtime::traits::{Block as BlockT, Extrinsic, HashFor, Header as HeaderT, NumberFor}; use sp_io::KillChildStorageResult; use sp_std::prelude::*; -use hash_db::{HashDB, EMPTY_PREFIX}; - use polkadot_parachain::primitives::{HeadData, ValidationParams, ValidationResult}; use codec::{Decode, Encode}; @@ -32,12 +30,9 @@ use sp_core::storage::ChildInfo; use sp_externalities::{set_and_run_with_externalities, Externalities}; use sp_trie::MemoryDB; -type Ext<'a, B> = sp_state_machine::Ext< - 'a, - HashFor, - NumberFor, - sp_state_machine::TrieBackend>, HashFor>, ->; +type TrieBackend = sp_state_machine::TrieBackend>, HashFor>; + +type Ext<'a, B> = sp_state_machine::Ext<'a, HashFor, NumberFor, TrieBackend>; fn with_externalities R, R>(f: F) -> R { sp_externalities::with_externalities(f).expect("Environmental externalities not set.") @@ -45,9 +40,18 @@ fn with_externalities R, R>(f: F) -> R { /// Validate a given parachain block on a validator. #[doc(hidden)] -pub fn validate_block, PSC: crate::Config>( +pub fn validate_block< + B: BlockT, + E: ExecuteBlock, + PSC: crate::Config, + CI: crate::CheckInherents, +>( params: ValidationParams, -) -> ValidationResult { +) -> ValidationResult +where + B::Extrinsic: ExtrinsicCall, + ::Call: IsSubType>, +{ let block_data = cumulus_primitives_core::ParachainBlockData::::decode(&mut ¶ms.block_data.0[..]) .expect("Invalid parachain block data"); @@ -77,9 +81,6 @@ pub fn validate_block, PSC: crate::Config>( }; let backend = sp_state_machine::TrieBackend::new(db, root); - let mut overlay = sp_state_machine::OverlayedChanges::default(); - let mut cache = Default::default(); - let mut ext = Ext::::new(&mut overlay, &mut cache, &backend); let _guard = ( // Replace storage calls with our own implementations @@ -121,7 +122,38 @@ pub fn validate_block, PSC: crate::Config>( sp_io::offchain_index::host_clear.replace_implementation(host_offchain_index_clear), ); - set_and_run_with_externalities(&mut ext, || { + let inherent_data = block + .extrinsics() + .iter() + .filter_map(|e| e.call().is_sub_type()) + .find_map(|c| match c { + crate::Call::set_validation_data(validation_data) => Some(validation_data.clone()), + _ => None, + }) + .expect("Could not find `set_validation_data` inherent"); + + run_with_externalities::(&backend, || { + let relay_chain_proof = crate::RelayChainStateProof::new( + PSC::SelfParaId::get(), + inherent_data.validation_data.relay_parent_storage_root, + inherent_data.relay_chain_state.clone(), + ) + .expect("Invalid relay chain state proof"); + + let res = CI::check_inherents(block.extrinsics(), &relay_chain_proof); + + if !res.ok() { + if log::log_enabled!(log::Level::Error) { + res.into_errors().for_each(|e| { + log::error!("Checking inherent with identifier `{:?}` failed", e.0) + }); + } + + panic!("Checking inherents failed"); + } + }); + + run_with_externalities::(&backend, || { super::set_and_run_with_validation_params(params, || { E::execute_block(block); @@ -143,6 +175,18 @@ pub fn validate_block, PSC: crate::Config>( }) } +/// Run the given closure with the externalities set. +fn run_with_externalities R>( + backend: &TrieBackend, + execute: F, +) -> R { + let mut overlay = sp_state_machine::OverlayedChanges::default(); + let mut cache = Default::default(); + let mut ext = Ext::::new(&mut overlay, &mut cache, backend); + + set_and_run_with_externalities(&mut ext, || execute()) +} + fn host_storage_read(key: &[u8], value_out: &mut [u8], value_offset: u32) -> Option { match with_externalities(|ext| ext.storage(key)) { Some(value) => { diff --git a/pallets/parachain-system/src/validate_block/mod.rs b/pallets/parachain-system/src/validate_block/mod.rs index 72bbb09ec60..44886efd4fe 100644 --- a/pallets/parachain-system/src/validate_block/mod.rs +++ b/pallets/parachain-system/src/validate_block/mod.rs @@ -49,64 +49,3 @@ pub(crate) fn with_validation_params(f: impl FnOnce(&ValidationParams) -> R) fn set_and_run_with_validation_params(mut params: ValidationParams, f: impl FnOnce() -> R) -> R { VALIDATION_PARAMS::using(&mut params, f) } - -/// Register the `validate_block` function that is used by parachains to validate blocks on a -/// validator. -/// -/// Does *nothing* when `std` feature is enabled. -/// -/// Expects as parameters the runtime and a block executor. -/// -/// # Example -/// -/// ``` -/// struct BlockExecutor; -/// struct Runtime; -/// -/// cumulus_pallet_parachain_system::register_validate_block!(Runtime, BlockExecutor); -/// -/// # fn main() {} -/// ``` -#[macro_export] -macro_rules! register_validate_block { - ($runtime:ty, $block_executor:ty $( , )? ) => { - $crate::register_validate_block_impl!($runtime, $block_executor); - }; -} - -/// The actual implementation of `register_validate_block` for `no_std`. -#[cfg(not(feature = "std"))] -#[doc(hidden)] -#[macro_export] -macro_rules! register_validate_block_impl { - ($runtime:ty, $block_executor:ty) => { - #[doc(hidden)] - mod parachain_validate_block { - use super::*; - - #[no_mangle] - unsafe fn validate_block(arguments: *const u8, arguments_len: usize) -> u64 { - let params = $crate::validate_block::polkadot_parachain::load_params( - arguments, - arguments_len, - ); - - let res = $crate::validate_block::implementation::validate_block::< - <$runtime as $crate::validate_block::GetRuntimeBlockType>::RuntimeBlock, - $block_executor, - $runtime, - >(params); - - $crate::validate_block::polkadot_parachain::write_result(&res) - } - } - }; -} - -/// The actual implementation of `register_validate_block` for `std`. -#[cfg(feature = "std")] -#[doc(hidden)] -#[macro_export] -macro_rules! register_validate_block_impl { - ($runtime:ty, $block_executor:ty) => {}; -} diff --git a/pallets/parachain-system/src/validate_block/tests.rs b/pallets/parachain-system/src/validate_block/tests.rs index d2aa547b21d..575b5101a3f 100644 --- a/pallets/parachain-system/src/validate_block/tests.rs +++ b/pallets/parachain-system/src/validate_block/tests.rs @@ -94,8 +94,8 @@ fn build_block_with_witness( client: &Client, extra_extrinsics: Vec, parent_head: Header, + sproof_builder: RelayStateSproofBuilder, ) -> TestBlockData { - let sproof_builder = RelayStateSproofBuilder::default(); let (relay_parent_storage_root, _) = sproof_builder.clone().into_state_root_and_proof(); let block_id = BlockId::Hash(client.info().best_hash); let mut validation_data = PersistedValidationData { @@ -137,7 +137,7 @@ fn validate_block_no_extra_extrinsics() { block, witness, validation_data, - } = build_block_with_witness(&client, vec![], parent_head.clone()); + } = build_block_with_witness(&client, vec![], parent_head.clone(), Default::default()); let (header, extrinsics) = block.deconstruct(); let block_data = ParachainBlockData::new(header.clone(), extrinsics, witness); @@ -167,7 +167,12 @@ fn validate_block_with_extra_extrinsics() { block, witness, validation_data, - } = build_block_with_witness(&client, extra_extrinsics, parent_head.clone()); + } = build_block_with_witness( + &client, + extra_extrinsics, + parent_head.clone(), + Default::default(), + ); let (header, extrinsics) = block.deconstruct(); let block_data = ParachainBlockData::new(header.clone(), extrinsics, witness); @@ -192,7 +197,7 @@ fn validate_block_invalid_parent_hash() { block, witness, validation_data, - } = build_block_with_witness(&client, vec![], parent_head.clone()); + } = build_block_with_witness(&client, vec![], parent_head.clone(), Default::default()); let (mut header, extrinsics) = block.deconstruct(); header.set_parent_hash(Hash::from_low_u64_be(1)); @@ -212,18 +217,44 @@ fn validate_block_fails_on_invalid_validation_data() { let (client, longest_chain) = create_test_client(); let parent_head = longest_chain.best_chain().expect("Best block exists"); + let TestBlockData { block, witness, .. } = + build_block_with_witness(&client, vec![], parent_head.clone(), Default::default()); + let (header, extrinsics) = block.deconstruct(); + + let block_data = ParachainBlockData::new(header, extrinsics, witness); + call_validate_block(parent_head, block_data, Hash::random()).expect("Calls `validate_block`"); +} + +#[test] +#[should_panic(expected = "Calls `validate_block`: Other(\"Trap: Trap { kind: Unreachable }\")")] +fn check_inherent_fails_on_validate_block_as_expected() { + let _ = env_logger::try_init(); + + let (client, longest_chain) = create_test_client(); + let parent_head = longest_chain.best_chain().expect("Best block exists"); + let TestBlockData { block, witness, - .. - } = build_block_with_witness(&client, vec![], parent_head.clone()); + validation_data, + } = build_block_with_witness( + &client, + vec![], + parent_head.clone(), + RelayStateSproofBuilder { + current_slot: 1337.into(), + ..Default::default() + }, + ); let (header, extrinsics) = block.deconstruct(); - let block_data = ParachainBlockData::new(header, extrinsics, witness); - call_validate_block( + let block_data = ParachainBlockData::new(header.clone(), extrinsics, witness); + + let res_header = call_validate_block( parent_head, block_data, - Hash::random(), + validation_data.relay_parent_storage_root, ) .expect("Calls `validate_block`"); + assert_eq!(header, res_header); } diff --git a/polkadot-parachains/rococo-runtime/src/lib.rs b/polkadot-parachains/rococo-runtime/src/lib.rs index 1cc30fdace2..bc103209776 100644 --- a/polkadot-parachains/rococo-runtime/src/lib.rs +++ b/polkadot-parachains/rococo-runtime/src/lib.rs @@ -591,7 +591,19 @@ impl_runtime_apis! { } } -cumulus_pallet_parachain_system::register_validate_block!( - Runtime, - cumulus_pallet_aura_ext::BlockExecutor::, -); +struct CheckInherents; + +impl cumulus_pallet_parachain_system::CheckInherents for CheckInherents { + fn check_inherents( + _: &[UncheckedExtrinsic], + _: &cumulus_pallet_parachain_system::RelayChainStateProof, + ) -> sp_inherents::CheckInherentsResult { + sp_inherents::CheckInherentsResult::new() + } +} + +cumulus_pallet_parachain_system::register_validate_block! { + Runtime = Runtime, + BlockExecutor = cumulus_pallet_aura_ext::BlockExecutor::, + CheckInherents = CheckInherents, +} diff --git a/polkadot-parachains/shell-runtime/src/lib.rs b/polkadot-parachains/shell-runtime/src/lib.rs index 547115cafe4..7b88ee9ce42 100644 --- a/polkadot-parachains/shell-runtime/src/lib.rs +++ b/polkadot-parachains/shell-runtime/src/lib.rs @@ -369,4 +369,19 @@ impl_runtime_apis! { } } -cumulus_pallet_parachain_system::register_validate_block!(Runtime, Executive); +struct CheckInherents; + +impl cumulus_pallet_parachain_system::CheckInherents for CheckInherents { + fn check_inherents( + _: &[UncheckedExtrinsic], + _: &cumulus_pallet_parachain_system::RelayChainStateProof, + ) -> sp_inherents::CheckInherentsResult { + sp_inherents::CheckInherentsResult::new() + } +} + +cumulus_pallet_parachain_system::register_validate_block! { + Runtime = Runtime, + BlockExecutor = Executive, + CheckInherents = CheckInherents, +} diff --git a/polkadot-parachains/statemine-runtime/src/lib.rs b/polkadot-parachains/statemine-runtime/src/lib.rs index 9677d0057f8..cd83cc34b16 100644 --- a/polkadot-parachains/statemine-runtime/src/lib.rs +++ b/polkadot-parachains/statemine-runtime/src/lib.rs @@ -897,7 +897,19 @@ impl_runtime_apis! { } } -cumulus_pallet_parachain_system::register_validate_block!( -Runtime, -cumulus_pallet_aura_ext::BlockExecutor::, -); +struct CheckInherents; + +impl cumulus_pallet_parachain_system::CheckInherents for CheckInherents { + fn check_inherents( + _: &[UncheckedExtrinsic], + _: &cumulus_pallet_parachain_system::RelayChainStateProof, + ) -> sp_inherents::CheckInherentsResult { + sp_inherents::CheckInherentsResult::new() + } +} + +cumulus_pallet_parachain_system::register_validate_block! { + Runtime = Runtime, + BlockExecutor = cumulus_pallet_aura_ext::BlockExecutor::, + CheckInherents = CheckInherents, +} diff --git a/polkadot-parachains/statemint-runtime/src/lib.rs b/polkadot-parachains/statemint-runtime/src/lib.rs index 7913f189bdd..b95033d4d6f 100644 --- a/polkadot-parachains/statemint-runtime/src/lib.rs +++ b/polkadot-parachains/statemint-runtime/src/lib.rs @@ -827,7 +827,19 @@ impl_runtime_apis! { } } -cumulus_pallet_parachain_system::register_validate_block!( -Runtime, -cumulus_pallet_aura_ext::BlockExecutor::, -); +struct CheckInherents; + +impl cumulus_pallet_parachain_system::CheckInherents for CheckInherents { + fn check_inherents( + _: &[UncheckedExtrinsic], + _: &cumulus_pallet_parachain_system::RelayChainStateProof, + ) -> sp_inherents::CheckInherentsResult { + sp_inherents::CheckInherentsResult::new() + } +} + +cumulus_pallet_parachain_system::register_validate_block! { + Runtime = Runtime, + BlockExecutor = cumulus_pallet_aura_ext::BlockExecutor::, + CheckInherents = CheckInherents, +} diff --git a/polkadot-parachains/westmint-runtime/src/lib.rs b/polkadot-parachains/westmint-runtime/src/lib.rs index e4d5db3b9f9..8875d09e01c 100644 --- a/polkadot-parachains/westmint-runtime/src/lib.rs +++ b/polkadot-parachains/westmint-runtime/src/lib.rs @@ -827,7 +827,19 @@ impl_runtime_apis! { } } -cumulus_pallet_parachain_system::register_validate_block!( -Runtime, -cumulus_pallet_aura_ext::BlockExecutor::, -); +struct CheckInherents; + +impl cumulus_pallet_parachain_system::CheckInherents for CheckInherents { + fn check_inherents( + _: &[UncheckedExtrinsic], + _: &cumulus_pallet_parachain_system::RelayChainStateProof, + ) -> sp_inherents::CheckInherentsResult { + sp_inherents::CheckInherentsResult::new() + } +} + +cumulus_pallet_parachain_system::register_validate_block! { + Runtime = Runtime, + BlockExecutor = cumulus_pallet_aura_ext::BlockExecutor::, + CheckInherents = CheckInherents, +} diff --git a/primitives/parachain-inherent/src/client_side.rs b/primitives/parachain-inherent/src/client_side.rs index 7f183639a36..1ab6a1847b6 100644 --- a/primitives/parachain-inherent/src/client_side.rs +++ b/primitives/parachain-inherent/src/client_side.rs @@ -166,6 +166,7 @@ fn collect_relay_storage_proof( .unwrap_or_default(); let mut relevant_keys = vec![]; + relevant_keys.push(relay_well_known_keys::CURRENT_SLOT.to_vec()); relevant_keys.push(relay_well_known_keys::ACTIVE_CONFIG.to_vec()); relevant_keys.push(relay_well_known_keys::dmq_mqc_head(para_id)); relevant_keys.push(relay_well_known_keys::relay_dispatch_queue_size(para_id)); @@ -279,7 +280,11 @@ where fn execute_with_client( self, client: std::sync::Arc, - ) -> Self::Output where Client: ProvideRuntimeApi, Client::Api: ParachainHost { + ) -> Self::Output + where + Client: ProvideRuntimeApi, + Client::Api: ParachainHost, + { ParachainInherentData::create_at( self.relay_parent, &*client, diff --git a/primitives/parachain-inherent/src/lib.rs b/primitives/parachain-inherent/src/lib.rs index 3ef23dea48e..fd678af13e0 100644 --- a/primitives/parachain-inherent/src/lib.rs +++ b/primitives/parachain-inherent/src/lib.rs @@ -50,6 +50,7 @@ pub struct ParachainInherentData { /// /// Specifically this witness contains the data for: /// + /// - the current slot number at the given relay parent /// - active host configuration as per the relay parent, /// - the relay dispatch queue sizes /// - the list of egress HRMP channels (in the list of recipients form) diff --git a/test/relay-sproof-builder/src/lib.rs b/test/relay-sproof-builder/src/lib.rs index 693106b3943..2c7ad67ba5e 100644 --- a/test/relay-sproof-builder/src/lib.rs +++ b/test/relay-sproof-builder/src/lib.rs @@ -14,7 +14,9 @@ // You should have received a copy of the GNU General Public License // along with Cumulus. If not, see . -use cumulus_primitives_core::{relay_chain, AbridgedHostConfiguration, AbridgedHrmpChannel, ParaId}; +use cumulus_primitives_core::{ + relay_chain, AbridgedHostConfiguration, AbridgedHrmpChannel, ParaId, +}; use sp_runtime::traits::HashFor; use sp_state_machine::MemoryDB; use sp_std::collections::btree_map::BTreeMap; @@ -38,6 +40,7 @@ pub struct RelayStateSproofBuilder { pub hrmp_ingress_channel_index: Option>, pub hrmp_egress_channel_index: Option>, pub hrmp_channels: BTreeMap, + pub current_slot: relay_chain::v1::Slot, } impl Default for RelayStateSproofBuilder { @@ -60,6 +63,7 @@ impl Default for RelayStateSproofBuilder { hrmp_ingress_channel_index: None, hrmp_egress_channel_index: None, hrmp_channels: BTreeMap::new(), + current_slot: 0.into(), } } } @@ -151,6 +155,11 @@ impl RelayStateSproofBuilder { metadata.encode(), ); } + + insert( + relay_chain::well_known_keys::CURRENT_SLOT.to_vec(), + self.current_slot.encode(), + ); } let root = backend.root().clone(); diff --git a/test/runtime/src/lib.rs b/test/runtime/src/lib.rs index 339c2369c89..2a90cba758a 100644 --- a/test/runtime/src/lib.rs +++ b/test/runtime/src/lib.rs @@ -427,4 +427,29 @@ impl_runtime_apis! { } } -cumulus_pallet_parachain_system::register_validate_block!(Runtime, Executive); +struct CheckInherents; + +impl cumulus_pallet_parachain_system::CheckInherents for CheckInherents { + fn check_inherents( + _: &[UncheckedExtrinsic], + relay_state_proof: &cumulus_pallet_parachain_system::RelayChainStateProof, + ) -> sp_inherents::CheckInherentsResult { + if relay_state_proof.read_slot().expect("Reads slot") == 1337u64 { + let mut res = sp_inherents::CheckInherentsResult::new(); + res.put_error( + [1u8; 8], + &sp_inherents::MakeFatalError::from("You are wrong"), + ) + .expect("Puts error"); + res + } else { + sp_inherents::CheckInherentsResult::new() + } + } +} + +cumulus_pallet_parachain_system::register_validate_block! { + Runtime = Runtime, + BlockExecutor = Executive, + CheckInherents = CheckInherents, +}