git.delta.rocks / unique-network / refs/commits / c8aac156edde

difftreelog

Merge pull request #307 from UniqueNetwork/feature/divide-runtimes-into-3

kozyrevdev2022-03-22parents: #d6336d8 #9c44795.patch.diff
in: master
divide runtimes into Opal, Quartz and Unique

26 files changed

modifiedCargo.lockdiffbeforeafterboth
5193source = "registry+https://github.com/rust-lang/crates.io-index"5193source = "registry+https://github.com/rust-lang/crates.io-index"
5194checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9"5194checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9"
5195
5196[[package]]
5197name = "opal-runtime"
5198version = "0.1.0"
5199dependencies = [
5200 "cumulus-pallet-aura-ext",
5201 "cumulus-pallet-dmp-queue",
5202 "cumulus-pallet-parachain-system",
5203 "cumulus-pallet-xcm",
5204 "cumulus-pallet-xcmp-queue",
5205 "cumulus-primitives-core",
5206 "cumulus-primitives-timestamp",
5207 "cumulus-primitives-utility",
5208 "derivative",
5209 "fp-rpc",
5210 "fp-self-contained",
5211 "frame-benchmarking",
5212 "frame-executive",
5213 "frame-support",
5214 "frame-system",
5215 "frame-system-benchmarking",
5216 "frame-system-rpc-runtime-api",
5217 "hex-literal",
5218 "orml-vesting",
5219 "pallet-aura",
5220 "pallet-balances",
5221 "pallet-base-fee",
5222 "pallet-common",
5223 "pallet-ethereum",
5224 "pallet-evm",
5225 "pallet-evm-coder-substrate",
5226 "pallet-evm-contract-helpers",
5227 "pallet-evm-migration",
5228 "pallet-evm-transaction-payment",
5229 "pallet-fungible",
5230 "pallet-inflation",
5231 "pallet-nonfungible",
5232 "pallet-randomness-collective-flip",
5233 "pallet-refungible",
5234 "pallet-sudo",
5235 "pallet-template-transaction-payment",
5236 "pallet-timestamp",
5237 "pallet-transaction-payment",
5238 "pallet-transaction-payment-rpc-runtime-api",
5239 "pallet-treasury",
5240 "pallet-unique",
5241 "pallet-unq-scheduler",
5242 "pallet-xcm",
5243 "parachain-info",
5244 "parity-scale-codec",
5245 "polkadot-parachain",
5246 "scale-info",
5247 "serde",
5248 "smallvec",
5249 "sp-api",
5250 "sp-arithmetic",
5251 "sp-block-builder",
5252 "sp-consensus-aura",
5253 "sp-core",
5254 "sp-inherents",
5255 "sp-io",
5256 "sp-offchain",
5257 "sp-runtime",
5258 "sp-session",
5259 "sp-std",
5260 "sp-transaction-pool",
5261 "sp-version",
5262 "substrate-wasm-builder",
5263 "unique-runtime-common",
5264 "up-data-structs",
5265 "up-evm-mapping",
5266 "up-rpc",
5267 "xcm",
5268 "xcm-builder",
5269 "xcm-executor",
5270]
51955271
5196[[package]]5272[[package]]
5197name = "opaque-debug"5273name = "opaque-debug"
8259 "cc",8335 "cc",
8260]8336]
8337
8338[[package]]
8339name = "quartz-runtime"
8340version = "0.1.0"
8341dependencies = [
8342 "cumulus-pallet-aura-ext",
8343 "cumulus-pallet-dmp-queue",
8344 "cumulus-pallet-parachain-system",
8345 "cumulus-pallet-xcm",
8346 "cumulus-pallet-xcmp-queue",
8347 "cumulus-primitives-core",
8348 "cumulus-primitives-timestamp",
8349 "cumulus-primitives-utility",
8350 "derivative",
8351 "fp-rpc",
8352 "fp-self-contained",
8353 "frame-benchmarking",
8354 "frame-executive",
8355 "frame-support",
8356 "frame-system",
8357 "frame-system-benchmarking",
8358 "frame-system-rpc-runtime-api",
8359 "hex-literal",
8360 "orml-vesting",
8361 "pallet-aura",
8362 "pallet-balances",
8363 "pallet-base-fee",
8364 "pallet-common",
8365 "pallet-ethereum",
8366 "pallet-evm",
8367 "pallet-evm-coder-substrate",
8368 "pallet-evm-contract-helpers",
8369 "pallet-evm-migration",
8370 "pallet-evm-transaction-payment",
8371 "pallet-fungible",
8372 "pallet-inflation",
8373 "pallet-nonfungible",
8374 "pallet-randomness-collective-flip",
8375 "pallet-refungible",
8376 "pallet-sudo",
8377 "pallet-template-transaction-payment",
8378 "pallet-timestamp",
8379 "pallet-transaction-payment",
8380 "pallet-transaction-payment-rpc-runtime-api",
8381 "pallet-treasury",
8382 "pallet-unique",
8383 "pallet-unq-scheduler",
8384 "pallet-xcm",
8385 "parachain-info",
8386 "parity-scale-codec",
8387 "polkadot-parachain",
8388 "scale-info",
8389 "serde",
8390 "smallvec",
8391 "sp-api",
8392 "sp-arithmetic",
8393 "sp-block-builder",
8394 "sp-consensus-aura",
8395 "sp-core",
8396 "sp-inherents",
8397 "sp-io",
8398 "sp-offchain",
8399 "sp-runtime",
8400 "sp-session",
8401 "sp-std",
8402 "sp-transaction-pool",
8403 "sp-version",
8404 "substrate-wasm-builder",
8405 "unique-runtime-common",
8406 "up-data-structs",
8407 "up-evm-mapping",
8408 "up-rpc",
8409 "xcm",
8410 "xcm-builder",
8411 "xcm-executor",
8412]
82618413
8262[[package]]8414[[package]]
8263name = "quick-error"8415name = "quick-error"
11787 "jsonrpc-core",11939 "jsonrpc-core",
11788 "jsonrpc-pubsub",11940 "jsonrpc-pubsub",
11789 "log",11941 "log",
11942 "opal-runtime",
11790 "pallet-ethereum",11943 "pallet-ethereum",
11791 "pallet-transaction-payment-rpc",11944 "pallet-transaction-payment-rpc",
11945 "pallet-transaction-payment-rpc-runtime-api",
11792 "parity-scale-codec",11946 "parity-scale-codec",
11793 "parking_lot 0.11.2",11947 "parking_lot 0.11.2",
11794 "polkadot-cli",11948 "polkadot-cli",
11795 "polkadot-parachain",11949 "polkadot-parachain",
11796 "polkadot-primitives",11950 "polkadot-primitives",
11797 "polkadot-service",11951 "polkadot-service",
11798 "polkadot-test-service",11952 "polkadot-test-service",
11953 "quartz-runtime",
11799 "sc-basic-authorship",11954 "sc-basic-authorship",
11800 "sc-chain-spec",11955 "sc-chain-spec",
11801 "sc-cli",11956 "sc-cli",
11834 "substrate-prometheus-endpoint",11989 "substrate-prometheus-endpoint",
11835 "unique-rpc",11990 "unique-rpc",
11836 "unique-runtime",11991 "unique-runtime",
11992 "unique-runtime-common",
11837 "up-data-structs",11993 "up-data-structs",
11994 "up-rpc",
11838]11995]
1183911996
11840[[package]]11997[[package]]
11849 "futures 0.3.21",12006 "futures 0.3.21",
11850 "jsonrpc-core",12007 "jsonrpc-core",
11851 "jsonrpc-pubsub",12008 "jsonrpc-pubsub",
12009 "pallet-common",
11852 "pallet-ethereum",12010 "pallet-ethereum",
11853 "pallet-transaction-payment-rpc",12011 "pallet-transaction-payment-rpc",
11854 "pallet-transaction-payment-rpc-runtime-api",12012 "pallet-transaction-payment-rpc-runtime-api",
11864 "sc-rpc-api",12022 "sc-rpc-api",
11865 "sc-service",12023 "sc-service",
11866 "sc-transaction-pool",12024 "sc-transaction-pool",
12025 "serde",
11867 "sp-api",12026 "sp-api",
11868 "sp-block-builder",12027 "sp-block-builder",
11869 "sp-blockchain",12028 "sp-blockchain",
11878 "substrate-frame-rpc-system",12037 "substrate-frame-rpc-system",
11879 "tokio 0.2.25",12038 "tokio 0.2.25",
11880 "uc-rpc",12039 "uc-rpc",
11881 "unique-runtime",12040 "unique-runtime-common",
11882 "up-rpc",12041 "up-rpc",
11883]12042]
1188412043
11949 "sp-transaction-pool",12108 "sp-transaction-pool",
11950 "sp-version",12109 "sp-version",
11951 "substrate-wasm-builder",12110 "substrate-wasm-builder",
12111 "unique-runtime-common",
11952 "up-data-structs",12112 "up-data-structs",
11953 "up-evm-mapping",12113 "up-evm-mapping",
11954 "up-rpc",12114 "up-rpc",
11957 "xcm-executor",12117 "xcm-executor",
11958]12118]
12119
12120[[package]]
12121name = "unique-runtime-common"
12122version = "0.1.0"
12123dependencies = [
12124 "fp-rpc",
12125 "frame-support",
12126 "frame-system",
12127 "pallet-common",
12128 "parity-scale-codec",
12129 "scale-info",
12130 "sp-consensus-aura",
12131 "sp-core",
12132 "sp-runtime",
12133]
1195912134
11960[[package]]12135[[package]]
11961name = "universal-hash"12136name = "universal-hash"
modifiedCargo.tomldiffbeforeafterboth
5 'pallets/*',5 'pallets/*',
6 'client/*',6 'client/*',
7 'primitives/*',7 'primitives/*',
8 'runtime',8 'runtime/*',
9 'crates/*',9 'crates/*',
10]10]
11[profile.release]11[profile.release]
modifiedREADME.mddiffbeforeafterboth
27- [Unique Wallet and UI](https://uniqueapps.usetech.com/#/nft)27- [Unique Wallet and UI](https://uniqueapps.usetech.com/#/nft)
28- [NFT Asset for Unity Framework](https://github.com/usetech-llc/nft_unity)28- [NFT Asset for Unity Framework](https://github.com/usetech-llc/nft_unity)
2929
30Please see our [walk-thorugh instructions](doc/hackusama_walk_through.md) to try everything out!30Please see our [walk-through instructions](doc/hackusama_walk_through.md) to try everything out!
3131
32## Application Development32## Application Development
3333
158```158```
159assetRegistry -> registerForeignAsset(location, metadata)159assetRegistry -> registerForeignAsset(location, metadata)
160location:160location:
161 V0(X2(Parent, Parachain(PARA_ID))) 161 V0(X2(Parent, Parachain(PARA_ID)))
162metadata:162metadata:
163 name OPL163 name OPL
164 symbol OPL164 symbol OPL
170```170```
171polkadotXcm -> reserveTransferAssets171polkadotXcm -> reserveTransferAssets
172dest:172dest:
173 V0(X2(Parent, Parachain(<KARURA_PARA_ID>))) 173 V0(X2(Parent, Parachain(<KARURA_PARA_ID>)))
174beneficiary:174beneficiary:
175 X1(AccountId(Any, <ACCOUNT>))175 X1(AccountId(Any, <ACCOUNT>))
176assets:176assets:
177 V1(Concrete(0,Here), Fungible(<AMOUNT>))177 V1(Concrete(0,Here), Fungible(<AMOUNT>))
178feeAssetItem: 178feeAssetItem:
179 0 179 0
180weightLimit:180weightLimit:
181 <LIMIT>181 <LIMIT>
182``` 182```
183183
184The result will be displayed in ChainState 184The result will be displayed in ChainState
185tokens -> accounts 185tokens -> accounts
186186
187### To send tokens from Karura to Opal:187### To send tokens from Karura to Opal:
188```188```
197dest:197dest:
198 V1198 V1
199 (199 (
200 Parents:1, 200 Parents:1,
201 X2(Parachain(<KARURA_PARA_ID>), AccountId(Any, <ACCOUNT>)201 X2(Parachain(<KARURA_PARA_ID>), AccountId(Any, <ACCOUNT>)
202 )202 )
203destWeight:203destWeight:
modifiednode/cli/Cargo.tomldiffbeforeafterboth
168[dependencies.serde_json]168[dependencies.serde_json]
169version = '1.0.68'169version = '1.0.68'
170170
171[dependencies.sc-consensus-manual-seal]
172git = 'https://github.com/paritytech/substrate.git'
173branch = 'polkadot-v0.9.17'
171174
172################################################################################175################################################################################
173# Cumulus dependencies176# Cumulus dependencies
238################################################################################241################################################################################
239# Local dependencies242# Local dependencies
243
244[dependencies.unique-runtime-common]
245default-features = false
246path = "../../runtime/common"
240247
241[dependencies.unique-runtime]248[dependencies.unique-runtime]
242path = '../../runtime'249path = '../../runtime/unique'
250optional = true
251
252[dependencies.quartz-runtime]
253path = '../../runtime/quartz'
254optional = true
255
256[dependencies.opal-runtime]
257path = '../../runtime/opal'
243258
244[dependencies.up-data-structs]259[dependencies.up-data-structs]
245path = "../../primitives/data-structs"260path = "../../primitives/data-structs"
246default-features = false261default-features = false
262
263[dependencies.up-rpc]
264path = "../../primitives/rpc"
265
266[dependencies.pallet-transaction-payment-rpc-runtime-api]
267git = 'https://github.com/paritytech/substrate.git'
268branch = 'polkadot-v0.9.17'
247269
248################################################################################270################################################################################
249# Package271# Package
283fp-rpc = { git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.17" }305fp-rpc = { git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.17" }
284pallet-ethereum = { git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.17" }306pallet-ethereum = { git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.17" }
285307
286unique-rpc = { path = "../rpc" }308unique-rpc = { default-features = false, path = "../rpc" }
287309
288[features]310[features]
289default = []311default = ["unique-runtime", "quartz-runtime"]
290runtime-benchmarks = [312runtime-benchmarks = [
291 'unique-runtime/runtime-benchmarks',313 'unique-runtime/runtime-benchmarks',
292 'polkadot-service/runtime-benchmarks',314 'polkadot-service/runtime-benchmarks',
modifiednode/cli/src/chain_spec.rsdiffbeforeafterboth
15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
1616
17use cumulus_primitives_core::ParaId;17use cumulus_primitives_core::ParaId;
18use unique_runtime::*;
19use sc_chain_spec::{ChainSpecExtension, ChainSpecGroup};18use sc_chain_spec::{ChainSpecExtension, ChainSpecGroup};
20use sc_service::ChainType;19use sc_service::ChainType;
21use sp_core::{sr25519, Pair, Public};20use sp_core::{sr25519, Pair, Public};
25use serde::{Deserialize, Serialize};24use serde::{Deserialize, Serialize};
26use serde_json::map::Map;25use serde_json::map::Map;
2726
28/// Specialized `ChainSpec`. This is a specialization of the general Substrate ChainSpec type.27use unique_runtime_common::types::*;
28
29/// The `ChainSpec` parameterized for the unique runtime.
30#[cfg(feature = "unique-runtime")]
29pub type ChainSpec = sc_service::GenericChainSpec<unique_runtime::GenesisConfig, Extensions>;31pub type UniqueChainSpec = sc_service::GenericChainSpec<unique_runtime::GenesisConfig, Extensions>;
32
33/// The `ChainSpec` parameterized for the quartz runtime.
34#[cfg(feature = "quartz-runtime")]
35pub type QuartzChainSpec = sc_service::GenericChainSpec<quartz_runtime::GenesisConfig, Extensions>;
36
37/// The `ChainSpec` parameterized for the opal runtime.
38pub type OpalChainSpec = sc_service::GenericChainSpec<opal_runtime::GenesisConfig, Extensions>;
39
40pub enum RuntimeId {
41 Unique,
42 Quartz,
43 Opal,
44 Unknown(String),
45}
46
47pub trait RuntimeIdentification {
48 fn runtime_id(&self) -> RuntimeId;
49}
50
51impl RuntimeIdentification for Box<dyn sc_service::ChainSpec> {
52 fn runtime_id(&self) -> RuntimeId {
53 #[cfg(feature = "unique-runtime")]
54 if self.id().starts_with("unique") {
55 return RuntimeId::Unique;
56 }
57
58 #[cfg(feature = "quartz-runtime")]
59 if self.id().starts_with("quartz") {
60 return RuntimeId::Quartz;
61 }
62
63 if self.id().starts_with("opal") || self.id() == "dev" || self.id() == "local_testnet" {
64 return RuntimeId::Opal;
65 }
66
67 RuntimeId::Unknown(self.id().into())
68 }
69}
70
71pub enum ServiceId {
72 Prod,
73 Dev,
74}
75
76pub trait ServiceIdentification {
77 fn service_id(&self) -> ServiceId;
78}
79
80impl ServiceIdentification for Box<dyn sc_service::ChainSpec> {
81 fn service_id(&self) -> ServiceId {
82 if self.id().ends_with("dev") {
83 ServiceId::Dev
84 } else {
85 ServiceId::Prod
86 }
87 }
88}
3089
31/// Helper function to generate a crypto pair from seed90/// Helper function to generate a crypto pair from seed
32pub fn get_from_seed<TPublic: Public>(seed: &str) -> <TPublic::Pair as Pair>::Public {91pub fn get_from_seed<TPublic: Public>(seed: &str) -> <TPublic::Pair as Pair>::Public {
62 AccountPublic::from(get_from_seed::<TPublic>(seed)).into_account()121 AccountPublic::from(get_from_seed::<TPublic>(seed)).into_account()
63}122}
64123
65pub fn development_config() -> ChainSpec {124pub fn development_config() -> OpalChainSpec {
66 let mut properties = Map::new();125 let mut properties = Map::new();
67 properties.insert("tokenSymbol".into(), "OPL".into());126 properties.insert("tokenSymbol".into(), "OPL".into());
68 properties.insert("tokenDecimals".into(), 15.into());127 properties.insert("tokenDecimals".into(), 15.into());
69 properties.insert("ss58Format".into(), 42.into());128 properties.insert("ss58Format".into(), 42.into());
70129
71 ChainSpec::from_genesis(130 OpalChainSpec::from_genesis(
72 // Name131 // Name
73 "Development",132 "Development",
74 // ID133 // ID
107 )166 )
108}167}
109168
110pub fn local_testnet_rococo_config() -> ChainSpec {169pub fn local_testnet_rococo_config() -> OpalChainSpec {
111 ChainSpec::from_genesis(170 OpalChainSpec::from_genesis(
112 // Name171 // Name
113 "Local Testnet",172 "Local Testnet",
114 // ID173 // ID
157 )216 )
158}217}
159
160pub fn local_testnet_westend_config() -> ChainSpec {
161 ChainSpec::from_genesis(
162 // Name
163 "Local Testnet",
164 // ID
165 "local_testnet",
166 ChainType::Local,
167 move || {
168 testnet_genesis(
169 // Sudo account
170 get_account_id_from_seed::<sr25519::Public>("Alice"),
171 vec![
172 get_from_seed::<AuraId>("Alice"),
173 get_from_seed::<AuraId>("Bob"),
174 get_from_seed::<AuraId>("Charlie"),
175 get_from_seed::<AuraId>("Dave"),
176 get_from_seed::<AuraId>("Eve"),
177 ],
178 // Pre-funded accounts
179 vec![
180 get_account_id_from_seed::<sr25519::Public>("Alice"),
181 get_account_id_from_seed::<sr25519::Public>("Bob"),
182 get_account_id_from_seed::<sr25519::Public>("Charlie"),
183 get_account_id_from_seed::<sr25519::Public>("Dave"),
184 get_account_id_from_seed::<sr25519::Public>("Eve"),
185 get_account_id_from_seed::<sr25519::Public>("Ferdie"),
186 get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
187 get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
188 get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),
189 get_account_id_from_seed::<sr25519::Public>("Dave//stash"),
190 get_account_id_from_seed::<sr25519::Public>("Eve//stash"),
191 get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),
192 ],
193 1000.into(),
194 )
195 },
196 // Bootnodes
197 vec![],
198 // Telemetry
199 None,
200 // Protocol ID
201 None,
202 None,
203 // Properties
204 None,
205 // Extensions
206 Extensions {
207 relay_chain: "westend-local".into(),
208 para_id: 1000,
209 },
210 )
211}
212218
213fn testnet_genesis(219fn testnet_genesis(
214 root_key: AccountId,220 root_key: AccountId,
215 initial_authorities: Vec<AuraId>,221 initial_authorities: Vec<AuraId>,
216 endowed_accounts: Vec<AccountId>,222 endowed_accounts: Vec<AccountId>,
217 id: ParaId,223 id: ParaId,
218) -> GenesisConfig {224) -> opal_runtime::GenesisConfig {
225 use opal_runtime::*;
226
219 GenesisConfig {227 GenesisConfig {
220 system: unique_runtime::SystemConfig {228 system: SystemConfig {
221 code: unique_runtime::WASM_BINARY229 code: WASM_BINARY
222 .expect("WASM binary was not build, please build it!")230 .expect("WASM binary was not build, please build it!")
223 .to_vec(),231 .to_vec(),
224 },232 },
235 key: Some(root_key),243 key: Some(root_key),
236 },244 },
237 vesting: VestingConfig { vesting: vec![] },245 vesting: VestingConfig { vesting: vec![] },
238 parachain_info: unique_runtime::ParachainInfoConfig { parachain_id: id },246 parachain_info: ParachainInfoConfig { parachain_id: id },
239 parachain_system: Default::default(),247 parachain_system: Default::default(),
240 aura: unique_runtime::AuraConfig {248 aura: AuraConfig {
241 authorities: initial_authorities,249 authorities: initial_authorities,
242 },250 },
243 aura_ext: Default::default(),251 aura_ext: Default::default(),
modifiednode/cli/src/command.rsdiffbeforeafterboth
33// limitations under the License.33// limitations under the License.
3434
35use crate::{35use crate::{
36 chain_spec,36 chain_spec::{self, RuntimeId, RuntimeIdentification, ServiceId, ServiceIdentification},
37 cli::{Cli, RelayChainCli, Subcommand},37 cli::{Cli, RelayChainCli, Subcommand},
38 service::{new_partial, ParachainRuntimeExecutor},38 service::{new_partial, start_node, start_dev_node},
39};39};
40
41#[cfg(feature = "unique-runtime")]
42use crate::service::UniqueRuntimeExecutor;
43
44#[cfg(feature = "quartz-runtime")]
45use crate::service::QuartzRuntimeExecutor;
46
47use crate::service::OpalRuntimeExecutor;
48
40use codec::Encode;49use codec::Encode;
41use cumulus_primitives_core::ParaId;50use cumulus_primitives_core::ParaId;
42use cumulus_client_service::genesis::generate_genesis_block;51use cumulus_client_service::genesis::generate_genesis_block;
43use log::info;52use log::info;
44use unique_runtime::Block;
45use polkadot_parachain::primitives::AccountIdConversion;53use polkadot_parachain::primitives::AccountIdConversion;
46use sc_cli::{54use sc_cli::{
47 ChainSpec, CliConfiguration, DefaultConfigurationValues, ImportParams, KeystoreParams,55 ChainSpec, CliConfiguration, DefaultConfigurationValues, ImportParams, KeystoreParams,
54use sp_runtime::traits::Block as BlockT;62use sp_runtime::traits::Block as BlockT;
55use std::{io::Write, net::SocketAddr};63use std::{io::Write, net::SocketAddr};
64
65use unique_runtime_common::types::Block;
66
67macro_rules! no_runtime_err {
68 ($chain_name:expr) => {
69 format!(
70 "No runtime valid runtime was found for chain {}",
71 $chain_name
72 )
73 };
74}
5675
57fn load_spec(id: &str) -> std::result::Result<Box<dyn sc_service::ChainSpec>, String> {76fn load_spec(id: &str) -> std::result::Result<Box<dyn sc_service::ChainSpec>, String> {
58 Ok(match id {77 Ok(match id {
59 "westend-local" => Box::new(chain_spec::local_testnet_westend_config()),78 "dev" => Box::new(chain_spec::development_config()),
60 "rococo-local" => Box::new(chain_spec::local_testnet_rococo_config()),79 "" | "local" => Box::new(chain_spec::local_testnet_rococo_config()),
61 "dev" => Box::new(chain_spec::development_config()),80 path => {
81 let path = std::path::PathBuf::from(path);
62 "" | "local" => Box::new(chain_spec::local_testnet_rococo_config()),82 let chain_spec = Box::new(chain_spec::OpalChainSpec::from_json_file(path.clone())?)
83 as Box<dyn sc_service::ChainSpec>;
84
85 match chain_spec.runtime_id() {
86 #[cfg(feature = "unique-runtime")]
63 path => Box::new(chain_spec::ChainSpec::from_json_file(87 RuntimeId::Unique => Box::new(chain_spec::UniqueChainSpec::from_json_file(path)?),
88
89 #[cfg(feature = "quartz-runtime")]
64 std::path::PathBuf::from(path),90 RuntimeId::Quartz => Box::new(chain_spec::QuartzChainSpec::from_json_file(path)?),
65 )?),91
92 RuntimeId::Opal => chain_spec,
93 RuntimeId::Unknown(chain) => return Err(no_runtime_err!(chain)),
94 }
95 }
66 })96 })
67}97}
6898
69impl SubstrateCli for Cli {99impl SubstrateCli for Cli {
70 // TODO use args100 // TODO use args
71 fn impl_name() -> String {101 fn impl_name() -> String {
72 "Opal Node".into()102 "Unique Node".into()
73 }103 }
74104
75 fn impl_version() -> String {105 fn impl_version() -> String {
78 // TODO use args108 // TODO use args
79 fn description() -> String {109 fn description() -> String {
80 format!(110 format!(
81 "Opal Node\n\nThe command-line arguments provided first will be \111 "Unique Node\n\nThe command-line arguments provided first will be \
82 passed to the parachain node, while the arguments provided after -- will be passed \112 passed to the parachain node, while the arguments provided after -- will be passed \
83 to the relaychain node.\n\n\113 to the relaychain node.\n\n\
84 {} [parachain-args] -- [relaychain-args]",114 {} [parachain-args] -- [relaychain-args]",
85 Self::executable_name()115 Self::executable_name()
86 )116 )
87 }117 }
103 load_spec(id)133 load_spec(id)
104 }134 }
105135
106 fn native_runtime_version(_: &Box<dyn ChainSpec>) -> &'static RuntimeVersion {136 fn native_runtime_version(chain_spec: &Box<dyn ChainSpec>) -> &'static RuntimeVersion {
137 match chain_spec.runtime_id() {
138 #[cfg(feature = "unique-runtime")]
107 &unique_runtime::VERSION139 RuntimeId::Unique => &unique_runtime::VERSION,
140
141 #[cfg(feature = "quartz-runtime")]
142 RuntimeId::Quartz => &quartz_runtime::VERSION,
143
144 RuntimeId::Opal => &opal_runtime::VERSION,
145 RuntimeId::Unknown(chain) => panic!("{}", no_runtime_err!(chain)),
146 }
108 }147 }
109}148}
110149
111impl SubstrateCli for RelayChainCli {150impl SubstrateCli for RelayChainCli {
112 // TODO use args151 // TODO use args
113 fn impl_name() -> String {152 fn impl_name() -> String {
114 "Opal Node".into()153 "Unique Node".into()
115 }154 }
116155
117 fn impl_version() -> String {156 fn impl_version() -> String {
118 env!("SUBSTRATE_CLI_IMPL_VERSION").into()157 env!("SUBSTRATE_CLI_IMPL_VERSION").into()
119 }158 }
120 // TODO use args159 // TODO use args
121 fn description() -> String {160 fn description() -> String {
122 "Opal Node\n\nThe command-line arguments provided first will be \161 "Unique Node\n\nThe command-line arguments provided first will be \
123 passed to the parachain node, while the arguments provided after -- will be passed \162 passed to the parachain node, while the arguments provided after -- will be passed \
124 to the relaychain node.\n\n\163 to the relaychain node.\n\n\
125 parachain-collator [parachain-args] -- [relaychain-args]"164 parachain-collator [parachain-args] -- [relaychain-args]"
126 .into()165 .into()
127 }166 }
128167
157 .ok_or_else(|| "Could not find wasm file in genesis state!".into())196 .ok_or_else(|| "Could not find wasm file in genesis state!".into())
158}197}
159198
160macro_rules! construct_async_run {199macro_rules! async_run_with_runtime {
161 (|$components:ident, $cli:ident, $cmd:ident, $config:ident| $( $code:tt )* ) => {{200 (
162 let runner = $cli.create_runner($cmd)?;201 $runtime_api:path, $executor:path,
202 $runner:ident, $components:ident, $cli:ident, $cmd:ident, $config:ident,
203 $( $code:tt )*
204 ) => {
163 runner.async_run(|$config| {205 $runner.async_run(|$config| {
164 let $components = new_partial::<206 let $components = new_partial::<
165 _207 $runtime_api, $executor, _
166 >(208 >(
167 &$config,209 &$config,
168 crate::service::parachain_build_import_queue,210 crate::service::parachain_build_import_queue,
169 )?;211 )?;
170 let task_manager = $components.task_manager;212 let task_manager = $components.task_manager;
213
171 { $( $code )* }.map(|v| (v, task_manager))214 { $( $code )* }.map(|v| (v, task_manager))
172 })215 })
173 }}216 };
174}217}
218
219macro_rules! construct_async_run {
220 (|$components:ident, $cli:ident, $cmd:ident, $config:ident| $( $code:tt )* ) => {{
221 let runner = $cli.create_runner($cmd)?;
222
223 match runner.config().chain_spec.runtime_id() {
224 #[cfg(feature = "unique-runtime")]
225 RuntimeId::Unique => async_run_with_runtime!(
226 unique_runtime::RuntimeApi, UniqueRuntimeExecutor,
227 runner, $components, $cli, $cmd, $config, $( $code )*
228 ),
229
230 #[cfg(feature = "quartz-runtime")]
231 RuntimeId::Quartz => async_run_with_runtime!(
232 quartz_runtime::RuntimeApi, QuartzRuntimeExecutor,
233 runner, $components, $cli, $cmd, $config, $( $code )*
234 ),
235
236 RuntimeId::Opal => async_run_with_runtime!(
237 opal_runtime::RuntimeApi, OpalRuntimeExecutor,
238 runner, $components, $cli, $cmd, $config, $( $code )*
239 ),
240
241 RuntimeId::Unknown(chain) => Err(no_runtime_err!(chain).into())
242 }
243 }}
244}
245
246macro_rules! start_node_using_chain_runtime {
247 ($start_node_fn:ident($config:expr $(, $($args:expr),+)?) $($code:tt)*) => {
248 match $config.chain_spec.runtime_id() {
249 #[cfg(feature = "unique-runtime")]
250 RuntimeId::Unique => $start_node_fn::<
251 unique_runtime::Runtime,
252 unique_runtime::RuntimeApi,
253 UniqueRuntimeExecutor,
254 >($config $(, $($args),+)?) $($code)*,
255
256 #[cfg(feature = "quartz-runtime")]
257 RuntimeId::Quartz => $start_node_fn::<
258 quartz_runtime::Runtime,
259 quartz_runtime::RuntimeApi,
260 QuartzRuntimeExecutor,
261 >($config $(, $($args),+)?) $($code)*,
262
263 RuntimeId::Opal => $start_node_fn::<
264 opal_runtime::Runtime,
265 opal_runtime::RuntimeApi,
266 OpalRuntimeExecutor,
267 >($config $(, $($args),+)?) $($code)*,
268
269 RuntimeId::Unknown(chain) => Err(no_runtime_err!(chain).into()),
270 }
271 };
272}
175273
176/// Parse command line arguments into service configuration.274/// Parse command line arguments into service configuration.
177pub fn run() -> Result<()> {275pub fn run() -> Result<()> {
274 if cfg!(feature = "runtime-benchmarks") {372 if cfg!(feature = "runtime-benchmarks") {
275 let runner = cli.create_runner(cmd)?;373 let runner = cli.create_runner(cmd)?;
276
277 runner.sync_run(|config| cmd.run::<Block, ParachainRuntimeExecutor>(config))374 runner.sync_run(|config| match config.chain_spec.runtime_id() {
375 #[cfg(feature = "unique-runtime")]
376 RuntimeId::Unique => cmd.run::<Block, UniqueRuntimeExecutor>(config),
377
378 #[cfg(feature = "quartz-runtime")]
379 RuntimeId::Quartz => cmd.run::<Block, QuartzRuntimeExecutor>(config),
380
381 RuntimeId::Opal => cmd.run::<Block, OpalRuntimeExecutor>(config),
382 RuntimeId::Unknown(chain) => Err(no_runtime_err!(chain).into()),
383 })
278 } else {384 } else {
279 Err("Benchmarking wasn't enabled when building the node. \385 Err("Benchmarking wasn't enabled when building the node. \
280 You can enable it with `--features runtime-benchmarks`."386 You can enable it with `--features runtime-benchmarks`."
285 let runner = cli.create_runner(&cli.run.normalize())?;391 let runner = cli.create_runner(&cli.run.normalize())?;
286392
287 runner.run_node_until_exit(|config| async move {393 runner.run_node_until_exit(|config| async move {
288 let para_id = chain_spec::Extensions::try_get(&*config.chain_spec)394 let extensions = chain_spec::Extensions::try_get(&*config.chain_spec);
395
396 let service_id = config.chain_spec.service_id();
397 let relay_chain_id = extensions.map(|e| e.relay_chain.clone());
398 let is_dev_service = matches![service_id, ServiceId::Dev]
399 || relay_chain_id == Some("dev-service".into());
400
401 if is_dev_service {
402 info!("Running Dev service");
403
404 return start_node_using_chain_runtime! {
405 start_dev_node(config).map_err(Into::into)
406 };
407 };
408
409 let para_id = extensions
289 .map(|e| e.para_id)410 .map(|e| e.para_id)
290 .ok_or("Could not find parachain ID in chain-spec.")?;411 .ok_or("Could not find parachain ID in chain-spec.")?;
291412
292 let polkadot_cli = RelayChainCli::new(413 let polkadot_cli = RelayChainCli::new(
296 .chain(cli.relaychain_args.iter()),417 .chain(cli.relaychain_args.iter()),
297 );418 );
298419
299 let id = ParaId::from(para_id);420 let para_id = ParaId::from(para_id);
300421
301 let parachain_account =422 let parachain_account =
302 AccountIdConversion::<polkadot_primitives::v0::AccountId>::into_account(&id);423 AccountIdConversion::<polkadot_primitives::v0::AccountId>::into_account(
424 &para_id,
425 );
303426
304 let state_version =427 let state_version =
315 )438 )
316 .map_err(|err| format!("Relay chain argument error: {}", err))?;439 .map_err(|err| format!("Relay chain argument error: {}", err))?;
317440
318 info!("Parachain id: {:?}", id);441 info!("Parachain id: {:?}", para_id);
319 info!("Parachain Account: {}", parachain_account);442 info!("Parachain Account: {}", parachain_account);
320 info!("Parachain genesis state: {}", genesis_state);443 info!("Parachain genesis state: {}", genesis_state);
321 info!("Parachain genesis hash: {}", genesis_hash);444 info!("Parachain genesis hash: {}", genesis_hash);
328 }451 }
329 );452 );
330453
454 start_node_using_chain_runtime! {
331 crate::service::start_node(config, polkadot_config, id)455 start_node(config, polkadot_config, para_id)
332 .await456 .await
333 .map(|r| r.0)457 .map(|r| r.0)
334 .map_err(Into::into)458 .map_err(Into::into)
459 }
335 })460 })
336 }461 }
337 }462 }
modifiednode/cli/src/service.rsdiffbeforeafterboth
25use futures::StreamExt;25use futures::StreamExt;
2626
27use unique_rpc::overrides_handle;27use unique_rpc::overrides_handle;
28// Local Runtime Types
29use unique_runtime::RuntimeApi;
3028
29use serde::{Serialize, Deserialize};
30
31// Cumulus Imports31// Cumulus Imports
32use cumulus_client_consensus_aura::{AuraConsensus, BuildAuraConsensusParams, SlotProportion};32use cumulus_client_consensus_aura::{AuraConsensus, BuildAuraConsensusParams, SlotProportion};
33use cumulus_client_consensus_common::ParachainConsensus;33use cumulus_client_consensus_common::ParachainConsensus;
56use fc_rpc_core::types::FilterPool;56use fc_rpc_core::types::FilterPool;
57use fc_mapping_sync::{MappingSyncWorker, SyncStrategy};57use fc_mapping_sync::{MappingSyncWorker, SyncStrategy};
5858
59// Runtime type overrides59use unique_runtime_common::types::{AuraId, RuntimeInstance, AccountId, Balance, Index, Hash, Block};
60type BlockNumber = u32;
61type Header = sp_runtime::generic::Header<BlockNumber, sp_runtime::traits::BlakeTwo256>;
62pub type Block = sp_runtime::generic::Block<Header, sp_runtime::OpaqueExtrinsic>;
63type Hash = sp_core::H256;
6460
65/// Native executor instance.61/// Native executor instance.
66pub struct ParachainRuntimeExecutor;62pub struct UniqueRuntimeExecutor;
63pub struct QuartzRuntimeExecutor;
64pub struct OpalRuntimeExecutor;
6765
66#[cfg(feature = "unique-runtime")]
68impl NativeExecutionDispatch for ParachainRuntimeExecutor {67impl NativeExecutionDispatch for UniqueRuntimeExecutor {
69 type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions;68 type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions;
7069
71 fn dispatch(method: &str, data: &[u8]) -> Option<Vec<u8>> {70 fn dispatch(method: &str, data: &[u8]) -> Option<Vec<u8>> {
77 }76 }
78}77}
7978
79#[cfg(feature = "quartz-runtime")]
80impl NativeExecutionDispatch for QuartzRuntimeExecutor {
81 type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions;
82
83 fn dispatch(method: &str, data: &[u8]) -> Option<Vec<u8>> {
84 quartz_runtime::api::dispatch(method, data)
85 }
86
87 fn native_version() -> sc_executor::NativeVersion {
88 quartz_runtime::native_version()
89 }
90}
91
92impl NativeExecutionDispatch for OpalRuntimeExecutor {
93 type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions;
94
95 fn dispatch(method: &str, data: &[u8]) -> Option<Vec<u8>> {
96 opal_runtime::api::dispatch(method, data)
97 }
98
99 fn native_version() -> sc_executor::NativeVersion {
100 opal_runtime::native_version()
101 }
102}
103
80pub fn open_frontier_backend(config: &Configuration) -> Result<Arc<fc_db::Backend<Block>>, String> {104pub fn open_frontier_backend(config: &Configuration) -> Result<Arc<fc_db::Backend<Block>>, String> {
81 let config_dir = config105 let config_dir = config
82 .base_path106 .base_path
97 )?))121 )?))
98}122}
99123
100type ExecutorDispatch = ParachainRuntimeExecutor;124type FullClient<RuntimeApi, ExecutorDispatch> =
101
102type FullClient =
103 sc_service::TFullClient<Block, RuntimeApi, NativeElseWasmExecutor<ExecutorDispatch>>;125 sc_service::TFullClient<Block, RuntimeApi, NativeElseWasmExecutor<ExecutorDispatch>>;
104type FullBackend = sc_service::TFullBackend<Block>;126type FullBackend = sc_service::TFullBackend<Block>;
105type FullSelectChain = sc_consensus::LongestChain<FullBackend, Block>;127type FullSelectChain = sc_consensus::LongestChain<FullBackend, Block>;
109/// Use this macro if you don't actually need the full service, but just the builder in order to131/// Use this macro if you don't actually need the full service, but just the builder in order to
110/// be able to perform chain operations.132/// be able to perform chain operations.
111#[allow(clippy::type_complexity)]133#[allow(clippy::type_complexity)]
112pub fn new_partial<BIQ>(134pub fn new_partial<RuntimeApi, ExecutorDispatch, BIQ>(
113 config: &Configuration,135 config: &Configuration,
114 build_import_queue: BIQ,136 build_import_queue: BIQ,
115) -> Result<137) -> Result<
116 PartialComponents<138 PartialComponents<
117 FullClient,139 FullClient<RuntimeApi, ExecutorDispatch>,
118 FullBackend,140 FullBackend,
119 FullSelectChain,141 FullSelectChain,
120 sc_consensus::DefaultImportQueue<Block, FullClient>,142 sc_consensus::DefaultImportQueue<Block, FullClient<RuntimeApi, ExecutorDispatch>>,
121 sc_transaction_pool::FullPool<Block, FullClient>,143 sc_transaction_pool::FullPool<Block, FullClient<RuntimeApi, ExecutorDispatch>>,
122 (144 (
123 Option<Telemetry>,145 Option<Telemetry>,
124 Option<FilterPool>,146 Option<FilterPool>,
131>153>
132where154where
133 sc_client_api::StateBackendFor<FullBackend, Block>: sp_api::StateBackend<BlakeTwo256>,155 sc_client_api::StateBackendFor<FullBackend, Block>: sp_api::StateBackend<BlakeTwo256>,
156 RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>
157 + Send
158 + Sync
159 + 'static,
160 RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>,
134 ExecutorDispatch: NativeExecutionDispatch + 'static,161 ExecutorDispatch: NativeExecutionDispatch + 'static,
135 BIQ: FnOnce(162 BIQ: FnOnce(
136 Arc<FullClient>,163 Arc<FullClient<RuntimeApi, ExecutorDispatch>>,
137 &Configuration,164 &Configuration,
138 Option<TelemetryHandle>,165 Option<TelemetryHandle>,
139 &TaskManager,166 &TaskManager,
140 ) -> Result<sc_consensus::DefaultImportQueue<Block, FullClient>, sc_service::Error>,167 ) -> Result<
168 sc_consensus::DefaultImportQueue<Block, FullClient<RuntimeApi, ExecutorDispatch>>,
169 sc_service::Error,
170 >,
141{171{
142 let _telemetry = config172 let _telemetry = config
143 .telemetry_endpoints173 .telemetry_endpoints
231///261///
232/// This is the actual implementation that is abstract over the executor and the runtime api.262/// This is the actual implementation that is abstract over the executor and the runtime api.
233#[sc_tracing::logging::prefix_logs_with("Parachain")]263#[sc_tracing::logging::prefix_logs_with("Parachain")]
234async fn start_node_impl<BIQ, BIC>(264async fn start_node_impl<Runtime, RuntimeApi, ExecutorDispatch, BIQ, BIC>(
235 parachain_config: Configuration,265 parachain_config: Configuration,
236 polkadot_config: Configuration,266 polkadot_config: Configuration,
237 id: ParaId,267 id: ParaId,
238 build_import_queue: BIQ,268 build_import_queue: BIQ,
239 build_consensus: BIC,269 build_consensus: BIC,
240) -> sc_service::error::Result<(TaskManager, Arc<FullClient>)>270) -> sc_service::error::Result<(TaskManager, Arc<FullClient<RuntimeApi, ExecutorDispatch>>)>
241where271where
242 sc_client_api::StateBackendFor<FullBackend, Block>: sp_api::StateBackend<BlakeTwo256>,272 sc_client_api::StateBackendFor<FullBackend, Block>: sp_api::StateBackend<BlakeTwo256>,
273 Runtime: RuntimeInstance + Send + Sync + 'static,
274 <Runtime as RuntimeInstance>::CrossAccountId: Serialize,
275 for<'de> <Runtime as RuntimeInstance>::CrossAccountId: Deserialize<'de>,
276 RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>
277 + Send
278 + Sync
279 + 'static,
280 RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>
281 + fp_rpc::EthereumRuntimeRPCApi<Block>
282 + sp_session::SessionKeys<Block>
283 + sp_block_builder::BlockBuilder<Block>
284 + pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance>
285 + sp_api::ApiExt<Block, StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>
286 + up_rpc::UniqueApi<Block, Runtime::CrossAccountId, AccountId>
287 + substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>
288 + sp_api::Metadata<Block>
289 + sp_offchain::OffchainWorkerApi<Block>
290 + cumulus_primitives_core::CollectCollationInfo<Block>,
243 ExecutorDispatch: NativeExecutionDispatch + 'static,291 ExecutorDispatch: NativeExecutionDispatch + 'static,
244 BIQ: FnOnce(292 BIQ: FnOnce(
245 Arc<FullClient>,293 Arc<FullClient<RuntimeApi, ExecutorDispatch>>,
246 &Configuration,294 &Configuration,
247 Option<TelemetryHandle>,295 Option<TelemetryHandle>,
248 &TaskManager,296 &TaskManager,
249 ) -> Result<sc_consensus::DefaultImportQueue<Block, FullClient>, sc_service::Error>,297 ) -> Result<
298 sc_consensus::DefaultImportQueue<Block, FullClient<RuntimeApi, ExecutorDispatch>>,
299 sc_service::Error,
300 >,
250 BIC: FnOnce(301 BIC: FnOnce(
251 Arc<FullClient>,302 Arc<FullClient<RuntimeApi, ExecutorDispatch>>,
252 Option<&Registry>,303 Option<&Registry>,
253 Option<TelemetryHandle>,304 Option<TelemetryHandle>,
254 &TaskManager,305 &TaskManager,
255 Arc<dyn RelayChainInterface>,306 Arc<dyn RelayChainInterface>,
256 Arc<sc_transaction_pool::FullPool<Block, FullClient>>,307 Arc<sc_transaction_pool::FullPool<Block, FullClient<RuntimeApi, ExecutorDispatch>>>,
257 Arc<NetworkService<Block, Hash>>,308 Arc<NetworkService<Block, Hash>>,
258 SyncCryptoStorePtr,309 SyncCryptoStorePtr,
259 bool,310 bool,
265316
266 let parachain_config = prepare_node_config(parachain_config);317 let parachain_config = prepare_node_config(parachain_config);
267318
268 let params = new_partial::<BIQ>(&parachain_config, build_import_queue)?;319 let params =
320 new_partial::<RuntimeApi, ExecutorDispatch, BIQ>(&parachain_config, build_import_queue)?;
269 let (mut telemetry, filter_pool, frontier_backend, telemetry_worker_handle, fee_history_cache) =321 let (mut telemetry, filter_pool, frontier_backend, telemetry_worker_handle, fee_history_cache) =
270 params.other;322 params.other;
271323
311363
312 let block_data_cache = Arc::new(fc_rpc::EthBlockDataCache::new(364 let block_data_cache = Arc::new(fc_rpc::EthBlockDataCache::new(
313 task_manager.spawn_handle(),365 task_manager.spawn_handle(),
314 overrides_handle(client.clone()),366 overrides_handle::<_, _, Runtime>(client.clone()),
315 50,367 50,
316 50,368 50,
317 ));369 ));
337 fee_history_limit: 2048,389 fee_history_limit: 2048,
338 };390 };
339391
340 Ok(unique_rpc::create_full::<_, _, _, _, RuntimeApi, _>(392 Ok(
393 unique_rpc::create_full::<_, _, _, _, Runtime, RuntimeApi, _>(
341 full_deps,394 full_deps,
342 subscription_executor.clone(),395 subscription_executor.clone(),
343 ))396 ),
397 )
344 });398 });
345399
346 task_manager.spawn_essential_handle().spawn(400 task_manager.spawn_essential_handle().spawn(
427}481}
428482
429/// Build the import queue for the the parachain runtime.483/// Build the import queue for the the parachain runtime.
430pub fn parachain_build_import_queue(484pub fn parachain_build_import_queue<RuntimeApi, ExecutorDispatch>(
431 client: Arc<FullClient>,485 client: Arc<FullClient<RuntimeApi, ExecutorDispatch>>,
432 config: &Configuration,486 config: &Configuration,
433 telemetry: Option<TelemetryHandle>,487 telemetry: Option<TelemetryHandle>,
434 task_manager: &TaskManager,488 task_manager: &TaskManager,
435) -> Result<sc_consensus::DefaultImportQueue<Block, FullClient>, sc_service::Error> {489) -> Result<
490 sc_consensus::DefaultImportQueue<Block, FullClient<RuntimeApi, ExecutorDispatch>>,
491 sc_service::Error,
492>
493where
494 RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>
495 + Send
496 + Sync
497 + 'static,
498 RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>
499 + sp_block_builder::BlockBuilder<Block>
500 + sp_consensus_aura::AuraApi<Block, AuraId>
501 + sp_api::ApiExt<Block, StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>,
502 ExecutorDispatch: NativeExecutionDispatch + 'static,
503{
436 let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?;504 let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?;
437505
438 cumulus_client_consensus_aura::import_queue::<506 cumulus_client_consensus_aura::import_queue::<
466}534}
467535
468/// Start a normal parachain node.536/// Start a normal parachain node.
469pub async fn start_node(537pub async fn start_node<Runtime, RuntimeApi, ExecutorDispatch>(
470 parachain_config: Configuration,538 parachain_config: Configuration,
471 polkadot_config: Configuration,539 polkadot_config: Configuration,
472 id: ParaId,540 id: ParaId,
473) -> sc_service::error::Result<(TaskManager, Arc<FullClient>)> {541) -> sc_service::error::Result<(TaskManager, Arc<FullClient<RuntimeApi, ExecutorDispatch>>)>
542where
543 Runtime: RuntimeInstance + Send + Sync + 'static,
544 <Runtime as RuntimeInstance>::CrossAccountId: Serialize,
545 for<'de> <Runtime as RuntimeInstance>::CrossAccountId: Deserialize<'de>,
546 RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>
547 + Send
548 + Sync
549 + 'static,
550 RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>
551 + fp_rpc::EthereumRuntimeRPCApi<Block>
552 + sp_session::SessionKeys<Block>
553 + sp_block_builder::BlockBuilder<Block>
554 + pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance>
555 + sp_api::ApiExt<Block, StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>
556 + up_rpc::UniqueApi<Block, Runtime::CrossAccountId, AccountId>
557 + substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>
558 + sp_api::Metadata<Block>
559 + sp_offchain::OffchainWorkerApi<Block>
560 + cumulus_primitives_core::CollectCollationInfo<Block>
561 + sp_consensus_aura::AuraApi<Block, AuraId>,
562 ExecutorDispatch: NativeExecutionDispatch + 'static,
563{
474 start_node_impl::<_, _>(564 start_node_impl::<Runtime, RuntimeApi, ExecutorDispatch, _, _>(
475 parachain_config,565 parachain_config,
476 polkadot_config,566 polkadot_config,
477 id,567 id,
547 },637 },
548 )638 )
549 .await639 .await
640}
641
642fn dev_build_import_queue<RuntimeApi, ExecutorDispatch>(
643 client: Arc<FullClient<RuntimeApi, ExecutorDispatch>>,
644 config: &Configuration,
645 _: Option<TelemetryHandle>,
646 task_manager: &TaskManager,
647) -> Result<
648 sc_consensus::DefaultImportQueue<Block, FullClient<RuntimeApi, ExecutorDispatch>>,
649 sc_service::Error,
650>
651where
652 RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>
653 + Send
654 + Sync
655 + 'static,
656 RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>
657 + sp_api::ApiExt<Block, StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>,
658 ExecutorDispatch: NativeExecutionDispatch + 'static,
659{
660 Ok(sc_consensus_manual_seal::import_queue(
661 Box::new(client.clone()),
662 &task_manager.spawn_essential_handle(),
663 config.prometheus_registry(),
664 ))
665}
666
667/// Builds a new development service. This service uses instant seal, and mocks
668/// the parachain inherent
669pub fn start_dev_node<Runtime, RuntimeApi, ExecutorDispatch>(
670 config: Configuration,
671) -> sc_service::error::Result<TaskManager>
672where
673 Runtime: RuntimeInstance + Send + Sync + 'static,
674 <Runtime as RuntimeInstance>::CrossAccountId: Serialize,
675 for<'de> <Runtime as RuntimeInstance>::CrossAccountId: Deserialize<'de>,
676 RuntimeApi: sp_api::ConstructRuntimeApi<Block, FullClient<RuntimeApi, ExecutorDispatch>>
677 + Send
678 + Sync
679 + 'static,
680 RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>
681 + fp_rpc::EthereumRuntimeRPCApi<Block>
682 + sp_session::SessionKeys<Block>
683 + sp_block_builder::BlockBuilder<Block>
684 + pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance>
685 + sp_api::ApiExt<Block, StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>
686 + up_rpc::UniqueApi<Block, Runtime::CrossAccountId, AccountId>
687 + substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>
688 + sp_api::Metadata<Block>
689 + sp_offchain::OffchainWorkerApi<Block>
690 + cumulus_primitives_core::CollectCollationInfo<Block>
691 + sp_consensus_aura::AuraApi<Block, AuraId>,
692 ExecutorDispatch: NativeExecutionDispatch + 'static,
693{
694 use futures::Stream;
695 use sc_consensus_manual_seal::{run_manual_seal, EngineCommand, ManualSealParams};
696 use fc_consensus::FrontierBlockImport;
697 use sc_client_api::HeaderBackend;
698
699 let sc_service::PartialComponents {
700 client,
701 backend,
702 mut task_manager,
703 import_queue,
704 keystore_container,
705 select_chain: maybe_select_chain,
706 transaction_pool,
707 other:
708 (telemetry, filter_pool, frontier_backend, _telemetry_worker_handle, fee_history_cache),
709 } = new_partial::<RuntimeApi, ExecutorDispatch, _>(
710 &config,
711 dev_build_import_queue::<RuntimeApi, ExecutorDispatch>,
712 )?;
713
714 let block_data_cache = Arc::new(fc_rpc::EthBlockDataCache::new(
715 task_manager.spawn_handle(),
716 overrides_handle::<_, _, Runtime>(client.clone()),
717 50,
718 50,
719 ));
720
721 let (network, system_rpc_tx, network_starter) =
722 sc_service::build_network(sc_service::BuildNetworkParams {
723 config: &config,
724 client: client.clone(),
725 transaction_pool: transaction_pool.clone(),
726 spawn_handle: task_manager.spawn_handle(),
727 import_queue,
728 block_announce_validator_builder: None,
729 warp_sync: None,
730 })?;
731
732 if config.offchain_worker.enabled {
733 sc_service::build_offchain_workers(
734 &config,
735 task_manager.spawn_handle(),
736 client.clone(),
737 network.clone(),
738 );
739 }
740
741 let prometheus_registry = config.prometheus_registry().cloned();
742 let collator = config.role.is_authority();
743
744 let select_chain = maybe_select_chain.clone();
745
746 if collator {
747 let block_import =
748 FrontierBlockImport::new(client.clone(), client.clone(), frontier_backend.clone());
749
750 let env = sc_basic_authorship::ProposerFactory::new(
751 task_manager.spawn_handle(),
752 client.clone(),
753 transaction_pool.clone(),
754 prometheus_registry.as_ref(),
755 telemetry.as_ref().map(|x| x.handle()),
756 );
757
758 let commands_stream: Box<dyn Stream<Item = EngineCommand<Hash>> + Send + Sync + Unpin> =
759 Box::new(
760 // This bit cribbed from the implementation of instant seal.
761 transaction_pool
762 .pool()
763 .validated_pool()
764 .import_notification_stream()
765 .map(|_| EngineCommand::SealNewBlock {
766 create_empty: true, // was false in Moonbeam
767 finalize: false,
768 parent_hash: None,
769 sender: None,
770 }),
771 );
772
773 let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?;
774 let client_set_aside_for_cidp = client.clone();
775
776 task_manager.spawn_essential_handle().spawn_blocking(
777 "authorship_task",
778 Some("block-authoring"),
779 run_manual_seal(ManualSealParams {
780 block_import,
781 env,
782 client: client.clone(),
783 pool: transaction_pool.clone(),
784 commands_stream,
785 select_chain: select_chain.clone(),
786 consensus_data_provider: None,
787 create_inherent_data_providers: move |block: Hash, ()| {
788 let current_para_block = client_set_aside_for_cidp
789 .number(block)
790 .expect("Header lookup should succeed")
791 .expect("Header passed in as parent should be present in backend.");
792
793 let client_for_xcm = client_set_aside_for_cidp.clone();
794 async move {
795 let time = sp_timestamp::InherentDataProvider::from_system_time();
796
797 let mocked_parachain = cumulus_primitives_parachain_inherent::MockValidationDataInherentDataProvider {
798 current_para_block,
799 relay_offset: 1000,
800 relay_blocks_per_para_block: 2,
801 xcm_config: cumulus_primitives_parachain_inherent::MockXcmConfig::new(
802 &*client_for_xcm,
803 block,
804 Default::default(),
805 Default::default(),
806 ),
807 raw_downward_messages: vec![],
808 raw_horizontal_messages: vec![],
809 };
810
811 let slot =
812 sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_duration(
813 *time,
814 slot_duration.slot_duration(),
815 );
816
817 Ok((time, slot, mocked_parachain))
818 }
819 },
820 }),
821 );
822 }
823
824 task_manager.spawn_essential_handle().spawn(
825 "frontier-mapping-sync-worker",
826 Some("block-authoring"),
827 MappingSyncWorker::new(
828 client.import_notification_stream(),
829 Duration::new(6, 0),
830 client.clone(),
831 backend.clone(),
832 frontier_backend.clone(),
833 SyncStrategy::Normal,
834 )
835 .for_each(|()| futures::future::ready(())),
836 );
837
838 let subscription_executor = sc_rpc::SubscriptionTaskExecutor::new(task_manager.spawn_handle());
839 let rpc_client = client.clone();
840 let rpc_pool = transaction_pool.clone();
841 let rpc_network = network.clone();
842 let rpc_frontier_backend = frontier_backend.clone();
843 let rpc_extensions_builder = Box::new(move |deny_unsafe, _| {
844 let full_deps = unique_rpc::FullDeps {
845 backend: rpc_frontier_backend.clone(),
846 deny_unsafe,
847 client: rpc_client.clone(),
848 pool: rpc_pool.clone(),
849 graph: rpc_pool.pool().clone(),
850 // TODO: Unhardcode
851 enable_dev_signer: false,
852 filter_pool: filter_pool.clone(),
853 network: rpc_network.clone(),
854 select_chain: select_chain.clone(),
855 is_authority: collator,
856 // TODO: Unhardcode
857 max_past_logs: 10000,
858 block_data_cache: block_data_cache.clone(),
859 fee_history_cache: fee_history_cache.clone(),
860 // TODO: Unhardcode
861 fee_history_limit: 2048,
862 };
863
864 Ok(
865 unique_rpc::create_full::<_, _, _, _, Runtime, RuntimeApi, _>(
866 full_deps,
867 subscription_executor.clone(),
868 ),
869 )
870 });
871
872 sc_service::spawn_tasks(sc_service::SpawnTasksParams {
873 network,
874 client,
875 keystore: keystore_container.sync_keystore(),
876 task_manager: &mut task_manager,
877 transaction_pool,
878 rpc_extensions_builder,
879 backend,
880 system_rpc_tx,
881 config,
882 telemetry: None,
883 })?;
884
885 network_starter.start_network();
886 Ok(task_manager)
550}887}
551888
modifiednode/rpc/Cargo.tomldiffbeforeafterboth
48fc-db = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.17" }48fc-db = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.17" }
49fc-mapping-sync = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.17" }49fc-mapping-sync = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.17" }
5050
51pallet-common = { default-features = false, path = "../../pallets/common" }
52unique-runtime-common = { default-features = false, path = "../../runtime/common" }
51pallet-unique = { path = "../../pallets/unique" }53pallet-unique = { path = "../../pallets/unique" }
52uc-rpc = { path = "../../client/rpc" }54uc-rpc = { path = "../../client/rpc" }
53up-rpc = { path = "../../primitives/rpc" }55up-rpc = { path = "../../primitives/rpc" }
54unique-runtime = { path = "../../runtime" }56
57[dependencies.serde]
58features = ['derive']
59version = '1.0.130'
5560
56[features]61[features]
62default = []
57std = []63std = []
5864
modifiednode/rpc/src/lib.rsdiffbeforeafterboth
15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
1616
17use sp_runtime::traits::BlakeTwo256;17use sp_runtime::traits::BlakeTwo256;
18use unique_runtime::{Hash, AccountId, CrossAccountId, Index, opaque::Block, BlockNumber, Balance};
19use fc_rpc::{18use fc_rpc::{
20 EthBlockDataCache, OverrideHandle, RuntimeApiStorageOverride, SchemaV1Override,19 EthBlockDataCache, OverrideHandle, RuntimeApiStorageOverride, SchemaV1Override,
21 StorageOverride, SchemaV2Override, SchemaV3Override,20 StorageOverride, SchemaV2Override, SchemaV3Override,
41use sc_service::TransactionPool;40use sc_service::TransactionPool;
42use std::{collections::BTreeMap, marker::PhantomData, sync::Arc};41use std::{collections::BTreeMap, marker::PhantomData, sync::Arc};
42
43use unique_runtime_common::types::{
44 Hash, AccountId, RuntimeInstance, Index, Block, BlockNumber, Balance,
45};
4346
44/// Public io handler for exporting into other modules47/// Public io handler for exporting into other modules
45pub type IoHandler = jsonrpc_core::IoHandler<sc_rpc::Metadata>;48pub type IoHandler = jsonrpc_core::IoHandler<sc_rpc::Metadata>;
90 pub block_data_cache: Arc<EthBlockDataCache<Block>>,93 pub block_data_cache: Arc<EthBlockDataCache<Block>>,
91}94}
9295
93struct AccountCodes<C, B> {96struct AccountCodes<C, B, R> {
94 client: Arc<C>,97 client: Arc<C>,
95 _marker: PhantomData<B>,98 _blk_marker: PhantomData<B>,
99 _runtime_marker: PhantomData<R>,
96}100}
97101
98impl<C, Block> AccountCodes<C, Block>102impl<C, Block, R> AccountCodes<C, Block, R>
99where103where
100 Block: sp_api::BlockT,104 Block: sp_api::BlockT,
101 C: ProvideRuntimeApi<Block>,105 C: ProvideRuntimeApi<Block>,
106 R: RuntimeInstance,
102{107{
103 fn new(client: Arc<C>) -> Self {108 fn new(client: Arc<C>) -> Self {
104 Self {109 Self {
105 client,110 client,
106 _marker: PhantomData,111 _blk_marker: PhantomData,
112 _runtime_marker: PhantomData,
107 }113 }
108 }114 }
109}115}
110116
111impl<C, Block> fc_rpc::AccountCodeProvider<Block> for AccountCodes<C, Block>117impl<C, Block, Runtime> fc_rpc::AccountCodeProvider<Block> for AccountCodes<C, Block, Runtime>
112where118where
113 Block: sp_api::BlockT,119 Block: sp_api::BlockT,
114 C: ProvideRuntimeApi<Block>,120 C: ProvideRuntimeApi<Block>,
115 C::Api: up_rpc::UniqueApi<Block, CrossAccountId, AccountId>,121 C::Api: up_rpc::UniqueApi<Block, <Runtime as RuntimeInstance>::CrossAccountId, AccountId>,
122 Runtime: RuntimeInstance,
116{123{
117 fn code(&self, block: &sp_api::BlockId<Block>, account: sp_core::H160) -> Option<Vec<u8>> {124 fn code(&self, block: &sp_api::BlockId<Block>, account: sp_core::H160) -> Option<Vec<u8>> {
118 use up_rpc::UniqueApi;125 use up_rpc::UniqueApi;
124 }131 }
125}132}
126133
127pub fn overrides_handle<C, BE>(client: Arc<C>) -> Arc<OverrideHandle<Block>>134pub fn overrides_handle<C, BE, R>(client: Arc<C>) -> Arc<OverrideHandle<Block>>
128where135where
129 C: ProvideRuntimeApi<Block> + StorageProvider<Block, BE> + AuxStore,136 C: ProvideRuntimeApi<Block> + StorageProvider<Block, BE> + AuxStore,
130 C: HeaderBackend<Block> + HeaderMetadata<Block, Error = BlockChainError>,137 C: HeaderBackend<Block> + HeaderMetadata<Block, Error = BlockChainError>,
131 C: Send + Sync + 'static,138 C: Send + Sync + 'static,
132 C::Api: fp_rpc::EthereumRuntimeRPCApi<Block>,139 C::Api: fp_rpc::EthereumRuntimeRPCApi<Block>,
133 C::Api: up_rpc::UniqueApi<Block, CrossAccountId, AccountId>,140 C::Api: up_rpc::UniqueApi<Block, <R as RuntimeInstance>::CrossAccountId, AccountId>,
134 BE: Backend<Block> + 'static,141 BE: Backend<Block> + 'static,
135 BE::State: StateBackend<BlakeTwo256>,142 BE::State: StateBackend<BlakeTwo256>,
143 R: RuntimeInstance + Send + Sync + 'static,
136{144{
137 let mut overrides_map = BTreeMap::new();145 let mut overrides_map = BTreeMap::new();
138 overrides_map.insert(146 overrides_map.insert(
139 EthereumStorageSchema::V1,147 EthereumStorageSchema::V1,
140 Box::new(SchemaV1Override::new_with_code_provider(148 Box::new(SchemaV1Override::new_with_code_provider(
141 client.clone(),149 client.clone(),
142 Arc::new(AccountCodes::<C, Block>::new(client.clone())),150 Arc::new(AccountCodes::<C, Block, R>::new(client.clone())),
143 )) as Box<dyn StorageOverride<_> + Send + Sync>,151 )) as Box<dyn StorageOverride<_> + Send + Sync>,
144 );152 );
145 overrides_map.insert(153 overrides_map.insert(
160}168}
161169
162/// Instantiate all Full RPC extensions.170/// Instantiate all Full RPC extensions.
163pub fn create_full<C, P, SC, CA, A, B>(171pub fn create_full<C, P, SC, CA, R, A, B>(
164 deps: FullDeps<C, P, SC, CA>,172 deps: FullDeps<C, P, SC, CA>,
165 subscription_task_executor: SubscriptionTaskExecutor,173 subscription_task_executor: SubscriptionTaskExecutor,
166) -> jsonrpc_core::IoHandler<sc_rpc_api::Metadata>174) -> jsonrpc_core::IoHandler<sc_rpc_api::Metadata>
174 // C::Api: pallet_contracts_rpc::ContractsRuntimeApi<Block, AccountId, Balance, BlockNumber, Hash>,182 // C::Api: pallet_contracts_rpc::ContractsRuntimeApi<Block, AccountId, Balance, BlockNumber, Hash>,
175 C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi<Block, Balance>,183 C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi<Block, Balance>,
176 C::Api: fp_rpc::EthereumRuntimeRPCApi<Block>,184 C::Api: fp_rpc::EthereumRuntimeRPCApi<Block>,
177 C::Api: up_rpc::UniqueApi<Block, CrossAccountId, AccountId>,185 C::Api: up_rpc::UniqueApi<Block, <R as RuntimeInstance>::CrossAccountId, AccountId>,
178 B: sc_client_api::Backend<Block> + Send + Sync + 'static,186 B: sc_client_api::Backend<Block> + Send + Sync + 'static,
179 B::State: sc_client_api::backend::StateBackend<sp_runtime::traits::HashFor<Block>>,187 B::State: sc_client_api::backend::StateBackend<sp_runtime::traits::HashFor<Block>>,
180 P: TransactionPool<Block = Block> + 'static,188 P: TransactionPool<Block = Block> + 'static,
181 CA: ChainApi<Block = Block> + 'static,189 CA: ChainApi<Block = Block> + 'static,
190 R: RuntimeInstance + Send + Sync + 'static,
191 <R as RuntimeInstance>::CrossAccountId: serde::Serialize,
192 for<'de> <R as RuntimeInstance>::CrossAccountId: serde::Deserialize<'de>,
182{193{
183 use fc_rpc::{194 use fc_rpc::{
184 EthApi, EthApiServer, EthDevSigner, EthFilterApi, EthFilterApiServer, EthPubSubApi,195 EthApi, EthApiServer, EthDevSigner, EthFilterApi, EthFilterApiServer, EthPubSubApi,
225 signers.push(Box::new(EthDevSigner::new()) as Box<dyn EthSigner>);236 signers.push(Box::new(EthDevSigner::new()) as Box<dyn EthSigner>);
226 }237 }
227238
228 let overrides = overrides_handle(client.clone());239 let overrides = overrides_handle::<_, _, R>(client.clone());
229240
230 io.extend_with(EthApiServer::to_delegate(EthApi::new(241 io.extend_with(EthApiServer::to_delegate(EthApi::new(
231 client.clone(),242 client.clone(),
232 pool.clone(),243 pool.clone(),
233 graph,244 graph,
234 unique_runtime::TransactionConverter,245 <R as RuntimeInstance>::get_transaction_converter(),
235 network.clone(),246 network.clone(),
236 signers,247 signers,
237 overrides.clone(),248 overrides.clone(),
deletedruntime/Cargo.tomldiffbeforeafterboth

no changes

deletedruntime/build.rsdiffbeforeafterboth

no changes

addedruntime/common/Cargo.tomldiffbeforeafterboth

no changes

addedruntime/common/src/constants.rsdiffbeforeafterboth

no changes

addedruntime/common/src/lib.rsdiffbeforeafterboth

no changes

addedruntime/common/src/runtime_apis.rsdiffbeforeafterboth

no changes

addedruntime/common/src/types.rsdiffbeforeafterboth

no changes

addedruntime/opal/Cargo.tomldiffbeforeafterboth

no changes

addedruntime/opal/build.rsdiffbeforeafterboth

no changes

addedruntime/opal/src/lib.rsdiffbeforeafterboth

no changes

addedruntime/quartz/Cargo.tomldiffbeforeafterboth

no changes

addedruntime/quartz/build.rsdiffbeforeafterboth

no changes

addedruntime/quartz/src/lib.rsdiffbeforeafterboth

no changes

deletedruntime/src/lib.rsdiffbeforeafterboth

no changes

addedruntime/unique/Cargo.tomldiffbeforeafterboth

no changes

addedruntime/unique/build.rsdiffbeforeafterboth

no changes

addedruntime/unique/src/lib.rsdiffbeforeafterboth

no changes