Files
pezkuwi-subxt/cumulus/pallets/parachain-system/src/lib.rs
T
Branislav Kontur 39aec7c14f BridgeHub Rococo/Wococo runtimes (#2111)
* Fixes

* Fixes

* Fixes

* cargo fmt

* Fixes

* Fixes

* Fixes

* Fixes

* Update BridgeHub runtime version

* Fixes

* Zombienet for bridge-hub setup

* Fixes

* Remove unused import

* Fixes for gav-xcm-v3 (#1835)

* Fix for FungiblesAdapter - trait changes: Contains -> AssetChecking

* Fix for missing weight for `fn unpaid_execution()`

* Used NonLocalMint for all NonZeroIssuance

* Fix

* Fixes

* Fixes

* Fixes

* Fixes

* Fixes

* Fix tests

* Fixes

* Trying to fix sed expression?

* Trying to fix sed expression?

* Use the `relay-headers-and-messages` command (#1913)

* Bridge hubs readme: fixes and additions

* Use the relay-headers-and-messages command

* cargo fmt

* Fix README.md + zombienet

* Parachain ID update of bridge-hub-wococo

* Update bridge-hub-wococo chainspec

* Squashed 'bridges/' content from commit 062554430

git-subtree-dir: bridges
git-subtree-split: 0625544309ff299307f7e110f252f04eac383102

* Add SafeCallFilter

* Add missing config items

* Add TODO

* Fixes (xcm Superuser + DispatchLevelResult)

* Fix cargo

* Change runtime version

* Unit-tests for dispatch bridging messages and XCM routing on BridgeHubs + HRMP

* Removed Sudo pallet

* Use () as the PriceForParentDelivery

* Fixes

* Fixes

* Fixes

* Fixes

* Update transact_origin to transact_origin_and_runtime_call

* Add ReachableDest config item to XCM pallet

* Add BridgeRejectObsoleteHeadersAndMessages to bridge hubs (#1972)

* Update SafeCallFilter to allow remark_with_event in runtime benchmarks

* cargo fmt

* Update substrate

* Fix worst_case_holding

* Fix DMQ queue unit tests

* Remove unused label

* cargo fmt

* Actually process incoming XCMs

* Fixes

* Fixes

* Fixes

* Fixes - return back Weightless

* Simplify local run + readme

* Added measured benchmarks for `pallet_xcm` (#1968)

* Fix

Fix

Fix

* Fix

* Fixes for transact benchmark

* Fixes add pallet_xcm to benchmarks

* Revert remark_with_event

* ".git/.scripts/bench-bot.sh" xcm statemine assets pallet_xcm_benchmarks::generic

* Fixes

* TMP

* Fix for reserve_asset_deposited

* ".git/.scripts/bench-bot.sh" pallet statemine assets pallet_xcm

* Fix

* ".git/.scripts/bench-bot.sh" pallet statemint assets pallet_xcm

* Fix

* ".git/.scripts/bench-bot.sh" pallet westmint assets pallet_xcm

* Fix westmint

* ".git/.scripts/bench-bot.sh" xcm statemine assets pallet_xcm_benchmarks::generic

* Fix

* ".git/.scripts/bench-bot.sh" xcm westmint assets pallet_xcm_benchmarks::generic

* ".git/.scripts/bench-bot.sh" xcm statemint assets pallet_xcm_benchmarks::generic

* ".git/.scripts/bench-bot.sh" pallet collectives-polkadot collectives pallet_xcm

* Fix for collectives

* ".git/.scripts/bench-bot.sh" pallet bridge-hub-kusama bridge-hubs pallet_xcm

* ".git/.scripts/bench-bot.sh" pallet bridge-hub-rococo bridge-hubs pallet_xcm

* Fixes for bridge-hubs

* Fixes - return back Weightless

* Fix - removed MigrateToTrackInactive for contracts-rococo

Co-authored-by: command-bot <>

* cargo fmt

* Fix benchmarks

* Bko gav xcm v3 (#1993)

* Fix

* ".git/.scripts/bench-bot.sh" xcm statemint assets pallet_xcm_benchmarks::fungible

* ".git/.scripts/bench-bot.sh" xcm statemine assets pallet_xcm_benchmarks::fungible

* ".git/.scripts/bench-bot.sh" xcm westmint assets pallet_xcm_benchmarks::fungible

* ".git/.scripts/bench-bot.sh" xcm statemine assets pallet_xcm_benchmarks::generic

* ".git/.scripts/bench-bot.sh" xcm statemint assets pallet_xcm_benchmarks::generic

* ".git/.scripts/bench-bot.sh" xcm westmint assets pallet_xcm_benchmarks::generic

* ".git/.scripts/bench-bot.sh" pallet statemine assets pallet_xcm

* ".git/.scripts/bench-bot.sh" pallet westmint assets pallet_xcm

* ".git/.scripts/bench-bot.sh" pallet statemint assets pallet_xcm

* ".git/.scripts/bench-bot.sh" pallet collectives-polkadot collectives pallet_xcm

* ".git/.scripts/bench-bot.sh" pallet bridge-hub-kusama bridge-hubs pallet_xcm

* ".git/.scripts/bench-bot.sh" pallet bridge-hub-rococo bridge-hubs pallet_xcm

Co-authored-by: command-bot <>

* Change AllowUnpaidExecutionFrom to be explicit

* Turn on more xcm logs for parachains

* Added polkadot-parachain-mint binary instructions

* xcm-v3 benchmarks, weights, fixes for bridge-hubs (#2035)

* Dumy weights to get compile

* Change UniversalLocation according to https://github.com/paritytech/polkadot/pull/4097 (Location Inversion Removed)

* Fix bridge-hubs weights

* ".git/.scripts/bench-bot.sh" pallet statemine assets pallet_xcm

* ".git/.scripts/bench-bot.sh" pallet statemint assets pallet_xcm

* ".git/.scripts/bench-bot.sh" pallet collectives-polkadot collectives pallet_xcm

* ".git/.scripts/bench-bot.sh" pallet westmint assets pallet_xcm

* ".git/.scripts/bench-bot.sh" xcm bridge-hub-kusama bridge-hubs pallet_xcm_benchmarks::generic

* ".git/.scripts/bench-bot.sh" xcm bridge-hub-kusama bridge-hubs pallet_xcm_benchmarks::fungible

* ".git/.scripts/bench-bot.sh" pallet bridge-hub-kusama bridge-hubs pallet_xcm

* ".git/.scripts/bench-bot.sh" pallet bridge-hub-rococo bridge-hubs pallet_xcm

* ".git/.scripts/bench-bot.sh" xcm bridge-hub-rococo bridge-hubs pallet_xcm_benchmarks::fungible

* ".git/.scripts/bench-bot.sh" xcm bridge-hub-rococo bridge-hubs pallet_xcm_benchmarks::generic

* Change NetworkId to Option<NetworkId>

Co-authored-by: command-bot <>
Co-authored-by: Keith Yeung <kungfukeith11@gmail.com>

* remove shift session manager from bridge-hub-rococo (#2047)

* remove shift session manager from bridge-hub-rococo

* also remove from Cargo.toml

* Add event for showing the hash of an UMP sent message (#1228)

* Add UpwardMessageSent event in parachain-system

* additional fixes

* Message Id

* Fix errors from merge

* fmt

* more fmt

* Remove todo

* more formatting

* Fixes

* Fixes

* Fixes

* Fixes

* Updated README.md and scripts/bridges_rococo_wococo.sh for sending messages (local, live)

* Allow explicit unpaid executions from the relay chains for system parachains (#2060)

* Allow explicit unpaid executions from the relay chains for system parachains

* Put origin-filtering barriers into WithComputedOrigin

* Use ConstU32<8>

* Small nits

* formatting

* cargo fmt

* Align laneId to 00000001

* Allow receiving XCMs from any relay chain plurality

* Fixes

* Use Rococo/Wococo runtime APIs defined in bridge primitives (#2080)

* Patched dependencies (polkadot, substrate) for xcm-v3 (compiles + tests work)

* Replace serial_test and fix with thread_local

* Very init of script for bumping bridges repo

* Squashed 'bridges/' changes from 062554430..984749ba0

984749ba0 Define separate signed extension for BHR/BHW (#1776)
72b03d463 update Substrate/Polkadot/Cumulus deps to master (#1775)
3065c7903 Added crate-level docs for the parachains pallet (#1772)
a0f41b2d8 added/updated pallet level docs to grandpa and messages pallets (#1771)
6d69d1f4d docs: add Security Policy doc (#1770)
ff8c0f727 Fix cargo deny issues (#1769)
6fc931d07 Bump xcm-v3 + substrate (#1767)
5840197c3 Define method for checking message lane weights (#1766)
881af0219 increase MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX and MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX for RBH/WBH (#1765)
41d91e961 fixed receive_delivery_proof_for_two_messages_by_two_relayers (#1764)
ac0cf7b78 Fix some cargo-deny issues (#1763)
6d9dc6367 `cargo machete` removed unused deps (#1761)
c265b5430 Remove sp-version dependency from bin-substrate (#1758)
1327c9d97 Set `R/WococoBridgeHub` bundle runtime version (#1756)
a3a2a06ae Expose relay version metric (#1750)
13f4a0164 Use indirect runtime calls for RialtoParachain (#1753)
9563f9eee fix nightly clippy again (#1752)
21b75b893 no-grafana-startup-delay option in run.sh (#1751)
a5fe0dfc4 Remove TODO (#1749)
6c826a6c3 Deduplicate pallet call structs used for indirect runtime calls (#1744)
e575269e5 fix nightly clippy (#1746)
209cba353 Update project level docs (#1734)
b05cef5b4 Improve relayer initialization behaviour (#1743)
c7b6bae9d Make debug display of LaneId compatible with its previous version (#1740)
221e4e80c Remove CliChain::KeyPair (#1741)
3d9d2907f Use TypedLaneId instead of LaneId (#1738)
6683b8136 Simplify read_client_state() (#1739)
3f7353b82 Expose metrics of on-demand relay chain headers sync from with-parachain complex relays (#1737)
ab65d84e0 Handle `SIGTERM` for the docker containers + relay (#1735)
b9050e90c Replace `BATCH_CALL_SUPPORTED` (#1733)
c28b3ff66 Updated db weights and some experiments (#1732)
023689c6c Do not require new headers if lane is empty (#1725)
bddf1fa19 remove messages pallet owner relay argument (#1728)
ef55226c6 more traces + remove signer override (#1727)
4d50df6ed remove BatchDeliveryTransaction::new and BatchConfirmationTransaction::new to avoid expects (#1726)
15244e53e Batch transactions in complex relays (#1669)
c209bb9ac fix pallet names at bridge hubs (#1722)
036e6696e tests (#1720)
3d56e2089 Check origin? (#1718)
af9abbeb8 Remove SOURCE_PARACHAIN_PARA_ID (#1716)
d1cb5d1a8 fix parachains benchmarks (#1717)
84bdf864b Changed docker image name for substrate-relay (#1714)
5698fb465 Remove WeightToFee (#1713)
9f4106bc1 Fix bridge hub rococo/wococo weights (#1712)
114b1502f Only store header state root (pallet-bridge-parachains) (#1701)
92e86f07b New relayer rewards scheme integration (#1652)
8649d12af Signed extension to refund relayer at the target chain (#1657)
ec6bafaf0 DeliveryConfirmationPayments trait for paying relayer rewards at the source chain (#1653)
fab2344f4 only store header state root (pallet-bridge-grandpa) (#1699)
b5e916f64 fixed benchmarks of relayers pallet (#1700)
5cce3e86d fix clippy (#1698)
f78e8867b removed MintReward and added PayLaneRewardFromAccount (#1693)
0c19db305 added version guards to RBH<>WBH GRANDPA finality (and complex) relay (#1697)
c003b951d removed ESTIMATE_MESSAGE_FEE_METHOD (#1696)
4903b7929 refund_pay_dispatch_fee removed (#1695)
61c3b22ca Replace const parameters types (#1691)

git-subtree-dir: bridges
git-subtree-split: 984749ba021b5b8ec16f65cd1e50b234640d838b

* Fixes after merge

* Fixes

* Use auto runtime version for local runs (#2113)

* Squashed 'bridges/' changes from 984749ba0..fb3c5ef5d

fb3c5ef5d Add integrity check for signed extensions (#1780)
3959628ff add try-runtime feature to pallets (#1779)
be36ff00c Default impl for some methods in messages benchmarking pallet config (#1777)
68344e329 Relayer reward metric (#1742)
6b455597b Crate-level documentation on finality relays and relayers pallet (#1773)

git-subtree-dir: bridges
git-subtree-split: fb3c5ef5dae42553522c7eff37678de9bf4f6c67

* Fixed try-runtime

* Fix cargo.lock

* Fix BridgePalletIsNotInitialized (#2114)

* Squashed 'bridges/' changes from fb3c5ef5d..e2e9fa7f9

e2e9fa7f9 Expose EXTRA_STORAGE_PROOF_SIZE in bp-bridge-hub-cumulus (#1788)
ba85532b1 Removed unecesserry test + substrate/polkadot (#1787)

git-subtree-dir: bridges
git-subtree-split: e2e9fa7f94d2f105c1816402a9ae4b85bfc34145

* Fix cargo.toml

* Squashed 'bridges/' changes from e2e9fa7f9..d5f95c14a

d5f95c14a use wss to connect to the Rialto node in test deployments (#1809)
722d47b06 fix compilation
a48732676 Bump sysinfo from 0.15.9 to 0.27.7
9a6e8bb1d Bump env_logger from 0.8.4 to 0.10.0
89c5e7981 Bump async-trait from 0.1.61 to 0.1.62
ddd0a5742 Bump fixed-hash from 0.7.0 to 0.8.0
e8b0b8192 Bump impl-serde from 0.3.2 to 0.4.0
c5227460f Bump jsonpath_lib from 0.2.6 to 0.3.0
9f4771d38 Bump parking_lot from 0.11.2 to 0.12.1
dab5d72ae Bump backoff from 0.2.1 to 0.4.0
d7dd3acce Bump strum from 0.21.0 to 0.24.1
c49799017 Bump tokio from 1.24.1 to 1.24.2
db614681e Bump clap from 4.1.0 to 4.1.1
3c155214d update ignored dependencies for dependabot (#1790)
4c791472c No wildcard patterns in Cargo.toml (#1789)
33632313d Remove chain-specific dependencies from crates that will be used in Cumulus (#1783)

git-subtree-dir: bridges
git-subtree-split: d5f95c14a2771d7ad51db95670d08a5d0da526a0

* Fix `send-remark-local` script because of new xcm-v3

* Refactor haul/dispatch xcm stuff

* Add Rococo <> Wococo integrity tests (#1975)

* Remove 1 integrity test

In sync with https://github.com/paritytech/parity-bridges-common/pull/1816

* use TargetHeaderChainAdapter and SourceHeaderChainAdapter

* Rococo <-> Wococo integrity tests

* Add message lane weights tests

* Add signed extension integrity test

* Bridge benchmarks for bridge hub rococo/wococo (#2107)

* fix benchmarks compilation and add bridges benchmarks (prototype) to RBH/WBH

* post-merge fixes

* remove duplicate "pallet-collator-selection/runtime-benchmarks"

* ".git/.scripts/commands/bench/bench.sh" pallet bridge-hub-rococo bridge-hubs pallet_bridge_grandpa

* ".git/.scripts/commands/bench/bench.sh" pallet bridge-hub-rococo bridge-hubs pallet_bridge_parachains

* remove methods that are no longer required

* fixed helpers used in bridge hub messages palelt benchmarks

* unused imports

* compilation

* compilation

* benchmarks-ci.sh

* ".git/.scripts/commands/bench/bench.sh" pallet bridge-hub-rococo bridge-hubs pallet_bridge_messages

* use generated weights in pallets configuration

* add mod for new weights

* impl WeightInfoExt

Co-authored-by: command-bot <>

* Ensure governance can call `initialize` with `xcm:Transact` bridge grandpa pallets

* Just in case changed spec_version

* Some scripts for enabling asset transfer on local statemine->westmint

* script

* Squashed 'bridges/' changes from d5f95c14a..b39cb0dea

b39cb0dea MaxValues limit for storage maps in the pallet-bridge-grandpa (#1861)
11b3a611d fixed TODOs for weights v2 (#1860)
5a44f9fea Message delivery transaction is not free!!! (#1859)
59a42bd58 fixed BEEFY genesis (#1858)
ab7c7ad0f Use parity-util-mem 0.12.0 (#1856)
8fd346e5a changed some tests for weights v2 (#1855)
c438b9f74 Add separate Cargo.lock for `tools/runtime-codegen` (#1854)
fc55a97d7 Fix `HeadersToKeep` and `MaxBridgedAuthorities` in Millau benchmarks (#1851)
72e64a3d7 Decrease number of GRANDPA authorities in Polkadot-like chains from 100_000 to 2_048 (#1852)
d60a331ed Update Substrate/Polkadot/Cumulus dependencies + weights v2 (#1850)
61b229b65 Bump async-trait from 0.1.63 to 0.1.64
366333108 Bump serde_json from 1.0.91 to 1.0.92 (#1845)
4d917bb3a Bump trie-db from 0.24.0 to 0.25.0
8d919eac9 Bump anyhow from 1.0.68 to 1.0.69
ef9364dd0 Bump proc-macro2 from 1.0.49 to 1.0.51
9ddeebed5 Bump futures from 0.3.25 to 0.3.26
e02eb7573 connect using wss under flag condition (#1843)
99754a07f remove extra tracing on test deployments (#1842)
bdb84cea6 Add tool for auto generating runtime code from metadata (#1812)
86662f263 fix bridge-runtime-common build (#1839)
f656ac77d Change some macro names (#1837)
50f2980e9 Verify partial repo build on CI (#1832)
f70f8231b fix bridge hubs blocks interval (#1836)
ddbe5cddf [ci] change runners (#1833)
45a68ad39 Fix on demand parachains relay when no parachain head at target (#1834)
6dbce7258 Use GitLab env vars to get git commit (#1831)
b1a8161e8 bump bridge hub versions (#1830)
e909595e0 Use specific error for case when para head is missing from the bridge pallet (#1829)
d517da8a2 Do not read parachain heads from ancient relay headers (#1827)
217bc72f5 Reconnect source client (#1826)
47bf5f693 Bump tokio from 1.24.2 to 1.25.0
6b307b48a Bump clap from 4.1.3 to 4.1.4
90bc29a17 Use named parameters for indirect calls (#1823)
986eeb556 Fix: typos (#1822)
450823b01 docs: fix broken link and minor nits (#1821)
3ed01ae31 do not call best_finalized_para_block_at_source for ancient block (#1819)
001956290 Functions to benchmark messages pallet with linked to parachain (#1817)
e9b0a1c48 Remove InboundPayload check (#1816)
873ea4e40 Bump clap from 4.1.1 to 4.1.3
97eccaa8b also ignore the base xcm crate (#1798)
2d3dcd00b Update bundled runtime version for bridge hub r/wococo (#1814)
7167c0067 Bump bumpalo from 3.10.0 to 3.12.0 in /fuzz/storage-proof
067687520 Bump async-trait from 0.1.62 to 0.1.63 (#1811)

git-subtree-dir: bridges
git-subtree-split: b39cb0dea5751847ea73ab9946667003625eaf1a

* Squashed 'bridges/' changes from b39cb0dea..4c4a7eae1

4c4a7eae1 Small stuff from Cumulus integration (#1865)

git-subtree-dir: bridges
git-subtree-split: 4c4a7eae1503aa63a84fb65d56d67599d362d645

* Squashed 'bridges/' changes from 4c4a7eae1..dcaec27aa

dcaec27aa RefundRelayerForMessagesFromParachain improvements (#1879)
5457f0672 clippy fixes (#1880)
29e8a305c MaxValues for OutboundLanes map (#1871)
5219b56f8 More tests for message pallet weights (#1870)
c4c0c7a1b Bump signal-hook from 0.3.14 to 0.3.15
0ff597b96 Bump serde_json from 1.0.92 to 1.0.93
1c5132eb1 Bump subxt from `20adb19` to `9e2acff`
adb07816b update parachains relay doc (#1874)
972ef3133 Update README.md (#1872)
94648061b MaxValues for maps in parachain maps (#1868)
662267a6f "refund" proof size in GRANDPa pallet (#1863)

git-subtree-dir: bridges
git-subtree-split: dcaec27aaa6f41070fbdfbfd4fde2029697eb85f

* Squashed 'bridges/' changes from dcaec27aa..91e66cfb9

91e66cfb9 Fix clippy issues (#1884)
0bd77f457 Reject storage proofs with unused nodes: begin (#1878)
77a3672f9 Refund extra proof bytes in message delivery transaction (#1864)

git-subtree-dir: bridges
git-subtree-split: 91e66cfb99c1a7b247e435515dd0f62b4058974e

* Fix tests

* Squashed 'bridges/' changes from 91e66cfb9..d39f563be

d39f563be Make `weights::WeightInfo` pub (#1886)
c67d06aa5 ChainWithGrandpa in primitives (#1885)

git-subtree-dir: bridges
git-subtree-split: d39f563bea57528c16763f458af3036842a0ea5f

* Merge fix

* Squashed 'bridges/' changes from d39f563be..78e3357c0

78e3357c0 RefundRelayerForMessagesFromParachain improvements (#1895)
131b17359 optimize justification before submit (#1887)
5bc279ebb use complex transactions on RBH/WBH bridge hubs (#1893)
8f0c09ab9 Bump clap from 4.1.4 to 4.1.6
66429b06a Bump sysinfo from 0.27.7 to 0.28.0
8b329ee8f Bump trie-db from 0.25.0 to 0.25.1
635cfccfd Bump time from 0.3.17 to 0.3.19

git-subtree-dir: bridges
git-subtree-split: 78e3357c0387c95317b8c3e5c4d9316f3a9f3ef4

* Squashed 'bridges/' changes from 78e3357c0..5b5627e90

5b5627e90 Rewards refund for relaying BridgeHubRococo/BridgeHubWococo (#1894)

git-subtree-dir: bridges
git-subtree-split: 5b5627e9081640ed5691eb2891182843563fb99a

* Rewards for relayers setup (#2194)

* Rewards for relayers setup

* ".git/.scripts/commands/bench/bench.sh" pallet bridge-hub-rococo bridge-hubs pallet_bridge_relayers

* Setup weight for relayer

* Setup `DeliveryConfirmationPayments` + `RefundRelayerForMessagesFromParachain`

* No need to have more than one collator per parachain

* Setup multi refund signed extensions

* Rewards sign ext test

* test

* fixes

---------

Co-authored-by: command-bot <>

* Squashed 'bridges/' changes from 5b5627e90..3c15c3645

3c15c3645 get rid of ChainWithMessages::WeightInfo, because we can't have exact weights for "external chains" (#1899)
8ccaa0213 Wrap confirmation and finality transactions into batch_all in Millau -> RialtoParachain bridge (#1898)
9b7285edb Weight+size limits for bridge GRANDPA pallet calls (#1882)

git-subtree-dir: bridges
git-subtree-split: 3c15c36455f2ad944df6a492a8d82f7e0aaf7e9f

* Squashed 'bridges/' changes from 3c15c3645..d05a98473

d05a98473 Refund messages confirmation tx (#1904)
e2e8a7198 Relayers pallet: extend payment source id (#1907)
cccf73b3f fix nightly clippy issues (#1915)
a33a91e79 Bump tempfile from 3.3.0 to 3.4.0
1df768a2e Bump time from 0.3.17 to 0.3.20
cf17b424f Bump sysinfo from 0.28.0 to 0.28.1
0b6276b41 Bump jsonrpsee from 0.15.1 to 0.16.2
328dde02b Bump rand from 0.7.3 to 0.8.5
2f302a4b6 Bump trie-db from 0.25.1 to 0.26.0
b5d5d03ab CI add jobs to publish Docker images description to hub.docker.com (#1906)
db5168f18 Do not stall on lost transaction (#1903)
2d83d6389 Fix init-bridge (#1900)

git-subtree-dir: bridges
git-subtree-split: d05a98473dc933cfed9e5f59023efa2ec811f03c

* Rewards adjustments

* Update RBH/WBH spec version

* Squashed 'bridges/' changes from d05a98473..ce7cf9a49

ce7cf9a49 Removed deprecated `#[pallet::generate_store(pub(super) trait Store)]` according to latest Cumulus (#1964)
897b1c0b2 Bump substrate/polkadot/cumulus (#1962)
7b946da2d Backport xcm bridging extensions to the bridge repo (#1813)
88c1114ec Bump futures from 0.3.26 to 0.3.27
8668f73bf Bump serde from 1.0.152 to 1.0.155
3df8823e1 Bump subxt from `a7b45ef` to `d4545de`
ef1b1bcd0 Some error improvements (#1956)
434c5e014 optimize justifications before they're included into complex transaction (#1949)
7bac365a6 Actually clone client data by reference when cloning the client (#1941)
764ddd4a8 remove lock file after checks are done (#1942)
c18a758f8 Fix invalid messages relay delivery transactions (#1940)
8ad152b06 fix nightly benchmarks test (#1939)
d451b4f84 Bump tokio from 1.25.0 to 1.26.0
8019c50aa Bump async-trait from 0.1.64 to 0.1.66
aa055fcee Bump serde_json from 1.0.93 to 1.0.94
ec2ef31c4 Bump subxt from `1c5faf3` to `a7b45ef`
20026366f Bump sysinfo from 0.28.1 to 0.28.2
fe246d1e3 Bump thiserror from 1.0.38 to 1.0.39
c95e0cf02 Fix deploy step in CI (#1931)
15b41c2dd Improve some relay errors readability (#1930)
792deae5e Added deploy Job (#1929)
d86c3ce21 Reconnect on-demand clients from MessagesSource::reconnect and MessagesTarget::reconnect (#1927)
4161b51f0 get rid of obsolete weight functions (#1926)
9b3b00e0f cargo update -p clap@4.1.6 (#1925)
13ab28c37 Bump subxt from `9e2acff` to `1c5faf3`
bb6171a05 Remove subxt dependency features (#1924)
66d200abb Verify with-parachain message benchmarks on CI (#1923)
b6af2116f Update BHR and BHW spec version (#1922)
d464e78d9 Fix benchmarks (#1919)
74574d53e fix master compilation (#1920)
1b373dff9 Fix multiple parachain headers submission for single message delivery (#1916)

git-subtree-dir: bridges
git-subtree-split: ce7cf9a4977fe614d35b6a7a84d5057e2c4ccaf5

* fixed npm install call (#2323)

* New weights (#2315)

* New weights

* Fix compile benchmarks

* Fix import

* Fix all weights

* Remove bridge_common_config replaced by bridges impl

* Cargo.lock

* fixed bridge pallets compilation

* Cargo.lock

* fix bridge pallets compilation after substrate+polkadot bump

* BridgeHubs: XCM ExportMessage benchmark - just Rococo now

* bench export_message()

* include Bridge::haul_blob() weight in ExportMessage weight

* fix import

* more build fixes

* Squashed 'bridges/' changes from ce7cf9a49..6343a7d37

6343a7d37 bump substrate+polkadot refs and fix builds (#1989)
8efc2b3cc Added receive_single_message_proof_with_dispatch benchmark (#1990)
6540f74dc Remove deprecated code from bridge-runtime-common (#1983)
c4f368be3 minor cosmetic updates (#1985)
bef11ac43 remove invalid weight, returned by send_message (#1984)
28cf5c957 Kusama <> Polkadot relay prototype (#1982)
b195223d1 Bump serde from 1.0.156 to 1.0.157
70caa75d7 ignore binary-merkle-tree (#1980)
3dc640d30 Bump thiserror from 1.0.39 to 1.0.40
8a2729101 Bump subxt from `d4545de` to `ae63d3d`
40937e8a3 Bump clap from 4.1.8 to 4.1.11
d72394c4e Bump finality-grandpa from 0.16.1 to 0.16.2
54147603d Bump serde from 1.0.155 to 1.0.156
b513193e6 Bump anyhow from 1.0.69 to 1.0.70
20867abd9 Bump sysinfo from 0.28.2 to 0.28.3
4d9a45305 Bump async-trait from 0.1.66 to 0.1.67
8a88a7536 Bump trie-db from 0.26.0 to 0.27.1
0add06edd move signed extension stuff from prolkadot-core primitives to bridge-hub-cumulus-primitives (#1968)
7481ce6eb added UpdatedBestFinalizedHeader event to pallet-bridge-grandpa (#1967)
6787cd0cb RBH <> WBH dashboards and alerts (#1966)
036f7be76 enable relayer rewards metrics at bridge hubs (#1965)
a3f07d5dd Fix invalid batch transaction (#1957)

git-subtree-dir: bridges
git-subtree-split: 6343a7d37c32191413be91afb537b8bc6c770285

* dispatch message weight for bridge messages (#2378)

Co-authored-by: Svyatoslav Nikolsky <svyatonik@gmail.com>

* Fixes

* Squashed 'bridges/' changes from 6343a7d37..c1d5990e8

c1d5990e8 Try check-rustdoc pipeline (#1782)

git-subtree-dir: bridges
git-subtree-split: c1d5990e840b8ee4981beb61a8099271ee629ae5

* Removed imports

* Fix compile

* fixed benchmarks compilation

* fix rustdoc

* Squashed 'bridges/' changes from c1d5990e8..ecddd4a31

ecddd4a31 Rust cargo doc for all features (#1995)
e0997c14d Fix gitlab-check (#1994)
5284850ef Bump clap from 4.1.11 to 4.1.13
743cd60df Bump sysinfo from 0.28.3 to 0.28.4
dc322bae2 Bump async-trait from 0.1.67 to 0.1.68

git-subtree-dir: bridges
git-subtree-split: ecddd4a315470d85135aafbdb96753af9b07b854

* Updated scripts for transfer assets

* Cargo.lock

* Script updates for `ping-via-bridge-from-statemine-rococo`

* Added `transfer-asset-from-statemine-rococo`

* Finished scripts

* README.md

* Compile fix + log xcm trace all

* Initial version of bridges pallet as subtree of https://github.com/paritytech/parity-bridges-common
Added `Bridges subtree files` pr review rule

* Squashed 'bridges/' changes from ecddd4a31..d30927c08

d30927c08 Revert dispatch-results (#2048)
fa454c3b4 Remove unneeded files (#2044)
956a2c687 Bump clap from 4.2.1 to 4.2.2
91951583a Bump serde_json from 1.0.95 to 1.0.96
fcf462051 Bump h2 from 0.3.16 to 0.3.17 in /tools/runtime-codegen
b751fb24f Bump h2 from 0.3.16 to 0.3.17
0bf31ab78 update refs (#2041)
a490ecbd3 Fix CI build (#2039)
01139ebbc Define `RangeInclusiveExt` (#2037)
2db2f3fe3 Impl review suggestions from #2021 (#2036)
36292760f fix build step on CI (#2034)
3a2311b7a refund extra weight in receive_messages_delivery_proof call (#2031)
77f1641d1 Boost message delivery transaction priority (#2023)
c23c4e441 Reject delivery transactions with at least one obsolete message (#2021)
68ba699b7 Reintroduce msg dispatch status reporting (#2027)
d1e852cc3 Bump hex-literal from 0.4.0 to 0.4.1
16f25d613 Relay node down alert (#2002)
4bb1a6406 only refund if all bundled messages have been delivered (#2019)
b9acf52bc fail with InsufficientDispatchWeight if dispatch_weight doesn't cover weight of all bundled messages (#2018)
e10097fe2 Remove unneeded error debug strings (#2017)
f5e38f057 enable metrics on all validator nodes (#2016)
c35f1a187 Bump scale-info from 2.4.0 to 2.5.0
04c56977c Bump clap from 4.1.13 to 4.2.1
481371f3c Bump hex-literal from 0.3.4 to 0.4.0
6b9c1400d Bump serde from 1.0.158 to 1.0.159
e71877a2e Bump futures from 0.3.27 to 0.3.28
c019f4faa Bump tempfile from 3.4.0 to 3.5.0
2e6e79ef6 Bump serde_json from 1.0.94 to 1.0.95
0698b1ff9 Bump tokio from 1.26.0 to 1.27.0
35b149830 fix test step on CI (#2003)
0c3acc858 cleanup removed lane traces (#2001)
8bf81749e bump BridgeHubRococo/BridgeHubWococo versions (#2000)
e53bb7f36 MaxRequests -> MaxFreeMandatoryHeadersPerBlock in pallet-bridge-grandpa (#1997)
dfcc09043 Run tests for `runtime-benchmarks` feature only (#1998)
efcc8db17 Run benchmarks for mock runtimes (#1996)

git-subtree-dir: bridges
git-subtree-split: d30927c089bd9e73092d1ec1a62895603cb277a3

* Fixes

* Squashed 'bridges/' content from commit d30927c08

git-subtree-dir: bridges
git-subtree-split: d30927c089bd9e73092d1ec1a62895603cb277a3

* Updated REAMDE.md and BRIDGES.md (inspired by original https://github.com/paritytech/polkadot/blob/d22eb62fe40e55e15eb91d375f48cc540d83a47e/BRIDGES.md)

* Squashed 'bridges/' changes from d30927c08..d3970944b

d3970944b Small simplifications (#2050)

git-subtree-dir: bridges
git-subtree-split: d3970944b0cfc4ea5226225e1ca07dab234c3556

* Squashed 'bridges/' changes from d3970944b..2180797fb

2180797fb Removed CODEOWNERS (#2051)

git-subtree-dir: bridges
git-subtree-split: 2180797fbf8a990490c67853dcffd81bc8dd083c

* Reused `teleports_for_native_asset_works` test to all bridge-hub runtime
Extract runtime_para_id for test
Fix test
Typos
Added helper for `execute_as_governance`

* Added test case `initialize_bridge_by_governance_works`

* Added test case `handle_export_message_from_system_parachain_to_outbound_queue_works`
fix script
Removed BridgeGrandpaRococoInstance

* Added test-case `message_dispatch_routing_works`

* Squashed 'bridges/' changes from 2180797fbf..4850aac8ce

4850aac8ce Removed relayer_account: &AccountId from MessageDispatch  (#2080)
8c8adafd54 Revert "Fix max-size messages at test chains (#2064)" (#2077)
c01a63efd8 Fixed off-by-one when confirming rewards in messages pallet (#2075)
a298be96aa Update subxt dependencies (#2072)
c0eef51eab Fix max-size messages at test chains (#2064)
3a658e3697 Messages relay fixes (#2073)
0022b5ab22 Slash relayers for invalid transactions (#2025)
198104007f Bump enumflags2 from 0.7.5 to 0.7.7
9229b257e5 [ci] Fix rules for docker build (#2069)
660d791390 [ci] Update buildah command and version (#2058)
e4535c0ca4 fix the way latest_confirmed_nonce_at_source is "calculated" (#2067)
dbc2d37590 select nothing if we have already selected nonces to submit or have submitted something (#2065)
a7eedd21fe [relay-substrate-client] Bump jsonrpsee (#2066)
8875d5aeae Bump clap from 4.2.2 to 4.2.4
25f9cf55e2 Another use of RangeInclusiveExt::checked_len() (#2060)
4942c12a5f submit lane unblock transactions from relay (#2030)
c0325d3c9c Test deployments fixes (#2057)
fc7b9b7ed7 Use the new matrix server (#2056)
63bcb5c10b Fixed delivery alert rule (#2052)

git-subtree-dir: bridges
git-subtree-split: 4850aac8ce6c34e5ca6246b88cd14c873a879cba

* Fmt

* Squashed 'bridges/' changes from 4850aac8ce..66aaf0dd23

66aaf0dd23 Nits (#2083)

git-subtree-dir: bridges
git-subtree-split: 66aaf0dd239dde40b64264061a77c921e2c82568

* Cleaning

* bridge-hub-rococo: minor fixes

Signed-off-by: Adrian Catangiu <adrian@parity.io>

* Squashed 'bridges/' changes from 66aaf0dd23..557ecbcecc

557ecbcecc Fix sized messages (Follow-up on #2064) (#2103)
54f587a066 Add weight of refund extension post_dispatch to the weights of messages pallet (#2089)
5b1626f8c4 fix pallet param for nightly benchmarks check (#2099)
ae44c6b7a1 Add millau specific messages weights (#2097)
6ad0bd1f1e Add integrity tests to rialto parachain runtiime (#2096)
6919556de5 Bump tokio from 1.27.0 to 1.28.0
58795fcb75 Bump clap from 4.2.4 to 4.2.5
01bf31085b Bump scale-info from 2.5.0 to 2.6.0
8fe383240d Bump anyhow from 1.0.70 to 1.0.71
8d94e82ad5 deployments: add new BEEFY metrics and alarms (#2090)
e9a4749e7e Bump wasmtime from 6.0.1 to 6.0.2
9d9936c0d9 Bump wasmtime from 6.0.1 to 6.0.2 in /tools/runtime-codegen
5d77cd7bee Add more logs to relayer and message pallets (#2082)
75fbb9d3ef Update comment (#2081)
9904d09cf6 Benchmarks for new relayers pallet calls (#2040)

git-subtree-dir: bridges
git-subtree-split: 557ecbcecc585547b744a5ac9fb8d7f3b9de4521

* fmt

* Fix compile

* Fix benchmark

* Squashed 'bridges/' changes from 557ecbcecc..04b3dda6aa

04b3dda6aa Remove from subtree (#2111)
f8ff15e7e7 Add `MessagesPalletInstance` for integrity tests (#2107)
92ccef58e6 Use generated runtimes for BHR/BHW (#2106)
b33e0a585b Fix comment (#2105)

git-subtree-dir: bridges
git-subtree-split: 04b3dda6aa38599e612ff637710b6d2cff275ef3

* Fix

* ".git/.scripts/commands/fmt/fmt.sh"

* ".git/.scripts/commands/bench/bench.sh" pallet bridge-hub-rococo bridge-hubs pallet_bridge_grandpa

* ".git/.scripts/commands/bench/bench.sh" pallet bridge-hub-rococo bridge-hubs pallet_bridge_parachains

* ".git/.scripts/commands/bench/bench.sh" pallet bridge-hub-rococo bridge-hubs pallet_bridge_messages

* ".git/.scripts/commands/bench/bench.sh" pallet bridge-hub-rococo bridge-hubs pallet_bridge_relayers

---------

Signed-off-by: Adrian Catangiu <adrian@parity.io>
Co-authored-by: Keith Yeung <kungfukeith11@gmail.com>
Co-authored-by: Anthony Lazam <xlzm.tech@gmail.com>
Co-authored-by: Serban Iorga <serban300@gmail.com>
Co-authored-by: Svyatoslav Nikolsky <svyatonik@gmail.com>
Co-authored-by: girazoki <gorka.irazoki@gmail.com>
Co-authored-by: parity-processbot <>
Co-authored-by: Serban Iorga <serban@parity.io>
Co-authored-by: acatangiu <adrian@parity.io>
2023-05-04 07:08:05 +00:00

1243 lines
47 KiB
Rust

// Copyright 2020 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 <http://www.gnu.org/licenses/>.
#![cfg_attr(not(feature = "std"), no_std)]
//! `cumulus-pallet-parachain-system` is a base pallet for Cumulus-based parachains.
//!
//! This pallet handles low-level details of being a parachain. Its responsibilities include:
//!
//! - ingestion of the parachain validation data;
//! - ingestion and dispatch of incoming downward and lateral messages;
//! - coordinating upgrades with the Relay Chain; and
//! - communication of parachain outputs, such as sent messages, signaling an upgrade, etc.
//!
//! Users must ensure that they register this pallet as an inherent provider.
use codec::{Decode, Encode, MaxEncodedLen};
use cumulus_primitives_core::{
relay_chain, AbridgedHostConfiguration, ChannelStatus, CollationInfo, DmpMessageHandler,
GetChannelInfo, InboundDownwardMessage, InboundHrmpMessage, MessageSendError,
OutboundHrmpMessage, ParaId, PersistedValidationData, UpwardMessage, UpwardMessageSender,
XcmpMessageHandler, XcmpMessageSource,
};
use cumulus_primitives_parachain_inherent::{MessageQueueChain, ParachainInherentData};
use frame_support::{
dispatch::{DispatchError, DispatchResult, Pays, PostDispatchInfo},
ensure,
inherent::{InherentData, InherentIdentifier, ProvideInherent},
storage,
traits::Get,
weights::Weight,
RuntimeDebug,
};
use frame_system::{ensure_none, ensure_root};
use polkadot_parachain::primitives::RelayChainBlockNumber;
use scale_info::TypeInfo;
use sp_runtime::{
traits::{Block as BlockT, BlockNumberProvider, Hash},
transaction_validity::{
InvalidTransaction, TransactionLongevity, TransactionSource, TransactionValidity,
ValidTransaction,
},
};
use sp_std::{cmp, collections::btree_map::BTreeMap, prelude::*};
use xcm::latest::XcmHash;
mod migration;
mod relay_state_snapshot;
#[macro_use]
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::{MessagingStateSnapshot, RelayChainStateProof};
pub use pallet::*;
/// Something that can check the associated relay block number.
///
/// Each Parachain block is built in the context of a relay chain block, this trait allows us
/// to validate the given relay chain block number. With async backing it is legal to build
/// multiple Parachain blocks per relay chain parent. With this trait it is possible for the
/// Parachain to ensure that still only one Parachain block is build per relay chain parent.
///
/// By default [`RelayNumberStrictlyIncreases`] and [`AnyRelayNumber`] are provided.
pub trait CheckAssociatedRelayNumber {
/// Check the current relay number versus the previous relay number.
///
/// The implementation should panic when there is something wrong.
fn check_associated_relay_number(
current: RelayChainBlockNumber,
previous: RelayChainBlockNumber,
);
}
/// Provides an implementation of [`CheckAssociatedRelayNumber`].
///
/// It will ensure that the associated relay block number strictly increases between Parachain
/// blocks. This should be used by production Parachains when in doubt.
pub struct RelayNumberStrictlyIncreases;
impl CheckAssociatedRelayNumber for RelayNumberStrictlyIncreases {
fn check_associated_relay_number(
current: RelayChainBlockNumber,
previous: RelayChainBlockNumber,
) {
if current <= previous {
panic!("Relay chain block number needs to strictly increase between Parachain blocks!")
}
}
}
/// Provides an implementation of [`CheckAssociatedRelayNumber`].
///
/// This will accept any relay chain block number combination. This is mainly useful for
/// test parachains.
pub struct AnyRelayNumber;
impl CheckAssociatedRelayNumber for AnyRelayNumber {
fn check_associated_relay_number(_: RelayChainBlockNumber, _: RelayChainBlockNumber) {}
}
/// Information needed when a new runtime binary is submitted and needs to be authorized before
/// replacing the current runtime.
#[derive(Decode, Encode, Default, PartialEq, Eq, MaxEncodedLen, TypeInfo)]
#[scale_info(skip_type_params(T))]
struct CodeUpgradeAuthorization<T>
where
T: Config,
{
/// Hash of the new runtime binary.
code_hash: T::Hash,
/// Whether or not to carry out version checks.
check_version: bool,
}
#[frame_support::pallet]
pub mod pallet {
use super::*;
use frame_support::pallet_prelude::*;
use frame_system::pallet_prelude::*;
#[pallet::pallet]
#[pallet::storage_version(migration::STORAGE_VERSION)]
#[pallet::without_storage_info]
pub struct Pallet<T>(_);
#[pallet::config]
pub trait Config: frame_system::Config<OnSetCode = ParachainSetCode<Self>> {
/// The overarching event type.
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
/// Something which can be notified when the validation data is set.
type OnSystemEvent: OnSystemEvent;
/// Returns the parachain ID we are running with.
type SelfParaId: Get<ParaId>;
/// The place where outbound XCMP messages come from. This is queried in `finalize_block`.
type OutboundXcmpMessageSource: XcmpMessageSource;
/// The message handler that will be invoked when messages are received via DMP.
type DmpMessageHandler: DmpMessageHandler;
/// The weight we reserve at the beginning of the block for processing DMP messages.
type ReservedDmpWeight: Get<Weight>;
/// The message handler that will be invoked when messages are received via XCMP.
///
/// The messages are dispatched in the order they were relayed by the relay chain. If
/// multiple messages were relayed at one block, these will be dispatched in ascending
/// order of the sender's para ID.
type XcmpMessageHandler: XcmpMessageHandler;
/// The weight we reserve at the beginning of the block for processing XCMP messages.
type ReservedXcmpWeight: Get<Weight>;
/// Something that can check the associated relay parent block number.
type CheckAssociatedRelayNumber: CheckAssociatedRelayNumber;
}
#[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
fn on_runtime_upgrade() -> Weight {
migration::on_runtime_upgrade::<T>()
}
fn on_finalize(_: T::BlockNumber) {
<DidSetValidationCode<T>>::kill();
<UpgradeRestrictionSignal<T>>::kill();
assert!(
<ValidationData<T>>::exists(),
"set_validation_data inherent needs to be present in every block!"
);
let host_config = match Self::host_configuration() {
Some(ok) => ok,
None => {
debug_assert!(
false,
"host configuration is promised to set until `on_finalize`; qed",
);
return
},
};
let relevant_messaging_state = match Self::relevant_messaging_state() {
Some(ok) => ok,
None => {
debug_assert!(
false,
"relevant messaging state is promised to be set until `on_finalize`; \
qed",
);
return
},
};
<PendingUpwardMessages<T>>::mutate(|up| {
let (count, size) = relevant_messaging_state.relay_dispatch_queue_size;
let available_capacity = cmp::min(
host_config.max_upward_queue_count.saturating_sub(count),
host_config.max_upward_message_num_per_candidate,
);
let available_size = host_config.max_upward_queue_size.saturating_sub(size);
// Count the number of messages we can possibly fit in the given constraints, i.e.
// available_capacity and available_size.
let num = up
.iter()
.scan((available_capacity as usize, available_size as usize), |state, msg| {
let (cap_left, size_left) = *state;
match (cap_left.checked_sub(1), size_left.checked_sub(msg.len())) {
(Some(new_cap), Some(new_size)) => {
*state = (new_cap, new_size);
Some(())
},
_ => None,
}
})
.count();
// TODO: #274 Return back messages that do not longer fit into the queue.
UpwardMessages::<T>::put(&up[..num]);
*up = up.split_off(num);
});
// Sending HRMP messages is a little bit more involved. There are the following
// constraints:
//
// - a channel should exist (and it can be closed while a message is buffered),
// - at most one message can be sent in a channel,
// - the sent out messages should be ordered by ascension of recipient para id.
// - the capacity and total size of the channel is limited,
// - the maximum size of a message is limited (and can potentially be changed),
let maximum_channels = host_config
.hrmp_max_message_num_per_candidate
.min(<AnnouncedHrmpMessagesPerCandidate<T>>::take()) as usize;
let outbound_messages =
T::OutboundXcmpMessageSource::take_outbound_messages(maximum_channels)
.into_iter()
.map(|(recipient, data)| OutboundHrmpMessage { recipient, data })
.collect::<Vec<_>>();
HrmpOutboundMessages::<T>::put(outbound_messages);
}
fn on_initialize(_n: T::BlockNumber) -> Weight {
let mut weight = Weight::zero();
// To prevent removing `NewValidationCode` that was set by another `on_initialize`
// like for example from scheduler, we only kill the storage entry if it was not yet
// updated in the current block.
if !<DidSetValidationCode<T>>::get() {
NewValidationCode::<T>::kill();
weight += T::DbWeight::get().writes(1);
}
// Remove the validation from the old block.
ValidationData::<T>::kill();
ProcessedDownwardMessages::<T>::kill();
HrmpWatermark::<T>::kill();
UpwardMessages::<T>::kill();
HrmpOutboundMessages::<T>::kill();
CustomValidationHeadData::<T>::kill();
weight += T::DbWeight::get().writes(6);
// Here, in `on_initialize` we must report the weight for both `on_initialize` and
// `on_finalize`.
//
// One complication here, is that the `host_configuration` is updated by an inherent
// and those are processed after the block initialization phase. Therefore, we have to
// be content only with the configuration as per the previous block. That means that
// the configuration can be either stale (or be abscent altogether in case of the
// beginning of the chain).
//
// In order to mitigate this, we do the following. At the time, we are only concerned
// about `hrmp_max_message_num_per_candidate`. We reserve the amount of weight to
// process the number of HRMP messages according to the potentially stale
// configuration. In `on_finalize` we will process only the maximum between the
// announced number of messages and the actual received in the fresh configuration.
//
// In the common case, they will be the same. In the case the actual value is smaller
// than the announced, we would waste some of weight. In the case the actual value is
// greater than the announced, we will miss opportunity to send a couple of messages.
weight += T::DbWeight::get().reads_writes(1, 1);
let hrmp_max_message_num_per_candidate = Self::host_configuration()
.map(|cfg| cfg.hrmp_max_message_num_per_candidate)
.unwrap_or(0);
<AnnouncedHrmpMessagesPerCandidate<T>>::put(hrmp_max_message_num_per_candidate);
// NOTE that the actual weight consumed by `on_finalize` may turn out lower.
weight += T::DbWeight::get().reads_writes(
3 + hrmp_max_message_num_per_candidate as u64,
4 + hrmp_max_message_num_per_candidate as u64,
);
weight
}
}
#[pallet::call]
impl<T: Config> Pallet<T> {
/// Set the current validation data.
///
/// This should be invoked exactly once per block. It will panic at the finalization
/// phase if the call was not invoked.
///
/// The dispatch origin for this call must be `Inherent`
///
/// As a side effect, this function upgrades the current validation function
/// if the appropriate time has come.
#[pallet::call_index(0)]
#[pallet::weight((0, DispatchClass::Mandatory))]
// TODO: This weight should be corrected.
pub fn set_validation_data(
origin: OriginFor<T>,
data: ParachainInherentData,
) -> DispatchResultWithPostInfo {
ensure_none(origin)?;
assert!(
!<ValidationData<T>>::exists(),
"ValidationData must be updated only once in a block",
);
let ParachainInherentData {
validation_data: vfp,
relay_chain_state,
downward_messages,
horizontal_messages,
} = data;
// Check that the associated relay chain block number is as expected.
T::CheckAssociatedRelayNumber::check_associated_relay_number(
vfp.relay_parent_number,
LastRelayChainBlockNumber::<T>::get(),
);
LastRelayChainBlockNumber::<T>::put(vfp.relay_parent_number);
let relay_state_proof = RelayChainStateProof::new(
T::SelfParaId::get(),
vfp.relay_parent_storage_root,
relay_chain_state.clone(),
)
.expect("Invalid relay chain state proof");
// initialization logic: we know that this runs exactly once every block,
// which means we can put the initialization logic here to remove the
// sequencing problem.
let upgrade_go_ahead_signal = relay_state_proof
.read_upgrade_go_ahead_signal()
.expect("Invalid upgrade go ahead signal");
match upgrade_go_ahead_signal {
Some(relay_chain::UpgradeGoAhead::GoAhead) => {
assert!(
<PendingValidationCode<T>>::exists(),
"No new validation function found in storage, GoAhead signal is not expected",
);
let validation_code = <PendingValidationCode<T>>::take();
Self::put_parachain_code(&validation_code);
<T::OnSystemEvent as OnSystemEvent>::on_validation_code_applied();
Self::deposit_event(Event::ValidationFunctionApplied {
relay_chain_block_num: vfp.relay_parent_number,
});
},
Some(relay_chain::UpgradeGoAhead::Abort) => {
<PendingValidationCode<T>>::kill();
Self::deposit_event(Event::ValidationFunctionDiscarded);
},
None => {},
}
<UpgradeRestrictionSignal<T>>::put(
relay_state_proof
.read_upgrade_restriction_signal()
.expect("Invalid upgrade restriction signal"),
);
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");
<ValidationData<T>>::put(&vfp);
<RelayStateProof<T>>::put(relay_chain_state);
<RelevantMessagingState<T>>::put(relevant_messaging_state.clone());
<HostConfiguration<T>>::put(host_config);
<T::OnSystemEvent as OnSystemEvent>::on_validation_data(&vfp);
// TODO: This is more than zero, but will need benchmarking to figure out what.
let mut total_weight = Weight::zero();
total_weight += Self::process_inbound_downward_messages(
relevant_messaging_state.dmq_mqc_head,
downward_messages,
);
total_weight += Self::process_inbound_horizontal_messages(
&relevant_messaging_state.ingress_channels,
horizontal_messages,
vfp.relay_parent_number,
);
Ok(PostDispatchInfo { actual_weight: Some(total_weight), pays_fee: Pays::No })
}
#[pallet::call_index(1)]
#[pallet::weight((1_000, DispatchClass::Operational))]
pub fn sudo_send_upward_message(
origin: OriginFor<T>,
message: UpwardMessage,
) -> DispatchResult {
ensure_root(origin)?;
let _ = Self::send_upward_message(message);
Ok(())
}
/// Authorize an upgrade to a given `code_hash` for the runtime. The runtime can be supplied
/// later.
///
/// The `check_version` parameter sets a boolean flag for whether or not the runtime's spec
/// version and name should be verified on upgrade. Since the authorization only has a hash,
/// it cannot actually perform the verification.
///
/// This call requires Root origin.
#[pallet::call_index(2)]
#[pallet::weight((1_000_000, DispatchClass::Operational))]
pub fn authorize_upgrade(
origin: OriginFor<T>,
code_hash: T::Hash,
check_version: bool,
) -> DispatchResult {
ensure_root(origin)?;
AuthorizedUpgrade::<T>::put(CodeUpgradeAuthorization {
code_hash: code_hash.clone(),
check_version,
});
Self::deposit_event(Event::UpgradeAuthorized { code_hash });
Ok(())
}
/// Provide the preimage (runtime binary) `code` for an upgrade that has been authorized.
///
/// If the authorization required a version check, this call will ensure the spec name
/// remains unchanged and that the spec version has increased.
///
/// Note that this function will not apply the new `code`, but only attempt to schedule the
/// upgrade with the Relay Chain.
///
/// All origins are allowed.
#[pallet::call_index(3)]
#[pallet::weight({1_000_000})]
pub fn enact_authorized_upgrade(
_: OriginFor<T>,
code: Vec<u8>,
) -> DispatchResultWithPostInfo {
Self::validate_authorized_upgrade(&code[..])?;
Self::schedule_code_upgrade(code)?;
AuthorizedUpgrade::<T>::kill();
Ok(Pays::No.into())
}
}
#[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config> {
/// The validation function has been scheduled to apply.
ValidationFunctionStored,
/// The validation function was applied as of the contained relay chain block number.
ValidationFunctionApplied { relay_chain_block_num: RelayChainBlockNumber },
/// The relay-chain aborted the upgrade process.
ValidationFunctionDiscarded,
/// An upgrade has been authorized.
UpgradeAuthorized { code_hash: T::Hash },
/// Some downward messages have been received and will be processed.
DownwardMessagesReceived { count: u32 },
/// Downward messages were processed using the given weight.
DownwardMessagesProcessed { weight_used: Weight, dmq_head: relay_chain::Hash },
/// An upward message was sent to the relay chain.
UpwardMessageSent { message_hash: Option<XcmHash> },
}
#[pallet::error]
pub enum Error<T> {
/// Attempt to upgrade validation function while existing upgrade pending.
OverlappingUpgrades,
/// Polkadot currently prohibits this parachain from upgrading its validation function.
ProhibitedByPolkadot,
/// The supplied validation function has compiled into a blob larger than Polkadot is
/// willing to run.
TooBig,
/// The inherent which supplies the validation data did not run this block.
ValidationDataNotAvailable,
/// The inherent which supplies the host configuration did not run this block.
HostConfigurationNotAvailable,
/// No validation function upgrade is currently scheduled.
NotScheduled,
/// No code upgrade has been authorized.
NothingAuthorized,
/// The given code upgrade has not been authorized.
Unauthorized,
}
/// In case of a scheduled upgrade, this storage field contains the validation code to be applied.
///
/// As soon as the relay chain gives us the go-ahead signal, we will overwrite the [`:code`][well_known_keys::CODE]
/// which will result the next block process with the new validation code. This concludes the upgrade process.
///
/// [well_known_keys::CODE]: sp_core::storage::well_known_keys::CODE
#[pallet::storage]
#[pallet::getter(fn new_validation_function)]
pub(super) type PendingValidationCode<T: Config> = StorageValue<_, Vec<u8>, ValueQuery>;
/// Validation code that is set by the parachain and is to be communicated to collator and
/// consequently the relay-chain.
///
/// This will be cleared in `on_initialize` of each new block if no other pallet already set
/// the value.
#[pallet::storage]
pub(super) type NewValidationCode<T: Config> = StorageValue<_, Vec<u8>, OptionQuery>;
/// The [`PersistedValidationData`] set for this block.
/// This value is expected to be set only once per block and it's never stored
/// in the trie.
#[pallet::storage]
#[pallet::getter(fn validation_data)]
pub(super) type ValidationData<T: Config> = StorageValue<_, PersistedValidationData>;
/// Were the validation data set to notify the relay chain?
#[pallet::storage]
pub(super) type DidSetValidationCode<T: Config> = StorageValue<_, bool, ValueQuery>;
/// The relay chain block number associated with the last parachain block.
#[pallet::storage]
pub(super) type LastRelayChainBlockNumber<T: Config> =
StorageValue<_, RelayChainBlockNumber, ValueQuery>;
/// An option which indicates if the relay-chain restricts signalling a validation code upgrade.
/// In other words, if this is `Some` and [`NewValidationCode`] is `Some` then the produced
/// candidate will be invalid.
///
/// This storage item is a mirror of the corresponding value for the current parachain from the
/// relay-chain. This value is ephemeral which means it doesn't hit the storage. This value is
/// set after the inherent.
#[pallet::storage]
pub(super) type UpgradeRestrictionSignal<T: Config> =
StorageValue<_, Option<relay_chain::UpgradeRestriction>, ValueQuery>;
/// The state proof for the last relay parent block.
///
/// This field is meant to be updated each block with the validation data inherent. Therefore,
/// before processing of the inherent, e.g. in `on_initialize` this data may be stale.
///
/// This data is also absent from the genesis.
#[pallet::storage]
#[pallet::getter(fn relay_state_proof)]
pub(super) type RelayStateProof<T: Config> = StorageValue<_, sp_trie::StorageProof>;
/// The snapshot of some state related to messaging relevant to the current parachain as per
/// the relay parent.
///
/// This field is meant to be updated each block with the validation data inherent. Therefore,
/// before processing of the inherent, e.g. in `on_initialize` this data may be stale.
///
/// This data is also absent from the genesis.
#[pallet::storage]
#[pallet::getter(fn relevant_messaging_state)]
pub(super) type RelevantMessagingState<T: Config> = StorageValue<_, MessagingStateSnapshot>;
/// The parachain host configuration that was obtained from the relay parent.
///
/// This field is meant to be updated each block with the validation data inherent. Therefore,
/// before processing of the inherent, e.g. in `on_initialize` this data may be stale.
///
/// This data is also absent from the genesis.
#[pallet::storage]
#[pallet::getter(fn host_configuration)]
pub(super) type HostConfiguration<T: Config> = StorageValue<_, AbridgedHostConfiguration>;
/// The last downward message queue chain head we have observed.
///
/// This value is loaded before and saved after processing inbound downward messages carried
/// by the system inherent.
#[pallet::storage]
pub(super) type LastDmqMqcHead<T: Config> = StorageValue<_, MessageQueueChain, ValueQuery>;
/// The message queue chain heads we have observed per each channel incoming channel.
///
/// This value is loaded before and saved after processing inbound downward messages carried
/// by the system inherent.
#[pallet::storage]
pub(super) type LastHrmpMqcHeads<T: Config> =
StorageValue<_, BTreeMap<ParaId, MessageQueueChain>, ValueQuery>;
/// Number of downward messages processed in a block.
///
/// This will be cleared in `on_initialize` of each new block.
#[pallet::storage]
pub(super) type ProcessedDownwardMessages<T: Config> = StorageValue<_, u32, ValueQuery>;
/// HRMP watermark that was set in a block.
///
/// This will be cleared in `on_initialize` of each new block.
#[pallet::storage]
pub(super) type HrmpWatermark<T: Config> =
StorageValue<_, relay_chain::BlockNumber, ValueQuery>;
/// HRMP messages that were sent in a block.
///
/// This will be cleared in `on_initialize` of each new block.
#[pallet::storage]
pub(super) type HrmpOutboundMessages<T: Config> =
StorageValue<_, Vec<OutboundHrmpMessage>, ValueQuery>;
/// Upward messages that were sent in a block.
///
/// This will be cleared in `on_initialize` of each new block.
#[pallet::storage]
pub(super) type UpwardMessages<T: Config> = StorageValue<_, Vec<UpwardMessage>, ValueQuery>;
/// Upward messages that are still pending and not yet send to the relay chain.
#[pallet::storage]
pub(super) type PendingUpwardMessages<T: Config> =
StorageValue<_, Vec<UpwardMessage>, ValueQuery>;
/// The number of HRMP messages we observed in `on_initialize` and thus used that number for
/// announcing the weight of `on_initialize` and `on_finalize`.
#[pallet::storage]
pub(super) type AnnouncedHrmpMessagesPerCandidate<T: Config> = StorageValue<_, u32, ValueQuery>;
/// The weight we reserve at the beginning of the block for processing XCMP messages. This
/// overrides the amount set in the Config trait.
#[pallet::storage]
pub(super) type ReservedXcmpWeightOverride<T: Config> = StorageValue<_, Weight>;
/// The weight we reserve at the beginning of the block for processing DMP messages. This
/// overrides the amount set in the Config trait.
#[pallet::storage]
pub(super) type ReservedDmpWeightOverride<T: Config> = StorageValue<_, Weight>;
/// The next authorized upgrade, if there is one.
#[pallet::storage]
pub(super) type AuthorizedUpgrade<T: Config> = StorageValue<_, CodeUpgradeAuthorization<T>>;
/// A custom head data that should be returned as result of `validate_block`.
///
/// See [`Pallet::set_custom_validation_head_data`] for more information.
#[pallet::storage]
pub(super) type CustomValidationHeadData<T: Config> = StorageValue<_, Vec<u8>, OptionQuery>;
#[pallet::inherent]
impl<T: Config> ProvideInherent for Pallet<T> {
type Call = Call<T>;
type Error = sp_inherents::MakeFatalError<()>;
const INHERENT_IDENTIFIER: InherentIdentifier =
cumulus_primitives_parachain_inherent::INHERENT_IDENTIFIER;
fn create_inherent(data: &InherentData) -> Option<Self::Call> {
let data: ParachainInherentData =
data.get_data(&Self::INHERENT_IDENTIFIER).ok().flatten().expect(
"validation function params are always injected into inherent data; qed",
);
Some(Call::set_validation_data { data })
}
fn is_inherent(call: &Self::Call) -> bool {
matches!(call, Call::set_validation_data { .. })
}
}
#[pallet::genesis_config]
#[derive(Default)]
pub struct GenesisConfig;
#[pallet::genesis_build]
impl<T: Config> GenesisBuild<T> for GenesisConfig {
fn build(&self) {
// TODO: Remove after https://github.com/paritytech/cumulus/issues/479
sp_io::storage::set(b":c", &[]);
}
}
#[pallet::validate_unsigned]
impl<T: Config> sp_runtime::traits::ValidateUnsigned for Pallet<T> {
type Call = Call<T>;
fn validate_unsigned(_source: TransactionSource, call: &Self::Call) -> TransactionValidity {
if let Call::enact_authorized_upgrade { ref code } = call {
if let Ok(hash) = Self::validate_authorized_upgrade(code) {
return Ok(ValidTransaction {
priority: 100,
requires: Vec::new(),
provides: vec![hash.as_ref().to_vec()],
longevity: TransactionLongevity::max_value(),
propagate: true,
})
}
}
if let Call::set_validation_data { .. } = call {
return Ok(Default::default())
}
Err(InvalidTransaction::Call.into())
}
}
}
impl<T: Config> Pallet<T> {
fn validate_authorized_upgrade(code: &[u8]) -> Result<T::Hash, DispatchError> {
let authorization = AuthorizedUpgrade::<T>::get().ok_or(Error::<T>::NothingAuthorized)?;
// ensure that the actual hash matches the authorized hash
let actual_hash = T::Hashing::hash(&code[..]);
ensure!(actual_hash == authorization.code_hash, Error::<T>::Unauthorized);
// check versions if required as part of the authorization
if authorization.check_version {
frame_system::Pallet::<T>::can_set_code(code)?;
}
Ok(actual_hash)
}
}
impl<T: Config> GetChannelInfo for Pallet<T> {
fn get_channel_status(id: ParaId) -> ChannelStatus {
// Note, that we are using `relevant_messaging_state` which may be from the previous
// block, in case this is called from `on_initialize`, i.e. before the inherent with
// fresh data is submitted.
//
// That shouldn't be a problem though because this is anticipated and already can
// happen. This is because sending implies that a message is buffered until there is
// space to send a message in the candidate. After a while waiting in a buffer, it may
// be discovered that the channel to which a message were addressed is now closed.
// Another possibility, is that the maximum message size was decreased so that a
// message in the buffer doesn't fit. Should any of that happen the sender should be
// notified about the message was discarded.
//
// Here it a similar case, with the difference that the realization that the channel is
// closed came the same block.
let channels = match Self::relevant_messaging_state() {
None => {
log::warn!("calling `get_channel_status` with no RelevantMessagingState?!");
return ChannelStatus::Closed
},
Some(d) => d.egress_channels,
};
// ^^^ NOTE: This storage field should carry over from the previous block. So if it's
// None then it must be that this is an edge-case where a message is attempted to be
// sent at the first block. It should be safe to assume that there are no channels
// opened at all so early. At least, relying on this assumption seems to be a better
// trade-off, compared to introducing an error variant that the clients should be
// prepared to handle.
let index = match channels.binary_search_by_key(&id, |item| item.0) {
Err(_) => return ChannelStatus::Closed,
Ok(i) => i,
};
let meta = &channels[index].1;
if meta.msg_count + 1 > meta.max_capacity {
// The channel is at its capacity. Skip it for now.
return ChannelStatus::Full
}
let max_size_now = meta.max_total_size - meta.total_size;
let max_size_ever = meta.max_message_size;
ChannelStatus::Ready(max_size_now as usize, max_size_ever as usize)
}
fn get_channel_max(id: ParaId) -> Option<usize> {
let channels = Self::relevant_messaging_state()?.egress_channels;
let index = channels.binary_search_by_key(&id, |item| item.0).ok()?;
Some(channels[index].1.max_message_size as usize)
}
}
impl<T: Config> Pallet<T> {
/// Process all inbound downward messages relayed by the collator.
///
/// Checks if the sequence of the messages is valid, dispatches them and communicates the
/// number of processed messages to the collator via a storage update.
///
/// # Panics
///
/// If it turns out that after processing all messages the Message Queue Chain
/// hash doesn't match the expected.
fn process_inbound_downward_messages(
expected_dmq_mqc_head: relay_chain::Hash,
downward_messages: Vec<InboundDownwardMessage>,
) -> Weight {
let dm_count = downward_messages.len() as u32;
let mut dmq_head = <LastDmqMqcHead<T>>::get();
let mut weight_used = Weight::zero();
if dm_count != 0 {
Self::deposit_event(Event::DownwardMessagesReceived { count: dm_count });
let max_weight =
<ReservedDmpWeightOverride<T>>::get().unwrap_or_else(T::ReservedDmpWeight::get);
let message_iter = downward_messages
.into_iter()
.inspect(|m| {
dmq_head.extend_downward(m);
})
.map(|m| (m.sent_at, m.msg));
weight_used += T::DmpMessageHandler::handle_dmp_messages(message_iter, max_weight);
<LastDmqMqcHead<T>>::put(&dmq_head);
Self::deposit_event(Event::DownwardMessagesProcessed {
weight_used,
dmq_head: dmq_head.head(),
});
}
// After hashing each message in the message queue chain submitted by the collator, we
// should arrive to the MQC head provided by the relay chain.
//
// A mismatch means that at least some of the submitted messages were altered, omitted or
// added improperly.
assert_eq!(dmq_head.head(), expected_dmq_mqc_head);
ProcessedDownwardMessages::<T>::put(dm_count);
weight_used
}
/// Process all inbound horizontal messages relayed by the collator.
///
/// This is similar to [`process_inbound_downward_messages`], but works on multiple inbound
/// channels.
///
/// **Panics** if either any of horizontal messages submitted by the collator was sent from
/// a para which has no open channel to this parachain or if after processing
/// messages across all inbound channels MQCs were obtained which do not
/// correspond to the ones found on the relay-chain.
fn process_inbound_horizontal_messages(
ingress_channels: &[(ParaId, cumulus_primitives_core::AbridgedHrmpChannel)],
horizontal_messages: BTreeMap<ParaId, Vec<InboundHrmpMessage>>,
relay_parent_number: relay_chain::BlockNumber,
) -> Weight {
// First, check that all submitted messages are sent from channels that exist. The
// channel exists if its MQC head is present in `vfp.hrmp_mqc_heads`.
for sender in horizontal_messages.keys() {
// A violation of the assertion below indicates that one of the messages submitted
// by the collator was sent from a sender that doesn't have a channel opened to
// this parachain, according to the relay-parent state.
assert!(ingress_channels.binary_search_by_key(sender, |&(s, _)| s).is_ok(),);
}
// Second, prepare horizontal messages for a more convenient processing:
//
// instead of a mapping from a para to a list of inbound HRMP messages, we will have a
// list of tuples `(sender, message)` first ordered by `sent_at` (the relay chain block
// number in which the message hit the relay-chain) and second ordered by para id
// ascending.
//
// The messages will be dispatched in this order.
let mut horizontal_messages = horizontal_messages
.into_iter()
.flat_map(|(sender, channel_contents)| {
channel_contents.into_iter().map(move |message| (sender, message))
})
.collect::<Vec<_>>();
horizontal_messages.sort_by(|a, b| {
// first sort by sent-at and then by the para id
match a.1.sent_at.cmp(&b.1.sent_at) {
cmp::Ordering::Equal => a.0.cmp(&b.0),
ord => ord,
}
});
let last_mqc_heads = <LastHrmpMqcHeads<T>>::get();
let mut running_mqc_heads = BTreeMap::new();
let mut hrmp_watermark = None;
{
for (sender, ref horizontal_message) in &horizontal_messages {
if hrmp_watermark.map(|w| w < horizontal_message.sent_at).unwrap_or(true) {
hrmp_watermark = Some(horizontal_message.sent_at);
}
running_mqc_heads
.entry(sender)
.or_insert_with(|| last_mqc_heads.get(sender).cloned().unwrap_or_default())
.extend_hrmp(horizontal_message);
}
}
let message_iter = horizontal_messages
.iter()
.map(|&(sender, ref message)| (sender, message.sent_at, &message.data[..]));
let max_weight =
<ReservedXcmpWeightOverride<T>>::get().unwrap_or_else(T::ReservedXcmpWeight::get);
let weight_used = T::XcmpMessageHandler::handle_xcmp_messages(message_iter, max_weight);
// Check that the MQC heads for each channel provided by the relay chain match the MQC
// heads we have after processing all incoming messages.
//
// Along the way we also carry over the relevant entries from the `last_mqc_heads` to
// `running_mqc_heads`. Otherwise, in a block where no messages were sent in a channel
// it won't get into next block's `last_mqc_heads` and thus will be all zeros, which
// would corrupt the message queue chain.
for &(ref sender, ref channel) in ingress_channels {
let cur_head = running_mqc_heads
.entry(sender)
.or_insert_with(|| last_mqc_heads.get(&sender).cloned().unwrap_or_default())
.head();
let target_head = channel.mqc_head.unwrap_or_default();
assert!(cur_head == target_head);
}
<LastHrmpMqcHeads<T>>::put(running_mqc_heads);
// If we processed at least one message, then advance watermark to that location or if there
// were no messages, set it to the block number of the relay parent.
HrmpWatermark::<T>::put(hrmp_watermark.unwrap_or(relay_parent_number));
weight_used
}
/// Put a new validation function into a particular location where polkadot
/// monitors for updates. Calling this function notifies polkadot that a new
/// upgrade has been scheduled.
fn notify_polkadot_of_pending_upgrade(code: &[u8]) {
NewValidationCode::<T>::put(code);
<DidSetValidationCode<T>>::put(true);
}
/// Put a new validation function into a particular location where this
/// parachain will execute it on subsequent blocks.
fn put_parachain_code(code: &[u8]) {
storage::unhashed::put_raw(sp_core::storage::well_known_keys::CODE, code);
}
/// The maximum code size permitted, in bytes.
///
/// Returns `None` if the relay chain parachain host configuration hasn't been submitted yet.
pub fn max_code_size() -> Option<u32> {
<HostConfiguration<T>>::get().map(|cfg| cfg.max_code_size)
}
/// The implementation of the runtime upgrade functionality for parachains.
pub fn schedule_code_upgrade(validation_function: Vec<u8>) -> DispatchResult {
// Ensure that `ValidationData` exists. We do not care about the validation data per se,
// but we do care about the [`UpgradeRestrictionSignal`] which arrives with the same inherent.
ensure!(<ValidationData<T>>::exists(), Error::<T>::ValidationDataNotAvailable,);
ensure!(<UpgradeRestrictionSignal<T>>::get().is_none(), Error::<T>::ProhibitedByPolkadot);
ensure!(!<PendingValidationCode<T>>::exists(), Error::<T>::OverlappingUpgrades);
let cfg = Self::host_configuration().ok_or(Error::<T>::HostConfigurationNotAvailable)?;
ensure!(validation_function.len() <= cfg.max_code_size as usize, Error::<T>::TooBig);
// When a code upgrade is scheduled, it has to be applied in two
// places, synchronized: both polkadot and the individual parachain
// have to upgrade on the same relay chain block.
//
// `notify_polkadot_of_pending_upgrade` notifies polkadot; the `PendingValidationCode`
// storage keeps track locally for the parachain upgrade, which will
// be applied later: when the relay-chain communicates go-ahead signal to us.
Self::notify_polkadot_of_pending_upgrade(&validation_function);
<PendingValidationCode<T>>::put(validation_function);
Self::deposit_event(Event::ValidationFunctionStored);
Ok(())
}
/// Returns the [`CollationInfo`] of the current active block.
///
/// The given `header` is the header of the built block we are collecting the collation info for.
///
/// This is expected to be used by the
/// [`CollectCollationInfo`](cumulus_primitives_core::CollectCollationInfo) runtime api.
pub fn collect_collation_info(header: &T::Header) -> CollationInfo {
CollationInfo {
hrmp_watermark: HrmpWatermark::<T>::get(),
horizontal_messages: HrmpOutboundMessages::<T>::get(),
upward_messages: UpwardMessages::<T>::get(),
processed_downward_messages: ProcessedDownwardMessages::<T>::get(),
new_validation_code: NewValidationCode::<T>::get().map(Into::into),
// Check if there is a custom header that will also be returned by the validation phase.
// If so, we need to also return it here.
head_data: CustomValidationHeadData::<T>::get()
.map_or_else(|| header.encode(), |v| v)
.into(),
}
}
/// Set a custom head data that should be returned as result of `validate_block`.
///
/// This will overwrite the head data that is returned as result of `validate_block` while
/// validating a `PoV` on the relay chain. Normally the head data that is being returned
/// by `validate_block` is the header of the block that is validated, thus it can be
/// enacted as the new best block. However, for features like forking it can be useful
/// to overwrite the head data with a custom header.
///
/// # Attention
///
/// This should only be used when you are sure what you are doing as this can brick
/// your Parachain.
pub fn set_custom_validation_head_data(head_data: Vec<u8>) {
CustomValidationHeadData::<T>::put(head_data);
}
/// Open HRMP channel for using it in benchmarks.
///
/// The caller assumes that the pallet will accept regular outbound message to the sibling
/// `target_parachain` after this call. No other assumptions are made.
#[cfg(feature = "runtime-benchmarks")]
pub fn open_outbound_hrmp_channel_for_benchmarks(target_parachain: ParaId) {
RelevantMessagingState::<T>::put(MessagingStateSnapshot {
dmq_mqc_head: Default::default(),
relay_dispatch_queue_size: Default::default(),
ingress_channels: Default::default(),
egress_channels: vec![(
target_parachain,
cumulus_primitives_core::AbridgedHrmpChannel {
max_capacity: 10,
max_total_size: 10_000_000_u32,
max_message_size: 10_000_000_u32,
msg_count: 5,
total_size: 5_000_000_u32,
mqc_head: None,
},
)],
})
}
}
pub struct ParachainSetCode<T>(sp_std::marker::PhantomData<T>);
impl<T: Config> frame_system::SetCode<T> for ParachainSetCode<T> {
fn set_code(code: Vec<u8>) -> DispatchResult {
Pallet::<T>::schedule_code_upgrade(code)
}
}
impl<T: Config> Pallet<T> {
pub fn send_upward_message(message: UpwardMessage) -> Result<(u32, XcmHash), MessageSendError> {
// Check if the message fits into the relay-chain constraints.
//
// Note, that we are using `host_configuration` here which may be from the previous
// block, in case this is called from `on_initialize`, i.e. before the inherent with fresh
// data is submitted.
//
// That shouldn't be a problem since this is a preliminary check and the actual check would
// be performed just before submitting the message from the candidate, and it already can
// happen that during the time the message is buffered for sending the relay-chain setting
// may change so that the message is no longer valid.
//
// However, changing this setting is expected to be rare.
match Self::host_configuration() {
Some(cfg) =>
if message.len() > cfg.max_upward_message_size as usize {
return Err(MessageSendError::TooBig)
},
None => {
// This storage field should carry over from the previous block. So if it's None
// then it must be that this is an edge-case where a message is attempted to be
// sent at the first block.
//
// Let's pass this message through. I think it's not unreasonable to expect that
// the message is not huge and it comes through, but if it doesn't it can be
// returned back to the sender.
//
// Thus fall through here.
},
};
<PendingUpwardMessages<T>>::append(message.clone());
// The relay ump does not use using_encoded
// We apply the same this to use the same hash
let hash = sp_io::hashing::blake2_256(&message);
Self::deposit_event(Event::UpwardMessageSent { message_hash: Some(hash) });
Ok((0, hash))
}
}
impl<T: Config> UpwardMessageSender for Pallet<T> {
fn send_upward_message(message: UpwardMessage) -> Result<(u32, XcmHash), MessageSendError> {
Self::send_upward_message(message)
}
}
/// Something that can check the inherents of a block.
pub trait CheckInherents<Block: BlockT> {
/// 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(
block: &Block,
validation_data: &RelayChainStateProof,
) -> frame_support::inherent::CheckInherentsResult;
}
/// Something that should be informed about system related events.
///
/// This includes events like [`on_validation_data`](Self::on_validation_data) that is being
/// called when the parachain inherent is executed that contains the validation data.
/// Or like [`on_validation_code_applied`](Self::on_validation_code_applied) that is called
/// when the new validation is written to the state. This means that
/// from the next block the runtime is being using this new code.
#[impl_trait_for_tuples::impl_for_tuples(30)]
pub trait OnSystemEvent {
/// Called in each blocks once when the validation data is set by the inherent.
fn on_validation_data(data: &PersistedValidationData);
/// Called when the validation code is being applied, aka from the next block on this is the new runtime.
fn on_validation_code_applied();
}
/// Holds the most recent relay-parent state root and block number of the current parachain block.
#[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, Default, RuntimeDebug)]
pub struct RelayChainState {
/// Current relay chain height.
pub number: relay_chain::BlockNumber,
/// State root for current relay chain height.
pub state_root: relay_chain::Hash,
}
/// This exposes the [`RelayChainState`] to other runtime modules.
///
/// Enables parachains to read relay chain state via state proofs.
pub trait RelaychainStateProvider {
/// May be called by any runtime module to obtain the current state of the relay chain.
///
/// **NOTE**: This is not guaranteed to return monotonically increasing relay parents.
fn current_relay_chain_state() -> RelayChainState;
}
/// Implements [`BlockNumberProvider`] that returns relay chain block number fetched from validation data.
/// When validation data is not available (e.g. within on_initialize), 0 will be returned.
///
/// **NOTE**: This has been deprecated, please use [`RelaychainDataProvider`]
#[deprecated = "Use `RelaychainDataProvider` instead"]
pub struct RelaychainBlockNumberProvider<T>(sp_std::marker::PhantomData<T>);
#[allow(deprecated)]
impl<T: Config> BlockNumberProvider for RelaychainBlockNumberProvider<T> {
type BlockNumber = relay_chain::BlockNumber;
fn current_block_number() -> relay_chain::BlockNumber {
Pallet::<T>::validation_data()
.map(|d| d.relay_parent_number)
.unwrap_or_default()
}
#[cfg(feature = "runtime-benchmarks")]
fn set_block_number(block: Self::BlockNumber) {
let mut validation_data = Pallet::<T>::validation_data().unwrap_or_else(||
// PersistedValidationData does not impl default in non-std
PersistedValidationData {
parent_head: vec![].into(),
relay_parent_number: Default::default(),
max_pov_size: Default::default(),
relay_parent_storage_root: Default::default(),
});
validation_data.relay_parent_number = block;
ValidationData::<T>::put(validation_data)
}
}
impl<T: Config> RelaychainStateProvider for RelaychainDataProvider<T> {
fn current_relay_chain_state() -> RelayChainState {
Pallet::<T>::validation_data()
.map(|d| RelayChainState {
number: d.relay_parent_number,
state_root: d.relay_parent_storage_root,
})
.unwrap_or_default()
}
}
/// Implements [`BlockNumberProvider`] and [`RelaychainStateProvider`] that returns relevant relay data fetched from
/// validation data.
/// NOTE: When validation data is not available (e.g. within on_initialize), default values will be returned.
pub struct RelaychainDataProvider<T>(sp_std::marker::PhantomData<T>);
impl<T: Config> BlockNumberProvider for RelaychainDataProvider<T> {
type BlockNumber = relay_chain::BlockNumber;
fn current_block_number() -> relay_chain::BlockNumber {
Pallet::<T>::validation_data()
.map(|d| d.relay_parent_number)
.unwrap_or_default()
}
#[cfg(feature = "runtime-benchmarks")]
fn set_block_number(block: Self::BlockNumber) {
let mut validation_data = Pallet::<T>::validation_data().unwrap_or_else(||
// PersistedValidationData does not impl default in non-std
PersistedValidationData {
parent_head: vec![].into(),
relay_parent_number: Default::default(),
max_pov_size: Default::default(),
relay_parent_storage_root: Default::default(),
});
validation_data.relay_parent_number = block;
ValidationData::<T>::put(validation_data)
}
}