mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-10-22 11:46:20 +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:
1 parent
eeca2bb61a
commit
4d319d0fae
13 files changed
+3174
-295
No files matched your search
Generated
+505
-275
File diff suppressed because it is too large.
Load diff
@@ -32,6 +32,7 @@ members = [
|
||||
"polkadot-parachains/statemint",
|
||||
"polkadot-parachains/statemine",
|
||||
"polkadot-parachains/westmint",
|
||||
"polkadot-parachains/canvas-kusama",
|
||||
"test/client",
|
||||
"test/relay-sproof-builder",
|
||||
"test/relay-validation-worker-provider",
|
||||
|
||||
+111
-14
@@ -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
|
||||
[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,
|
||||
beautiful and functional.
|
||||
|
||||
## Consensus
|
||||
### Consensus
|
||||
|
||||
[`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
|
||||
@@ -25,18 +30,18 @@ to follow,
|
||||
[finalize](https://wiki.polkadot.network/docs/en/learn-consensus#probabilistic-vs-provable-finality),
|
||||
and treat as best.
|
||||
|
||||
## Collator
|
||||
### Collator
|
||||
|
||||
A Polkadot [collator](https://wiki.polkadot.network/docs/en/learn-collator) for the parachain is
|
||||
implemented by the `polkadot-collator` binary.
|
||||
|
||||
# Statemint 🪙
|
||||
## Statemint 🪙
|
||||
|
||||
This repository also contains the Statemint runtime (as well as the canary runtime Statemine and the
|
||||
test runtime Westmint).
|
||||
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
|
||||
`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.
|
||||
|
||||
# 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 is an elaborate style of design and the name describes the painstaking effort that has gone
|
||||
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
|
||||
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
|
||||
```
|
||||
|
||||
## 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 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.
|
||||
|
||||
## Local Setup
|
||||
### Local Setup
|
||||
|
||||
Launch a local setup including a Relay Chain and a Parachain.
|
||||
|
||||
### Launch the Relay Chain
|
||||
#### Launch the Relay Chain
|
||||
|
||||
```bash
|
||||
# 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
|
||||
```
|
||||
|
||||
### Launch the Parachain
|
||||
#### Launch the Parachain
|
||||
|
||||
```bash
|
||||
# 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
|
||||
```
|
||||
|
||||
### 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),
|
||||
the following will allow producing a new docker image where the compiled binary is injected:
|
||||
|
||||
@@ -0,0 +1,764 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="829mm"
|
||||
height="715mm"
|
||||
viewBox="0 0 829 715"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20, custom)"
|
||||
sodipodi:docname="how-it-works.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
|
||||
<defs
|
||||
id="defs2">
|
||||
<marker
|
||||
style="overflow:visible"
|
||||
id="marker7726"
|
||||
refX="0.0"
|
||||
refY="0.0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow1Lstart"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
transform="scale(0.8) translate(12.5,0)"
|
||||
style="fill-rule:evenodd;fill:context-stroke;stroke:context-stroke;stroke-width:1.0pt"
|
||||
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||
id="path7465" />
|
||||
</marker>
|
||||
<marker
|
||||
style="overflow:visible"
|
||||
id="marker32724"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow1Lend"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
transform="matrix(-0.8,0,0,-0.8,-10,0)"
|
||||
style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:1pt"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 Z"
|
||||
id="path32466" />
|
||||
</marker>
|
||||
<marker
|
||||
style="overflow:visible"
|
||||
id="marker2343"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow1Lstart"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
transform="matrix(0.8,0,0,0.8,10,0)"
|
||||
style="fill:#d8b6ff;fill-opacity:1;fill-rule:evenodd;stroke:#d8b6ff;stroke-width:1pt;stroke-opacity:1"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 Z"
|
||||
id="path2341" />
|
||||
</marker>
|
||||
<marker
|
||||
style="overflow:visible"
|
||||
id="marker2279"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow1Lend"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
transform="matrix(-0.8,0,0,-0.8,-10,0)"
|
||||
style="fill:#d8b6ff;fill-opacity:1;fill-rule:evenodd;stroke:#d8b6ff;stroke-width:1pt;stroke-opacity:1"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 Z"
|
||||
id="path2277" />
|
||||
</marker>
|
||||
<marker
|
||||
style="overflow:visible"
|
||||
id="Arrow1Lend"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow1Lend"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
transform="matrix(-0.8,0,0,-0.8,-10,0)"
|
||||
style="fill:#e50000;fill-opacity:1;fill-rule:evenodd;stroke:#e50000;stroke-width:1pt;stroke-opacity:1"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 Z"
|
||||
id="path1510" />
|
||||
</marker>
|
||||
<marker
|
||||
style="overflow:visible"
|
||||
id="Arrow1Lstart"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow1Lstart"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
transform="matrix(0.8,0,0,0.8,10,0)"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 Z"
|
||||
id="path1507" />
|
||||
</marker>
|
||||
<marker
|
||||
style="overflow:visible"
|
||||
id="marker1813-6"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow1Lend"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
transform="matrix(-0.8,0,0,-0.8,-10,0)"
|
||||
style="fill:#d8b6ff;fill-opacity:1;fill-rule:evenodd;stroke:#d8b6ff;stroke-width:1pt;stroke-opacity:1"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 Z"
|
||||
id="path1811-1" />
|
||||
</marker>
|
||||
<marker
|
||||
style="overflow:visible"
|
||||
id="marker1813-6-6"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow1Lend"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
transform="matrix(-0.8,0,0,-0.8,-10,0)"
|
||||
style="fill:#d8b6ff;fill-opacity:1;fill-rule:evenodd;stroke:#d8b6ff;stroke-width:1pt;stroke-opacity:1"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 Z"
|
||||
id="path1811-1-1" />
|
||||
</marker>
|
||||
<clipPath
|
||||
id="ga18cbd6cb1_1_0.4">
|
||||
<path
|
||||
d="M 0,0 H 512 V 512 H 0 Z"
|
||||
clip-rule="evenodd"
|
||||
id="path3358" />
|
||||
</clipPath>
|
||||
<clipPath
|
||||
id="ga18cbd6cb1_1_0.4-6">
|
||||
<path
|
||||
d="M 0,0 H 512 V 512 H 0 Z"
|
||||
clip-rule="evenodd"
|
||||
id="path3358-7" />
|
||||
</clipPath>
|
||||
<clipPath
|
||||
id="ga18cbd6cb1_1_0.4-6-3">
|
||||
<path
|
||||
d="M 0,0 H 512 V 512 H 0 Z"
|
||||
clip-rule="evenodd"
|
||||
id="path3358-7-6" />
|
||||
</clipPath>
|
||||
<marker
|
||||
style="overflow:visible"
|
||||
id="marker32724-2"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow1Lend"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
transform="matrix(-0.8,0,0,-0.8,-10,0)"
|
||||
style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:1pt"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 Z"
|
||||
id="path32466-9" />
|
||||
</marker>
|
||||
<marker
|
||||
style="overflow:visible"
|
||||
id="marker32724-27"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow1Lend"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
transform="matrix(-0.8,0,0,-0.8,-10,0)"
|
||||
style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:1pt"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 Z"
|
||||
id="path32466-0" />
|
||||
</marker>
|
||||
<marker
|
||||
style="overflow:visible"
|
||||
id="marker32724-27-3"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow1Lend"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
transform="matrix(-0.8,0,0,-0.8,-10,0)"
|
||||
style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:1pt"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 Z"
|
||||
id="path32466-0-6" />
|
||||
</marker>
|
||||
<marker
|
||||
style="overflow:visible"
|
||||
id="marker32724-27-3-6"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow1Lend"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
transform="matrix(-0.8,0,0,-0.8,-10,0)"
|
||||
style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:1pt"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 Z"
|
||||
id="path32466-0-6-2" />
|
||||
</marker>
|
||||
<marker
|
||||
style="overflow:visible"
|
||||
id="marker32724-1"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow1Lend"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
transform="matrix(-0.8,0,0,-0.8,-10,0)"
|
||||
style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:1pt"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 Z"
|
||||
id="path32466-8" />
|
||||
</marker>
|
||||
<marker
|
||||
style="overflow:visible"
|
||||
id="marker32724-9"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow1Lend"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
transform="matrix(-0.8,0,0,-0.8,-10,0)"
|
||||
style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:1pt"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 Z"
|
||||
id="path32466-2" />
|
||||
</marker>
|
||||
<marker
|
||||
style="overflow:visible"
|
||||
id="marker32724-3"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow1Lend"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
transform="matrix(-0.8,0,0,-0.8,-10,0)"
|
||||
style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:1pt"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 Z"
|
||||
id="path32466-7" />
|
||||
</marker>
|
||||
<marker
|
||||
style="overflow:visible"
|
||||
id="marker32724-3-2"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow1Lend"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
transform="matrix(-0.8,0,0,-0.8,-10,0)"
|
||||
style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:1pt"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 Z"
|
||||
id="path32466-7-2" />
|
||||
</marker>
|
||||
<marker
|
||||
style="overflow:visible"
|
||||
id="marker32724-97"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow1Lend"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
transform="matrix(-0.8,0,0,-0.8,-10,0)"
|
||||
style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:1pt"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 Z"
|
||||
id="path32466-3" />
|
||||
</marker>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.12114248"
|
||||
inkscape:cx="429.24663"
|
||||
inkscape:cy="1943.9919"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
inkscape:document-rotation="0"
|
||||
showgrid="false"
|
||||
showguides="true"
|
||||
inkscape:window-width="1471"
|
||||
inkscape:window-height="1080"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="23"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:guide-bbox="true"
|
||||
width="829mm">
|
||||
<sodipodi:guide
|
||||
position="289.8806,728.03695"
|
||||
orientation="0,-1"
|
||||
id="guide44197" />
|
||||
<sodipodi:guide
|
||||
position="40.94359,185.59939"
|
||||
orientation="1,0"
|
||||
id="guide81698" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<rect
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:14.5058;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:113.386;stroke-opacity:1"
|
||||
id="rect1440"
|
||||
width="829.57776"
|
||||
height="715.97333"
|
||||
x="0"
|
||||
y="0"
|
||||
ry="0" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:10.5833px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
|
||||
x="542.16547"
|
||||
y="419.47101"
|
||||
id="text1127"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan1125"
|
||||
x="542.16547"
|
||||
y="419.47101"
|
||||
style="stroke-width:0.264583" /></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:14.1111px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;white-space:pre;inline-size:372.233;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
|
||||
x="455.81284"
|
||||
y="231.4695"
|
||||
id="text835-3"
|
||||
transform="translate(14.142967,413.67741)" />
|
||||
<g
|
||||
id="g52787"
|
||||
transform="translate(-76.682965,-41.563407)">
|
||||
<path
|
||||
id="rect2466"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 103.20932,424.05872 H 883.96988 V 724.38367 H 103.20932 Z" />
|
||||
<g
|
||||
id="g32738"
|
||||
transform="translate(39.470311,-37.284235)">
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:15.875px;line-height:1.25;font-family:sans-serif;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
|
||||
x="449.05841"
|
||||
y="378.08499"
|
||||
id="text835-3-2"><tspan
|
||||
sodipodi:role="line"
|
||||
x="449.05841"
|
||||
y="378.08499"
|
||||
style="font-size:15.875px;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke-width:0.264583"
|
||||
id="tspan1083">The .contract file contains the WebAssembly</tspan><tspan
|
||||
sodipodi:role="line"
|
||||
x="449.05841"
|
||||
y="397.92874"
|
||||
style="font-size:15.875px;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke-width:0.264583"
|
||||
id="tspan2077">blob and metadata for the contract.</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:25.4px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
|
||||
x="340.15393"
|
||||
y="338.19156"
|
||||
id="text1975-2"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan1973-2"
|
||||
x="340.15393"
|
||||
y="338.19156"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:25.4px;font-family:monospace;-inkscape-font-specification:monospace;fill:#000000;stroke-width:0.264583">.contract File</tspan></text>
|
||||
</g>
|
||||
<path
|
||||
style="mix-blend-mode:normal;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:2, 2;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker32724)"
|
||||
d="m 162.44329,210.7796 65.19725,40.25153"
|
||||
id="path1809-0" />
|
||||
<path
|
||||
style="mix-blend-mode:normal;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:2, 2;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker32724-97)"
|
||||
d="m 356.93917,210.7796 65.19725,40.25153"
|
||||
id="path1809-0-6" />
|
||||
<path
|
||||
style="mix-blend-mode:normal;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:2, 2;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker32724-3)"
|
||||
d="m 619.41079,210.7796 -65.19725,40.25153"
|
||||
id="path1809-0-59" />
|
||||
<path
|
||||
style="mix-blend-mode:normal;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:2, 2;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker32724-3-2)"
|
||||
d="m 813.90671,210.7796 -65.19725,40.25153"
|
||||
id="path1809-0-59-8" />
|
||||
<g
|
||||
id="g18870"
|
||||
transform="translate(-155.99885,-105.40214)">
|
||||
<g
|
||||
id="g28235"
|
||||
style="stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none">
|
||||
<g
|
||||
id="g3104"
|
||||
transform="translate(57.106751,132.51159)"
|
||||
style="stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none">
|
||||
<rect
|
||||
style="fill:#18ffb2;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="rect2468"
|
||||
width="376.05222"
|
||||
height="185.83325"
|
||||
x="404.45572"
|
||||
y="489.5585"
|
||||
ry="0" />
|
||||
<g
|
||||
id="g84315"
|
||||
transform="translate(-0.51935474,6.1523713)"
|
||||
style="stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none">
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:15.875px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
x="592.87457"
|
||||
y="620.01123"
|
||||
id="text835-3-7"><tspan
|
||||
sodipodi:role="line"
|
||||
x="592.87457"
|
||||
y="620.01123"
|
||||
style="font-size:15.875px;text-align:center;text-anchor:middle;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
id="tspan1097">Substrate's module for smart contracts</tspan></text>
|
||||
<g
|
||||
id="g4054"
|
||||
style="stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
transform="translate(19.524257,10.054167)">
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:25.4px;line-height:1.25;font-family:monospace;-inkscape-font-specification:monospace;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
x="474.41205"
|
||||
y="566.8855"
|
||||
id="text1975-0-1"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan1973-9-7"
|
||||
x="474.41205"
|
||||
y="566.8855"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:25.4px;font-family:monospace;-inkscape-font-specification:monospace;fill:#000000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none">pallet-contracts</tspan></text>
|
||||
<image
|
||||
clip-path="url(#ga18cbd6cb1_1_0.4-6-3)"
|
||||
fill="#000000"
|
||||
width="512"
|
||||
height="512"
|
||||
x="0"
|
||||
y="0"
|
||||
preserveAspectRatio="none"
|
||||
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AAB3AklEQVR42uydB3hVVfbFgwUBHQgtSFMEpSiEphIUIUCoIgRQQIqGIthQio4KEkOVUaSIQbBAFAsYmhTFhkHsIk0RFRkDip0RFbDP+bPOcPN/vLxy33v3nHvue2t/3/5mbOS+m+Tu391n77WShBBJTCaTyWQyEyt5E5hMJpPJJAAwmUwmk8kkADCZTCaTySQAMJlMJpPJJAAwmUwmk8kkADCZTCaTySQAMJlMJpPJJAAwmUwmk8kkADCZTCaTyfQCADAYmqPJ0Uz3WA47mqN8spsHPwOTGa/Zz+/30zetfyc5Hh6eBACGF6LW0cw8mjlHs+BobsPPLpPJZLqcB489k/KOPZ88BQcEAIapBR+0verYLxgfNEwm00u57RgUZJoMBAQAhklFP4dv90wmMw4TLzNZpsEAAYDhZiQf+6Vg0WcymYmSeceOCggAjIQt/Dls7zOZzATOwmMvQAQABgs/k8lkEgQIAAwWfiaTyUw0EEgnADDiKTKP/WDzF5zJZDLDZ0HS/4aiCQAMT7/1r+IvM5PJZEalLzCKAMDw6ls/2/1MJpNpcDeAAMBwOmbzl5bJZDId7QZkEgAYprf8uc/PZDKZajKHAMAwMWDIU8hfUCaTyVQuIpRMAGCYVPx53s9kMpn6fAaSCQAMtyOLxZ/JZDK9CQEEAEYsxZ+/iEwmk+lRCCAAMKJt+/MXkMlkMj0MAQQABs/8mUwmMwEhgADAiCRqsfgzmUymkdsBBACGsuCeP5PJZMaRTgABgGE38vgLxmQymUZnppcBAC3mVay1xkWWST/ktWvXFpmZmWL48OHiX//6l3jsscfE888/z2QyPZL4nS1Tpowxz5RTTz1VnHnmmaJ+/frioosuktmtW7eAaf1z/Lv4b/DfGvR8PJgUgXeAaQBg6cjPZs3lub+VeFBkZGSI7OxskZ+fLx8gDAbDm4Hf39TUVNeLZfny5UXDhg3lswWFfe3atVEl/lv8Gfiz8GcaAAEFXgUA30KTxdprRBS49YOckpIixowZI4s+g8GIj0Dnzq1nSsmSJUWdOnViLvrhYABfA1/LRQgY5TUAyAzwIdJZf12NUW4Vfrzt802fwYivcKv1j2KMln3nzp0dL/rBEl8LX9MlELB1FGASAKwK8iGasA67NvWvtfWPBwPe+Fn4GQy2/p1KvI3rLPyBQADXYOJRgCkAUCvEhyhMctD9iGHm1H9aWhpb/QxGHAcGdnUP9lnDfG4Vf9+jAVyLCwOD6V4AgJyk8EpHDH2hVeqXb/0MRvy//eNoT9czBdP5br71h+oG4No0Pl8LvQAAhTY+SB7rcnwN/qHln5uby+LPYMR5APJ1FT1M45vw1h+qG4Br1AgBWSYDQGYEHySHtVl5pCdp2uXHQBCDweDbv1PZtGlTo4u/LwTgWt3uApgAAKucohmGN97+Ufx53s9g8O0/EYu/SxCQZSIA1Iryw3AzQE3UStLQ9mfxZzD49p/Ixd8FCCg0EQBykjTIHTLMmPy3zvwZDEZihI7Jf9PP/A2aCUg3DQAKY/gwUXsgMwKG8r1/iPswGIzEefuHKp7qaX8vF39fCNCwHZBnEgA4MWxWwLrtWGSp/OGDeQ+n/RmMxAkc9ane8zdx1S+WFUENOgHJpgBAniqqYUQVq5IUSvvy3J/BSKxQPfwHYZ14Kf5W4jPpHAZ0CwCSHf5Qo1i/Y27/K/uhwzkgg8FIrPY/1D2TFMr7xkPrP9BRgGLZ4FUmAMCoJI1iBwz32v94CLD1z2Cw/e9Uwlwnnlr/gY4CFBsIJbsNAIVJmhWPGO5M/1Psh8FIvMDAr6pnChz24rX4W4nPqBAAMt0EAJU683QPjC6UTP9jAphv/wxG4oWq6f94f/vX1AXIcxMAZiseciAERBbKgIw7/wxG4gWgH2qfqs7+4734W6lwFmCbmwCgw2OeEGA/VMxjyAcA3/4ZjMQLlef/6CwkCgAo1lBIdgMAMpP06B4TAlw+/x8+fDifhAxGAoYq9b/y5cvH5eR/qI0AfOYkhaqAugEgTyMAEALsRQGH/xgMhlPRv39/ZZK/iVL8rVQoEZzjBgAc1AwAhIDwwfY/g8FwLFS1rhOp/a/hGCBPNwCku1D8CQGho1aSItlfBoORmJGamqpE9jeR2v++xwCK5IELdAPAbBcBwIKATNZ89VBG0x8GIzEDnT+4fjr9TIFRTqIVfysVmQQd1A0AhS4DAMWCNA1l8vyfwUhcAKD4j2dEgbQBQC1Dij+9A46PHBX3l+f/DEZihqoVwHg0/jHAIChZFwCMMgwA6CKoCAA4AMhgJG6oWgEkAKhZBdQFAKsMBABrECKZAOBcYgCIwWAQAJzMRBwA9B0E9DoAHDQUACxZxCYEAAIAg8EgABAAnAWAJgYX/0TfEJhNAGAwGAQAAoAqABjlAQA4Th2JABB9QgWMwWAQAAgABACTz/85F6DgCIAAwGAQAAgABADT9v8jycIEmQsgADAYDAIAAUAJANTyYPFPpCMBAgCDwSAAEACUAECmxwHAOhKoRQAgADAYDAIAAcA+AOTEAQBYWwJZBAACAIPBIAAQAOwBQEGcAICVq+JsQJAAwGAwCAAEACUAcDDOACDeNAMIAAwGgwBAAHAcAJLjsPjH22wAAYDBYBAACACOA0C6ioveWenywzmnNfu1b6napnQDcsTpw5K8mEdjAwGAwWAQAELmf4/m7wSAyADAcQVAFP1fqwz+62jxEnPKtjxsCARYfgLpHgSAAgIAg8EwHQDgiOdWXnjhhb+ee+65+9LS0v5w6xq8CAA5KgAAxd/K5ckZhwyCAGtIsBYBgMFgEACYhqdSAHC8uKD17wsAyHcq9jANAg4eg59kAgCDwSAAMBMRALY5fcGLyrU+5A8AyL2V+8mZAMNAAHLCWYYDQB4BgMFgEAAIAE4DgOMXjLf9QABg5ZDSdf82DAKMng/gFgCDwSAAEACcBgAlHgAHUgb9HgoAkAZtCARaG0wnADAYDAIAM54BIF3FAKC1ARAuDRwONBIECAAMBoMAQABwGgAyVQCAneJvJfQCDJwLMAoECAAMBoMAQABwGgBy3AYAK0ef2vB3gyHAVRA4GlMJAAwGgwBAADAaAAKtANpNbA8YDgGugMDRmE4AYDAYTgV+/1lYCQCrnL5YKP9FCwAeORLwBYEsTQAwgwDAYDCcCoWytUwPAYDjAjMY7IsFADywJRBQR0CloNDRmEkAYDAYBAACgNEAEE4DIJJ8qUKXQx6BAF9lwVoEAAaDQQBgmg4AB00GACRWCg0VDgqVeU7OCRAAGAyGk3H77bezsHonk1UBgCsiQHE8IBhIXTDm4wECAIPBcDK4BeCpGmK/rrsNAHZFgKLtBnhgXTDY8cDsaI8HjsZ9BAAGg0EASLgcRQDw9mxAzNsDR+NeAgDDyfjtt9/EU08+Jdq2SRf/vPVW8fPPP/OmEACY5r04JqsCAMd9ACKRAXaiG+ChTYGYugJH4x4CAMOp2LRpkxg0cJDomNFB5OXliV9++YU3hQDANC+zit7UFQCAEh8AHcXfXzfAg0OCEXUFKATEcCL27Nkj3/YvadVKTJo4Sezfv583hQDANHeQPIkAYDMNNxaKqStwNKYRABjRxg8//CByH8iVb/wjhg8XW7ds5U0hALDImpuzk/yCAJAYxwIBNwiO5hQCACPS+OOPP8TqZ58V3S/rLnpmZop169aJv//+mzeGQQAwV1QuPSlAEAAiyL2V+/3q0W2BUDBAAGDYDrzlDxk8WLRLbyvmPzhf/Pjjj7wpDAKAmce/ecEKPwEghoQoURzMByhJAkB8RmFhoci+c4Jo07q1GHfHHfLcn8HQCAAMBUEAcGBtkCBAAIjX+Omnn8TDDz0kOrTPEIOzBos333yTN4VBACAAEAD8BwUJAgSAeAmc6b/4wovyjP/SrpeK5cuWid9//503hkEAIAAQAAgCBIB4jfc3vy+uv/Y6ec4/e/ZsceDAAd4UBgGAAEAAIAgQAOI1vvnmGzH97rtF60suEbfecovYtWsXbwqDAEAAIAAQBAgA8RpQ7IN8b5dOncWAK/tLRT8T4+uvvxYff/yxlBtmEAAYBACCgAF50kkniVKlSsn/HThwIJ+CHooNr2wQfa/oI8V8AAFHjhwx7hqhO5D/TL64qOVFonnTZuLDDz/kN44AwCAAeCsTYX2wc+fOYsyYMSI/P59PQ4Pjs88+E6NHjZbyvfccfWh/9dVXRl7nW2+9Ja7s208kly0nWrZIE4sXLxb/+c9/+A0kADAIAN4FgTgTFCqWZcqUERkZGSI3N1c8//zzfDIa1EafNXOmaN+2nRh5w41ix/btRl4ndAegN1Czeg1R9+xzJKTg2hlmx8SJEwkABAACgF1lwTiSGA6aKSkpYvjw4bIrQBhwJ/7880+x5Okl4rJul4nevXqJV15+xUj53oMHD4oH5z0oGjdKFSmVKoubRt4kPvzgA34DPRL4PScAEAAIABF6DSwq1zohBgbZFdAf77zzjsi6Okt06tBRLHz0USNtegEo8BfALEK5f5SV2gMvvfgSv3kEAAKAxwAgSQUAoEjGMwT4qgsmgsxwamqqnBUgCKgLTMyPHzdOrvVBxnff3n1GXqflL1CpQkXR4oILRV5enlQgZBAACAAEAJmJAgCBjgfiGQZ8jwcYzrXR594/V2S0ay+uGTZMCvuYGACS7AnZoka16uKMGjXFpImTxP79+/kN9HCMGjWKAEAAIABwjTDyoUFoCDz22GPsCkQZkOpds2aN6NG9u8js0UP+fxPP+Q8fPizyFi0SzZo0lW/9w4YOFe+++y6/gXEQ3AIgACgBALwRJyoAWLmz0uWH4317wJoTIAhEFiigeNuHfG/uA7lG2vTinB/Dh5hFwFofDIbgN4A9fwYBgAAQPwBQ6PQPAFbnEhLine truncated
|
||||
id="image3361"
|
||||
transform="matrix(0.08465155,0,0,0.08465645,429.03528,538.77455)"
|
||||
style="stroke-width:11.8127909;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<rect
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#00000f;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:10;stroke-opacity:1"
|
||||
id="rect859"
|
||||
width="326.8931"
|
||||
height="92.220352"
|
||||
x="486.14203"
|
||||
y="575.13098"
|
||||
ry="27.279261" />
|
||||
<path
|
||||
style="fill:#000000;stroke:#000000;stroke-width:1.715;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1.715, 1.715;stroke-dashoffset:0;stroke-opacity:1;marker-start:url(#marker7726);marker-end:url(#marker32724)"
|
||||
d="M 642.70694,491.17751 V 567.7991"
|
||||
id="path1809-0-5" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:14.1111px;line-height:0;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
|
||||
x="649.55072"
|
||||
y="591.22406"
|
||||
id="text835-0-9"><tspan
|
||||
sodipodi:role="line"
|
||||
x="649.55072"
|
||||
y="591.22406"
|
||||
style="font-size:14.1111px;line-height:1.25;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke-width:0.264583"
|
||||
id="tspan1075-9" /><tspan
|
||||
sodipodi:role="line"
|
||||
x="649.55072"
|
||||
y="617.64673"
|
||||
style="font-size:15.875px;line-height:0.72;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke-width:0.264583"
|
||||
id="tspan2428">The WebAssembly blob targets</tspan><tspan
|
||||
sodipodi:role="line"
|
||||
x="649.55072"
|
||||
y="640.50671"
|
||||
style="font-size:15.875px;line-height:0.72;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke-width:0.264583"
|
||||
id="tspan2430">an API exposed by Substrate's</tspan><tspan
|
||||
sodipodi:role="line"
|
||||
x="649.55072"
|
||||
y="651.93671"
|
||||
style="font-size:15.875px;line-height:0.72;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke-width:0.264583"
|
||||
id="tspan2432">contracts module.</tspan></text>
|
||||
<g
|
||||
id="g1342">
|
||||
<g
|
||||
id="g37555"
|
||||
transform="translate(177.66064,94.365491)">
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:15.875px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.264583"
|
||||
x="177.42126"
|
||||
y="689.06769"
|
||||
id="text1087"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan1085"
|
||||
x="177.42126"
|
||||
y="689.06769"
|
||||
style="font-size:15.875px;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583" /><tspan
|
||||
sodipodi:role="line"
|
||||
x="177.42126"
|
||||
y="708.91144"
|
||||
style="font-size:15.875px;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
|
||||
id="tspan2399">Blockchain-Framework</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
id="g30494"
|
||||
transform="matrix(1.3732612,0,0,1.3732612,276.72012,1009.2471)">
|
||||
<path
|
||||
d="m 8.2218148,-178.09322 a 4.3841458,4.3841458 0 0 1 1.5160625,2.667 h -3.048 a 1.7039166,1.7039166 0 0 0 -0.6006041,-1.02129 1.8335625,1.8335625 0 0 0 -1.1721042,-0.37042 1.2832292,1.2832292 0 0 0 -0.8387291,0.23812 0.83079166,0.83079166 0 0 0 -0.28575,0.67734 0.79374999,0.79374999 0 0 0 0.5291666,0.74083 8.3476041,8.3476041 0 0 0 1.6483542,0.49742 16.644937,16.644937 0 0 1 2.00025,0.57944 3.3125833,3.3125833 0 0 1 1.3520208,0.96308 2.6458333,2.6458333 0 0 1 0.5662083,1.79652 2.746375,2.746375 0 0 1 -0.4947708,1.61925 3.2808333,3.2808333 0 0 1 -1.42875,1.10331 5.5747708,5.5747708 0 0 1 -2.2119166,0.39423 q -2.1563542,0 -3.4395833,-0.9525 a 4.0137291,4.0137291 0 0 1 -1.58750002,-2.72256 H 3.869419 a 1.4049375,1.4049375 0 0 0 0.5820834,1.05833 2.1854583,2.1854583 0 0 0 1.30175,0.3519 1.2144375,1.2144375 0 0 0 0.8387291,-0.26459 0.86254166,0.86254166 0 0 0 0.28575,-0.67468 0.81491666,0.81491666 0 0 0 -0.5291667,-0.79375 9.5752707,9.5752707 0 0 0 -1.7065624,-0.50536 13.554604,13.554604 0 0 1 -1.9420417,-0.52916 3.20675,3.20675 0 0 1 -1.3229166,-0.92605 2.5691041,2.5691041 0 0 1 -0.53710419,-1.73566 2.8442708,2.8442708 0 0 1 1.08743749,-2.30188 q 1.0821458,-0.88371 3.0665208,-0.88635 1.984375,-0.003 3.2279166,0.99748 z"
|
||||
id="path28110"
|
||||
style="stroke-width:0.264583" />
|
||||
<path
|
||||
d="m 22.519898,-178.97164 v 10.63096 h -3.272896 v -1.92617 a 3.52425,3.52425 0 0 1 -1.362604,1.48432 3.937,3.937 0 0 1 -2.103437,0.55297 q -1.828271,0 -2.910417,-1.21972 -1.082146,-1.21973 -1.076854,-3.34963 v -6.17273 h 3.2385 v 5.77321 a 2.3627291,2.3627291 0 0 0 0.563562,1.6854 1.9737916,1.9737916 0 0 0 1.513417,0.6006 1.9976041,1.9976041 0 0 0 1.561042,-0.62971 c 0.381,-0.41804 0.576791,-1.016 0.576791,-1.78858 v -5.64092 z"
|
||||
id="path28112"
|
||||
style="stroke-width:0.264583" />
|
||||
<path
|
||||
d="m 34.166856,-178.44776 a 4.5376041,4.5376041 0 0 1 1.640417,1.88648 6.5669583,6.5669583 0 0 1 0.597958,2.91041 6.5801874,6.5801874 0 0 1 -0.597958,2.91042 4.5111458,4.5111458 0 0 1 -1.640417,1.89442 4.2915416,4.2915416 0 0 1 -2.352146,0.65616 3.8549791,3.8549791 0 0 1 -2.0955,-0.55033 3.2173333,3.2173333 0 0 1 -1.275291,-1.52665 v 1.92352 h -3.257021 v -14.09435 h 3.257021 v 5.39221 a 3.2041041,3.2041041 0 0 1 1.275291,-1.50548 3.8549791,3.8549791 0 0 1 2.0955,-0.55298 4.3127083,4.3127083 0 0 1 2.352146,0.65617 z m -5.085291,2.88925 a 2.6458333,2.6458333 0 0 0 -0.656167,1.89441 2.6458333,2.6458333 0 0 0 0.656167,1.88648 2.38125,2.38125 0 0 0 3.370791,0.0185 2.6881666,2.6881666 0 0 0 0.640292,-1.905 2.6881666,2.6881666 0 0 0 -0.640292,-1.905 2.1881041,2.1881041 0 0 0 -1.685396,-0.68527 2.2198541,2.2198541 0 0 0 -1.685395,0.69586 z"
|
||||
id="path28114"
|
||||
style="stroke-width:0.264583" />
|
||||
<path
|
||||
d="m 45.311106,-178.09322 a 4.3841458,4.3841458 0 0 1 1.516062,2.667 h -3.047999 a 1.6906875,1.6906875 0 0 0 -0.600605,-1.02129 1.8335625,1.8335625 0 0 0 -1.172104,-0.37042 1.2832292,1.2832292 0 0 0 -0.838729,0.23812 0.83079166,0.83079166 0 0 0 -0.28575,0.67734 0.79374999,0.79374999 0 0 0 0.529167,0.74083 8.3476041,8.3476041 0 0 0 1.648354,0.49742 16.644937,16.644937 0 0 1 2.00025,0.57944 3.3125833,3.3125833 0 0 1 1.352021,0.96308 2.6458333,2.6458333 0 0 1 0.566208,1.79652 2.746375,2.746375 0 0 1 -0.494771,1.61925 3.2808333,3.2808333 0 0 1 -1.42875,1.10331 5.5562499,5.5562499 0 0 1 -2.209271,0.39952 q -2.151062,0 -3.439583,-0.9525 a 4.0137291,4.0137291 0 0 1 -1.5875,-2.72256 h 3.14325 a 1.412875,1.412875 0 0 0 0.582083,1.05833 2.1854583,2.1854583 0 0 0 1.304396,0.36248 1.2144375,1.2144375 0 0 0 0.838729,-0.26458 0.86254166,0.86254166 0 0 0 0.28575,-0.67469 0.81491666,0.81491666 0 0 0 -0.529166,-0.79375 9.5752707,9.5752707 0 0 0 -1.706563,-0.51329 13.554604,13.554604 0 0 1 -1.942041,-0.52917 3.20675,3.20675 0 0 1 -1.322917,-0.92604 2.5691041,2.5691041 0 0 1 -0.552979,-1.74096 2.8442708,2.8442708 0 0 1 1.098021,-2.30452 q 1.082145,-0.88371 3.06652,-0.88635 1.984375,-0.003 3.227917,0.99748 z"
|
||||
id="path28116"
|
||||
style="stroke-width:0.264583" />
|
||||
<path
|
||||
d="m 55.074231,-171.13997 v 2.79929 h -1.465792 c -1.243541,0 -2.214562,-0.30692 -2.910416,-0.9234 -0.695855,-0.61648 -1.023938,-1.63512 -1.023938,-3.05858 v -3.90525 h -1.426104 v -2.74373 h 1.426104 v -2.60879 h 3.259667 v 2.60879 h 2.132541 v 2.74373 h -2.132541 v 3.96875 a 1.190625,1.190625 0 0 0 0.264583,0.87577 1.2356042,1.2356042 0 0 0 0.867833,0.24871 z"
|
||||
id="path28118"
|
||||
style="stroke-width:0.264583" />
|
||||
<path
|
||||
d="m 62.342335,-178.51391 a 4.0057916,4.0057916 0 0 1 2.084917,-0.5715 v 3.48721 h -0.931334 c -0.865187,0 -1.534583,0.18256 -2.010833,0.55298 -0.47625,0.37041 -0.714375,0.98954 -0.714375,1.86531 v 4.83923 h -3.257021 v -10.63096 h 3.257021 v 2.00025 a 4.6593124,4.6593124 0 0 1 1.571625,-1.54252 z"
|
||||
id="path28120"
|
||||
style="stroke-width:0.264583" />
|
||||
<path
|
||||
d="m 71.973168,-178.55095 a 3.3205208,3.3205208 0 0 1 1.293813,1.50548 v -1.92617 h 3.2385 v 10.63096 h -3.2385 v -1.92617 a 3.33375,3.33375 0 0 1 -1.293813,1.50548 3.8549791,3.8549791 0 0 1 -2.0955,0.55034 4.2994791,4.2994791 0 0 1 -2.354791,-0.65617 4.4979166,4.4979166 0 0 1 -1.637771,-1.89442 6.5801874,6.5801874 0 0 1 -0.600604,-2.91041 6.5669583,6.5669583 0 0 1 0.600604,-2.91042 4.5323124,4.5323124 0 0 1 1.637771,-1.88648 4.3232916,4.3232916 0 0 1 2.354791,-0.65617 3.8549791,3.8549791 0 0 1 2.0955,0.57415 z m -2.735791,2.99244 a 2.69875,2.69875 0 0 0 -0.637646,1.905 2.69875,2.69875 0 0 0 0.637646,1.905 2.3944791,2.3944791 0 0 0 3.373437,-0.0185 2.6617083,2.6617083 0 0 0 0.656167,-1.88648 2.6458333,2.6458333 0 0 0 -0.656167,-1.905 2.2198541,2.2198541 0 0 0 -1.685396,-0.69586 2.1986875,2.1986875 0 0 0 -1.688041,0.69586 z"
|
||||
id="path28122"
|
||||
style="stroke-width:0.264583" />
|
||||
<path
|
||||
d="m 85.077981,-171.13997 v 2.79929 h -1.465792 q -1.867958,0 -2.910417,-0.9234 -1.042458,-0.92339 -1.039812,-3.05858 v -3.90525 h -1.412875 v -2.74373 h 1.42875 v -2.60879 h 3.259666 v 2.60879 h 2.132542 v 2.74373 h -2.132542 v 3.96875 a 1.190625,1.190625 0 0 0 0.264584,0.87577 1.2329583,1.2329583 0 0 0 0.865187,0.24871 z"
|
||||
id="path28124"
|
||||
style="stroke-width:0.264583" />
|
||||
<path
|
||||
d="M 97.098001,-173.06614 H 89.72671 q 0.05556,1.20386 0.608541,1.72508 a 1.9658541,1.9658541 0 0 0 1.410229,0.52917 1.93675,1.93675 0 0 0 1.201209,-0.36248 1.68275,1.68275 0 0 0 0.627062,-0.94456 h 3.439584 a 4.4979166,4.4979166 0 0 1 -0.912813,2.01083 4.9053749,4.9053749 0 0 1 -1.791229,1.39171 6.1303958,6.1303958 0 0 1 -5.191125,-0.15346 4.6804791,4.6804791 0 0 1 -1.87325,-1.88912 5.8790416,5.8790416 0 0 1 -0.687917,-2.91042 5.9531249,5.9531249 0 0 1 0.677334,-2.91042 4.6460833,4.6460833 0 0 1 1.894416,-1.88647 6.2600416,6.2600416 0 0 1 5.55625,0 4.5852291,4.5852291 0 0 1 1.852084,1.81768 5.4398333,5.4398333 0 0 1 0.656166,2.69611 4.4979166,4.4979166 0 0 1 -0.09525,0.88635 z m -3.767666,-2.94217 a 2.06375,2.06375 0 0 0 -1.436688,-0.52916 2.1166666,2.1166666 0 0 0 -1.486958,0.52916 2.2251458,2.2251458 0 0 0 -0.66675,1.56105 h 4.153958 c 0.01588,-0.68792 -0.169333,-1.2118 -0.563562,-1.56105 z"
|
||||
id="path28126"
|
||||
style="stroke-width:0.264583" />
|
||||
<path
|
||||
class="cls-1"
|
||||
d="m 111.78502,-170.24303 v 3.175 H 99.995189 v -3.175 z"
|
||||
id="path28128"
|
||||
style="fill:#18ffb2;stroke-width:0.264583" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
id="g38048"
|
||||
transform="translate(-58.664253)">
|
||||
<g
|
||||
style="clip-rule:evenodd;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421"
|
||||
id="g1956"
|
||||
transform="matrix(0.04069094,0,0,0.04069094,170.72405,85.326523)">
|
||||
<g
|
||||
id="g1942"
|
||||
style="fill:#000000;fill-opacity:1">
|
||||
<path
|
||||
id="inc"
|
||||
d="m 1811.78,748.385 c -50.595,18.311 -78.758,71.865 -62.852,119.517 15.906,47.653 69.897,71.474 120.492,53.164 50.595,-18.311 78.758,-71.865 62.852,-119.518 -15.906,-47.652 -69.897,-71.474 -120.492,-53.163 z M 160.58,264.179 c 13.209,0.001 19.813,6.605 19.813,19.814 v 620.821 c 0,13.209 -6.604,19.813 -19.813,19.814 H 29.811 c -13.209,0 -19.814,-6.605 -19.814,-19.814 V 283.993 c 0,-13.209 6.605,-19.813 19.814,-19.814 z m 537.605,-5.283 c 143.978,0 194.171,97.746 194.171,232.478 v 413.44 c 0,13.209 -6.604,19.813 -19.813,19.814 H 741.774 c -13.209,0 -19.813,-6.605 -19.813,-19.814 V 471.56 c 0,-44.91 -33.022,-60.761 -71.329,-60.761 h -15.85 c -56.799,0 -97.747,23.776 -112.277,47.552 v 446.463 c 0,13.209 -6.604,19.813 -19.813,19.814 H 371.923 c -13.209,0 -19.813,-6.605 -19.813,-19.814 V 283.993 c 0,-13.209 6.604,-19.813 19.813,-19.814 h 130.769 c 13.209,0.001 19.813,6.605 19.813,19.814 v 58.119 c 19.814,-33.022 70.008,-83.216 167.754,-83.216 z M 1201.446,0 c 13.21,0 19.814,6.605 19.814,19.813 V 478.165 L 1408.827,280.03 c 7.925,-9.246 19.813,-15.85 30.381,-15.851 h 136.052 c 17.173,0.001 33.022,19.814 9.246,44.911 l -196.813,211.343 229.836,368.53 c 7.925,14.53 6.604,35.664 -15.851,35.665 h -124.164 c -17.172,0 -33.023,-5.284 -43.59,-23.776 L 1272.775,634.03 1221.26,685.545 v 219.269 c 0,13.209 -6.604,19.813 -19.814,19.814 h -130.768 c -13.209,0 -19.814,-6.605 -19.814,-19.814 V 19.813 C 1050.864,6.605 1057.468,0 1070.678,0 Z M 69.566,31.383 C 19.982,46.375 -9.857,96.406 2.975,143.038 15.808,189.669 66.482,215.357 116.067,200.364 165.652,185.372 195.49,135.341 182.658,88.71 169.826,42.078 119.151,16.391 69.566,31.383 Z"
|
||||
style="fill:#000000;fill-opacity:1" />
|
||||
<path
|
||||
d="m 1795.61,594.617 -28.783,-0.213 c -13.209,0 -19.813,-6.605 -19.813,-19.814 V 19.813 C 1747.014,6.605 1753.618,0 1766.827,0 h 134.732 c 13.209,0 19.813,6.605 19.813,19.813 l -0.081,18.721 c -51.238,12.482 -91.137,64.695 -94.329,129.8 -2.564,52.29 19.2,99.658 53.607,126.46 -25.633,17.438 -44.472,46.887 -49.193,82.159 -5.141,38.403 7.648,74.783 31.364,98.837 -23.939,10.508 -45.741,31.983 -58.147,60.301 -8.77,20.019 -11.509,40.408 -8.983,58.526 z"
|
||||
style="fill:#000000;fill-opacity:1"
|
||||
id="path1938" />
|
||||
<path
|
||||
d="m 1837.23,549.753 c -9.822,22.417 -2.309,46.088 16.766,52.827 19.074,6.738 42.534,-5.992 52.356,-28.41 9.821,-22.418 2.308,-46.089 -16.766,-52.827 -19.075,-6.739 -42.535,5.992 -52.356,28.41 z m 35.572,-164.125 c -6.558,34.707 11.744,67.29 40.844,72.716 29.1,5.426 58.05,-18.347 64.607,-53.054 6.558,-34.707 -11.744,-67.29 -40.844,-72.716 -29.1,-5.425 -58.05,18.347 -64.607,53.054 z m -7.312,-204.559 c -2.328,47.49 28.18,88.336 68.085,91.158 39.905,2.821 74.194,-33.443 76.522,-80.933 2.329,-47.49 -28.179,-88.336 -68.084,-91.158 -39.906,-2.821 -74.194,33.444 -76.523,80.933 z"
|
||||
style="fill:#000000;fill-opacity:1"
|
||||
id="path1940" />
|
||||
</g>
|
||||
</g>
|
||||
<image
|
||||
preserveAspectRatio="none"
|
||||
inkscape:svg-dpi="96"
|
||||
width="75.484314"
|
||||
height="75.484314"
|
||||
xlink:href="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iOTBweCIg aGVpZ2h0PSI5MHB4IiB2aWV3Qm94PSIwIDAgMTEyIDExMiIgdmVyc2lvbj0iMS4xIiB4bWxucz0i aHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9y Zy8xOTk5L3hsaW5rIj4KICAgIDx0aXRsZT5Bc2shPC90aXRsZT4KICAgIDxnIGlkPSLpobXpnaIt MSIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0i ZXZlbm9kZCI+CiAgICAgICAgPGcgaWQ9IlByb2R1Y3RzIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgt NDc4LjAwMDAwMCwgLTE5NDUuMDAwMDAwKSI+CiAgICAgICAgICAgIDxnIGlkPSJBc2shIiB0cmFu c2Zvcm09InRyYW5zbGF0ZSg0NzguMDAwMDAwLCAxOTQ1LjAwMDAwMCkiPgogICAgICAgICAgICAg ICAgPHJlY3QgaWQ9IuefqeW9oiIgeD0iMCIgeT0iMCIgd2lkdGg9IjExMiIgaGVpZ2h0PSIxMTIi PjwvcmVjdD4KICAgICAgICAgICAgICAgIDxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDcuMDAwMDAw LCAxMS4wMDAwMDApIiBmaWxsLXJ1bGU9Im5vbnplcm8iIGlkPSLotYTmupAtNyI+CiAgICAgICAg ICAgICAgICAgICAgPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMC4wMDAwMDAsIDAuMDAwMDAwKSI+ CiAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0yMC4yNjIxNjMsMTEuNjAzMDE1NyBM NTYuMDIyMzU5NSwxMS42MDMwMTU3IEM1OS41NTY5ODE5LDExLjYwMzAxNTcgNjIuNDIyMzU5NSwx NC40NjgzOTMzIDYyLjQyMjM1OTUsMTguMDAzMDE1NyBMNjIuNDIyMzU5NSw3MS4zMTIxMDY2IEM2 Mi40MjIzNTk1LDc0Ljg0NjcyOSA1OS41NTY5ODE5LDc3LjcxMjEwNjYgNTYuMDIyMzU5NSw3Ny43 MTIxMDY2IEwyMC4yNjIxNjMsNzcuNzEyMTA2NiBDMTYuNzI3NTQwNiw3Ny43MTIxMDY2IDEzLjg2 MjE2Myw3NC44NDY3MjkgMTMuODYyMTYzLDcxLjMxMjEwNjYgTDEzLjg2MjE2MywxOC4wMDMwMTU3 IEMxMy44NjIxNjMsMTQuNDY4MzkzMyAxNi43Mjc1NDA2LDExLjYwMzAxNTcgMjAuMjYyMTYzLDEx LjYwMzAxNTcgWiIgaWQ9IuefqeW9oiIgc3Ryb2tlPSIjMDAwMDcyIiBzdHJva2Utd2lkdGg9IjIi IGZpbGw9IiNGRkZGRkYiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDM4LjE0MjI2MSwgNDQuNjU3NTYx KSByb3RhdGUoLTMwLjAwMDAwMCkgdHJhbnNsYXRlKC0zOC4xNDIyNjEsIC00NC42NTc1NjEpICI+ PC9wYXRoPgogICAgICAgICAgICAgICAgICAgICAgICA8bGluZSB4MT0iMTcuMzM2NjA5MyIgeTE9 IjQyLjk4NzcxNSIgeDI9IjQ0LjkzMzY2MDkiIHkyPSIyNy4wNjYzMzkxIiBpZD0i6Lev5b6EIiBz dHJva2U9IiMwMDAwNzIiIHN0cm9rZS13aWR0aD0iMiIgZmlsbD0iIzAwRkZGRiIgc3Ryb2tlLWxp bmVjYXA9InJvdW5kIj48L2xpbmU+CiAgICAgICAgICAgICAgICAgICAgICAgIDxsaW5lIHgxPSIy My4wODU5OTUxIiB5MT0iNTIuOTgyODAxIiB4Mj0iNTAuNjgzMDQ2NyIgeTI9IjM3LjA2MTQyNTEi IGlkPSLot6/lvoQiIHN0cm9rZT0iIzAwMDA3MiIgc3Ryb2tlLXdpZHRoPSIyIiBmaWxsPSIjMDBG RkZGIiBzdHJva2UtbGluZWNhcD0icm91bmQiPjwvbGluZT4KICAgICAgICAgICAgICAgICAgICAg ICAgPGxpbmUgeDE9IjI4LjgzNTM4MDgiIHkxPSI2Mi44ODk0MzQ5IiB4Mj0iNTYuNDMyNDMyNCIg eTI9IjQ2Ljk2ODA1OSIgaWQ9Iui3r+W+hCIgc3Ryb2tlPSIjMDAwMDcyIiBzdHJva2Utd2lkdGg9 IjIiIGZpbGw9IiMwMEZGRkYiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCI+PC9saW5lPgogICAgICAg ICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMzQuNjAxNDg5Nyw5LjUyOTcyNDI3IEw3Ni45MDcx NDA4LDkuNTI5NzI0MjcgQzgwLjQ0MTc2MzIsOS41Mjk3MjQyNyA4My4zMDcxNDA4LDEyLjM5NTEw MTkgODMuMzA3MTQwOCwxNS45Mjk3MjQzIEw4My4zMDcxNDA4LDczLjIyODAwNDQgQzgzLjMwNzE0 MDgsNzYuNzYyNjI2OCA4MC40NDE3NjMyLDc5LjYyODAwNDQgNzYuOTA3MTQwOCw3OS42MjgwMDQ0 IEwzNC42MDE0ODk3LDc5LjYyODAwNDQgQzMxLjA2Njg2NzMsNzkuNjI4MDA0NCAyOC4yMDE0ODk3 LDc2Ljc2MjYyNjggMjguMjAxNDg5Nyw3My4yMjgwMDQ0IEwyOC4yMDE0ODk3LDE1LjkyOTcyNDMg QzI4LjIwMTQ4OTcsMTIuMzk1MTAxOSAzMS4wNjY4NjczLDkuNTI5NzI0MjcgMzQuNjAxNDg5Nyw5 LjUyOTcyNDI3IFoiIGlkPSLnn6nlvaIiIHN0cm9rZT0iIzAwMDA3MiIgc3Ryb2tlLXdpZHRoPSIy IiBmaWxsPSIjRkZGRkZGIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg1NS43NTQzMTUsIDQ0LjU3ODg2 NCkgcm90YXRlKC0zMC4wMDAwMDApIHRyYW5zbGF0ZSgtNTUuNzU0MzE1LCAtNDQuNTc4ODY0KSAi PjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICAgICAgPGNpcmNsZSBpZD0i5qSt5ZyG5b2iIiBm aWxsPSIjRkYxRTk3IiBjeD0iODMuMTQ0OTYzMSIgY3k9IjU4LjM3ODM3ODQiIHI9IjMuNTM4MDgz NTQiPjwvY2lyY2xlPgogICAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNNjEuMDE0NDU4 NCwzLjUwMDgwODY5IEM2Mi40MTkzNTQsMy44NzcyNDkzNiA2My42MTcxNjg0LDQuNzk2MzY0NjQg NjQuMzQ0Mzk1OSw2LjA1NTk1OTY2IEw5My41Nzc4MTEyLDU2LjY4OTcyMDEgQzk0LjIxMTIwMjks NTcuNzg2Nzg2OCA5NC4zODI4NDQ1LDU5LjA5MDUzNDMgOTQuMDU0OTc2OCw2MC4zMTQxNTMxIEM5 My43MjcxMDkxLDYxLjUzNzc3MTkgOTIuOTI2NTg5NCw2Mi41ODEwMjk2IDkxLjgyOTUyMjcsNjMu MjE0NDIxMyBMNTMuNzU4NDUwMiw4NS4xOTQ3NjUzIEM1Mi42NjEzODM2LDg1LjgyODE1NyA1MS4z NTc2MzYxLDg1Ljk5OTc5ODYgNTAuMTM0MDE3Miw4NS42NzE5MzEgQzQ4LjkxMDM5ODQsODUuMzQ0 MDYzMyA0Ny44NjcxNDA3LDg0LjU0MzU0MzUgNDcuMjMzNzQ5LDgzLjQ0NjQ3NjkgTDE4LjAwMDMz MzgsMzIuODEyNzE2NCBDMTYuNDg1OTYwOSwzMC4xODk3NDU2IDE3LjM4NDY1NywyNi44MzU3NjU4 IDIwLjAwNzYyNzksMjUuMzIxMzkyOCBMMjkuNjU2MDQxLDE5Ljc1MTAxIEMzMS4xOTU3NDk4LDIw LjY4ODQ5ODUgMzMuMDA0MTAwMiwyMS4yMjg1MDEyIDM0LjkzODU3NDksMjEuMjI4NTAxMiBDNDAu NTU2NDEsMjEuMjI4NTAxMiA0NS4xMTA1NjUxLDE2LjY3NDM0NjEgNDUuMTEwNTY1MSwxMS4wNTY1 MTExIEw0NS4xMDc2OTc0LDEwLjgyODkzMSBMNTYuODUzMDcyMyw0LjA0ODY2NTU2IEM1OC4xMTI2 Njc0LDMuMzIxNDM4MDMgNTkuNjA5NTYyNywzLjEyNDM2ODAzIDYxLjAxNDQ1ODQsMy41MDA4MDg2 OSBaIiBpZD0i5b2i54q257uT5ZCIIiBmaWxsPSIjMDA3QkQyIj48L3BhdGg+CiAgICAgICAgICAg ICAgICAgICAgICAgIDxnIGlkPSLnvJbnu4QiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDI0Ljc2NjU4 NSwgMC44ODQ1MjEpIiBmaWxsPSIjRkZGRkZGIj4KICAgICAgICAgICAgICAgICAgICAgICAgICAg IDxnIGlkPSJvN29JMW4iIHRyYW5zZm9ybT0idHJhbnNsYXRlKDExLjQ5ODc3MSwgMjIuOTk3NTQz KSI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTE0LjIxMjk4Njcs Ny44NDIwODQ5IEwxNC42MjAwMTAxLDcuODQyMDg0OSBMMjUuMTczNjczOCwzMS4xMjE0MDk2IEwy MC4xODUyNzU4LDMxLjEyMTLine truncated
|
||||
id="image3074"
|
||||
x="637.16882"
|
||||
y="66.449432" />
|
||||
<g
|
||||
id="Page-1"
|
||||
sketch:type="MSPage"
|
||||
transform="matrix(0.0688834,0,0,0.0688834,365.32312,60.801204)">
|
||||
<g
|
||||
id="solidity"
|
||||
transform="translate(402,118)"
|
||||
sketch:type="MSLayerGroup">
|
||||
<g
|
||||
id="Group"
|
||||
sketch:type="MSShapeGroup">
|
||||
<path
|
||||
id="Shape"
|
||||
opacity="0.45"
|
||||
enable-background="new "
|
||||
d="M 371.772,135.308 241.068,367.61 H -20.158 L 110.456,135.308 h 261.316" />
|
||||
<path
|
||||
id="Shape_1_"
|
||||
opacity="0.6"
|
||||
enable-background="new "
|
||||
d="M 241.068,367.61 H 502.386 L 371.772,135.308 H 110.456 Z" />
|
||||
<path
|
||||
id="Shape_2_"
|
||||
opacity="0.8"
|
||||
enable-background="new "
|
||||
d="M 110.456,599.822 241.068,367.61 110.456,135.308 -20.158,367.61 Z" />
|
||||
<path
|
||||
id="Shape_3_"
|
||||
opacity="0.45"
|
||||
enable-background="new "
|
||||
d="M 111.721,948.275 242.425,715.972 H 503.743 L 373.038,948.275 H 111.721" />
|
||||
<path
|
||||
id="Shape_4_"
|
||||
opacity="0.6"
|
||||
enable-background="new "
|
||||
d="M 242.424,715.973 H -18.893 L 111.72,948.276 h 261.317 z" />
|
||||
<path
|
||||
id="Shape_5_"
|
||||
opacity="0.8"
|
||||
enable-background="new "
|
||||
d="M 373.038,483.761 242.424,715.973 373.038,948.276 503.742,715.973 Z" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:15.875px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
|
||||
x="409.41479"
|
||||
y="169.30264"
|
||||
id="text835-5"><tspan
|
||||
sodipodi:role="line"
|
||||
x="409.41479"
|
||||
y="169.30264"
|
||||
style="font-size:15.875px;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke-width:0.264583"
|
||||
id="tspan1079-3">Solidity</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:15.875px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
|
||||
x="674.48651"
|
||||
y="169.30264"
|
||||
id="text835-5-5"><tspan
|
||||
sodipodi:role="line"
|
||||
x="674.48651"
|
||||
y="169.30264"
|
||||
style="font-size:15.875px;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke-width:0.264583"
|
||||
id="tspan1079-3-6">ask! Assembly Script eDSL</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:15.875px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
|
||||
x="215.62152"
|
||||
y="169.30264"
|
||||
id="text835"><tspan
|
||||
sodipodi:role="line"
|
||||
x="215.62152"
|
||||
y="169.30264"
|
||||
style="font-size:15.875px;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke-width:0.264583"
|
||||
id="tspan1079">Parity's Rust eDSL</tspan></text>
|
||||
<g
|
||||
id="g102807"
|
||||
transform="translate(0,6.3500003)">
|
||||
<circle
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="path51541"
|
||||
cx="864.93872"
|
||||
cy="109.19419"
|
||||
r="5.4990706" />
|
||||
<circle
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="path51541-1"
|
||||
cx="880.50763"
|
||||
cy="109.19419"
|
||||
r="5.4990706" />
|
||||
<circle
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="path51541-2"
|
||||
cx="896.0766"
|
||||
cy="109.19419"
|
||||
r="5.4990706" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
id="g1493">
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:25.4px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.264583"
|
||||
x="223.87091"
|
||||
y="475.59076"
|
||||
id="text1087-3"><tspan
|
||||
sodipodi:role="line"
|
||||
x="223.87091"
|
||||
y="475.59076"
|
||||
style="font-size:25.4px;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.264583"
|
||||
id="tspan2399-7">Canvas</tspan></text>
|
||||
<g
|
||||
id="g9297"
|
||||
transform="translate(187.58423,255.21786)">
|
||||
<circle
|
||||
cx="-43.440742"
|
||||
cy="211.92067"
|
||||
r="26.458332"
|
||||
fill="#000000"
|
||||
id="circle9169"
|
||||
style="stroke-width:0.264583" />
|
||||
<path
|
||||
d="m -48.732408,217.21233 h 10.583334 v 10.58333 h -10.583334 z"
|
||||
fill="#ffffff"
|
||||
id="path9171"
|
||||
style="stroke-width:0.264583" />
|
||||
<path
|
||||
d="m -48.732408,196.04566 h 10.583334 V 206.629 h -10.583334 z"
|
||||
fill="#ffffff"
|
||||
id="path9173"
|
||||
style="stroke-width:0.264583" />
|
||||
<path
|
||||
d="m -59.315741,206.629 h 10.583333 v 10.58333 h -10.583333 z"
|
||||
fill="#ffffff"
|
||||
id="path9175"
|
||||
style="stroke-width:0.264583" />
|
||||
<path
|
||||
d="m -27.565741,206.629 c 0,-1.38983 -0.273844,-2.76604 -0.805656,-4.05006 -0.531813,-1.28405 -1.311275,-2.45073 -2.294202,-3.4335 -0.982663,-0.98274 -2.149475,-1.76231 -3.433498,-2.29417 -1.284023,-0.53187 -2.660121,-0.80561 -4.049977,-0.80561 V 206.629 Z"
|
||||
fill="#ffffff"
|
||||
id="path9177"
|
||||
style="stroke-width:0.264583" />
|
||||
<path
|
||||
d="m -38.149074,227.79566 c 1.389856,0 2.765954,-0.27384 4.049977,-0.80565 1.284023,-0.53182 2.450835,-1.31128 3.433498,-2.29421 0.982927,-0.98266 1.762389,-2.14947 2.294202,-3.43349 0.531812,-1.28403 0.805656,-2.66012 0.805656,-4.04998 h -10.583333 z"
|
||||
fill="#ffffff"
|
||||
id="path9179"
|
||||
style="stroke-width:0.264583" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 88 KiB |
@@ -25,6 +25,7 @@ seedling-runtime = { path = "seedling" }
|
||||
statemint-runtime = { path = "statemint" }
|
||||
statemine-runtime = { path = "statemine" }
|
||||
westmint-runtime = { path = "westmint" }
|
||||
canvas-kusama-runtime = { path = "canvas-kusama" }
|
||||
parachains-common = { path = "parachains-common" }
|
||||
|
||||
# Substrate dependencies
|
||||
@@ -66,6 +67,7 @@ jsonrpc-core = "18.0.0"
|
||||
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" }
|
||||
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-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,
|
||||
cli::{Cli, RelayChainCli, Subcommand},
|
||||
service::{
|
||||
new_partial, Block, RococoParachainRuntimeExecutor, SeedlingRuntimeExecutor,
|
||||
ShellRuntimeExecutor, StatemineRuntimeExecutor, StatemintRuntimeExecutor,
|
||||
WestmintRuntimeExecutor,
|
||||
new_partial, Block, CanvasKusamaRuntimeExecutor, RococoParachainRuntimeExecutor,
|
||||
SeedlingRuntimeExecutor, ShellRuntimeExecutor, StatemineRuntimeExecutor,
|
||||
StatemintRuntimeExecutor, WestmintRuntimeExecutor,
|
||||
},
|
||||
};
|
||||
use codec::Encode;
|
||||
@@ -47,6 +47,7 @@ trait IdentifyChain {
|
||||
fn is_statemint(&self) -> bool;
|
||||
fn is_statemine(&self) -> bool;
|
||||
fn is_westmint(&self) -> bool;
|
||||
fn is_canvas_kusama(&self) -> bool;
|
||||
}
|
||||
|
||||
impl IdentifyChain for dyn sc_service::ChainSpec {
|
||||
@@ -65,6 +66,10 @@ impl IdentifyChain for dyn sc_service::ChainSpec {
|
||||
fn is_westmint(&self) -> bool {
|
||||
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 {
|
||||
@@ -83,6 +88,9 @@ impl<T: sc_service::ChainSpec + 'static> IdentifyChain for T {
|
||||
fn is_westmint(&self) -> bool {
|
||||
<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> {
|
||||
@@ -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(
|
||||
&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()),
|
||||
path => {
|
||||
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())?)
|
||||
} else if chain_spec.is_seedling() {
|
||||
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 {
|
||||
Box::new(chain_spec)
|
||||
}
|
||||
@@ -192,6 +206,8 @@ impl SubstrateCli for Cli {
|
||||
&shell_runtime::VERSION
|
||||
} else if chain_spec.is_seedling() {
|
||||
&seedling_runtime::VERSION
|
||||
} else if chain_spec.is_canvas_kusama() {
|
||||
&canvas_kusama_runtime::VERSION
|
||||
} else {
|
||||
&rococo_parachain_runtime::VERSION
|
||||
}
|
||||
@@ -296,6 +312,15 @@ macro_rules! construct_async_run {
|
||||
let task_manager = $components.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 {
|
||||
runner.async_run(|$config| {
|
||||
let $components = new_partial::<
|
||||
@@ -542,6 +567,11 @@ pub fn run() -> Result<()> {
|
||||
.await
|
||||
.map(|r| r.0)
|
||||
.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 {
|
||||
crate::service::start_rococo_parachain_node(config, polkadot_config, id)
|
||||
.await
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
|
||||
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;
|
||||
pub use sc_rpc::{DenyUnsafe, SubscriptionTaskExecutor};
|
||||
use sc_transaction_pool_api::TransactionPool;
|
||||
@@ -27,8 +29,6 @@ use sp_api::ProvideRuntimeApi;
|
||||
use sp_block_builder::BlockBuilder;
|
||||
use sp_blockchain::{Error as BlockChainError, HeaderBackend, HeaderMetadata};
|
||||
|
||||
use parachains_common::{AccountId, Balance, Block, Index as Nonce};
|
||||
|
||||
/// A type representing all RPC extensions.
|
||||
pub type RpcExtension = jsonrpc_core::IoHandler<sc_rpc::Metadata>;
|
||||
|
||||
@@ -68,3 +68,32 @@ where
|
||||
|
||||
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 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 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.
|
||||
///
|
||||
/// 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
|
||||
}
|
||||
|
||||
#[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