mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 08:11:03 +00:00
Add canvas-kusama runtime (#980)
* Added kanvas runtime * Fix up benchmarking * Fixup markdown stucture * replace :emoji_name: by utf8 * fix up header hierarchy * Merge canvas README * Only use "Canvas" as a name * Remove reference to Rocanvas
This commit is contained in:
committed by
GitHub
parent
81e7db5bc8
commit
230978b683
Generated
+505
-275
File diff suppressed because it is too large
Load Diff
@@ -32,6 +32,7 @@ members = [
|
|||||||
"polkadot-parachains/statemint",
|
"polkadot-parachains/statemint",
|
||||||
"polkadot-parachains/statemine",
|
"polkadot-parachains/statemine",
|
||||||
"polkadot-parachains/westmint",
|
"polkadot-parachains/westmint",
|
||||||
|
"polkadot-parachains/canvas-kusama",
|
||||||
"test/client",
|
"test/client",
|
||||||
"test/relay-sproof-builder",
|
"test/relay-sproof-builder",
|
||||||
"test/relay-validation-worker-provider",
|
"test/relay-validation-worker-provider",
|
||||||
|
|||||||
@@ -1,4 +1,9 @@
|
|||||||
# Cumulus :cloud:
|
# Cumulus ☁️
|
||||||
|
|
||||||
|
This repository contains both the Cumulus SDK and also specific chains implemented
|
||||||
|
on top of this SDK.
|
||||||
|
|
||||||
|
## Cumulus SDK
|
||||||
|
|
||||||
A set of tools for writing [Substrate](https://substrate.io/)-based
|
A set of tools for writing [Substrate](https://substrate.io/)-based
|
||||||
[Polkadot](https://wiki.polkadot.network/en/)
|
[Polkadot](https://wiki.polkadot.network/en/)
|
||||||
@@ -14,7 +19,7 @@ make it easy to write parachains for Polkadot by leveraging the power of Substra
|
|||||||
Cumulus clouds are shaped sort of like dots; together they form a system that is intricate,
|
Cumulus clouds are shaped sort of like dots; together they form a system that is intricate,
|
||||||
beautiful and functional.
|
beautiful and functional.
|
||||||
|
|
||||||
## Consensus
|
### Consensus
|
||||||
|
|
||||||
[`parachain-consensus`](https://github.com/paritytech/cumulus/blob/master/client/consensus/common/src/parachain_consensus.rs) is a
|
[`parachain-consensus`](https://github.com/paritytech/cumulus/blob/master/client/consensus/common/src/parachain_consensus.rs) is a
|
||||||
[consensus engine](https://docs.substrate.io/v3/advanced/consensus) for Substrate
|
[consensus engine](https://docs.substrate.io/v3/advanced/consensus) for Substrate
|
||||||
@@ -25,18 +30,18 @@ to follow,
|
|||||||
[finalize](https://wiki.polkadot.network/docs/en/learn-consensus#probabilistic-vs-provable-finality),
|
[finalize](https://wiki.polkadot.network/docs/en/learn-consensus#probabilistic-vs-provable-finality),
|
||||||
and treat as best.
|
and treat as best.
|
||||||
|
|
||||||
## Collator
|
### Collator
|
||||||
|
|
||||||
A Polkadot [collator](https://wiki.polkadot.network/docs/en/learn-collator) for the parachain is
|
A Polkadot [collator](https://wiki.polkadot.network/docs/en/learn-collator) for the parachain is
|
||||||
implemented by the `polkadot-collator` binary.
|
implemented by the `polkadot-collator` binary.
|
||||||
|
|
||||||
# Statemint 🪙
|
## Statemint 🪙
|
||||||
|
|
||||||
This repository also contains the Statemint runtime (as well as the canary runtime Statemine and the
|
This repository also contains the Statemint runtime (as well as the canary runtime Statemine and the
|
||||||
test runtime Westmint).
|
test runtime Westmint).
|
||||||
Statemint is a common good parachain providing an asset store for the Polkadot ecosystem.
|
Statemint is a common good parachain providing an asset store for the Polkadot ecosystem.
|
||||||
|
|
||||||
## Build & Launch a Node
|
### Build & Launch a Node
|
||||||
|
|
||||||
To run a Statemine or Westmint node (Statemint is not deployed, yet) you will need to compile the
|
To run a Statemine or Westmint node (Statemint is not deployed, yet) you will need to compile the
|
||||||
`polkadot-collator` binary:
|
`polkadot-collator` binary:
|
||||||
@@ -54,14 +59,104 @@ CHAIN=westmint # or statemine
|
|||||||
|
|
||||||
Refer to the [setup instructions below](#local-setup) to run a local network for development.
|
Refer to the [setup instructions below](#local-setup) to run a local network for development.
|
||||||
|
|
||||||
# Rococo :crown:
|
## Canvas 🧑🎨
|
||||||
|
|
||||||
|
[![matrix][k1]][k2] [![discord][l1]][l2]
|
||||||
|
|
||||||
|
[k1]: https://img.shields.io/badge/matrix-chat-brightgreen.svg?style=flat
|
||||||
|
[k2]: https://riot.im/app/#/room/#ink:matrix.parity.io
|
||||||
|
[l1]: https://img.shields.io/discord/722223075629727774?style=flat-square&label=discord
|
||||||
|
[l2]: https://discord.com/invite/wGUDt2p
|
||||||
|
|
||||||
|
This is a node implementation of `Canvas`, a common good parachain for `pallet-contracts`
|
||||||
|
based wasm smart contracts. Right now this repository only contains the `canvas-kusama` runtime
|
||||||
|
which we plan to use for both Rococo and Kusama.
|
||||||
|
|
||||||
|
If you have any questions, feel free to talk to us on [Element][k2] or on [Discord][l2]
|
||||||
|
(in the [`ink_smart-contracts`](https://discord.com/channels/722223075629727774/765280480609828864) channel).
|
||||||
|
|
||||||
|
## Developing Smart Contracts for Canvas
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
This node contains Substrate's smart contracts module ‒ the
|
||||||
|
[`contracts`](https://github.com/paritytech/substrate/tree/master/frame/contracts) pallet.
|
||||||
|
This `contracts` pallet takes smart contracts as WebAssembly blobs and defines an API
|
||||||
|
for everything a smart contract needs (storage access, …).
|
||||||
|
As long as a programming language compiles to WebAssembly and there exists an implementation
|
||||||
|
of this API in it, you can write a smart contract for this pallet ‒ and thus for Canvas ‒ in
|
||||||
|
that language.
|
||||||
|
|
||||||
|
This is a list of languages you can currently choose from:
|
||||||
|
|
||||||
|
* [Parity's ink!](https://github.com/paritytech/ink) for Rust
|
||||||
|
* [ask!](https://github.com/patractlabs/ask) for Assembly Script
|
||||||
|
* The [Solang](https://github.com/hyperledger-labs/solang) compiler for Solidity
|
||||||
|
|
||||||
|
There are also different user interfaces and command-line tools you can use to deploy
|
||||||
|
or interact with contracts:
|
||||||
|
|
||||||
|
* [polkadot-js](https://polkadot.js.org/apps/)
|
||||||
|
* [Canvas UI](https://paritytech.github.io/canvas-ui/) (outdated)
|
||||||
|
|
||||||
|
If you are looking for a quickstart, we can recommend
|
||||||
|
[ink!'s Guided Tutorial for Beginners](https://docs.substrate.io/tutorials/v3/ink-workshop/pt1/).
|
||||||
|
|
||||||
|
### Build & Launch a Node
|
||||||
|
|
||||||
|
To run a Canvas node that connects to Rococo (Kusama and Polkadot parachains are not deployed, yet)
|
||||||
|
you will need to compile the `polkadot-collator` binary:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo build --release --locked -p polkadot-collator
|
||||||
|
```
|
||||||
|
|
||||||
|
Once the executable is built, launch the parachain node via:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./target/release/polkadot-collator --chain rocanvas
|
||||||
|
```
|
||||||
|
|
||||||
|
Refer to the [setup instructions below](#local-setup) to run a local network for development.
|
||||||
|
|
||||||
|
### Rococo Deployment
|
||||||
|
|
||||||
|
We have a live deployment of the Canvas parachain on [Rococo](https://wiki.polkadot.network/docs/build-pdk#rococo-testnet) ‒
|
||||||
|
a testnet for Polkadot and Kusama parachains.
|
||||||
|
You can interact with the network through Polkadot JS Apps,
|
||||||
|
[click here for a direct link to Canvas](https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Frococo-canvas-rpc.polkadot.io#/explorer).
|
||||||
|
|
||||||
|
The Canvas parachain uses the Rococo relay chain's native token (ROC) instead of having its own token.
|
||||||
|
Due to this you'll need ROC in order to deploy contracts on Canvas.
|
||||||
|
|
||||||
|
As a first step, you should create an account. See [here](https://wiki.polkadot.network/docs/learn-account-generation)
|
||||||
|
for a detailed guide.
|
||||||
|
|
||||||
|
As a second step, you have to get ROC testnet tokens through the [Rococo Faucet](https://wiki.polkadot.network/docs/learn-DOT#getting-rococo-tokens).
|
||||||
|
This is a chat room in which you need to write:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
!drip YOUR_SS_58_ADDRESS:1002
|
||||||
|
```
|
||||||
|
|
||||||
|
The number `1002` is the parachain id of Canvas on Rococo, by supplying it the faucet will teleport ROC
|
||||||
|
tokens directly to your account on the parachain.
|
||||||
|
|
||||||
|
If everything worked out, the teleported ROC tokens will show up under
|
||||||
|
[the "Accounts" tab for Canvas](https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Frococo-canvas-rpc.polkadot.io#/accounts).
|
||||||
|
|
||||||
|
Once you have ROC on Canvas you can deploy a contract as you would normally.
|
||||||
|
If you're unsure about this, our [guided tutorial](https://docs.substrate.io/tutorials/v3/ink-workshop/pt1/)
|
||||||
|
will clarify that for you in no time.
|
||||||
|
|
||||||
|
## Rococo 👑
|
||||||
|
|
||||||
[Rococo](https://polkadot.js.org/apps/?rpc=wss://rococo-rpc.polkadot.io) is becoming a [Community Parachain Testbed](https://polkadot.network/blog/rococo-revamp-becoming-a-community-parachain-testbed/) for parachain teams in the Polkadot ecosystem. It supports multiple parachains with the differentiation of long-term connections and recurring short-term connections, to see which parachains are currently connected and how long they will be connected for [see here](https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Frococo-rpc.polkadot.io#/parachains).
|
[Rococo](https://polkadot.js.org/apps/?rpc=wss://rococo-rpc.polkadot.io) is becoming a [Community Parachain Testbed](https://polkadot.network/blog/rococo-revamp-becoming-a-community-parachain-testbed/) for parachain teams in the Polkadot ecosystem. It supports multiple parachains with the differentiation of long-term connections and recurring short-term connections, to see which parachains are currently connected and how long they will be connected for [see here](https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Frococo-rpc.polkadot.io#/parachains).
|
||||||
|
|
||||||
Rococo is an elaborate style of design and the name describes the painstaking effort that has gone
|
Rococo is an elaborate style of design and the name describes the painstaking effort that has gone
|
||||||
into this project.
|
into this project.
|
||||||
|
|
||||||
## Build & Launch Rococo Collators
|
### Build & Launch Rococo Collators
|
||||||
|
|
||||||
Collators are similar to validators in the relay chain. These nodes build the blocks that will
|
Collators are similar to validators in the relay chain. These nodes build the blocks that will
|
||||||
eventually be included by the relay chain for a parachain.
|
eventually be included by the relay chain for a parachain.
|
||||||
@@ -92,19 +187,21 @@ Once the executable is built, launch collators for each parachain (repeat once e
|
|||||||
./target/release/polkadot-collator --chain $CHAIN --validator
|
./target/release/polkadot-collator --chain $CHAIN --validator
|
||||||
```
|
```
|
||||||
|
|
||||||
## Parachains
|
### Parachains
|
||||||
|
|
||||||
- [Canvas - WASM Smart Contract](https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Frococo-canvas-rpc.polkadot.io#/explorer)
|
* [Statemint](https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Frococo-statemint-rpc.polkadot.io#/explorer)
|
||||||
|
* [Canvas on Rococo](https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Frococo-canvas-rpc.polkadot.io#/explorer)
|
||||||
|
* [RILT](https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Frococo.kilt.io#/explorer)
|
||||||
|
|
||||||
The network uses horizontal message passing (HRMP) to enable communication between parachains and
|
The network uses horizontal message passing (HRMP) to enable communication between parachains and
|
||||||
the relay chain and, in turn, between parachains. This means that every message is sent to the relay
|
the relay chain and, in turn, between parachains. This means that every message is sent to the relay
|
||||||
chain, and from the relay chain to its destination parachain.
|
chain, and from the relay chain to its destination parachain.
|
||||||
|
|
||||||
## Local Setup
|
### Local Setup
|
||||||
|
|
||||||
Launch a local setup including a Relay Chain and a Parachain.
|
Launch a local setup including a Relay Chain and a Parachain.
|
||||||
|
|
||||||
### Launch the Relay Chain
|
#### Launch the Relay Chain
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Compile Polkadot with the real overseer feature
|
# Compile Polkadot with the real overseer feature
|
||||||
@@ -121,7 +218,7 @@ cargo build --release
|
|||||||
./target/release/polkadot --chain rococo-local-cfde.json --bob --tmp --port 30334
|
./target/release/polkadot --chain rococo-local-cfde.json --bob --tmp --port 30334
|
||||||
```
|
```
|
||||||
|
|
||||||
### Launch the Parachain
|
#### Launch the Parachain
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Compile
|
# Compile
|
||||||
@@ -144,11 +241,11 @@ cargo build --release
|
|||||||
./target/release/polkadot-collator --tmp --port 40337 --ws-port 9948 -- --execution wasm --chain ../polkadot/rococo-local-cfde.json --port 30337
|
./target/release/polkadot-collator --tmp --port 40337 --ws-port 9948 -- --execution wasm --chain ../polkadot/rococo-local-cfde.json --port 30337
|
||||||
```
|
```
|
||||||
|
|
||||||
### Register the parachain
|
#### Register the parachain
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## Containerize
|
### Containerize
|
||||||
|
|
||||||
After building `polkadot-collator` with cargo or with Parity CI image as documented in [this chapter](#build--launch-rococo-collators),
|
After building `polkadot-collator` with cargo or with Parity CI image as documented in [this chapter](#build--launch-rococo-collators),
|
||||||
the following will allow producing a new docker image where the compiled binary is injected:
|
the following will allow producing a new docker image where the compiled binary is injected:
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 88 KiB |
@@ -25,6 +25,7 @@ seedling-runtime = { path = "seedling" }
|
|||||||
statemint-runtime = { path = "statemint" }
|
statemint-runtime = { path = "statemint" }
|
||||||
statemine-runtime = { path = "statemine" }
|
statemine-runtime = { path = "statemine" }
|
||||||
westmint-runtime = { path = "westmint" }
|
westmint-runtime = { path = "westmint" }
|
||||||
|
canvas-kusama-runtime = { path = "canvas-kusama" }
|
||||||
parachains-common = { path = "parachains-common" }
|
parachains-common = { path = "parachains-common" }
|
||||||
|
|
||||||
# Substrate dependencies
|
# Substrate dependencies
|
||||||
@@ -66,6 +67,7 @@ jsonrpc-core = "18.0.0"
|
|||||||
sc-transaction-pool-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sc-transaction-pool-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
frame-rpc-system = { package = "substrate-frame-rpc-system", git = "https://github.com/paritytech/substrate", branch = "master" }
|
frame-rpc-system = { package = "substrate-frame-rpc-system", git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
pallet-transaction-payment-rpc = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
pallet-transaction-payment-rpc = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
pallet-contracts-rpc = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
|
||||||
# Cumulus dependencies
|
# Cumulus dependencies
|
||||||
cumulus-client-cli = { path = "../client/cli" }
|
cumulus-client-cli = { path = "../client/cli" }
|
||||||
|
|||||||
@@ -0,0 +1,174 @@
|
|||||||
|
[package]
|
||||||
|
name = "canvas-kusama-runtime"
|
||||||
|
version = "0.2.0"
|
||||||
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[package.metadata.docs.rs]
|
||||||
|
targets = ["x86_64-unknown-linux-gnu"]
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
substrate-wasm-builder = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
hex-literal = { version = '0.3.1', optional = true }
|
||||||
|
codec = { package = 'parity-scale-codec', version = '2.0.0', default-features = false, features = ['derive']}
|
||||||
|
log = { version = "0.4.14", default-features = false }
|
||||||
|
scale-info = { version = "1.0.0", default-features = false, features = ["derive"] }
|
||||||
|
serde = { version = '1.0.119', optional = true, features = ['derive'] }
|
||||||
|
smallvec = "1.6.1"
|
||||||
|
|
||||||
|
# Substrate Dependencies
|
||||||
|
## Substrate Primitive Dependencies
|
||||||
|
sp-api = { git = 'https://github.com/paritytech/substrate', default-features = false , branch = "master" }
|
||||||
|
sp-block-builder = { git = 'https://github.com/paritytech/substrate', default-features = false , branch = "master" }
|
||||||
|
sp-consensus-aura = { git = 'https://github.com/paritytech/substrate', default-features = false , branch = "master" }
|
||||||
|
sp-core = { git = 'https://github.com/paritytech/substrate', default-features = false , branch = "master" }
|
||||||
|
sp-inherents = { git = 'https://github.com/paritytech/substrate', default-features = false , branch = "master" }
|
||||||
|
sp-io = { git = 'https://github.com/paritytech/substrate', default-features = false , branch = "master" }
|
||||||
|
sp-offchain = { git = 'https://github.com/paritytech/substrate', default-features = false , branch = "master" }
|
||||||
|
sp-runtime = { git = 'https://github.com/paritytech/substrate', default-features = false , branch = "master" }
|
||||||
|
sp-session = { git = 'https://github.com/paritytech/substrate', default-features = false , branch = "master" }
|
||||||
|
sp-std = { git = 'https://github.com/paritytech/substrate', default-features = false , branch = "master" }
|
||||||
|
sp-transaction-pool = { git = 'https://github.com/paritytech/substrate', default-features = false , branch = "master" }
|
||||||
|
sp-version = { git = 'https://github.com/paritytech/substrate', default-features = false , branch = "master" }
|
||||||
|
node-primitives = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||||
|
|
||||||
|
## Substrate FRAME Dependencies
|
||||||
|
frame-benchmarking = { git = 'https://github.com/paritytech/substrate', default-features = false, optional = true , branch = "master" }
|
||||||
|
frame-try-runtime = { git = "https://github.com/paritytech/substrate", default-features = false, optional = true , branch = "master" }
|
||||||
|
frame-executive = { git = 'https://github.com/paritytech/substrate', default-features = false , branch = "master" }
|
||||||
|
frame-support = { git = 'https://github.com/paritytech/substrate', default-features = false, branch = "master" }
|
||||||
|
frame-system = { git = 'https://github.com/paritytech/substrate', default-features = false , branch = "master" }
|
||||||
|
frame-system-benchmarking = { git = 'https://github.com/paritytech/substrate', default-features = false, optional = true , branch = "master" }
|
||||||
|
frame-system-rpc-runtime-api = { git = 'https://github.com/paritytech/substrate', default-features = false , branch = "master" }
|
||||||
|
|
||||||
|
## Substrate Pallet Dependencies
|
||||||
|
pallet-aura = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" }
|
||||||
|
pallet-authorship = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" }
|
||||||
|
pallet-randomness-collective-flip = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" }
|
||||||
|
pallet-balances = { git = 'https://github.com/paritytech/substrate', default-features = false , branch = "master" }
|
||||||
|
pallet-multisig = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||||
|
pallet-session = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" }
|
||||||
|
pallet-timestamp = { git = 'https://github.com/paritytech/substrate', default-features = false , branch = "master" }
|
||||||
|
pallet-transaction-payment = { git = 'https://github.com/paritytech/substrate', default-features = false , branch = "master" }
|
||||||
|
pallet-transaction-payment-rpc-runtime-api = { git = 'https://github.com/paritytech/substrate', default-features = false , branch = "master" }
|
||||||
|
pallet-utility = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||||
|
pallet-sudo = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" }
|
||||||
|
|
||||||
|
# Cumulus Dependencies
|
||||||
|
cumulus-pallet-aura-ext = { path = "../../pallets/aura-ext", default-features = false }
|
||||||
|
cumulus-pallet-parachain-system = { path = "../../pallets/parachain-system", default-features = false }
|
||||||
|
cumulus-primitives-core = { path = "../../primitives/core", default-features = false }
|
||||||
|
cumulus-primitives-timestamp = { path = "../../primitives/timestamp", default-features = false }
|
||||||
|
cumulus-primitives-utility = { path = "../../primitives/utility", default-features = false }
|
||||||
|
cumulus-pallet-dmp-queue = { path = "../../pallets/dmp-queue", default-features = false }
|
||||||
|
cumulus-pallet-xcmp-queue = { path = "../../pallets/xcmp-queue", default-features = false }
|
||||||
|
cumulus-pallet-xcm = { path = "../../pallets/xcm", default-features = false }
|
||||||
|
cumulus-pallet-session-benchmarking = { path = "../../pallets/session-benchmarking", default-features = false }
|
||||||
|
pallet-collator-selection = { path = "../../pallets/collator-selection", default-features = false }
|
||||||
|
parachains-common = { path = "../parachains-common", default-features = false }
|
||||||
|
parachain-info = { path = "../pallets/parachain-info", default-features = false }
|
||||||
|
|
||||||
|
# Polkadot Dependencies
|
||||||
|
polkadot-parachain = { git = 'https://github.com/paritytech/polkadot', default-features = false , branch = "master" }
|
||||||
|
polkadot-runtime-common = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "master" }
|
||||||
|
kusama-runtime-constants = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "master" }
|
||||||
|
xcm = { git = 'https://github.com/paritytech/polkadot', default-features = false , branch = "master" }
|
||||||
|
xcm-builder = { git = 'https://github.com/paritytech/polkadot', default-features = false , branch = "master" }
|
||||||
|
xcm-executor = { git = 'https://github.com/paritytech/polkadot', default-features = false , branch = "master" }
|
||||||
|
pallet-xcm = { git = 'https://github.com/paritytech/polkadot', default-features = false , branch = "master" }
|
||||||
|
|
||||||
|
# Contracts specific packages
|
||||||
|
pallet-contracts = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||||
|
pallet-contracts-primitives = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||||
|
pallet-contracts-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = [
|
||||||
|
"std",
|
||||||
|
]
|
||||||
|
std = [
|
||||||
|
"codec/std",
|
||||||
|
"serde",
|
||||||
|
"scale-info/std",
|
||||||
|
"log/std",
|
||||||
|
"sp-api/std",
|
||||||
|
"sp-block-builder/std",
|
||||||
|
"sp-consensus-aura/std",
|
||||||
|
"sp-core/std",
|
||||||
|
"sp-inherents/std",
|
||||||
|
"sp-io/std",
|
||||||
|
"sp-offchain/std",
|
||||||
|
"sp-runtime/std",
|
||||||
|
"sp-session/std",
|
||||||
|
"sp-std/std",
|
||||||
|
"sp-transaction-pool/std",
|
||||||
|
"sp-version/std",
|
||||||
|
"node-primitives/std",
|
||||||
|
"frame-executive/std",
|
||||||
|
"frame-support/std",
|
||||||
|
"frame-system/std",
|
||||||
|
"frame-system-rpc-runtime-api/std",
|
||||||
|
"pallet-authorship/std",
|
||||||
|
"pallet-aura/std",
|
||||||
|
"pallet-sudo/std",
|
||||||
|
"pallet-balances/std",
|
||||||
|
"pallet-multisig/std",
|
||||||
|
"pallet-collator-selection/std",
|
||||||
|
"pallet-randomness-collective-flip/std",
|
||||||
|
"pallet-contracts-primitives/std",
|
||||||
|
"pallet-contracts-rpc-runtime-api/std",
|
||||||
|
"pallet-contracts/std",
|
||||||
|
"pallet-session/std",
|
||||||
|
"pallet-timestamp/std",
|
||||||
|
"pallet-transaction-payment/std",
|
||||||
|
"pallet-transaction-payment-rpc-runtime-api/std",
|
||||||
|
"pallet-utility/std",
|
||||||
|
"pallet-xcm/std",
|
||||||
|
"cumulus-pallet-aura-ext/std",
|
||||||
|
"cumulus-pallet-dmp-queue/std",
|
||||||
|
"cumulus-pallet-parachain-system/std",
|
||||||
|
"cumulus-pallet-xcm/std",
|
||||||
|
"cumulus-pallet-xcmp-queue/std",
|
||||||
|
"cumulus-primitives-core/std",
|
||||||
|
"cumulus-primitives-timestamp/std",
|
||||||
|
"cumulus-primitives-utility/std",
|
||||||
|
"parachains-common/std",
|
||||||
|
"parachain-info/std",
|
||||||
|
"polkadot-parachain/std",
|
||||||
|
"polkadot-runtime-common/std",
|
||||||
|
"kusama-runtime-constants/std",
|
||||||
|
"xcm/std",
|
||||||
|
"xcm-builder/std",
|
||||||
|
"xcm-executor/std",
|
||||||
|
]
|
||||||
|
|
||||||
|
# Make contract callable functions marked as __unstable__ available. Do not enable
|
||||||
|
# on live chains as those are subject to change.
|
||||||
|
contracts-unstable-interface = [
|
||||||
|
"pallet-contracts/unstable-interface"
|
||||||
|
]
|
||||||
|
|
||||||
|
runtime-benchmarks = [
|
||||||
|
"hex-literal",
|
||||||
|
"sp-runtime/runtime-benchmarks",
|
||||||
|
"xcm-builder/runtime-benchmarks",
|
||||||
|
"frame-benchmarking/runtime-benchmarks",
|
||||||
|
"frame-system-benchmarking",
|
||||||
|
"frame-support/runtime-benchmarks",
|
||||||
|
"frame-system/runtime-benchmarks",
|
||||||
|
"pallet-balances/runtime-benchmarks",
|
||||||
|
"pallet-contracts/runtime-benchmarks",
|
||||||
|
"pallet-multisig/runtime-benchmarks",
|
||||||
|
"pallet-timestamp/runtime-benchmarks",
|
||||||
|
"pallet-utility/runtime-benchmarks",
|
||||||
|
"pallet-xcm/runtime-benchmarks",
|
||||||
|
"pallet-collator-selection/runtime-benchmarks",
|
||||||
|
"cumulus-pallet-session-benchmarking/runtime-benchmarks",
|
||||||
|
]
|
||||||
|
|
||||||
|
try-runtime = [
|
||||||
|
"frame-try-runtime",
|
||||||
|
"frame-executive/try-runtime",
|
||||||
|
]
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
use substrate_wasm_builder::WasmBuilder;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
WasmBuilder::new()
|
||||||
|
.with_current_project()
|
||||||
|
.export_heap_base()
|
||||||
|
.import_memory()
|
||||||
|
.build()
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
// Copyright (C) 2021 Parity Technologies (UK) Ltd.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
pub mod currency {
|
||||||
|
use kusama_runtime_constants as constants;
|
||||||
|
use node_primitives::Balance;
|
||||||
|
|
||||||
|
/// The existential deposit. Set to 1/10 of its parent Relay Chain.
|
||||||
|
pub const EXISTENTIAL_DEPOSIT: Balance = constants::currency::EXISTENTIAL_DEPOSIT / 10;
|
||||||
|
|
||||||
|
pub const UNITS: Balance = constants::currency::UNITS;
|
||||||
|
pub const CENTS: Balance = constants::currency::CENTS;
|
||||||
|
pub const GRAND: Balance = constants::currency::GRAND;
|
||||||
|
pub const MILLICENTS: Balance = constants::currency::MILLICENTS;
|
||||||
|
|
||||||
|
pub const fn deposit(items: u32, bytes: u32) -> Balance {
|
||||||
|
// map to 1/10 of what the kusama relay chain charges (v9020)
|
||||||
|
constants::currency::deposit(items, bytes) / 10
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Fee-related.
|
||||||
|
pub mod fee {
|
||||||
|
use frame_support::weights::{
|
||||||
|
constants::ExtrinsicBaseWeight, WeightToFeeCoefficient, WeightToFeeCoefficients,
|
||||||
|
WeightToFeePolynomial,
|
||||||
|
};
|
||||||
|
use node_primitives::Balance;
|
||||||
|
use smallvec::smallvec;
|
||||||
|
pub use sp_runtime::Perbill;
|
||||||
|
|
||||||
|
/// The block saturation level. Fees will be updates based on this value.
|
||||||
|
pub const TARGET_BLOCK_FULLNESS: Perbill = Perbill::from_percent(25);
|
||||||
|
|
||||||
|
/// Handles converting a weight scalar to a fee value, based on the scale and granularity of the
|
||||||
|
/// node's balance type.
|
||||||
|
///
|
||||||
|
/// This should typically create a mapping between the following ranges:
|
||||||
|
/// - [0, MAXIMUM_BLOCK_WEIGHT]
|
||||||
|
/// - [Balance::min, Balance::max]
|
||||||
|
///
|
||||||
|
/// Yet, it can be used for any other sort of change to weight-fee. Some examples being:
|
||||||
|
/// - Setting it to `0` will essentially disable the weight fee.
|
||||||
|
/// - Setting it to `1` will cause the literal `#[weight = x]` values to be charged.
|
||||||
|
pub struct WeightToFee;
|
||||||
|
impl WeightToFeePolynomial for WeightToFee {
|
||||||
|
type Balance = Balance;
|
||||||
|
fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
|
||||||
|
// in Kusama, extrinsic base weight (smallest non-zero weight) is mapped to 1/10 CENT:
|
||||||
|
// in Statemine, we map to 1/10 of that, or 1/100 CENT
|
||||||
|
let p = super::currency::CENTS;
|
||||||
|
let q = 100 * Balance::from(ExtrinsicBaseWeight::get());
|
||||||
|
smallvec![WeightToFeeCoefficient {
|
||||||
|
degree: 1,
|
||||||
|
negative: false,
|
||||||
|
coeff_frac: Perbill::from_rational(p % q, q),
|
||||||
|
coeff_integer: p / q,
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,866 @@
|
|||||||
|
// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd.
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
|
||||||
|
//
|
||||||
|
// This program 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.
|
||||||
|
//
|
||||||
|
// This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
|
#![recursion_limit = "256"]
|
||||||
|
|
||||||
|
// Make the WASM binary available.
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
|
||||||
|
|
||||||
|
pub mod constants;
|
||||||
|
|
||||||
|
use sp_api::impl_runtime_apis;
|
||||||
|
use sp_core::{crypto::KeyTypeId, OpaqueMetadata};
|
||||||
|
use sp_runtime::{
|
||||||
|
create_runtime_str, generic, impl_opaque_keys,
|
||||||
|
traits::{AccountIdLookup, BlakeTwo256, Block as BlockT},
|
||||||
|
transaction_validity::{TransactionSource, TransactionValidity},
|
||||||
|
ApplyExtrinsicResult,
|
||||||
|
};
|
||||||
|
|
||||||
|
use sp_std::prelude::*;
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
use sp_version::NativeVersion;
|
||||||
|
use sp_version::RuntimeVersion;
|
||||||
|
|
||||||
|
use constants::{currency::*, fee::WeightToFee};
|
||||||
|
use frame_support::{
|
||||||
|
construct_runtime, match_type, parameter_types,
|
||||||
|
traits::{EnsureOneOf, Everything, Nothing},
|
||||||
|
weights::{
|
||||||
|
constants::{BlockExecutionWeight, ExtrinsicBaseWeight},
|
||||||
|
DispatchClass, IdentityFee, Weight,
|
||||||
|
},
|
||||||
|
PalletId,
|
||||||
|
};
|
||||||
|
use frame_system::{
|
||||||
|
limits::{BlockLength, BlockWeights},
|
||||||
|
EnsureRoot,
|
||||||
|
};
|
||||||
|
pub use parachains_common as common;
|
||||||
|
use parachains_common::{
|
||||||
|
impls::DealWithFees, opaque, AccountId, BlockNumber, Hash, Header, Index, Signature,
|
||||||
|
AVERAGE_ON_INITIALIZE_RATIO, HOURS, MAXIMUM_BLOCK_WEIGHT, NORMAL_DISPATCH_RATIO, SLOT_DURATION,
|
||||||
|
};
|
||||||
|
pub use parachains_common::{AuraId, Balance};
|
||||||
|
|
||||||
|
#[cfg(any(feature = "std", test))]
|
||||||
|
pub use sp_runtime::BuildStorage;
|
||||||
|
|
||||||
|
// Polkadot imports
|
||||||
|
use pallet_contracts::weights::WeightInfo;
|
||||||
|
use pallet_xcm::{EnsureXcm, IsMajorityOfBody, XcmPassthrough};
|
||||||
|
use polkadot_parachain::primitives::Sibling;
|
||||||
|
use polkadot_runtime_common::{BlockHashCount, RocksDbWeight, SlowAdjustingFeeUpdate};
|
||||||
|
use xcm::latest::prelude::*;
|
||||||
|
use xcm_builder::{
|
||||||
|
AccountId32Aliases, AllowKnownQueryResponses, AllowSubscriptionsFrom,
|
||||||
|
AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, CurrencyAdapter, EnsureXcmOrigin,
|
||||||
|
FixedWeightBounds, IsConcrete, LocationInverter, NativeAsset, ParentIsPreset,
|
||||||
|
RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia,
|
||||||
|
SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit,
|
||||||
|
UsingComponents,
|
||||||
|
};
|
||||||
|
use xcm_executor::{Config as XcmExecutorConfig, XcmExecutor};
|
||||||
|
|
||||||
|
/// The address format for describing accounts.
|
||||||
|
pub type Address = sp_runtime::MultiAddress<AccountId, ()>;
|
||||||
|
/// Block type as expected by this runtime.
|
||||||
|
pub type Block = generic::Block<Header, UncheckedExtrinsic>;
|
||||||
|
/// A Block signed with a Justification
|
||||||
|
pub type SignedBlock = generic::SignedBlock<Block>;
|
||||||
|
/// BlockId type as expected by this runtime.
|
||||||
|
pub type BlockId = generic::BlockId<Block>;
|
||||||
|
/// The SignedExtension to the basic transaction logic.
|
||||||
|
pub type SignedExtra = (
|
||||||
|
frame_system::CheckNonZeroSender<Runtime>,
|
||||||
|
frame_system::CheckSpecVersion<Runtime>,
|
||||||
|
frame_system::CheckTxVersion<Runtime>,
|
||||||
|
frame_system::CheckGenesis<Runtime>,
|
||||||
|
frame_system::CheckEra<Runtime>,
|
||||||
|
frame_system::CheckNonce<Runtime>,
|
||||||
|
frame_system::CheckWeight<Runtime>,
|
||||||
|
pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
|
||||||
|
);
|
||||||
|
/// Unchecked extrinsic type as expected by this runtime.
|
||||||
|
pub type UncheckedExtrinsic = generic::UncheckedExtrinsic<Address, Call, Signature, SignedExtra>;
|
||||||
|
/// Extrinsic type that has already been checked.
|
||||||
|
pub type CheckedExtrinsic = generic::CheckedExtrinsic<AccountId, Call, SignedExtra>;
|
||||||
|
/// Executive: handles dispatch to the various modules.
|
||||||
|
pub type Executive = frame_executive::Executive<
|
||||||
|
Runtime,
|
||||||
|
Block,
|
||||||
|
frame_system::ChainContext<Runtime>,
|
||||||
|
Runtime,
|
||||||
|
AllPalletsWithSystem,
|
||||||
|
>;
|
||||||
|
|
||||||
|
// Prints debug output of the `contracts` pallet to stdout if the node is
|
||||||
|
// started with `-lruntime::contracts=debug`.
|
||||||
|
pub const CONTRACTS_DEBUG_OUTPUT: bool = true;
|
||||||
|
|
||||||
|
impl_opaque_keys! {
|
||||||
|
pub struct SessionKeys {
|
||||||
|
pub aura: Aura,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[sp_version::runtime_version]
|
||||||
|
pub const VERSION: RuntimeVersion = RuntimeVersion {
|
||||||
|
spec_name: create_runtime_str!("canvas-kusama"),
|
||||||
|
impl_name: create_runtime_str!("canvas-kusama"),
|
||||||
|
authoring_version: 1,
|
||||||
|
spec_version: 15,
|
||||||
|
impl_version: 0,
|
||||||
|
apis: RUNTIME_API_VERSIONS,
|
||||||
|
transaction_version: 1,
|
||||||
|
// Since Canvas is a "live" chain (on Rococo anyways), we need to set this to `0` until a
|
||||||
|
// migration path to `state_version = 1` is ready.
|
||||||
|
//
|
||||||
|
// See the following PRs for more details:
|
||||||
|
// - https://github.com/paritytech/substrate/pull/9732
|
||||||
|
// - https://github.com/paritytech/substrate/pull/10073
|
||||||
|
state_version: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// The version information used to identify this runtime when compiled natively.
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
pub fn native_version() -> NativeVersion {
|
||||||
|
NativeVersion { runtime_version: VERSION, can_author_with: Default::default() }
|
||||||
|
}
|
||||||
|
|
||||||
|
parameter_types! {
|
||||||
|
pub const Version: RuntimeVersion = VERSION;
|
||||||
|
pub RuntimeBlockLength: BlockLength =
|
||||||
|
BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO);
|
||||||
|
pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder()
|
||||||
|
.base_block(BlockExecutionWeight::get())
|
||||||
|
.for_class(DispatchClass::all(), |weights| {
|
||||||
|
weights.base_extrinsic = ExtrinsicBaseWeight::get();
|
||||||
|
})
|
||||||
|
.for_class(DispatchClass::Normal, |weights| {
|
||||||
|
weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT);
|
||||||
|
})
|
||||||
|
.for_class(DispatchClass::Operational, |weights| {
|
||||||
|
weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT);
|
||||||
|
// Operational transactions have some extra reserved space, so that they
|
||||||
|
// are included even if block reached `MAXIMUM_BLOCK_WEIGHT`.
|
||||||
|
weights.reserved = Some(
|
||||||
|
MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO)
|
||||||
|
.build_or_panic();
|
||||||
|
pub const SS58Prefix: u8 = 42;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure FRAME pallets to include in runtime.
|
||||||
|
impl frame_system::Config for Runtime {
|
||||||
|
type BaseCallFilter = frame_support::traits::Everything;
|
||||||
|
type BlockWeights = RuntimeBlockWeights;
|
||||||
|
type BlockLength = RuntimeBlockLength;
|
||||||
|
type AccountId = AccountId;
|
||||||
|
type Call = Call;
|
||||||
|
type Lookup = AccountIdLookup<AccountId, ()>;
|
||||||
|
type Index = Index;
|
||||||
|
type BlockNumber = BlockNumber;
|
||||||
|
type Hash = Hash;
|
||||||
|
type Hashing = BlakeTwo256;
|
||||||
|
type Header = Header;
|
||||||
|
type Event = Event;
|
||||||
|
type Origin = Origin;
|
||||||
|
type BlockHashCount = BlockHashCount;
|
||||||
|
type DbWeight = RocksDbWeight;
|
||||||
|
type Version = Version;
|
||||||
|
type PalletInfo = PalletInfo;
|
||||||
|
type OnNewAccount = ();
|
||||||
|
type OnKilledAccount = ();
|
||||||
|
type AccountData = pallet_balances::AccountData<Balance>;
|
||||||
|
type SystemWeightInfo = frame_system::weights::SubstrateWeight<Runtime>;
|
||||||
|
type SS58Prefix = SS58Prefix;
|
||||||
|
type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode<Self>;
|
||||||
|
type MaxConsumers = frame_support::traits::ConstU32<16>;
|
||||||
|
}
|
||||||
|
|
||||||
|
parameter_types! {
|
||||||
|
pub const MinimumPeriod: u64 = SLOT_DURATION / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl pallet_timestamp::Config for Runtime {
|
||||||
|
/// A timestamp: milliseconds since the unix epoch.
|
||||||
|
type Moment = u64;
|
||||||
|
type OnTimestampSet = ();
|
||||||
|
type MinimumPeriod = MinimumPeriod;
|
||||||
|
type WeightInfo = pallet_timestamp::weights::SubstrateWeight<Runtime>;
|
||||||
|
}
|
||||||
|
|
||||||
|
parameter_types! {
|
||||||
|
pub const UncleGenerations: u32 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl pallet_authorship::Config for Runtime {
|
||||||
|
type FindAuthor = pallet_session::FindAccountFromAuthorIndex<Self, Aura>;
|
||||||
|
type UncleGenerations = UncleGenerations;
|
||||||
|
type FilterUncle = ();
|
||||||
|
type EventHandler = (CollatorSelection,);
|
||||||
|
}
|
||||||
|
|
||||||
|
parameter_types! {
|
||||||
|
pub const ExistentialDeposit: Balance = EXISTENTIAL_DEPOSIT;
|
||||||
|
pub const MaxLocks: u32 = 50;
|
||||||
|
pub const MaxReserves: u32 = 50;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl pallet_balances::Config for Runtime {
|
||||||
|
type MaxLocks = MaxLocks;
|
||||||
|
/// The type for recording an account's balance.
|
||||||
|
type Balance = Balance;
|
||||||
|
/// The ubiquitous event type.
|
||||||
|
type Event = Event;
|
||||||
|
type DustRemoval = ();
|
||||||
|
type ExistentialDeposit = ExistentialDeposit;
|
||||||
|
type AccountStore = System;
|
||||||
|
type WeightInfo = pallet_balances::weights::SubstrateWeight<Runtime>;
|
||||||
|
type MaxReserves = MaxReserves;
|
||||||
|
type ReserveIdentifier = [u8; 8];
|
||||||
|
}
|
||||||
|
|
||||||
|
parameter_types! {
|
||||||
|
/// Relay Chain `TransactionByteFee` / 10
|
||||||
|
pub const TransactionByteFee: Balance = 1 * MILLICENTS;
|
||||||
|
pub const OperationalFeeMultiplier: u8 = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl pallet_transaction_payment::Config for Runtime {
|
||||||
|
type OnChargeTransaction =
|
||||||
|
pallet_transaction_payment::CurrencyAdapter<Balances, DealWithFees<Runtime>>;
|
||||||
|
type TransactionByteFee = TransactionByteFee;
|
||||||
|
type WeightToFee = WeightToFee;
|
||||||
|
type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
|
||||||
|
type OperationalFeeMultiplier = OperationalFeeMultiplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
parameter_types! {
|
||||||
|
// One storage item; key size is 32; value is size 4+4+16+32 bytes = 56 bytes.
|
||||||
|
pub const DepositBase: Balance = deposit(1, 88);
|
||||||
|
// Additional storage item size of 32 bytes.
|
||||||
|
pub const DepositFactor: Balance = deposit(0, 32);
|
||||||
|
pub const MaxSignatories: u16 = 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl pallet_multisig::Config for Runtime {
|
||||||
|
type Event = Event;
|
||||||
|
type Call = Call;
|
||||||
|
type Currency = Balances;
|
||||||
|
type DepositBase = DepositBase;
|
||||||
|
type DepositFactor = DepositFactor;
|
||||||
|
type MaxSignatories = MaxSignatories;
|
||||||
|
type WeightInfo = pallet_multisig::weights::SubstrateWeight<Runtime>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl pallet_utility::Config for Runtime {
|
||||||
|
type Event = Event;
|
||||||
|
type Call = Call;
|
||||||
|
type PalletsOrigin = OriginCaller;
|
||||||
|
type WeightInfo = pallet_utility::weights::SubstrateWeight<Runtime>;
|
||||||
|
}
|
||||||
|
|
||||||
|
parameter_types! {
|
||||||
|
pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4;
|
||||||
|
pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl cumulus_pallet_parachain_system::Config for Runtime {
|
||||||
|
type Event = Event;
|
||||||
|
type OnSystemEvent = ();
|
||||||
|
type SelfParaId = parachain_info::Pallet<Runtime>;
|
||||||
|
type DmpMessageHandler = DmpQueue;
|
||||||
|
type ReservedDmpWeight = ReservedDmpWeight;
|
||||||
|
type OutboundXcmpMessageSource = XcmpQueue;
|
||||||
|
type XcmpMessageHandler = XcmpQueue;
|
||||||
|
type ReservedXcmpWeight = ReservedXcmpWeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
parameter_types! {
|
||||||
|
pub const DepositPerItem: Balance = deposit(1, 0);
|
||||||
|
pub const DepositPerByte: Balance = deposit(0, 1);
|
||||||
|
// The lazy deletion runs inside on_initialize.
|
||||||
|
pub DeletionWeightLimit: Weight = AVERAGE_ON_INITIALIZE_RATIO *
|
||||||
|
RuntimeBlockWeights::get().max_block;
|
||||||
|
// The weight needed for decoding the queue should be less or equal than a fifth
|
||||||
|
// of the overall weight dedicated to the lazy deletion.
|
||||||
|
pub DeletionQueueDepth: u32 = ((DeletionWeightLimit::get() / (
|
||||||
|
<Runtime as pallet_contracts::Config>::WeightInfo::on_initialize_per_queue_item(1) -
|
||||||
|
<Runtime as pallet_contracts::Config>::WeightInfo::on_initialize_per_queue_item(0)
|
||||||
|
)) / 5) as u32;
|
||||||
|
pub Schedule: pallet_contracts::Schedule<Runtime> = Default::default();
|
||||||
|
}
|
||||||
|
|
||||||
|
impl pallet_contracts::Config for Runtime {
|
||||||
|
type Time = Timestamp;
|
||||||
|
type Randomness = RandomnessCollectiveFlip;
|
||||||
|
type Currency = Balances;
|
||||||
|
type Event = Event;
|
||||||
|
type Call = Call;
|
||||||
|
/// The safest default is to allow no calls at all.
|
||||||
|
///
|
||||||
|
/// Runtimes should whitelist dispatchables that are allowed to be called from contracts
|
||||||
|
/// and make sure they are stable. Dispatchables exposed to contracts are not allowed to
|
||||||
|
/// change because that would break already deployed contracts. The `Call` structure itself
|
||||||
|
/// is not allowed to change the indices of existing pallets, too.
|
||||||
|
type CallFilter = frame_support::traits::Nothing;
|
||||||
|
type DepositPerItem = DepositPerItem;
|
||||||
|
type DepositPerByte = DepositPerByte;
|
||||||
|
type WeightPrice = pallet_transaction_payment::Pallet<Self>;
|
||||||
|
type WeightInfo = pallet_contracts::weights::SubstrateWeight<Self>;
|
||||||
|
type ChainExtension = ();
|
||||||
|
type DeletionQueueDepth = DeletionQueueDepth;
|
||||||
|
type DeletionWeightLimit = DeletionWeightLimit;
|
||||||
|
type Schedule = Schedule;
|
||||||
|
type CallStack = [pallet_contracts::Frame<Self>; 31];
|
||||||
|
type AddressGenerator = pallet_contracts::DefaultAddressGenerator;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl pallet_randomness_collective_flip::Config for Runtime {}
|
||||||
|
|
||||||
|
impl parachain_info::Config for Runtime {}
|
||||||
|
|
||||||
|
impl cumulus_pallet_aura_ext::Config for Runtime {}
|
||||||
|
|
||||||
|
parameter_types! {
|
||||||
|
pub const RelayLocation: MultiLocation = MultiLocation::parent();
|
||||||
|
pub const RelayNetwork: NetworkId = NetworkId::Any;
|
||||||
|
pub RelayChainOrigin: Origin = cumulus_pallet_xcm::Origin::Relay.into();
|
||||||
|
pub Ancestry: MultiLocation = Parachain(ParachainInfo::parachain_id().into()).into();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used
|
||||||
|
/// when determining ownership of accounts for asset transacting and when attempting to use XCM
|
||||||
|
/// `Transact` in order to determine the dispatch Origin.
|
||||||
|
pub type LocationToAccountId = (
|
||||||
|
// The parent (Relay-chain) origin converts to the parent `AccountId`.
|
||||||
|
ParentIsPreset<AccountId>,
|
||||||
|
// Sibling parachain origins convert to AccountId via the `ParaId::into`.
|
||||||
|
SiblingParachainConvertsVia<Sibling, AccountId>,
|
||||||
|
// Straight up local `AccountId32` origins just alias directly to `AccountId`.
|
||||||
|
AccountId32Aliases<RelayNetwork, AccountId>,
|
||||||
|
);
|
||||||
|
|
||||||
|
/// Means for transacting assets on this chain.
|
||||||
|
pub type LocalAssetTransactor = CurrencyAdapter<
|
||||||
|
// Use this currency:
|
||||||
|
Balances,
|
||||||
|
// Use this currency when it is a fungible asset matching the given location or name:
|
||||||
|
IsConcrete<RelayLocation>,
|
||||||
|
// Do a simple punn to convert an AccountId32 MultiLocation into a native chain account ID:
|
||||||
|
LocationToAccountId,
|
||||||
|
// Our chain's account ID type (we can't get away without mentioning it explicitly):
|
||||||
|
AccountId,
|
||||||
|
// We don't track any teleports.
|
||||||
|
(),
|
||||||
|
>;
|
||||||
|
|
||||||
|
/// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance,
|
||||||
|
/// ready for dispatching a transaction with Xcm's `Transact`. There is an `OriginKind` which can
|
||||||
|
/// biases the kind of local `Origin` it will become.
|
||||||
|
pub type XcmOriginToTransactDispatchOrigin = (
|
||||||
|
// Sovereign account converter; this attempts to derive an `AccountId` from the origin location
|
||||||
|
// using `LocationToAccountId` and then turn that into the usual `Signed` origin. Useful for
|
||||||
|
// foreign chains who want to have a local sovereign account on this chain which they control.
|
||||||
|
SovereignSignedViaLocation<LocationToAccountId, Origin>,
|
||||||
|
// Native converter for Relay-chain (Parent) location; will converts to a `Relay` origin when
|
||||||
|
// recognized.
|
||||||
|
RelayChainAsNative<RelayChainOrigin, Origin>,
|
||||||
|
// Native converter for sibling Parachains; will convert to a `SiblingPara` origin when
|
||||||
|
// recognized.
|
||||||
|
SiblingParachainAsNative<cumulus_pallet_xcm::Origin, Origin>,
|
||||||
|
// Native signed account converter; this just converts an `AccountId32` origin into a normal
|
||||||
|
// `Origin::Signed` origin of the same 32-byte value.
|
||||||
|
SignedAccountId32AsNative<RelayNetwork, Origin>,
|
||||||
|
// Xcm origins can be represented natively under the Xcm pallet's Xcm origin.
|
||||||
|
XcmPassthrough<Origin>,
|
||||||
|
);
|
||||||
|
|
||||||
|
parameter_types! {
|
||||||
|
// One XCM operation is 1_000_000_000 weight - almost certainly a conservative estimate.
|
||||||
|
pub UnitWeightCost: Weight = 1_000_000_000;
|
||||||
|
pub const MaxInstructions: u32 = 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
match_type! {
|
||||||
|
pub type ParentOrParentsExecutivePlurality: impl Contains<MultiLocation> = {
|
||||||
|
MultiLocation { parents: 1, interior: Here } |
|
||||||
|
MultiLocation { parents: 1, interior: X1(Plurality { id: BodyId::Executive, .. }) }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
match_type! {
|
||||||
|
pub type ParentOrSiblings: impl Contains<MultiLocation> = {
|
||||||
|
MultiLocation { parents: 1, interior: Here } |
|
||||||
|
MultiLocation { parents: 1, interior: X1(_) }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type Barrier = (
|
||||||
|
TakeWeightCredit,
|
||||||
|
AllowTopLevelPaidExecutionFrom<Everything>,
|
||||||
|
// Parent and its exec plurality get free execution
|
||||||
|
AllowUnpaidExecutionFrom<ParentOrParentsExecutivePlurality>,
|
||||||
|
// Expected responses are OK.
|
||||||
|
AllowKnownQueryResponses<PolkadotXcm>,
|
||||||
|
// Subscriptions for version tracking are OK.
|
||||||
|
AllowSubscriptionsFrom<ParentOrSiblings>,
|
||||||
|
);
|
||||||
|
|
||||||
|
pub struct XcmConfig;
|
||||||
|
impl XcmExecutorConfig for XcmConfig {
|
||||||
|
type Call = Call;
|
||||||
|
type XcmSender = XcmRouter;
|
||||||
|
// How to withdraw and deposit an asset.
|
||||||
|
type AssetTransactor = LocalAssetTransactor;
|
||||||
|
type OriginConverter = XcmOriginToTransactDispatchOrigin;
|
||||||
|
type IsReserve = NativeAsset;
|
||||||
|
type IsTeleporter = NativeAsset; // Should be enough to allow teleportation of ROC
|
||||||
|
type LocationInverter = LocationInverter<Ancestry>;
|
||||||
|
type Barrier = Barrier;
|
||||||
|
type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;
|
||||||
|
type Trader = UsingComponents<IdentityFee<Balance>, RelayLocation, AccountId, Balances, ()>;
|
||||||
|
type ResponseHandler = PolkadotXcm;
|
||||||
|
type AssetTrap = PolkadotXcm;
|
||||||
|
type AssetClaims = PolkadotXcm;
|
||||||
|
type SubscriptionService = PolkadotXcm;
|
||||||
|
}
|
||||||
|
|
||||||
|
parameter_types! {
|
||||||
|
pub const MaxDownwardMessageWeight: Weight = MAXIMUM_BLOCK_WEIGHT / 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Converts a local signed origin into an XCM multilocation.
|
||||||
|
/// Forms the basis for local origins sending/executing XCMs.
|
||||||
|
pub type LocalOriginToLocation = SignedToAccountId32<Origin, AccountId, RelayNetwork>;
|
||||||
|
|
||||||
|
/// The means for routing XCM messages which are not for local execution into the right message
|
||||||
|
/// queues.
|
||||||
|
pub type XcmRouter = (
|
||||||
|
// Two routers - use UMP to communicate with the relay chain:
|
||||||
|
cumulus_primitives_utility::ParentAsUmp<ParachainSystem, PolkadotXcm>,
|
||||||
|
// ..and XCMP to communicate with the sibling chains.
|
||||||
|
XcmpQueue,
|
||||||
|
);
|
||||||
|
|
||||||
|
impl pallet_xcm::Config for Runtime {
|
||||||
|
type Event = Event;
|
||||||
|
// We want to disallow users sending (arbitrary) XCMs from this chain.
|
||||||
|
type SendXcmOrigin = EnsureXcmOrigin<Origin, ()>;
|
||||||
|
type XcmRouter = XcmRouter;
|
||||||
|
// We support local origins dispatching XCM executions in principle...
|
||||||
|
type ExecuteXcmOrigin = EnsureXcmOrigin<Origin, LocalOriginToLocation>;
|
||||||
|
// ... but disallow generic XCM execution. As a result only teleports and reserve transfers are allowed.
|
||||||
|
type XcmExecuteFilter = Nothing;
|
||||||
|
type XcmExecutor = XcmExecutor<XcmConfig>;
|
||||||
|
type XcmTeleportFilter = Everything;
|
||||||
|
type XcmReserveTransferFilter = Everything;
|
||||||
|
type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;
|
||||||
|
type LocationInverter = LocationInverter<Ancestry>;
|
||||||
|
type Origin = Origin;
|
||||||
|
type Call = Call;
|
||||||
|
const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100;
|
||||||
|
type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl cumulus_pallet_xcm::Config for Runtime {
|
||||||
|
type Event = Event;
|
||||||
|
type XcmExecutor = XcmExecutor<XcmConfig>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl cumulus_pallet_xcmp_queue::Config for Runtime {
|
||||||
|
type Event = Event;
|
||||||
|
type XcmExecutor = XcmExecutor<XcmConfig>;
|
||||||
|
type ChannelInfo = ParachainSystem;
|
||||||
|
type VersionWrapper = PolkadotXcm;
|
||||||
|
type ExecuteOverweightOrigin = EnsureRoot<AccountId>;
|
||||||
|
type ControllerOrigin = EnsureOneOf<
|
||||||
|
EnsureRoot<AccountId>,
|
||||||
|
EnsureXcm<IsMajorityOfBody<RelayLocation, ExecutiveBody>>,
|
||||||
|
>;
|
||||||
|
type ControllerOriginConverter = XcmOriginToTransactDispatchOrigin;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl cumulus_pallet_dmp_queue::Config for Runtime {
|
||||||
|
type Event = Event;
|
||||||
|
type XcmExecutor = XcmExecutor<XcmConfig>;
|
||||||
|
type ExecuteOverweightOrigin = EnsureRoot<AccountId>;
|
||||||
|
}
|
||||||
|
|
||||||
|
parameter_types! {
|
||||||
|
pub const Period: u32 = 6 * HOURS;
|
||||||
|
pub const Offset: u32 = 0;
|
||||||
|
pub const MaxAuthorities: u32 = 100_000;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl pallet_session::Config for Runtime {
|
||||||
|
type Event = Event;
|
||||||
|
type ValidatorId = <Self as frame_system::Config>::AccountId;
|
||||||
|
// we don't have stash and controller, thus we don't need the convert as well.
|
||||||
|
type ValidatorIdOf = pallet_collator_selection::IdentityCollator;
|
||||||
|
type ShouldEndSession = pallet_session::PeriodicSessions<Period, Offset>;
|
||||||
|
type NextSessionRotation = pallet_session::PeriodicSessions<Period, Offset>;
|
||||||
|
type SessionManager = CollatorSelection;
|
||||||
|
// Essentially just Aura, but lets be pedantic.
|
||||||
|
type SessionHandler = <SessionKeys as sp_runtime::traits::OpaqueKeys>::KeyTypeIdProviders;
|
||||||
|
type Keys = SessionKeys;
|
||||||
|
type WeightInfo = pallet_session::weights::SubstrateWeight<Runtime>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl pallet_aura::Config for Runtime {
|
||||||
|
type AuthorityId = AuraId;
|
||||||
|
type DisabledValidators = ();
|
||||||
|
type MaxAuthorities = MaxAuthorities;
|
||||||
|
}
|
||||||
|
|
||||||
|
parameter_types! {
|
||||||
|
pub const PotId: PalletId = PalletId(*b"PotStake");
|
||||||
|
pub const MaxCandidates: u32 = 1000;
|
||||||
|
pub const MinCandidates: u32 = 5;
|
||||||
|
pub const SessionLength: BlockNumber = 6 * HOURS;
|
||||||
|
pub const MaxInvulnerables: u32 = 100;
|
||||||
|
pub const ExecutiveBody: BodyId = BodyId::Executive;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// We allow root and the Relay Chain council to execute privileged collator selection operations.
|
||||||
|
pub type CollatorSelectionUpdateOrigin =
|
||||||
|
EnsureOneOf<EnsureRoot<AccountId>, EnsureXcm<IsMajorityOfBody<RelayLocation, ExecutiveBody>>>;
|
||||||
|
|
||||||
|
impl pallet_collator_selection::Config for Runtime {
|
||||||
|
type Event = Event;
|
||||||
|
type Currency = Balances;
|
||||||
|
type UpdateOrigin = CollatorSelectionUpdateOrigin;
|
||||||
|
type PotId = PotId;
|
||||||
|
type MaxCandidates = MaxCandidates;
|
||||||
|
type MinCandidates = MinCandidates;
|
||||||
|
type MaxInvulnerables = MaxInvulnerables;
|
||||||
|
// should be a multiple of session or things will get inconsistent
|
||||||
|
type KickThreshold = Period;
|
||||||
|
type ValidatorId = <Self as frame_system::Config>::AccountId;
|
||||||
|
type ValidatorIdOf = pallet_collator_selection::IdentityCollator;
|
||||||
|
type ValidatorRegistration = Session;
|
||||||
|
type WeightInfo = pallet_collator_selection::weights::SubstrateWeight<Runtime>;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the runtime by composing the FRAME pallets that were previously configured.
|
||||||
|
construct_runtime!(
|
||||||
|
pub enum Runtime where
|
||||||
|
Block = Block,
|
||||||
|
NodeBlock = opaque::Block,
|
||||||
|
UncheckedExtrinsic = UncheckedExtrinsic,
|
||||||
|
{
|
||||||
|
// System support stuff.
|
||||||
|
System: frame_system::{Pallet, Call, Config, Storage, Event<T>} = 0,
|
||||||
|
ParachainSystem: cumulus_pallet_parachain_system::{
|
||||||
|
Pallet, Call, Config, Storage, Inherent, Event<T>, ValidateUnsigned,
|
||||||
|
} = 1,
|
||||||
|
RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Pallet, Storage} = 2,
|
||||||
|
Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 3,
|
||||||
|
ParachainInfo: parachain_info::{Pallet, Storage, Config} = 4,
|
||||||
|
|
||||||
|
// Monetary stuff.
|
||||||
|
Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>} = 10,
|
||||||
|
TransactionPayment: pallet_transaction_payment::{Pallet, Storage} = 11,
|
||||||
|
|
||||||
|
// Collator support. The order of these 5 are important and shall not change.
|
||||||
|
Authorship: pallet_authorship::{Pallet, Call, Storage} = 20,
|
||||||
|
CollatorSelection: pallet_collator_selection::{Pallet, Call, Storage, Event<T>, Config<T>} = 21,
|
||||||
|
Session: pallet_session::{Pallet, Call, Storage, Event, Config<T>} = 22,
|
||||||
|
Aura: pallet_aura::{Pallet, Storage, Config<T>} = 23,
|
||||||
|
AuraExt: cumulus_pallet_aura_ext::{Pallet, Storage, Config} = 24,
|
||||||
|
|
||||||
|
// XCM helpers.
|
||||||
|
XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event<T>} = 30,
|
||||||
|
PolkadotXcm: pallet_xcm::{Pallet, Call, Storage, Event<T>, Origin, Config} = 31,
|
||||||
|
CumulusXcm: cumulus_pallet_xcm::{Pallet, Event<T>, Origin} = 32,
|
||||||
|
DmpQueue: cumulus_pallet_dmp_queue::{Pallet, Call, Storage, Event<T>} = 33,
|
||||||
|
|
||||||
|
// Smart Contracts.
|
||||||
|
Contracts: pallet_contracts::{Pallet, Call, Storage, Event<T>} = 40,
|
||||||
|
|
||||||
|
// Handy utilities.
|
||||||
|
Utility: pallet_utility::{Pallet, Call, Event} = 50,
|
||||||
|
Multisig: pallet_multisig::{Pallet, Call, Storage, Event<T>} = 51,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
#[cfg(feature = "runtime-benchmarks")]
|
||||||
|
#[macro_use]
|
||||||
|
extern crate frame_benchmarking;
|
||||||
|
|
||||||
|
#[cfg(feature = "runtime-benchmarks")]
|
||||||
|
mod benches {
|
||||||
|
define_benchmarks!(
|
||||||
|
[frame_system, SystemBench::<Runtime>]
|
||||||
|
[pallet_balances, Balances]
|
||||||
|
[pallet_multisig, Multisig]
|
||||||
|
[pallet_session, SessionBench::<Runtime>]
|
||||||
|
[pallet_utility, Utility]
|
||||||
|
[pallet_timestamp, Timestamp]
|
||||||
|
[pallet_collator_selection, CollatorSelection]
|
||||||
|
[pallet_contracts, Contracts]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_runtime_apis! {
|
||||||
|
impl sp_consensus_aura::AuraApi<Block, AuraId> for Runtime {
|
||||||
|
fn slot_duration() -> sp_consensus_aura::SlotDuration {
|
||||||
|
sp_consensus_aura::SlotDuration::from_millis(Aura::slot_duration())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn authorities() -> Vec<AuraId> {
|
||||||
|
Aura::authorities().into_inner()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl sp_api::Core<Block> for Runtime {
|
||||||
|
fn version() -> RuntimeVersion {
|
||||||
|
VERSION
|
||||||
|
}
|
||||||
|
|
||||||
|
fn execute_block(block: Block) {
|
||||||
|
Executive::execute_block(block)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn initialize_block(header: &<Block as BlockT>::Header) {
|
||||||
|
Executive::initialize_block(header)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl sp_api::Metadata<Block> for Runtime {
|
||||||
|
fn metadata() -> OpaqueMetadata {
|
||||||
|
OpaqueMetadata::new(Runtime::metadata().into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl sp_block_builder::BlockBuilder<Block> for Runtime {
|
||||||
|
fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {
|
||||||
|
Executive::apply_extrinsic(extrinsic)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn finalize_block() -> <Block as BlockT>::Header {
|
||||||
|
Executive::finalize_block()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
|
||||||
|
data.create_extrinsics()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_inherents(
|
||||||
|
block: Block,
|
||||||
|
data: sp_inherents::InherentData,
|
||||||
|
) -> sp_inherents::CheckInherentsResult {
|
||||||
|
data.check_extrinsics(&block)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
|
||||||
|
fn validate_transaction(
|
||||||
|
source: TransactionSource,
|
||||||
|
tx: <Block as BlockT>::Extrinsic,
|
||||||
|
block_hash: <Block as BlockT>::Hash,
|
||||||
|
) -> TransactionValidity {
|
||||||
|
Executive::validate_transaction(source, tx, block_hash)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl sp_offchain::OffchainWorkerApi<Block> for Runtime {
|
||||||
|
fn offchain_worker(header: &<Block as BlockT>::Header) {
|
||||||
|
Executive::offchain_worker(header)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl sp_session::SessionKeys<Block> for Runtime {
|
||||||
|
fn generate_session_keys(seed: Option<Vec<u8>>) -> Vec<u8> {
|
||||||
|
SessionKeys::generate(seed)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn decode_session_keys(
|
||||||
|
encoded: Vec<u8>,
|
||||||
|
) -> Option<Vec<(Vec<u8>, KeyTypeId)>> {
|
||||||
|
SessionKeys::decode_into_raw_public_keys(&encoded)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Index> for Runtime {
|
||||||
|
fn account_nonce(account: AccountId) -> Index {
|
||||||
|
System::account_nonce(account)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance> for Runtime {
|
||||||
|
fn query_info(
|
||||||
|
uxt: <Block as BlockT>::Extrinsic,
|
||||||
|
len: u32,
|
||||||
|
) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo<Balance> {
|
||||||
|
TransactionPayment::query_info(uxt, len)
|
||||||
|
}
|
||||||
|
fn query_fee_details(
|
||||||
|
uxt: <Block as BlockT>::Extrinsic,
|
||||||
|
len: u32,
|
||||||
|
) -> pallet_transaction_payment::FeeDetails<Balance> {
|
||||||
|
TransactionPayment::query_fee_details(uxt, len)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl cumulus_primitives_core::CollectCollationInfo<Block> for Runtime {
|
||||||
|
fn collect_collation_info(header: &<Block as BlockT>::Header) -> cumulus_primitives_core::CollationInfo {
|
||||||
|
ParachainSystem::collect_collation_info(header)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl pallet_contracts_rpc_runtime_api::ContractsApi<Block, AccountId, Balance, BlockNumber, Hash>
|
||||||
|
for Runtime
|
||||||
|
{
|
||||||
|
fn call(
|
||||||
|
origin: AccountId,
|
||||||
|
dest: AccountId,
|
||||||
|
value: Balance,
|
||||||
|
gas_limit: u64,
|
||||||
|
storage_deposit_limit: Option<Balance>,
|
||||||
|
input_data: Vec<u8>,
|
||||||
|
) -> pallet_contracts_primitives::ContractExecResult<Balance> {
|
||||||
|
Contracts::bare_call(origin, dest, value, gas_limit, storage_deposit_limit, input_data, CONTRACTS_DEBUG_OUTPUT)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn instantiate(
|
||||||
|
origin: AccountId,
|
||||||
|
value: Balance,
|
||||||
|
gas_limit: u64,
|
||||||
|
storage_deposit_limit: Option<Balance>,
|
||||||
|
code: pallet_contracts_primitives::Code<Hash>,
|
||||||
|
data: Vec<u8>,
|
||||||
|
salt: Vec<u8>,
|
||||||
|
) -> pallet_contracts_primitives::ContractInstantiateResult<AccountId, Balance>
|
||||||
|
{
|
||||||
|
Contracts::bare_instantiate(origin, value, gas_limit, storage_deposit_limit, code, data, salt, CONTRACTS_DEBUG_OUTPUT)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn upload_code(
|
||||||
|
origin: AccountId,
|
||||||
|
code: Vec<u8>,
|
||||||
|
storage_deposit_limit: Option<Balance>,
|
||||||
|
) -> pallet_contracts_primitives::CodeUploadResult<Hash, Balance>
|
||||||
|
{
|
||||||
|
Contracts::bare_upload_code(origin, code, storage_deposit_limit)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_storage(
|
||||||
|
address: AccountId,
|
||||||
|
key: [u8; 32],
|
||||||
|
) -> pallet_contracts_primitives::GetStorageResult {
|
||||||
|
Contracts::get_storage(address, key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "try-runtime")]
|
||||||
|
impl frame_try_runtime::TryRuntime<Block> for Runtime {
|
||||||
|
fn on_runtime_upgrade() -> (Weight, Weight) {
|
||||||
|
log::info!("try-runtime::on_runtime_upgrade canvas");
|
||||||
|
let weight = Executive::try_runtime_upgrade().unwrap();
|
||||||
|
(weight, RuntimeBlockWeights::get().max_block)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn execute_block_no_check(block: Block) -> Weight {
|
||||||
|
Executive::execute_block_no_check(block)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "runtime-benchmarks")]
|
||||||
|
impl frame_benchmarking::Benchmark<Block> for Runtime {
|
||||||
|
fn benchmark_metadata(extra: bool) -> (
|
||||||
|
Vec<frame_benchmarking::BenchmarkList>,
|
||||||
|
Vec<frame_support::traits::StorageInfo>,
|
||||||
|
) {
|
||||||
|
use frame_benchmarking::{Benchmarking, BenchmarkList};
|
||||||
|
use frame_support::traits::StorageInfoTrait;
|
||||||
|
use frame_system_benchmarking::Pallet as SystemBench;
|
||||||
|
use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
|
||||||
|
|
||||||
|
let mut list = Vec::<BenchmarkList>::new();
|
||||||
|
list_benchmarks!(list, extra);
|
||||||
|
|
||||||
|
let storage_info = AllPalletsWithSystem::storage_info();
|
||||||
|
return (list, storage_info)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dispatch_benchmark(
|
||||||
|
config: frame_benchmarking::BenchmarkConfig
|
||||||
|
) -> Result<Vec<frame_benchmarking::BenchmarkBatch>, sp_runtime::RuntimeString> {
|
||||||
|
use frame_benchmarking::{Benchmarking, BenchmarkBatch, TrackedStorageKey};
|
||||||
|
|
||||||
|
use frame_system_benchmarking::Pallet as SystemBench;
|
||||||
|
impl frame_system_benchmarking::Config for Runtime {}
|
||||||
|
|
||||||
|
use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
|
||||||
|
impl cumulus_pallet_session_benchmarking::Config for Runtime {}
|
||||||
|
|
||||||
|
let whitelist: Vec<TrackedStorageKey> = vec![
|
||||||
|
// Block Number
|
||||||
|
hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef702a5c1b19ab7a04f536c519aca4983ac").to_vec().into(),
|
||||||
|
// Total Issuance
|
||||||
|
hex_literal::hex!("c2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80").to_vec().into(),
|
||||||
|
// Execution Phase
|
||||||
|
hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef7ff553b5a9862a516939d82b3d3d8661a").to_vec().into(),
|
||||||
|
// Event Count
|
||||||
|
hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef70a98fdbe9ce6c55837576c60c7af3850").to_vec().into(),
|
||||||
|
// System Events
|
||||||
|
hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef780d41e5e16056765bc8461851072c9d7").to_vec().into(),
|
||||||
|
];
|
||||||
|
|
||||||
|
let mut batches = Vec::<BenchmarkBatch>::new();
|
||||||
|
let params = (&config, &whitelist);
|
||||||
|
add_benchmarks!(params, batches);
|
||||||
|
|
||||||
|
if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) }
|
||||||
|
Ok(batches)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CheckInherents;
|
||||||
|
|
||||||
|
impl cumulus_pallet_parachain_system::CheckInherents<Block> for CheckInherents {
|
||||||
|
fn check_inherents(
|
||||||
|
block: &Block,
|
||||||
|
relay_state_proof: &cumulus_pallet_parachain_system::RelayChainStateProof,
|
||||||
|
) -> sp_inherents::CheckInherentsResult {
|
||||||
|
let relay_chain_slot = relay_state_proof
|
||||||
|
.read_slot()
|
||||||
|
.expect("Could not read the relay chain slot from the proof");
|
||||||
|
|
||||||
|
let inherent_data =
|
||||||
|
cumulus_primitives_timestamp::InherentDataProvider::from_relay_chain_slot_and_duration(
|
||||||
|
relay_chain_slot,
|
||||||
|
sp_std::time::Duration::from_secs(6),
|
||||||
|
)
|
||||||
|
.create_inherent_data()
|
||||||
|
.expect("Could not create the timestamp inherent data");
|
||||||
|
|
||||||
|
inherent_data.check_extrinsics(&block)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cumulus_pallet_parachain_system::register_validate_block! {
|
||||||
|
Runtime = Runtime,
|
||||||
|
BlockExecutor = cumulus_pallet_aura_ext::BlockExecutor::<Runtime, Executive>,
|
||||||
|
CheckInherents = CheckInherents,
|
||||||
|
}
|
||||||
@@ -834,3 +834,254 @@ fn westmint_genesis(
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// We use the same runtime on kusama and rococo.
|
||||||
|
pub type CanvasKusamaChainSpec =
|
||||||
|
sc_service::GenericChainSpec<canvas_kusama_runtime::GenesisConfig, Extensions>;
|
||||||
|
|
||||||
|
/// No relay chain suffix because the id is the same over all relay chains.
|
||||||
|
const CANVAS_PARACHAIN_ID: u32 = 1002;
|
||||||
|
|
||||||
|
/// The existential deposit is determined by the runtime "canvas-kusama".
|
||||||
|
const CANVAS_KUSAMA_ED: canvas_kusama_runtime::Balance =
|
||||||
|
canvas_kusama_runtime::constants::currency::EXISTENTIAL_DEPOSIT;
|
||||||
|
|
||||||
|
pub fn canvas_rococo_development_config() -> CanvasKusamaChainSpec {
|
||||||
|
let mut properties = sc_chain_spec::Properties::new();
|
||||||
|
properties.insert("tokenSymbol".into(), "ROC".into());
|
||||||
|
properties.insert("tokenDecimals".into(), 12.into());
|
||||||
|
|
||||||
|
CanvasKusamaChainSpec::from_genesis(
|
||||||
|
// Name
|
||||||
|
"Canvas on Rococo Development",
|
||||||
|
// ID
|
||||||
|
"canvas-rococo-dev",
|
||||||
|
ChainType::Development,
|
||||||
|
move || {
|
||||||
|
canvas_kusama_genesis(
|
||||||
|
// initial collators.
|
||||||
|
vec![
|
||||||
|
(
|
||||||
|
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||||
|
get_collator_keys_from_seed::<canvas_kusama_runtime::AuraId>("Alice"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||||
|
get_collator_keys_from_seed::<canvas_kusama_runtime::AuraId>("Bob"),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
vec![
|
||||||
|
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||||
|
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||||
|
get_account_id_from_seed::<sr25519::Public>("Charlie"),
|
||||||
|
get_account_id_from_seed::<sr25519::Public>("Dave"),
|
||||||
|
get_account_id_from_seed::<sr25519::Public>("Eve"),
|
||||||
|
get_account_id_from_seed::<sr25519::Public>("Ferdie"),
|
||||||
|
get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
|
||||||
|
get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
|
||||||
|
get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),
|
||||||
|
get_account_id_from_seed::<sr25519::Public>("Dave//stash"),
|
||||||
|
get_account_id_from_seed::<sr25519::Public>("Eve//stash"),
|
||||||
|
get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),
|
||||||
|
],
|
||||||
|
CANVAS_PARACHAIN_ID.into(),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
Vec::new(),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
Extensions {
|
||||||
|
relay_chain: "rococo-local".into(), // You MUST set this to the correct network!
|
||||||
|
para_id: CANVAS_PARACHAIN_ID,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn canvas_rococo_local_config() -> CanvasKusamaChainSpec {
|
||||||
|
let mut properties = sc_chain_spec::Properties::new();
|
||||||
|
properties.insert("tokenSymbol".into(), "ROC".into());
|
||||||
|
properties.insert("tokenDecimals".into(), 12.into());
|
||||||
|
|
||||||
|
CanvasKusamaChainSpec::from_genesis(
|
||||||
|
// Name
|
||||||
|
"Canvas on Rococo",
|
||||||
|
// ID
|
||||||
|
"canvas-rococo-local",
|
||||||
|
ChainType::Local,
|
||||||
|
move || {
|
||||||
|
canvas_kusama_genesis(
|
||||||
|
// initial collators.
|
||||||
|
vec![
|
||||||
|
(
|
||||||
|
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||||
|
get_collator_keys_from_seed::<canvas_kusama_runtime::AuraId>("Alice"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||||
|
get_collator_keys_from_seed::<canvas_kusama_runtime::AuraId>("Bob"),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
vec![
|
||||||
|
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||||
|
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||||
|
get_account_id_from_seed::<sr25519::Public>("Charlie"),
|
||||||
|
get_account_id_from_seed::<sr25519::Public>("Dave"),
|
||||||
|
get_account_id_from_seed::<sr25519::Public>("Eve"),
|
||||||
|
get_account_id_from_seed::<sr25519::Public>("Ferdie"),
|
||||||
|
get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
|
||||||
|
get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
|
||||||
|
get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),
|
||||||
|
get_account_id_from_seed::<sr25519::Public>("Dave//stash"),
|
||||||
|
get_account_id_from_seed::<sr25519::Public>("Eve//stash"),
|
||||||
|
get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),
|
||||||
|
],
|
||||||
|
CANVAS_PARACHAIN_ID.into(),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
// Bootnodes
|
||||||
|
Vec::new(),
|
||||||
|
// Telemetry
|
||||||
|
None,
|
||||||
|
// Protocol ID
|
||||||
|
None,
|
||||||
|
// Fork ID
|
||||||
|
None,
|
||||||
|
// Properties
|
||||||
|
Some(properties),
|
||||||
|
// Extensions
|
||||||
|
Extensions {
|
||||||
|
relay_chain: "rococo-local".into(), // You MUST set this to the correct network!
|
||||||
|
para_id: CANVAS_PARACHAIN_ID,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn canvas_rococo_config() -> CanvasKusamaChainSpec {
|
||||||
|
// Give your base currency a unit name and decimal places
|
||||||
|
let mut properties = sc_chain_spec::Properties::new();
|
||||||
|
properties.insert("tokenSymbol".into(), "ROC".into());
|
||||||
|
properties.insert("tokenDecimals".into(), 12.into());
|
||||||
|
|
||||||
|
CanvasKusamaChainSpec::from_genesis(
|
||||||
|
// Name
|
||||||
|
"Canvas on Rococo",
|
||||||
|
// ID
|
||||||
|
"canvas-rococo",
|
||||||
|
ChainType::Live,
|
||||||
|
move || {
|
||||||
|
canvas_kusama_genesis(
|
||||||
|
vec![
|
||||||
|
// 5GKFbTTgrVS4Vz1UWWHPqMZQNFWZtqo7H2KpCDyYhEL3aS26
|
||||||
|
(
|
||||||
|
hex!["bc09354c12c054c8f6b3da208485eacec4ac648bad348895273b37bab5a0937c"]
|
||||||
|
.into(),
|
||||||
|
hex!["bc09354c12c054c8f6b3da208485eacec4ac648bad348895273b37bab5a0937c"]
|
||||||
|
.unchecked_into(),
|
||||||
|
),
|
||||||
|
// 5EPRJHm2GpABVWcwnAujcrhnrjFZyDGd5TwKFzkBoGgdRyv2
|
||||||
|
(
|
||||||
|
hex!["66be63b7bcbfb91040e5248e2d1ceb822cf219c57848c5924ffa3a1f8e67ba72"]
|
||||||
|
.into(),
|
||||||
|
hex!["66be63b7bcbfb91040e5248e2d1ceb822cf219c57848c5924ffa3a1f8e67ba72"]
|
||||||
|
.unchecked_into(),
|
||||||
|
),
|
||||||
|
// 5GH62vrJrVZxLREcHzm2PR5uTLAT5RQMJitoztCGyaP4o3uM
|
||||||
|
(
|
||||||
|
hex!["ba62886472a0a9f66b5e39f1469ce1c5b3d8cad6be39078daf16f111e89d1e44"]
|
||||||
|
.into(),
|
||||||
|
hex!["ba62886472a0a9f66b5e39f1469ce1c5b3d8cad6be39078daf16f111e89d1e44"]
|
||||||
|
.unchecked_into(),
|
||||||
|
),
|
||||||
|
// 5FHfoJDLdjRYX5KXLRqMDYBbWrwHLMtti21uK4QByUoUAbJF
|
||||||
|
(
|
||||||
|
hex!["8e97f65cda001976311df9bed39e8d0c956089093e94a75ef76fe9347a0eda7b"]
|
||||||
|
.into(),
|
||||||
|
hex!["8e97f65cda001976311df9bed39e8d0c956089093e94a75ef76fe9347a0eda7b"]
|
||||||
|
.unchecked_into(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
// Warning: The configuration for a production chain should not contain
|
||||||
|
// any endowed accounts here, otherwise it'll be minting extra native tokens
|
||||||
|
// from the relay chain on the parachain.
|
||||||
|
vec![
|
||||||
|
// NOTE: Remove endowed accounts if deployed on other relay chains.
|
||||||
|
// Endowed accounts
|
||||||
|
hex!["baa78c7154c7f82d6d377177e20bcab65d327eca0086513f9964f5a0f6bdad56"].into(),
|
||||||
|
// AccountId of an account which `ink-waterfall` uses for automated testing
|
||||||
|
hex!["0e47e2344d523c3cc5c34394b0d58b9a4200e813a038e6c5a6163cc07d70b069"].into(),
|
||||||
|
],
|
||||||
|
CANVAS_PARACHAIN_ID.into(),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
// Bootnodes
|
||||||
|
vec![
|
||||||
|
"/ip4/34.90.191.237/tcp/30333/p2p/12D3KooWKg3Rpxcr9oJ8n6khoxpGKWztCZydtUZk2cojHqnfLrpj"
|
||||||
|
.parse()
|
||||||
|
.expect("MultiaddrWithPeerId"),
|
||||||
|
"/ip4/35.204.68.28/tcp/30333/p2p/12D3KooWPEXYrz8tHU3nDtPoPw4V7ou5dzMEWSTuUj7vaWiYVAVh"
|
||||||
|
.parse()
|
||||||
|
.expect("MultiaddrWithPeerId"),
|
||||||
|
"/ip4/34.90.139.15/tcp/30333/p2p/12D3KooWEVU8AFNary4nP4qEnEcwJaRuy59Wefekzdu9pKbnVEhk"
|
||||||
|
.parse()
|
||||||
|
.expect("MultiaddrWithPeerId"),
|
||||||
|
"/ip4/35.204.99.97/tcp/30333/p2p/12D3KooWP6pV3ZmcXzGDjv8ZMgA6nZxfAKDxSz4VNiLx6vVCQgJX"
|
||||||
|
.parse()
|
||||||
|
.expect("MultiaddrWithPeerId"),
|
||||||
|
],
|
||||||
|
// Telemetry
|
||||||
|
None,
|
||||||
|
// Protocol ID
|
||||||
|
None,
|
||||||
|
// Fork ID
|
||||||
|
None,
|
||||||
|
// Properties
|
||||||
|
Some(properties),
|
||||||
|
// Extensions
|
||||||
|
Extensions { relay_chain: "rococo".into(), para_id: CANVAS_PARACHAIN_ID },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn canvas_kusama_genesis(
|
||||||
|
invulnerables: Vec<(AccountId, AuraId)>,
|
||||||
|
endowed_accounts: Vec<AccountId>,
|
||||||
|
id: ParaId,
|
||||||
|
) -> canvas_kusama_runtime::GenesisConfig {
|
||||||
|
canvas_kusama_runtime::GenesisConfig {
|
||||||
|
system: canvas_kusama_runtime::SystemConfig {
|
||||||
|
code: canvas_kusama_runtime::WASM_BINARY
|
||||||
|
.expect("WASM binary was not build, please build it!")
|
||||||
|
.to_vec(),
|
||||||
|
},
|
||||||
|
balances: canvas_kusama_runtime::BalancesConfig {
|
||||||
|
balances: endowed_accounts.iter().cloned().map(|k| (k, 1 << 60)).collect(),
|
||||||
|
},
|
||||||
|
parachain_info: canvas_kusama_runtime::ParachainInfoConfig { parachain_id: id },
|
||||||
|
collator_selection: canvas_kusama_runtime::CollatorSelectionConfig {
|
||||||
|
invulnerables: invulnerables.iter().cloned().map(|(acc, _)| acc).collect(),
|
||||||
|
candidacy_bond: CANVAS_KUSAMA_ED * 16,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
session: canvas_kusama_runtime::SessionConfig {
|
||||||
|
keys: invulnerables
|
||||||
|
.into_iter()
|
||||||
|
.map(|(acc, aura)| {
|
||||||
|
(
|
||||||
|
acc.clone(), // account id
|
||||||
|
acc, // validator id
|
||||||
|
canvas_kusama_runtime::SessionKeys { aura }, // session keys
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect(),
|
||||||
|
},
|
||||||
|
// no need to pass anything to aura, in fact it will panic if we do. Session will take care
|
||||||
|
// of this.
|
||||||
|
aura: Default::default(),
|
||||||
|
aura_ext: Default::default(),
|
||||||
|
parachain_system: Default::default(),
|
||||||
|
polkadot_xcm: canvas_kusama_runtime::PolkadotXcmConfig {
|
||||||
|
safe_xcm_version: Some(SAFE_XCM_VERSION),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -18,9 +18,9 @@ use crate::{
|
|||||||
chain_spec,
|
chain_spec,
|
||||||
cli::{Cli, RelayChainCli, Subcommand},
|
cli::{Cli, RelayChainCli, Subcommand},
|
||||||
service::{
|
service::{
|
||||||
new_partial, Block, RococoParachainRuntimeExecutor, SeedlingRuntimeExecutor,
|
new_partial, Block, CanvasKusamaRuntimeExecutor, RococoParachainRuntimeExecutor,
|
||||||
ShellRuntimeExecutor, StatemineRuntimeExecutor, StatemintRuntimeExecutor,
|
SeedlingRuntimeExecutor, ShellRuntimeExecutor, StatemineRuntimeExecutor,
|
||||||
WestmintRuntimeExecutor,
|
StatemintRuntimeExecutor, WestmintRuntimeExecutor,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use codec::Encode;
|
use codec::Encode;
|
||||||
@@ -47,6 +47,7 @@ trait IdentifyChain {
|
|||||||
fn is_statemint(&self) -> bool;
|
fn is_statemint(&self) -> bool;
|
||||||
fn is_statemine(&self) -> bool;
|
fn is_statemine(&self) -> bool;
|
||||||
fn is_westmint(&self) -> bool;
|
fn is_westmint(&self) -> bool;
|
||||||
|
fn is_canvas_kusama(&self) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IdentifyChain for dyn sc_service::ChainSpec {
|
impl IdentifyChain for dyn sc_service::ChainSpec {
|
||||||
@@ -65,6 +66,10 @@ impl IdentifyChain for dyn sc_service::ChainSpec {
|
|||||||
fn is_westmint(&self) -> bool {
|
fn is_westmint(&self) -> bool {
|
||||||
self.id().starts_with("westmint")
|
self.id().starts_with("westmint")
|
||||||
}
|
}
|
||||||
|
fn is_canvas_kusama(&self) -> bool {
|
||||||
|
// we use the same runtime on rococo and kusama
|
||||||
|
self.id().starts_with("canvas-kusama") || self.id().starts_with("canvas-rococo")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: sc_service::ChainSpec + 'static> IdentifyChain for T {
|
impl<T: sc_service::ChainSpec + 'static> IdentifyChain for T {
|
||||||
@@ -83,6 +88,9 @@ impl<T: sc_service::ChainSpec + 'static> IdentifyChain for T {
|
|||||||
fn is_westmint(&self) -> bool {
|
fn is_westmint(&self) -> bool {
|
||||||
<dyn sc_service::ChainSpec>::is_westmint(self)
|
<dyn sc_service::ChainSpec>::is_westmint(self)
|
||||||
}
|
}
|
||||||
|
fn is_canvas_kusama(&self) -> bool {
|
||||||
|
<dyn sc_service::ChainSpec>::is_canvas_kusama(self)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_spec(id: &str) -> std::result::Result<Box<dyn sc_service::ChainSpec>, String> {
|
fn load_spec(id: &str) -> std::result::Result<Box<dyn sc_service::ChainSpec>, String> {
|
||||||
@@ -126,6 +134,10 @@ fn load_spec(id: &str) -> std::result::Result<Box<dyn sc_service::ChainSpec>, St
|
|||||||
"westmint" => Box::new(chain_spec::ChainSpec::from_json_bytes(
|
"westmint" => Box::new(chain_spec::ChainSpec::from_json_bytes(
|
||||||
&include_bytes!("../res/westmint.json")[..],
|
&include_bytes!("../res/westmint.json")[..],
|
||||||
)?),
|
)?),
|
||||||
|
// -- Canvas on Rococo
|
||||||
|
"canvas-rococo-dev" => Box::new(chain_spec::canvas_rococo_development_config()),
|
||||||
|
"canvas-rococo-local" => Box::new(chain_spec::canvas_rococo_local_config()),
|
||||||
|
"canvas-rococo" => Box::new(chain_spec::canvas_rococo_config()),
|
||||||
"" => Box::new(chain_spec::get_chain_spec()),
|
"" => Box::new(chain_spec::get_chain_spec()),
|
||||||
path => {
|
path => {
|
||||||
let chain_spec = chain_spec::ChainSpec::from_json_file(path.into())?;
|
let chain_spec = chain_spec::ChainSpec::from_json_file(path.into())?;
|
||||||
@@ -139,6 +151,8 @@ fn load_spec(id: &str) -> std::result::Result<Box<dyn sc_service::ChainSpec>, St
|
|||||||
Box::new(chain_spec::ShellChainSpec::from_json_file(path.into())?)
|
Box::new(chain_spec::ShellChainSpec::from_json_file(path.into())?)
|
||||||
} else if chain_spec.is_seedling() {
|
} else if chain_spec.is_seedling() {
|
||||||
Box::new(chain_spec::SeedlingChainSpec::from_json_file(path.into())?)
|
Box::new(chain_spec::SeedlingChainSpec::from_json_file(path.into())?)
|
||||||
|
} else if chain_spec.is_canvas_kusama() {
|
||||||
|
Box::new(chain_spec::CanvasKusamaChainSpec::from_json_file(path.into())?)
|
||||||
} else {
|
} else {
|
||||||
Box::new(chain_spec)
|
Box::new(chain_spec)
|
||||||
}
|
}
|
||||||
@@ -192,6 +206,8 @@ impl SubstrateCli for Cli {
|
|||||||
&shell_runtime::VERSION
|
&shell_runtime::VERSION
|
||||||
} else if chain_spec.is_seedling() {
|
} else if chain_spec.is_seedling() {
|
||||||
&seedling_runtime::VERSION
|
&seedling_runtime::VERSION
|
||||||
|
} else if chain_spec.is_canvas_kusama() {
|
||||||
|
&canvas_kusama_runtime::VERSION
|
||||||
} else {
|
} else {
|
||||||
&rococo_parachain_runtime::VERSION
|
&rococo_parachain_runtime::VERSION
|
||||||
}
|
}
|
||||||
@@ -296,6 +312,15 @@ macro_rules! construct_async_run {
|
|||||||
let task_manager = $components.task_manager;
|
let task_manager = $components.task_manager;
|
||||||
{ $( $code )* }.map(|v| (v, task_manager))
|
{ $( $code )* }.map(|v| (v, task_manager))
|
||||||
})
|
})
|
||||||
|
} else if runner.config().chain_spec.is_canvas_kusama() {
|
||||||
|
runner.async_run(|$config| {
|
||||||
|
let $components = new_partial::<canvas_kusama_runtime::RuntimeApi, CanvasKusamaRuntimeExecutor, _>(
|
||||||
|
&$config,
|
||||||
|
crate::service::canvas_kusama_build_import_queue,
|
||||||
|
)?;
|
||||||
|
let task_manager = $components.task_manager;
|
||||||
|
{ $( $code )* }.map(|v| (v, task_manager))
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
runner.async_run(|$config| {
|
runner.async_run(|$config| {
|
||||||
let $components = new_partial::<
|
let $components = new_partial::<
|
||||||
@@ -542,6 +567,11 @@ pub fn run() -> Result<()> {
|
|||||||
.await
|
.await
|
||||||
.map(|r| r.0)
|
.map(|r| r.0)
|
||||||
.map_err(Into::into)
|
.map_err(Into::into)
|
||||||
|
} else if config.chain_spec.is_canvas_kusama() {
|
||||||
|
crate::service::start_canvas_kusama_node(config, polkadot_config, id)
|
||||||
|
.await
|
||||||
|
.map(|r| r.0)
|
||||||
|
.map_err(Into::into)
|
||||||
} else {
|
} else {
|
||||||
crate::service::start_rococo_parachain_node(config, polkadot_config, id)
|
crate::service::start_rococo_parachain_node(config, polkadot_config, id)
|
||||||
.await
|
.await
|
||||||
|
|||||||
@@ -20,6 +20,8 @@
|
|||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use pallet_contracts_rpc::{Contracts, ContractsApi};
|
||||||
|
use parachains_common::{AccountId, Balance, Block, BlockNumber, Hash, Index as Nonce};
|
||||||
use sc_client_api::AuxStore;
|
use sc_client_api::AuxStore;
|
||||||
pub use sc_rpc::{DenyUnsafe, SubscriptionTaskExecutor};
|
pub use sc_rpc::{DenyUnsafe, SubscriptionTaskExecutor};
|
||||||
use sc_transaction_pool_api::TransactionPool;
|
use sc_transaction_pool_api::TransactionPool;
|
||||||
@@ -27,8 +29,6 @@ use sp_api::ProvideRuntimeApi;
|
|||||||
use sp_block_builder::BlockBuilder;
|
use sp_block_builder::BlockBuilder;
|
||||||
use sp_blockchain::{Error as BlockChainError, HeaderBackend, HeaderMetadata};
|
use sp_blockchain::{Error as BlockChainError, HeaderBackend, HeaderMetadata};
|
||||||
|
|
||||||
use parachains_common::{AccountId, Balance, Block, Index as Nonce};
|
|
||||||
|
|
||||||
/// A type representing all RPC extensions.
|
/// A type representing all RPC extensions.
|
||||||
pub type RpcExtension = jsonrpc_core::IoHandler<sc_rpc::Metadata>;
|
pub type RpcExtension = jsonrpc_core::IoHandler<sc_rpc::Metadata>;
|
||||||
|
|
||||||
@@ -68,3 +68,32 @@ where
|
|||||||
|
|
||||||
io
|
io
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Instantiate all RPCs we want at the canvas-kusama chain.
|
||||||
|
pub fn create_canvas_kusama<C, P>(deps: FullDeps<C, P>) -> RpcExtension
|
||||||
|
where
|
||||||
|
C: ProvideRuntimeApi<Block>
|
||||||
|
+ HeaderBackend<Block>
|
||||||
|
+ AuxStore
|
||||||
|
+ HeaderMetadata<Block, Error = BlockChainError>
|
||||||
|
+ Send
|
||||||
|
+ Sync
|
||||||
|
+ 'static,
|
||||||
|
C::Api: frame_rpc_system::AccountNonceApi<Block, AccountId, Nonce>,
|
||||||
|
C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi<Block, Balance>,
|
||||||
|
C::Api: pallet_contracts_rpc::ContractsRuntimeApi<Block, AccountId, Balance, BlockNumber, Hash>,
|
||||||
|
C::Api: BlockBuilder<Block>,
|
||||||
|
P: TransactionPool + Sync + Send + 'static,
|
||||||
|
{
|
||||||
|
use frame_rpc_system::{FullSystem, SystemApi};
|
||||||
|
use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApi};
|
||||||
|
|
||||||
|
let mut io = jsonrpc_core::IoHandler::default();
|
||||||
|
let FullDeps { client, pool, deny_unsafe } = deps;
|
||||||
|
|
||||||
|
io.extend_with(SystemApi::to_delegate(FullSystem::new(client.clone(), pool, deny_unsafe)));
|
||||||
|
io.extend_with(TransactionPaymentApi::to_delegate(TransactionPayment::new(client.clone())));
|
||||||
|
io.extend_with(ContractsApi::to_delegate(Contracts::new(client)));
|
||||||
|
|
||||||
|
io
|
||||||
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ use cumulus_relay_chain_local::build_relay_chain_interface;
|
|||||||
use polkadot_service::NativeExecutionDispatch;
|
use polkadot_service::NativeExecutionDispatch;
|
||||||
|
|
||||||
use crate::rpc;
|
use crate::rpc;
|
||||||
pub use parachains_common::{AccountId, Balance, Block, Hash, Header, Index as Nonce};
|
pub use parachains_common::{AccountId, Balance, Block, BlockNumber, Hash, Header, Index as Nonce};
|
||||||
|
|
||||||
use cumulus_client_consensus_relay_chain::Verifier as RelayChainVerifier;
|
use cumulus_client_consensus_relay_chain::Verifier as RelayChainVerifier;
|
||||||
use futures::lock::Mutex;
|
use futures::lock::Mutex;
|
||||||
@@ -148,6 +148,21 @@ impl sc_executor::NativeExecutionDispatch for WestmintRuntimeExecutor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Native Canvas on Kusama executor instance.
|
||||||
|
pub struct CanvasKusamaRuntimeExecutor;
|
||||||
|
|
||||||
|
impl sc_executor::NativeExecutionDispatch for CanvasKusamaRuntimeExecutor {
|
||||||
|
type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions;
|
||||||
|
|
||||||
|
fn dispatch(method: &str, data: &[u8]) -> Option<Vec<u8>> {
|
||||||
|
canvas_kusama_runtime::api::dispatch(method, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn native_version() -> sc_executor::NativeVersion {
|
||||||
|
canvas_kusama_runtime::native_version()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Starts a `ServiceBuilder` for a full service.
|
/// Starts a `ServiceBuilder` for a full service.
|
||||||
///
|
///
|
||||||
/// Use this macro if you don't actually need the full service, but just the builder in order to
|
/// Use this macro if you don't actually need the full service, but just the builder in order to
|
||||||
@@ -1252,3 +1267,341 @@ where
|
|||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[sc_tracing::logging::prefix_logs_with("Parachain")]
|
||||||
|
async fn start_canvas_kusama_node_impl<RuntimeApi, Executor, RB, BIQ, BIC>(
|
||||||
|
parachain_config: Configuration,
|
||||||
|
polkadot_config: Configuration,
|
||||||
|
id: ParaId,
|
||||||
|
_rpc_ext_builder: RB,
|
||||||
|
build_import_queue: BIQ,
|
||||||
|
build_consensus: BIC,
|
||||||
|
) -> sc_service::error::Result<(
|
||||||
|
TaskManager,
|
||||||
|
Arc<TFullClient<Block, RuntimeApi, NativeElseWasmExecutor<Executor>>>,
|
||||||
|
)>
|
||||||
|
where
|
||||||
|
RuntimeApi: ConstructRuntimeApi<Block, TFullClient<Block, RuntimeApi, NativeElseWasmExecutor<Executor>>>
|
||||||
|
+ Send
|
||||||
|
+ Sync
|
||||||
|
+ 'static,
|
||||||
|
RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>
|
||||||
|
+ sp_api::Metadata<Block>
|
||||||
|
+ sp_session::SessionKeys<Block>
|
||||||
|
+ sp_api::ApiExt<
|
||||||
|
Block,
|
||||||
|
StateBackend = sc_client_api::StateBackendFor<TFullBackend<Block>, Block>,
|
||||||
|
> + sp_offchain::OffchainWorkerApi<Block>
|
||||||
|
+ sp_block_builder::BlockBuilder<Block>
|
||||||
|
+ cumulus_primitives_core::CollectCollationInfo<Block>
|
||||||
|
+ pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi<Block, Balance>
|
||||||
|
+ frame_rpc_system::AccountNonceApi<Block, AccountId, Nonce>
|
||||||
|
+ pallet_contracts_rpc::ContractsRuntimeApi<Block, AccountId, Balance, BlockNumber, Hash>,
|
||||||
|
sc_client_api::StateBackendFor<TFullBackend<Block>, Block>: sp_api::StateBackend<BlakeTwo256>,
|
||||||
|
Executor: sc_executor::NativeExecutionDispatch + 'static,
|
||||||
|
RB: Fn(
|
||||||
|
Arc<TFullClient<Block, RuntimeApi, Executor>>,
|
||||||
|
) -> Result<jsonrpc_core::IoHandler<sc_rpc::Metadata>, sc_service::Error>
|
||||||
|
+ Send
|
||||||
|
+ 'static,
|
||||||
|
BIQ: FnOnce(
|
||||||
|
Arc<TFullClient<Block, RuntimeApi, NativeElseWasmExecutor<Executor>>>,
|
||||||
|
&Configuration,
|
||||||
|
Option<TelemetryHandle>,
|
||||||
|
&TaskManager,
|
||||||
|
) -> Result<
|
||||||
|
sc_consensus::DefaultImportQueue<
|
||||||
|
Block,
|
||||||
|
TFullClient<Block, RuntimeApi, NativeElseWasmExecutor<Executor>>,
|
||||||
|
>,
|
||||||
|
sc_service::Error,
|
||||||
|
> + 'static,
|
||||||
|
BIC: FnOnce(
|
||||||
|
Arc<TFullClient<Block, RuntimeApi, NativeElseWasmExecutor<Executor>>>,
|
||||||
|
Option<&Registry>,
|
||||||
|
Option<TelemetryHandle>,
|
||||||
|
&TaskManager,
|
||||||
|
Arc<dyn RelayChainInterface>,
|
||||||
|
Arc<
|
||||||
|
sc_transaction_pool::FullPool<
|
||||||
|
Block,
|
||||||
|
TFullClient<Block, RuntimeApi, NativeElseWasmExecutor<Executor>>,
|
||||||
|
>,
|
||||||
|
>,
|
||||||
|
Arc<NetworkService<Block, Hash>>,
|
||||||
|
SyncCryptoStorePtr,
|
||||||
|
bool,
|
||||||
|
) -> Result<Box<dyn ParachainConsensus<Block>>, sc_service::Error>,
|
||||||
|
{
|
||||||
|
if matches!(parachain_config.role, Role::Light) {
|
||||||
|
return Err("Light client not supported!".into())
|
||||||
|
}
|
||||||
|
|
||||||
|
let parachain_config = prepare_node_config(parachain_config);
|
||||||
|
|
||||||
|
let params = new_partial::<RuntimeApi, Executor, BIQ>(¶chain_config, build_import_queue)?;
|
||||||
|
let (mut telemetry, telemetry_worker_handle) = params.other;
|
||||||
|
|
||||||
|
let client = params.client.clone();
|
||||||
|
let backend = params.backend.clone();
|
||||||
|
let mut task_manager = params.task_manager;
|
||||||
|
|
||||||
|
let (relay_chain_interface, collator_key) =
|
||||||
|
build_relay_chain_interface(polkadot_config, telemetry_worker_handle, &mut task_manager)
|
||||||
|
.map_err(|e| match e {
|
||||||
|
polkadot_service::Error::Sub(x) => x,
|
||||||
|
s => format!("{}", s).into(),
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let block_announce_validator = BlockAnnounceValidator::new(relay_chain_interface.clone(), id);
|
||||||
|
|
||||||
|
let force_authoring = parachain_config.force_authoring;
|
||||||
|
let validator = parachain_config.role.is_authority();
|
||||||
|
let prometheus_registry = parachain_config.prometheus_registry().cloned();
|
||||||
|
let transaction_pool = params.transaction_pool.clone();
|
||||||
|
let import_queue = cumulus_client_service::SharedImportQueue::new(params.import_queue);
|
||||||
|
let (network, system_rpc_tx, start_network) =
|
||||||
|
sc_service::build_network(sc_service::BuildNetworkParams {
|
||||||
|
config: ¶chain_config,
|
||||||
|
client: client.clone(),
|
||||||
|
transaction_pool: transaction_pool.clone(),
|
||||||
|
spawn_handle: task_manager.spawn_handle(),
|
||||||
|
import_queue: import_queue.clone(),
|
||||||
|
block_announce_validator_builder: Some(Box::new(|_| {
|
||||||
|
Box::new(block_announce_validator)
|
||||||
|
})),
|
||||||
|
warp_sync: None,
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let rpc_extensions_builder = {
|
||||||
|
let client = client.clone();
|
||||||
|
let transaction_pool = transaction_pool.clone();
|
||||||
|
|
||||||
|
Box::new(move |deny_unsafe, _| {
|
||||||
|
let deps = crate::rpc::FullDeps {
|
||||||
|
client: client.clone(),
|
||||||
|
pool: transaction_pool.clone(),
|
||||||
|
deny_unsafe,
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(crate::rpc::create_canvas_kusama(deps))
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
sc_service::spawn_tasks(sc_service::SpawnTasksParams {
|
||||||
|
rpc_extensions_builder,
|
||||||
|
client: client.clone(),
|
||||||
|
transaction_pool: transaction_pool.clone(),
|
||||||
|
task_manager: &mut task_manager,
|
||||||
|
config: parachain_config,
|
||||||
|
keystore: params.keystore_container.sync_keystore(),
|
||||||
|
backend: backend.clone(),
|
||||||
|
network: network.clone(),
|
||||||
|
system_rpc_tx,
|
||||||
|
telemetry: telemetry.as_mut(),
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let announce_block = {
|
||||||
|
let network = network.clone();
|
||||||
|
Arc::new(move |hash, data| network.announce_block(hash, data))
|
||||||
|
};
|
||||||
|
|
||||||
|
let relay_chain_slot_duration = Duration::from_secs(6);
|
||||||
|
|
||||||
|
if validator {
|
||||||
|
let parachain_consensus = build_consensus(
|
||||||
|
client.clone(),
|
||||||
|
prometheus_registry.as_ref(),
|
||||||
|
telemetry.as_ref().map(|t| t.handle()),
|
||||||
|
&task_manager,
|
||||||
|
relay_chain_interface.clone(),
|
||||||
|
transaction_pool,
|
||||||
|
network,
|
||||||
|
params.keystore_container.sync_keystore(),
|
||||||
|
force_authoring,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let spawner = task_manager.spawn_handle();
|
||||||
|
|
||||||
|
let params = StartCollatorParams {
|
||||||
|
para_id: id,
|
||||||
|
block_status: client.clone(),
|
||||||
|
announce_block,
|
||||||
|
client: client.clone(),
|
||||||
|
task_manager: &mut task_manager,
|
||||||
|
relay_chain_interface,
|
||||||
|
spawner,
|
||||||
|
parachain_consensus,
|
||||||
|
import_queue,
|
||||||
|
collator_key,
|
||||||
|
relay_chain_slot_duration,
|
||||||
|
};
|
||||||
|
|
||||||
|
start_collator(params).await?;
|
||||||
|
} else {
|
||||||
|
let params = StartFullNodeParams {
|
||||||
|
client: client.clone(),
|
||||||
|
announce_block,
|
||||||
|
task_manager: &mut task_manager,
|
||||||
|
para_id: id,
|
||||||
|
relay_chain_interface,
|
||||||
|
relay_chain_slot_duration,
|
||||||
|
import_queue,
|
||||||
|
};
|
||||||
|
|
||||||
|
start_full_node(params)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
start_network.start_network();
|
||||||
|
|
||||||
|
Ok((task_manager, client))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::type_complexity)]
|
||||||
|
pub fn canvas_kusama_build_import_queue(
|
||||||
|
client: Arc<
|
||||||
|
TFullClient<
|
||||||
|
Block,
|
||||||
|
canvas_kusama_runtime::RuntimeApi,
|
||||||
|
NativeElseWasmExecutor<CanvasKusamaRuntimeExecutor>,
|
||||||
|
>,
|
||||||
|
>,
|
||||||
|
config: &Configuration,
|
||||||
|
telemetry: Option<TelemetryHandle>,
|
||||||
|
task_manager: &TaskManager,
|
||||||
|
) -> Result<
|
||||||
|
sc_consensus::DefaultImportQueue<
|
||||||
|
Block,
|
||||||
|
TFullClient<
|
||||||
|
Block,
|
||||||
|
canvas_kusama_runtime::RuntimeApi,
|
||||||
|
NativeElseWasmExecutor<CanvasKusamaRuntimeExecutor>,
|
||||||
|
>,
|
||||||
|
>,
|
||||||
|
sc_service::Error,
|
||||||
|
> {
|
||||||
|
let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?;
|
||||||
|
|
||||||
|
cumulus_client_consensus_aura::import_queue::<
|
||||||
|
sp_consensus_aura::sr25519::AuthorityPair,
|
||||||
|
_,
|
||||||
|
_,
|
||||||
|
_,
|
||||||
|
_,
|
||||||
|
_,
|
||||||
|
_,
|
||||||
|
>(cumulus_client_consensus_aura::ImportQueueParams {
|
||||||
|
block_import: client.clone(),
|
||||||
|
client: client.clone(),
|
||||||
|
create_inherent_data_providers: move |_, _| async move {
|
||||||
|
let time = sp_timestamp::InherentDataProvider::from_system_time();
|
||||||
|
|
||||||
|
let slot =
|
||||||
|
sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_duration(
|
||||||
|
*time,
|
||||||
|
slot_duration.slot_duration(),
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok((time, slot))
|
||||||
|
},
|
||||||
|
registry: config.prometheus_registry(),
|
||||||
|
can_author_with: sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone()),
|
||||||
|
spawner: &task_manager.spawn_essential_handle(),
|
||||||
|
telemetry,
|
||||||
|
})
|
||||||
|
.map_err(Into::into)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Start a parachain node.
|
||||||
|
pub async fn start_canvas_kusama_node(
|
||||||
|
parachain_config: Configuration,
|
||||||
|
polkadot_config: Configuration,
|
||||||
|
id: ParaId,
|
||||||
|
) -> sc_service::error::Result<(
|
||||||
|
TaskManager,
|
||||||
|
Arc<
|
||||||
|
TFullClient<
|
||||||
|
Block,
|
||||||
|
canvas_kusama_runtime::RuntimeApi,
|
||||||
|
NativeElseWasmExecutor<CanvasKusamaRuntimeExecutor>,
|
||||||
|
>,
|
||||||
|
>,
|
||||||
|
)> {
|
||||||
|
start_canvas_kusama_node_impl::<
|
||||||
|
canvas_kusama_runtime::RuntimeApi,
|
||||||
|
CanvasKusamaRuntimeExecutor,
|
||||||
|
_,
|
||||||
|
_,
|
||||||
|
_,
|
||||||
|
>(
|
||||||
|
parachain_config,
|
||||||
|
polkadot_config,
|
||||||
|
id,
|
||||||
|
|_| Ok(Default::default()),
|
||||||
|
canvas_kusama_build_import_queue,
|
||||||
|
|client,
|
||||||
|
prometheus_registry,
|
||||||
|
telemetry,
|
||||||
|
task_manager,
|
||||||
|
relay_chain_interface,
|
||||||
|
transaction_pool,
|
||||||
|
sync_oracle,
|
||||||
|
keystore,
|
||||||
|
force_authoring| {
|
||||||
|
let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?;
|
||||||
|
|
||||||
|
let proposer_factory = sc_basic_authorship::ProposerFactory::with_proof_recording(
|
||||||
|
task_manager.spawn_handle(),
|
||||||
|
client.clone(),
|
||||||
|
transaction_pool,
|
||||||
|
prometheus_registry,
|
||||||
|
telemetry.clone(),
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(AuraConsensus::build::<sp_consensus_aura::sr25519::AuthorityPair, _, _, _, _, _, _>(
|
||||||
|
BuildAuraConsensusParams {
|
||||||
|
proposer_factory,
|
||||||
|
create_inherent_data_providers: move |_, (relay_parent, validation_data)| {
|
||||||
|
let relay_chain_interface = relay_chain_interface.clone();
|
||||||
|
async move {
|
||||||
|
let parachain_inherent =
|
||||||
|
cumulus_primitives_parachain_inherent::ParachainInherentData::create_at(
|
||||||
|
relay_parent,
|
||||||
|
&relay_chain_interface,
|
||||||
|
&validation_data,
|
||||||
|
id,
|
||||||
|
).await;
|
||||||
|
let time = sp_timestamp::InherentDataProvider::from_system_time();
|
||||||
|
|
||||||
|
let slot =
|
||||||
|
sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_duration(
|
||||||
|
*time,
|
||||||
|
slot_duration.slot_duration(),
|
||||||
|
);
|
||||||
|
|
||||||
|
let parachain_inherent = parachain_inherent.ok_or_else(|| {
|
||||||
|
Box::<dyn std::error::Error + Send + Sync>::from(
|
||||||
|
"Failed to create parachain inherent",
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
Ok((time, slot, parachain_inherent))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
block_import: client.clone(),
|
||||||
|
para_client: client,
|
||||||
|
backoff_authoring_blocks: Option::<()>::None,
|
||||||
|
sync_oracle,
|
||||||
|
keystore,
|
||||||
|
force_authoring,
|
||||||
|
slot_duration,
|
||||||
|
// We got around 500ms for proposing
|
||||||
|
block_proposal_slot_portion: SlotProportion::new(1f32 / 24f32),
|
||||||
|
// And a maximum of 750ms if slots are skipped
|
||||||
|
max_block_proposal_slot_portion: Some(SlotProportion::new(1f32 / 16f32)),
|
||||||
|
telemetry,
|
||||||
|
},
|
||||||
|
))
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user