From 38f1350370f29282d847c89300365290c0f14a90 Mon Sep 17 00:00:00 2001 From: Nazar Mokrynskyi Date: Sun, 27 Mar 2022 23:08:45 +0300 Subject: [PATCH] Revert "Combine runtimes" --- Cargo.lock | 86 +- crates/subspace-consensus-runtime/Cargo.toml | 112 -- crates/subspace-consensus-runtime/src/lib.rs | 984 ------------------ crates/subspace-node/src/bin/subspace-node.rs | 11 +- crates/subspace-node/src/chain_spec.rs | 25 +- crates/subspace-node/src/lib.rs | 6 +- crates/subspace-runtime/Cargo.toml | 97 +- crates/subspace-runtime/src/lib.rs | 984 +++++++++++++++++- .../tests/integration/main.rs | 0 .../tests/integration/object_mapping.rs | 2 +- cumulus/parachain-template/node/Cargo.toml | 5 +- .../parachain-template/node/src/chain_spec.rs | 14 +- .../parachain-template/node/src/command.rs | 4 +- cumulus/parachain-template/node/src/rpc.rs | 2 +- .../parachain-template/node/src/service.rs | 14 +- cumulus/parachain-template/runtime/Cargo.toml | 3 + cumulus/parachain-template/runtime/build.rs | 9 + cumulus/parachain-template/runtime/src/lib.rs | 4 + 18 files changed, 1167 insertions(+), 1195 deletions(-) delete mode 100644 crates/subspace-consensus-runtime/Cargo.toml delete mode 100644 crates/subspace-consensus-runtime/src/lib.rs rename crates/{subspace-consensus-runtime => subspace-runtime}/tests/integration/main.rs (100%) rename crates/{subspace-consensus-runtime => subspace-runtime}/tests/integration/object_mapping.rs (98%) create mode 100644 cumulus/parachain-template/runtime/build.rs diff --git a/Cargo.lock b/Cargo.lock index 7c93641ecd40f..51b90c46fd135 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5263,6 +5263,7 @@ dependencies = [ "jsonrpc-core", "log", "pallet-transaction-payment-rpc", + "parachain-template-runtime", "parity-scale-codec", "sc-basic-authorship", "sc-chain-spec", @@ -5328,6 +5329,7 @@ dependencies = [ "sp-std", "sp-transaction-pool", "sp-version", + "substrate-wasm-builder", ] [[package]] @@ -8680,50 +8682,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "subspace-consensus-runtime" -version = "0.1.0" -dependencies = [ - "frame-benchmarking", - "frame-executive", - "frame-support", - "frame-system", - "frame-system-benchmarking", - "frame-system-rpc-runtime-api", - "hex-literal", - "orml-vesting", - "pallet-balances", - "pallet-executor", - "pallet-feeds", - "pallet-object-store", - "pallet-offences-subspace", - "pallet-rewards", - "pallet-subspace", - "pallet-sudo", - "pallet-timestamp", - "pallet-transaction-fees", - "pallet-transaction-payment", - "pallet-transaction-payment-rpc-runtime-api", - "pallet-utility", - "parity-scale-codec", - "scale-info", - "sp-api", - "sp-block-builder", - "sp-consensus-slots", - "sp-consensus-subspace", - "sp-core", - "sp-executor", - "sp-inherents", - "sp-offchain", - "sp-runtime", - "sp-session", - "sp-std", - "sp-transaction-pool", - "sp-version", - "subspace-core-primitives", - "subspace-runtime-primitives", -] - [[package]] name = "subspace-core-primitives" version = "0.1.0" @@ -8840,8 +8798,44 @@ dependencies = [ name = "subspace-runtime" version = "0.1.0" dependencies = [ - "parachain-template-runtime", - "subspace-consensus-runtime", + "frame-benchmarking", + "frame-executive", + "frame-support", + "frame-system", + "frame-system-benchmarking", + "frame-system-rpc-runtime-api", + "hex-literal", + "orml-vesting", + "pallet-balances", + "pallet-executor", + "pallet-feeds", + "pallet-object-store", + "pallet-offences-subspace", + "pallet-rewards", + "pallet-subspace", + "pallet-sudo", + "pallet-timestamp", + "pallet-transaction-fees", + "pallet-transaction-payment", + "pallet-transaction-payment-rpc-runtime-api", + "pallet-utility", + "parity-scale-codec", + "scale-info", + "sp-api", + "sp-block-builder", + "sp-consensus-slots", + "sp-consensus-subspace", + "sp-core", + "sp-executor", + "sp-inherents", + "sp-offchain", + "sp-runtime", + "sp-session", + "sp-std", + "sp-transaction-pool", + "sp-version", + "subspace-core-primitives", + "subspace-runtime-primitives", "substrate-wasm-builder", ] diff --git a/crates/subspace-consensus-runtime/Cargo.toml b/crates/subspace-consensus-runtime/Cargo.toml deleted file mode 100644 index 80f63165e2b12..0000000000000 --- a/crates/subspace-consensus-runtime/Cargo.toml +++ /dev/null @@ -1,112 +0,0 @@ -[package] -name = "subspace-consensus-runtime" -version = "0.1.0" -authors = ["Subspace Labs "] -edition = "2021" -license = "GPL-3.0-or-later" -homepage = "https://subspace.network" -repository = "https://github.com/subspace/subspace" -include = [ - "/src", - "/Cargo.toml", -] - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] - -[dependencies] -codec = { package = "parity-scale-codec", version = "3.1.2", default-features = false, features = ["derive"] } -frame-executive = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998" } -frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998" } -frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998" } -hex-literal = { version = "0.3.3", optional = true } -orml-vesting = { version = "0.4.1-dev", default-features = false, git = "https://github.com/subspace/open-runtime-module-library", rev = "0e9f38313775b94c87c289f346e50f900db2bab7" } -pallet-balances = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998" } -pallet-executor = { version = "0.1.0", default-features = false, path = "../pallet-executor" } -pallet-feeds = { version = "0.1.0", default-features = false, path = "../pallet-feeds" } -pallet-object-store = { version = "0.1.0", default-features = false, path = "../pallet-object-store" } -pallet-offences-subspace = { version = "0.1.0", default-features = false, path = "../pallet-offences-subspace" } -pallet-rewards = { version = "0.1.0", default-features = false, path = "../pallet-rewards" } -pallet-subspace = { version = "0.1.0", default-features = false, features = ["no-early-solution-range-updates"], path = "../pallet-subspace" } -pallet-sudo = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998" } -pallet-timestamp = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998" } -pallet-transaction-fees = { version = "0.1.0", default-features = false, path = "../pallet-transaction-fees" } -pallet-transaction-payment = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998" } -pallet-utility = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998" } -scale-info = { version = "2.0.1", default-features = false, features = ["derive"] } -sp-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998" } -sp-block-builder = { git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998", default-features = false, version = "4.0.0-dev"} -sp-consensus-subspace = { version = "0.1.0", default-features = false, path = "../sp-consensus-subspace" } -sp-consensus-slots = { version = "0.10.0-dev", default-features = false, git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998" } -sp-core = { version = "6.0.0", default-features = false, git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998" } -sp-executor = { version = "0.1.0", default-features = false, path = "../sp-executor" } -sp-inherents = { git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998", default-features = false, version = "4.0.0-dev"} -sp-offchain = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998" } -sp-runtime = { version = "6.0.0", default-features = false, git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998" } -sp-session = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998" } -sp-std = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998" } -sp-transaction-pool = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998" } -sp-version = { version = "5.0.0", default-features = false, git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998" } -subspace-core-primitives = { version = "0.1.0", default-features = false, path = "../subspace-core-primitives" } -subspace-runtime-primitives = { version = "0.1.0", default-features = false, path = "../subspace-runtime-primitives" } - -# Used for the node template's RPCs -frame-system-rpc-runtime-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998" } -pallet-transaction-payment-rpc-runtime-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998" } - -# Used for runtime benchmarking -frame-benchmarking = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998", optional = true } -frame-system-benchmarking = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998", optional = true } - -[features] -default = ["std"] -std = [ - "codec/std", - "frame-executive/std", - "frame-support/std", - "frame-system/std", - "frame-system-rpc-runtime-api/std", - "orml-vesting/std", - "pallet-balances/std", - "pallet-executor/std", - "pallet-feeds/std", - "pallet-object-store/std", - "pallet-offences-subspace/std", - "pallet-rewards/std", - "pallet-subspace/std", - "pallet-sudo/std", - "pallet-timestamp/std", - "pallet-transaction-fees/std", - "pallet-transaction-payment-rpc-runtime-api/std", - "pallet-transaction-payment/std", - "pallet-utility/std", - "scale-info/std", - "sp-api/std", - "sp-block-builder/std", - "sp-consensus-subspace/std", - "sp-consensus-slots/std", - "sp-core/std", - "sp-executor/std", - "sp-inherents/std", - "sp-offchain/std", - "sp-runtime/std", - "sp-session/std", - "sp-std/std", - "sp-transaction-pool/std", - "sp-version/std", - "subspace-core-primitives/std", - "subspace-runtime-primitives/std", -] -runtime-benchmarks = [ - "frame-benchmarking/runtime-benchmarks", - "frame-support/runtime-benchmarks", - "frame-system-benchmarking", - "frame-system/runtime-benchmarks", - "hex-literal", - "orml-vesting/runtime-benchmarks", - "pallet-balances/runtime-benchmarks", - "pallet-timestamp/runtime-benchmarks", - "pallet-utility/runtime-benchmarks", - "sp-runtime/runtime-benchmarks", -] -do-not-enforce-cost-of-storage = [] diff --git a/crates/subspace-consensus-runtime/src/lib.rs b/crates/subspace-consensus-runtime/src/lib.rs deleted file mode 100644 index cbc725f7cd4d5..0000000000000 --- a/crates/subspace-consensus-runtime/src/lib.rs +++ /dev/null @@ -1,984 +0,0 @@ -// Copyright (C) 2021 Subspace Labs, Inc. -// SPDX-License-Identifier: GPL-3.0-or-later - -// 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 . - -#![cfg_attr(not(feature = "std"), no_std)] -#![feature(const_option)] -// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256. -#![recursion_limit = "256"] - -use codec::{Compact, CompactLen, Decode, Encode}; -use core::time::Duration; -use frame_support::traits::{ - ConstU128, ConstU16, ConstU32, ConstU64, ConstU8, Currency, ExistenceRequirement, Get, - Imbalance, WithdrawReasons, -}; -use frame_support::weights::{ - constants::{RocksDbWeight, WEIGHT_PER_SECOND}, - IdentityFee, -}; -use frame_support::{construct_runtime, parameter_types}; -use frame_system::limits::{BlockLength, BlockWeights}; -use frame_system::EnsureNever; -use pallet_balances::NegativeImbalance; -use sp_api::{impl_runtime_apis, BlockT, HashT, HeaderT}; -use sp_consensus_subspace::digests::CompatibleDigestItem; -use sp_consensus_subspace::{ - EquivocationProof, FarmerPublicKey, GlobalRandomnesses, Salts, SolutionRanges, -}; -use sp_core::{crypto::KeyTypeId, OpaqueMetadata}; -use sp_executor::{FraudProof, OpaqueBundle}; -use sp_runtime::traits::{AccountIdLookup, BlakeTwo256, DispatchInfoOf, PostDispatchInfoOf, Zero}; -use sp_runtime::transaction_validity::{ - InvalidTransaction, TransactionSource, TransactionValidity, TransactionValidityError, -}; -use sp_runtime::OpaqueExtrinsic; -use sp_runtime::{create_runtime_str, generic, ApplyExtrinsicResult, Perbill}; -use sp_std::prelude::*; -#[cfg(feature = "std")] -use sp_version::NativeVersion; -use sp_version::RuntimeVersion; -use subspace_core_primitives::objects::{BlockObject, BlockObjectMapping}; -use subspace_core_primitives::{Randomness, RootBlock, Sha256Hash, PIECE_SIZE}; -use subspace_runtime_primitives::{ - opaque, AccountId, Balance, BlockNumber, Hash, Index, Moment, Signature, CONFIRMATION_DEPTH_K, - MIN_REPLICATION_FACTOR, RECORDED_HISTORY_SEGMENT_SIZE, RECORD_SIZE, - STORAGE_FEES_ESCROW_BLOCK_REWARD, STORAGE_FEES_ESCROW_BLOCK_TAX, -}; - -sp_runtime::impl_opaque_keys! { - pub struct SessionKeys { - pub subspace: Subspace, - } -} - -// To learn more about runtime versioning and what each of the following value means: -// https://substrate.dev/docs/en/knowledgebase/runtime/upgrades#runtime-versioning -#[sp_version::runtime_version] -pub const VERSION: RuntimeVersion = RuntimeVersion { - spec_name: create_runtime_str!("subspace"), - impl_name: create_runtime_str!("subspace"), - authoring_version: 1, - // The version of the runtime specification. A full node will not attempt to use its native - // runtime in substitute for the on-chain Wasm runtime unless all of `spec_name`, - // `spec_version`, and `authoring_version` are the same between Wasm and native. - // This value is set to 100 to notify Polkadot-JS App (https://polkadot.js.org/apps) to use - // the compatible custom types. - spec_version: 100, - impl_version: 1, - apis: RUNTIME_API_VERSIONS, - transaction_version: 1, - state_version: 1, -}; - -/// 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(), - } -} - -/// The smallest unit of the token is called Shannon. -pub const SHANNON: Balance = 1; -/// Subspace Credits have 18 decimal places. -pub const DECIMAL_PLACES: u8 = 18; -/// One Subspace Credit. -pub const SSC: Balance = (10 * SHANNON).pow(DECIMAL_PLACES as u32); - -// TODO: Many of below constants should probably be updatable but currently they are not - -/// Since Subspace is probabilistic this is the average expected block time that -/// we are targeting. Blocks will be produced at a minimum duration defined -/// by `SLOT_DURATION`, but some slots will not be allocated to any -/// farmer and hence no block will be produced. We expect to have this -/// block time on average following the defined slot duration and the value -/// of `c` configured for Subspace (where `1 - c` represents the probability of -/// a slot being empty). -/// This value is only used indirectly to define the unit constants below -/// that are expressed in blocks. The rest of the code should use -/// `SLOT_DURATION` instead (like the Timestamp pallet for calculating the -/// minimum period). -/// -/// Based on: -/// -pub const MILLISECS_PER_BLOCK: u64 = 6000; - -// NOTE: Currently it is not possible to change the slot duration after the chain has started. -// Attempting to do so will brick block production. -const SLOT_DURATION: u64 = 1000; - -/// 1 in 6 slots (on average, not counting collisions) will have a block. -/// Must match ratio between block and slot duration in constants above. -const SLOT_PROBABILITY: (u64, u64) = (1, 6); - -/// The amount of time, in blocks, between updates of global randomness. -const GLOBAL_RANDOMNESS_UPDATE_INTERVAL: BlockNumber = 100; - -/// Era duration in blocks. -const ERA_DURATION_IN_BLOCKS: BlockNumber = 2016; - -const EQUIVOCATION_REPORT_LONGEVITY: BlockNumber = 256; - -/// Eon duration is 7 days -const EON_DURATION_IN_SLOTS: u64 = 3600 * 24 * 7; -/// Reveal next eon salt 1 day before eon end -const EON_NEXT_SALT_REVEAL: u64 = EON_DURATION_IN_SLOTS - .checked_sub(3600 * 24) - .expect("Offset is smaller than eon duration; qed"); - -// We assume initial plot size starts with the a single recorded history segment (which is erasure -// coded of course, hence `*2`). -const INITIAL_SOLUTION_RANGE: u64 = - u64::MAX / (RECORDED_HISTORY_SEGMENT_SIZE * 2 / RECORD_SIZE as u32) as u64 * SLOT_PROBABILITY.0 - / SLOT_PROBABILITY.1; - -/// A ratio of `Normal` dispatch class within block, for `BlockWeight` and `BlockLength`. -const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75); - -/// Maximum block length for non-`Normal` extrinsic is 5 MiB. -const MAX_BLOCK_LENGTH: u32 = 5 * 1024 * 1024; - -const MAX_OBJECT_MAPPING_RECURSION_DEPTH: u16 = 5; - -parameter_types! { - pub const Version: RuntimeVersion = VERSION; - pub const BlockHashCount: BlockNumber = 2400; - /// We allow for 2 seconds of compute with a 6 second average block time. - pub SubspaceBlockWeights: BlockWeights = BlockWeights::with_sensible_defaults(2 * WEIGHT_PER_SECOND, NORMAL_DISPATCH_RATIO); - /// We allow for 3.75 MiB for `Normal` extrinsic with 5 MiB maximum block length. - pub SubspaceBlockLength: BlockLength = BlockLength::max_with_normal_ratio(MAX_BLOCK_LENGTH, NORMAL_DISPATCH_RATIO); -} - -pub type SS58Prefix = ConstU16<2254>; - -// Configure FRAME pallets to include in runtime. - -impl frame_system::Config for Runtime { - /// The basic call filter to use in dispatchable. - type BaseCallFilter = frame_support::traits::Everything; - /// Block & extrinsics weights: base values and limits. - type BlockWeights = SubspaceBlockWeights; - /// The maximum length of a block (in bytes). - type BlockLength = SubspaceBlockLength; - /// The identifier used to distinguish between accounts. - type AccountId = AccountId; - /// The aggregated dispatch type that is available for extrinsics. - type Call = Call; - /// The lookup mechanism to get account ID from whatever is passed in dispatchers. - type Lookup = AccountIdLookup; - /// The index type for storing how many extrinsics an account has signed. - type Index = Index; - /// The index type for blocks. - type BlockNumber = BlockNumber; - /// The type for hashing blocks and tries. - type Hash = Hash; - /// The hashing algorithm used. - type Hashing = BlakeTwo256; - /// The header type. - type Header = Header; - /// The ubiquitous event type. - type Event = Event; - /// The ubiquitous origin type. - type Origin = Origin; - /// Maximum number of block number to block hash mappings to keep (oldest pruned first). - type BlockHashCount = ConstU32<250>; - /// The weight of database operations that the runtime can invoke. - type DbWeight = RocksDbWeight; - /// Version of the runtime. - type Version = Version; - /// Converts a module to the index of the module in `construct_runtime!`. - /// - /// This type is being generated by `construct_runtime!`. - type PalletInfo = PalletInfo; - /// What to do if a new account is created. - type OnNewAccount = (); - /// What to do if an account is fully reaped from the system. - type OnKilledAccount = (); - /// The data to be stored in an account. - type AccountData = pallet_balances::AccountData; - /// Weight information for the extrinsics of this pallet. - type SystemWeightInfo = (); - /// This is used as an identifier of the chain. - type SS58Prefix = SS58Prefix; - /// The set code logic, just the default since we're not a parachain. - type OnSetCode = (); - type MaxConsumers = ConstU32<16>; -} - -parameter_types! { - pub const SlotProbability: (u64, u64) = SLOT_PROBABILITY; - pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK; -} - -impl pallet_subspace::Config for Runtime { - type Event = Event; - type GlobalRandomnessUpdateInterval = ConstU32; - type EraDuration = ConstU32; - type EonDuration = ConstU64; - type EonNextSaltReveal = ConstU64; - type InitialSolutionRange = ConstU64; - type SlotProbability = SlotProbability; - type ExpectedBlockTime = ExpectedBlockTime; - type ConfirmationDepthK = ConstU32; - type RecordSize = ConstU32; - type RecordedHistorySegmentSize = ConstU32; - type GlobalRandomnessIntervalTrigger = pallet_subspace::NormalGlobalRandomnessInterval; - type EraChangeTrigger = pallet_subspace::NormalEraChange; - type EonChangeTrigger = pallet_subspace::NormalEonChange; - - type HandleEquivocation = pallet_subspace::equivocation::EquivocationHandler< - OffencesSubspace, - ConstU64<{ EQUIVOCATION_REPORT_LONGEVITY as u64 }>, - >; - - type WeightInfo = (); -} - -impl pallet_timestamp::Config for Runtime { - /// A timestamp: milliseconds since the unix epoch. - type Moment = Moment; - type OnTimestampSet = Subspace; - type MinimumPeriod = ConstU64<{ SLOT_DURATION / 2 }>; - type WeightInfo = (); -} - -impl pallet_balances::Config for Runtime { - type MaxLocks = ConstU32<50>; - type MaxReserves = (); - type ReserveIdentifier = [u8; 8]; - /// The type for recording an account's balance. - type Balance = Balance; - /// The ubiquitous event type. - type Event = Event; - type DustRemoval = (); - // TODO: Correct value - type ExistentialDeposit = ConstU128<{ 500 * SHANNON }>; - type AccountStore = System; - type WeightInfo = pallet_balances::weights::SubstrateWeight; -} - -parameter_types! { - pub const StorageFeesEscrowBlockReward: (u64, u64) = STORAGE_FEES_ESCROW_BLOCK_REWARD; - pub const StorageFeesEscrowBlockTax: (u64, u64) = STORAGE_FEES_ESCROW_BLOCK_TAX; -} - -pub struct CreditSupply; - -impl Get for CreditSupply { - fn get() -> Balance { - Balances::total_issuance() - } -} - -pub struct TotalSpacePledged; - -impl Get for TotalSpacePledged { - fn get() -> u64 { - let piece_size = u64::try_from(PIECE_SIZE) - .expect("Piece size is definitely small enough to fit into u64; qed"); - // Operations reordered to avoid u64 overflow, but essentially are: - // u64::MAX * SlotProbability / (solution_range / PIECE_SIZE) - u64::MAX / Subspace::solution_ranges().current * piece_size * SlotProbability::get().0 - / SlotProbability::get().1 - } -} - -pub struct BlockchainHistorySize; - -impl Get for BlockchainHistorySize { - fn get() -> u64 { - Subspace::archived_history_size() - } -} - -impl pallet_transaction_fees::Config for Runtime { - type Event = Event; - type MinReplicationFactor = ConstU16; - type StorageFeesEscrowBlockReward = StorageFeesEscrowBlockReward; - type StorageFeesEscrowBlockTax = StorageFeesEscrowBlockTax; - type CreditSupply = CreditSupply; - type TotalSpacePledged = TotalSpacePledged; - type BlockchainHistorySize = BlockchainHistorySize; - type Currency = Balances; - type FindBlockRewardAddress = Subspace; - type WeightInfo = (); -} - -pub struct TransactionByteFee; - -impl Get for TransactionByteFee { - fn get() -> Balance { - if cfg!(feature = "do-not-enforce-cost-of-storage") { - 1 - } else { - TransactionFees::transaction_byte_fee() - } - } -} - -pub struct LiquidityInfo { - storage_fee: Balance, - imbalance: NegativeImbalance, -} - -/// Implementation of [`pallet_transaction_payment::OnChargeTransaction`] that charges transaction -/// fees and distributes storage/compute fees and tip separately. -pub struct OnChargeTransaction; - -impl pallet_transaction_payment::OnChargeTransaction for OnChargeTransaction { - type LiquidityInfo = Option; - type Balance = Balance; - - fn withdraw_fee( - who: &AccountId, - call: &Call, - _info: &DispatchInfoOf, - fee: Self::Balance, - tip: Self::Balance, - ) -> Result { - if fee.is_zero() { - return Ok(None); - } - - let withdraw_reason = if tip.is_zero() { - WithdrawReasons::TRANSACTION_PAYMENT - } else { - WithdrawReasons::TRANSACTION_PAYMENT | WithdrawReasons::TIP - }; - - let withdraw_result = >::withdraw( - who, - fee, - withdraw_reason, - ExistenceRequirement::KeepAlive, - ); - let imbalance = withdraw_result.map_err(|_error| InvalidTransaction::Payment)?; - - // Separate storage fee while we have access to the call data structure to calculate it. - let storage_fee = TransactionByteFee::get() - * Balance::try_from(call.encoded_size()) - .expect("Size of the call never exceeds balance units; qed"); - - Ok(Some(LiquidityInfo { - storage_fee, - imbalance, - })) - } - - fn correct_and_deposit_fee( - who: &AccountId, - _dispatch_info: &DispatchInfoOf, - _post_info: &PostDispatchInfoOf, - corrected_fee: Self::Balance, - tip: Self::Balance, - liquidity_info: Self::LiquidityInfo, - ) -> Result<(), TransactionValidityError> { - if let Some(LiquidityInfo { - storage_fee, - imbalance, - }) = liquidity_info - { - // Calculate how much refund we should return - let refund_amount = imbalance.peek().saturating_sub(corrected_fee); - // Refund to the the account that paid the fees. If this fails, the account might have - // dropped below the existential balance. In that case we don't refund anything. - let refund_imbalance = Balances::deposit_into_existing(who, refund_amount) - .unwrap_or_else(|_| >::PositiveImbalance::zero()); - // Merge the imbalance caused by paying the fees and refunding parts of it again. - let adjusted_paid = imbalance - .offset(refund_imbalance) - .same() - .map_err(|_| TransactionValidityError::Invalid(InvalidTransaction::Payment))?; - - // Split the tip from the total fee that ended up being paid. - let (tip, fee) = adjusted_paid.split(tip); - // Split paid storage and compute fees so that they can be distributed separately. - let (paid_storage_fee, paid_compute_fee) = fee.split(storage_fee); - - TransactionFees::note_transaction_fees( - paid_storage_fee.peek(), - paid_compute_fee.peek(), - tip.peek(), - ); - } - Ok(()) - } -} - -impl pallet_transaction_payment::Config for Runtime { - type OnChargeTransaction = OnChargeTransaction; - type TransactionByteFee = TransactionByteFee; - type OperationalFeeMultiplier = ConstU8<5>; - type WeightToFee = IdentityFee; - type FeeMultiplierUpdate = (); -} - -impl pallet_utility::Config for Runtime { - type Event = Event; - type Call = Call; - type PalletsOrigin = OriginCaller; - type WeightInfo = pallet_utility::weights::SubstrateWeight; -} - -impl pallet_sudo::Config for Runtime { - type Event = Event; - type Call = Call; -} - -impl frame_system::offchain::SendTransactionTypes for Runtime -where - Call: From, -{ - type Extrinsic = UncheckedExtrinsic; - type OverarchingCall = Call; -} - -impl pallet_offences_subspace::Config for Runtime { - type Event = Event; - type OnOffenceHandler = Subspace; -} - -impl pallet_executor::Config for Runtime { - type Event = Event; -} - -parameter_types! { - pub const BlockReward: Balance = SSC; -} - -impl pallet_rewards::Config for Runtime { - type Event = Event; - type Currency = Balances; - type BlockReward = BlockReward; - type FindBlockRewardAddress = Subspace; - type WeightInfo = (); -} - -impl pallet_feeds::Config for Runtime { - type Event = Event; -} - -impl pallet_object_store::Config for Runtime { - type Event = Event; -} - -parameter_types! { - // This value doesn't matter, we don't use it (`VestedTransferOrigin = EnsureNever` below). - pub const MinVestedTransfer: Balance = 0; -} - -impl orml_vesting::Config for Runtime { - type Event = Event; - type Currency = Balances; - type MinVestedTransfer = MinVestedTransfer; - type VestedTransferOrigin = EnsureNever; - type WeightInfo = (); - type MaxVestingSchedules = ConstU32<2>; - type BlockNumberProvider = System; -} - -construct_runtime!( - pub enum Runtime where - Block = Block, - NodeBlock = opaque::Block, - UncheckedExtrinsic = UncheckedExtrinsic - { - System: frame_system = 0, - Timestamp: pallet_timestamp = 1, - - Subspace: pallet_subspace = 2, - OffencesSubspace: pallet_offences_subspace = 3, - Rewards: pallet_rewards = 9, - - Balances: pallet_balances = 4, - TransactionFees: pallet_transaction_fees = 12, - TransactionPayment: pallet_transaction_payment = 5, - Utility: pallet_utility = 8, - - Feeds: pallet_feeds = 6, - ObjectStore: pallet_object_store = 10, - Executor: pallet_executor = 11, - - Vesting: orml_vesting = 7, - - // Reserve some room for other pallets as we'll remove sudo pallet eventually. - Sudo: pallet_sudo = 100, - } -); - -/// The address format for describing accounts. -pub type Address = sp_runtime::MultiAddress; -/// Block header type as expected by this runtime. -pub type Header = generic::Header; -/// Block type as expected by this runtime. -pub type Block = generic::Block; -/// The SignedExtension to the basic transaction logic. -pub type SignedExtra = ( - frame_system::CheckNonZeroSender, - frame_system::CheckSpecVersion, - frame_system::CheckTxVersion, - frame_system::CheckGenesis, - frame_system::CheckEra, - frame_system::CheckNonce, - frame_system::CheckWeight, - pallet_transaction_payment::ChargeTransactionPayment, -); -/// Unchecked extrinsic type as expected by this runtime. -pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; -/// Executive: handles dispatch to the various modules. -pub type Executive = frame_executive::Executive< - Runtime, - Block, - frame_system::ChainContext, - Runtime, - AllPalletsWithSystem, ->; - -fn extract_root_blocks(ext: &UncheckedExtrinsic) -> Option> { - match &ext.function { - Call::Subspace(pallet_subspace::Call::store_root_blocks { root_blocks }) => { - Some(root_blocks.clone()) - } - _ => None, - } -} - -fn extract_feeds_block_object_mapping( - base_offset: u32, - objects: &mut Vec, - call: &pallet_feeds::Call, -) { - if let Some(call_object) = call.extract_call_object() { - objects.push(BlockObject::V0 { - hash: call_object.hash, - offset: base_offset + call_object.offset, - }); - } -} - -fn extract_object_store_block_object_mapping( - base_offset: u32, - objects: &mut Vec, - call: &pallet_object_store::Call, -) { - if let Some(call_object) = call.extract_call_object() { - objects.push(BlockObject::V0 { - hash: call_object.hash, - offset: base_offset + call_object.offset, - }); - } -} - -fn extract_utility_block_object_mapping( - mut base_offset: u32, - objects: &mut Vec, - call: &pallet_utility::Call, - mut recursion_depth_left: u16, -) { - if recursion_depth_left == 0 { - return; - } - - recursion_depth_left -= 1; - - // Add enum variant to the base offset. - base_offset += 1; - - match call { - pallet_utility::Call::batch { calls } | pallet_utility::Call::batch_all { calls } => { - base_offset += Compact::compact_len(&(calls.len() as u32)) as u32; - - for call in calls { - extract_call_block_object_mapping(base_offset, objects, call, recursion_depth_left); - - base_offset += call.encoded_size() as u32; - } - } - pallet_utility::Call::as_derivative { index, call } => { - base_offset += index.encoded_size() as u32; - - extract_call_block_object_mapping( - base_offset, - objects, - call.as_ref(), - recursion_depth_left, - ); - } - pallet_utility::Call::dispatch_as { as_origin, call } => { - base_offset += as_origin.encoded_size() as u32; - - extract_call_block_object_mapping( - base_offset, - objects, - call.as_ref(), - recursion_depth_left, - ); - } - pallet_utility::Call::__Ignore(_, _) => { - // Ignore. - } - } -} - -fn extract_call_block_object_mapping( - mut base_offset: u32, - objects: &mut Vec, - call: &Call, - recursion_depth_left: u16, -) { - // Add enum variant to the base offset. - base_offset += 1; - - match call { - Call::Feeds(call) => { - extract_feeds_block_object_mapping(base_offset, objects, call); - } - Call::ObjectStore(call) => { - extract_object_store_block_object_mapping(base_offset, objects, call); - } - Call::Utility(call) => { - extract_utility_block_object_mapping(base_offset, objects, call, recursion_depth_left); - } - _ => {} - } -} - -fn extract_block_object_mapping(block: Block) -> BlockObjectMapping { - let mut block_object_mapping = BlockObjectMapping::default(); - let mut base_offset = - block.header.encoded_size() + Compact::compact_len(&(block.extrinsics.len() as u32)); - for extrinsic in block.extrinsics { - let signature_size = extrinsic - .signature - .as_ref() - .map(|s| s.encoded_size()) - .unwrap_or_default(); - // Extrinsic starts with vector length and version byte, followed by optional signature and - // `function` encoding. - let base_extrinsic_offset = base_offset - + Compact::compact_len( - &((1 + signature_size + extrinsic.function.encoded_size()) as u32), - ) - + 1 - + signature_size; - - extract_call_block_object_mapping( - base_extrinsic_offset as u32, - &mut block_object_mapping.objects, - &extrinsic.function, - MAX_OBJECT_MAPPING_RECURSION_DEPTH, - ); - - base_offset += extrinsic.encoded_size(); - } - - block_object_mapping -} - -fn extract_bundles(extrinsics: Vec) -> Vec { - extrinsics - .into_iter() - .filter_map(|opaque_extrinsic| { - match ::decode(&mut opaque_extrinsic.encode().as_slice()) { - Ok(uxt) => { - if let Call::Executor(pallet_executor::Call::submit_transaction_bundle { - opaque_bundle, - }) = uxt.function - { - Some(opaque_bundle) - } else { - None - } - } - Err(_) => None, - } - }) - .collect() -} - -fn extrinsics_shuffling_seed(header: Block::Header) -> Randomness { - if header.number().is_zero() { - Randomness::default() - } else { - let mut pre_digest: Option<_> = None; - for log in header.digest().logs() { - match ( - log.as_subspace_pre_digest::(), - pre_digest.is_some(), - ) { - (Some(_), true) => panic!("Multiple Subspace pre-runtime digests in a header"), - (None, _) => {} - (s, false) => pre_digest = s, - } - } - - let pre_digest = pre_digest.expect("Header must contain one pre-runtime digest; qed"); - - BlakeTwo256::hash_of(&pre_digest.solution.signature).into() - } -} - -impl_runtime_apis! { - impl sp_api::Core for Runtime { - fn version() -> RuntimeVersion { - VERSION - } - - fn execute_block(block: Block) { - Executive::execute_block(block); - } - - fn initialize_block(header: &::Header) { - Executive::initialize_block(header) - } - } - - impl sp_api::Metadata for Runtime { - fn metadata() -> OpaqueMetadata { - OpaqueMetadata::new(Runtime::metadata().into()) - } - } - - impl sp_block_builder::BlockBuilder for Runtime { - fn apply_extrinsic(extrinsic: ::Extrinsic) -> ApplyExtrinsicResult { - Executive::apply_extrinsic(extrinsic) - } - - fn finalize_block() -> ::Header { - Executive::finalize_block() - } - - fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<::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 for Runtime { - fn validate_transaction( - source: TransactionSource, - tx: ::Extrinsic, - block_hash: ::Hash, - ) -> TransactionValidity { - Executive::validate_transaction(source, tx, block_hash) - } - } - - impl sp_offchain::OffchainWorkerApi for Runtime { - fn offchain_worker(header: &::Header) { - Executive::offchain_worker(header) - } - } - - impl sp_consensus_subspace::SubspaceApi for Runtime { - fn confirmation_depth_k() -> <::Header as HeaderT>::Number { - ::ConfirmationDepthK::get() - } - - fn record_size() -> u32 { - ::RecordSize::get() - } - - fn recorded_history_segment_size() -> u32 { - ::RecordedHistorySegmentSize::get() - } - - fn slot_duration() -> Duration { - Duration::from_millis(Subspace::slot_duration()) - } - - fn global_randomnesses() -> GlobalRandomnesses { - Subspace::global_randomnesses() - } - - fn solution_ranges() -> SolutionRanges { - Subspace::solution_ranges() - } - - fn salts() -> Salts { - Subspace::salts() - } - - fn submit_report_equivocation_extrinsic( - equivocation_proof: EquivocationProof<::Header>, - ) -> Option<()> { - Subspace::submit_equivocation_report(equivocation_proof) - } - - fn is_in_block_list(farmer_public_key: &FarmerPublicKey) -> bool { - // TODO: Either check tx pool too for pending equivocations or replace equivocation - // mechanism with an alternative one, so that blocking happens faster - Subspace::is_in_block_list(farmer_public_key) - } - - fn records_root(segment_index: u64) -> Option { - Subspace::records_root(segment_index) - } - - fn extract_root_blocks(ext: &::Extrinsic) -> Option> { - extract_root_blocks(ext) - } - - fn extract_block_object_mapping(block: Block) -> BlockObjectMapping { - extract_block_object_mapping(block) - } - } - - impl sp_executor::ExecutorApi for Runtime { - fn submit_execution_receipt_unsigned( - opaque_execution_receipt: sp_executor::OpaqueExecutionReceipt, - ) -> Option<()> { - ::Hash>>::decode( - &mut opaque_execution_receipt.encode().as_slice(), - ) - .ok() - .and_then(|execution_receipt| { - Executor::submit_execution_receipt_unsigned(execution_receipt).ok() - }) - } - - fn submit_transaction_bundle_unsigned(opaque_bundle: OpaqueBundle) -> Option<()> { - Executor::submit_transaction_bundle_unsigned(opaque_bundle).ok() - } - - fn submit_fraud_proof_unsigned(fraud_proof: FraudProof) -> Option<()> { - Executor::submit_fraud_proof_unsigned(fraud_proof).ok() - } - - fn submit_bundle_equivocation_proof_unsigned( - bundle_equivocation_proof: sp_executor::BundleEquivocationProof, - ) -> Option<()> { - Executor::submit_bundle_equivocation_proof_unsigned(bundle_equivocation_proof).ok() - } - - fn submit_invalid_transaction_proof_unsigned( - invalid_transaction_proof: sp_executor::InvalidTransactionProof, - ) -> Option<()> { - Executor::submit_invalid_transaction_proof_unsigned(invalid_transaction_proof).ok() - } - - fn extract_bundles(extrinsics: Vec) -> Vec { - extract_bundles(extrinsics) - } - - fn extrinsics_shuffling_seed(header: ::Header) -> Randomness { - extrinsics_shuffling_seed::(header) - } - } - - impl sp_session::SessionKeys for Runtime { - fn generate_session_keys(seed: Option>) -> Vec { - SessionKeys::generate(seed) - } - - fn decode_session_keys( - encoded: Vec, - ) -> Option, KeyTypeId)>> { - SessionKeys::decode_into_raw_public_keys(&encoded) - } - } - - impl frame_system_rpc_runtime_api::AccountNonceApi for Runtime { - fn account_nonce(account: AccountId) -> Index { - System::account_nonce(account) - } - } - - impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi for Runtime { - fn query_info( - uxt: ::Extrinsic, - len: u32, - ) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo { - TransactionPayment::query_info(uxt, len) - } - fn query_fee_details( - uxt: ::Extrinsic, - len: u32, - ) -> pallet_transaction_payment::FeeDetails { - TransactionPayment::query_fee_details(uxt, len) - } - } - - #[cfg(feature = "runtime-benchmarks")] - impl frame_benchmarking::Benchmark for Runtime { - fn benchmark_metadata(extra: bool) -> ( - Vec, - Vec, - ) { - use frame_benchmarking::{list_benchmark, baseline, Benchmarking, BenchmarkList}; - use frame_support::traits::StorageInfoTrait; - use frame_system_benchmarking::Pallet as SystemBench; - use baseline::Pallet as BaselineBench; - - let mut list = Vec::::new(); - - list_benchmark!(list, extra, frame_benchmarking, BaselineBench::); - list_benchmark!(list, extra, frame_system, SystemBench::); - list_benchmark!(list, extra, pallet_balances, Balances); - list_benchmark!(list, extra, pallet_timestamp, Timestamp); - list_benchmark!(params, batches, pallet_utility, Utility); - list_benchmark!(list, extra, pallet_template, TemplateModule); - - let storage_info = AllPalletsWithSystem::storage_info(); - - return (list, storage_info) - } - - fn dispatch_benchmark( - config: frame_benchmarking::BenchmarkConfig - ) -> Result, sp_runtime::RuntimeString> { - use frame_benchmarking::{baseline, Benchmarking, BenchmarkBatch, add_benchmark, TrackedStorageKey}; - - use frame_system_benchmarking::Pallet as SystemBench; - use baseline::Pallet as BaselineBench; - - impl frame_system_benchmarking::Config for Runtime {} - impl baseline::Config for Runtime {} - - let whitelist: Vec = 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::::new(); - let params = (&config, &whitelist); - - add_benchmark!(params, batches, frame_benchmarking, BaselineBench::); - add_benchmark!(params, batches, frame_system, SystemBench::); - add_benchmark!(params, batches, pallet_balances, Balances); - add_benchmark!(params, batches, pallet_timestamp, Timestamp); - add_benchmark!(params, batches, pallet_utility, Utility); - add_benchmark!(params, batches, pallet_template, TemplateModule); - - Ok(batches) - } - } -} diff --git a/crates/subspace-node/src/bin/subspace-node.rs b/crates/subspace-node/src/bin/subspace-node.rs index ce601ec437ab1..ce147fc9d9ee7 100644 --- a/crates/subspace-node/src/bin/subspace-node.rs +++ b/crates/subspace-node/src/bin/subspace-node.rs @@ -20,7 +20,7 @@ use futures::future::TryFutureExt; use sc_cli::{ChainSpec, SubstrateCli}; use sp_core::crypto::Ss58AddressFormat; use subspace_node::{Cli, ExecutorDispatch, Subcommand}; -use subspace_runtime::consensus::RuntimeApi; +use subspace_runtime::RuntimeApi; /// Subspace node error. #[derive(thiserror::Error, Debug)] @@ -182,7 +182,7 @@ fn main() -> std::result::Result<(), Error> { let runner = cli.create_runner(cmd)?; set_default_ss58_version(&runner.config().chain_spec); runner.sync_run(|config| { - cmd.run::(config) + cmd.run::(config) })?; } else { return Err(Error::Other( @@ -196,10 +196,9 @@ fn main() -> std::result::Result<(), Error> { let runner = cli.create_runner(&cli.run.base)?; set_default_ss58_version(&runner.config().chain_spec); runner.run_node_until_exit(|config| async move { - subspace_service::new_full::< - subspace_runtime::consensus::RuntimeApi, - ExecutorDispatch, - >(config, true) + subspace_service::new_full::( + config, true, + ) .await .map(|full| full.task_manager) })?; diff --git a/crates/subspace-node/src/chain_spec.rs b/crates/subspace-node/src/chain_spec.rs index c152184c1dabe..bc99ab7de7f55 100644 --- a/crates/subspace-node/src/chain_spec.rs +++ b/crates/subspace-node/src/chain_spec.rs @@ -55,8 +55,7 @@ const TOKEN_GRANTS: &[(&str, u128)] = &[ ]; /// The `ChainSpec` parameterized for the subspace runtime. -pub type SubspaceChainSpec = - sc_service::GenericChainSpec; +pub type SubspaceChainSpec = sc_service::GenericChainSpec; /// Generate a crypto pair from seed. pub fn get_from_seed(seed: &str) -> ::Public { @@ -78,13 +77,13 @@ pub fn subspace_testnet_config() -> Result { } #[cfg(not(feature = "json-chain-spec"))] pub fn subspace_testnet_config() -> Result { - use subspace_runtime::consensus::{SS58Prefix, SSC}; + use subspace_runtime::{SS58Prefix, SSC}; let mut properties = Properties::new(); properties.insert("ss58Format".into(), >::get().into()); properties.insert( "tokenDecimals".into(), - subspace_runtime::consensus::DECIMAL_PLACES.into(), + subspace_runtime::DECIMAL_PLACES.into(), ); properties.insert("tokenSymbol".into(), "tSSC".into()); @@ -116,7 +115,7 @@ pub fn subspace_testnet_config() -> Result { // TODO: Adjust start block to real value before mainnet launch let start_block = 100_000_000; let one_month_in_blocks = u32::try_from( - 3600 * 24 * 30 * subspace_runtime::consensus::MILLISECS_PER_BLOCK / 1000, + 3600 * 24 * 30 * subspace_runtime::MILLISECS_PER_BLOCK / 1000, ) .expect("One month of blocks always fits in u32; qed"); @@ -168,7 +167,7 @@ pub fn subspace_testnet_config() -> Result { } pub fn subspace_development_config() -> Result { - use subspace_runtime::consensus::SSC; + use subspace_runtime::SSC; let wasm_binary = subspace_runtime::WASM_BINARY .ok_or_else(|| "Development wasm not available".to_string())?; @@ -209,7 +208,7 @@ pub fn subspace_development_config() -> Result { } pub fn subspace_local_testnet_config() -> Result { - use subspace_runtime::consensus::SSC; + use subspace_runtime::SSC; let wasm_binary = subspace_runtime::WASM_BINARY .ok_or_else(|| "Development wasm not available".to_string())?; @@ -264,18 +263,18 @@ fn subspace_genesis_config( balances: Vec<(AccountId, Balance)>, // who, start, period, period_count, per_period vesting: Vec<(AccountId, BlockNumber, BlockNumber, u32, Balance)>, -) -> subspace_runtime::consensus::GenesisConfig { - subspace_runtime::consensus::GenesisConfig { - system: subspace_runtime::consensus::SystemConfig { +) -> subspace_runtime::GenesisConfig { + subspace_runtime::GenesisConfig { + system: subspace_runtime::SystemConfig { // Add Wasm runtime to storage. code: wasm_binary.to_vec(), }, - balances: subspace_runtime::consensus::BalancesConfig { balances }, + balances: subspace_runtime::BalancesConfig { balances }, transaction_payment: Default::default(), - sudo: subspace_runtime::consensus::SudoConfig { + sudo: subspace_runtime::SudoConfig { // Assign network admin rights. key: Some(sudo_account), }, - vesting: subspace_runtime::consensus::VestingConfig { vesting }, + vesting: subspace_runtime::VestingConfig { vesting }, } } diff --git a/crates/subspace-node/src/lib.rs b/crates/subspace-node/src/lib.rs index 71291045fc089..95bab260243d2 100644 --- a/crates/subspace-node/src/lib.rs +++ b/crates/subspace-node/src/lib.rs @@ -37,11 +37,11 @@ impl NativeExecutionDispatch for ExecutorDispatch { type ExtendHostFunctions = (); fn dispatch(method: &str, data: &[u8]) -> Option> { - subspace_runtime::consensus::api::dispatch(method, data) + subspace_runtime::api::dispatch(method, data) } fn native_version() -> sc_executor::NativeVersion { - subspace_runtime::consensus::native_version() + subspace_runtime::native_version() } } @@ -138,6 +138,6 @@ impl SubstrateCli for Cli { } fn native_runtime_version(_: &Box) -> &'static RuntimeVersion { - &subspace_runtime::consensus::VERSION + &subspace_runtime::VERSION } } diff --git a/crates/subspace-runtime/Cargo.toml b/crates/subspace-runtime/Cargo.toml index 6831ed1ad21f0..0f308267fc4ec 100644 --- a/crates/subspace-runtime/Cargo.toml +++ b/crates/subspace-runtime/Cargo.toml @@ -16,8 +16,48 @@ include = [ targets = ["x86_64-unknown-linux-gnu"] [dependencies] -parachain-template-runtime = { version = "0.1.0", default-features = false, path = "../../cumulus/parachain-template/runtime" } -subspace-consensus-runtime = { version = "0.1.0", default-features = false, path = "../subspace-consensus-runtime" } +codec = { package = "parity-scale-codec", version = "3.1.2", default-features = false, features = ["derive"] } +frame-executive = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998" } +frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998" } +frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998" } +hex-literal = { version = "0.3.3", optional = true } +orml-vesting = { version = "0.4.1-dev", default-features = false, git = "https://github.com/subspace/open-runtime-module-library", rev = "0e9f38313775b94c87c289f346e50f900db2bab7" } +pallet-balances = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998" } +pallet-executor = { version = "0.1.0", default-features = false, path = "../pallet-executor" } +pallet-feeds = { version = "0.1.0", default-features = false, path = "../pallet-feeds" } +pallet-object-store = { version = "0.1.0", default-features = false, path = "../pallet-object-store" } +pallet-offences-subspace = { version = "0.1.0", default-features = false, path = "../pallet-offences-subspace" } +pallet-rewards = { version = "0.1.0", default-features = false, path = "../pallet-rewards" } +pallet-subspace = { version = "0.1.0", default-features = false, features = ["no-early-solution-range-updates"], path = "../pallet-subspace" } +pallet-sudo = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998" } +pallet-timestamp = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998" } +pallet-transaction-fees = { version = "0.1.0", default-features = false, path = "../pallet-transaction-fees" } +pallet-transaction-payment = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998" } +pallet-utility = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998" } +scale-info = { version = "2.0.1", default-features = false, features = ["derive"] } +sp-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998" } +sp-block-builder = { git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998", default-features = false, version = "4.0.0-dev"} +sp-consensus-subspace = { version = "0.1.0", default-features = false, path = "../sp-consensus-subspace" } +sp-consensus-slots = { version = "0.10.0-dev", default-features = false, git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998" } +sp-core = { version = "6.0.0", default-features = false, git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998" } +sp-executor = { version = "0.1.0", default-features = false, path = "../sp-executor" } +sp-inherents = { git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998", default-features = false, version = "4.0.0-dev"} +sp-offchain = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998" } +sp-runtime = { version = "6.0.0", default-features = false, git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998" } +sp-session = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998" } +sp-std = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998" } +sp-transaction-pool = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998" } +sp-version = { version = "5.0.0", default-features = false, git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998" } +subspace-core-primitives = { version = "0.1.0", default-features = false, path = "../subspace-core-primitives" } +subspace-runtime-primitives = { version = "0.1.0", default-features = false, path = "../subspace-runtime-primitives" } + +# Used for the node template's RPCs +frame-system-rpc-runtime-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998" } +pallet-transaction-payment-rpc-runtime-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998" } + +# Used for runtime benchmarking +frame-benchmarking = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998", optional = true } +frame-system-benchmarking = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998", optional = true } [build-dependencies] substrate-wasm-builder = { version = "5.0.0-dev", git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998" } @@ -25,13 +65,52 @@ substrate-wasm-builder = { version = "5.0.0-dev", git = "https://github.com/pari [features] default = ["std"] std = [ - "parachain-template-runtime/std", - "subspace-consensus-runtime/std", + "codec/std", + "frame-executive/std", + "frame-support/std", + "frame-system/std", + "frame-system-rpc-runtime-api/std", + "orml-vesting/std", + "pallet-balances/std", + "pallet-executor/std", + "pallet-feeds/std", + "pallet-object-store/std", + "pallet-offences-subspace/std", + "pallet-rewards/std", + "pallet-subspace/std", + "pallet-sudo/std", + "pallet-timestamp/std", + "pallet-transaction-fees/std", + "pallet-transaction-payment-rpc-runtime-api/std", + "pallet-transaction-payment/std", + "pallet-utility/std", + "scale-info/std", + "sp-api/std", + "sp-block-builder/std", + "sp-consensus-subspace/std", + "sp-consensus-slots/std", + "sp-core/std", + "sp-executor/std", + "sp-inherents/std", + "sp-offchain/std", + "sp-runtime/std", + "sp-session/std", + "sp-std/std", + "sp-transaction-pool/std", + "sp-version/std", + "subspace-core-primitives/std", + "subspace-runtime-primitives/std", ] runtime-benchmarks = [ - "parachain-template-runtime/runtime-benchmarks", - "subspace-consensus-runtime/runtime-benchmarks", -] -do-not-enforce-cost-of-storage = [ - "subspace-consensus-runtime/do-not-enforce-cost-of-storage" + "frame-benchmarking/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "frame-system-benchmarking", + "frame-system/runtime-benchmarks", + "hex-literal", + "orml-vesting/runtime-benchmarks", + "pallet-balances/runtime-benchmarks", + "pallet-timestamp/runtime-benchmarks", + "pallet-utility/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", ] +do-not-enforce-cost-of-storage = [] diff --git a/crates/subspace-runtime/src/lib.rs b/crates/subspace-runtime/src/lib.rs index 8ec2bf6e8fee3..c9321f6094abd 100644 --- a/crates/subspace-runtime/src/lib.rs +++ b/crates/subspace-runtime/src/lib.rs @@ -1,10 +1,988 @@ -//! Subspace runtime +// Copyright (C) 2021 Subspace Labs, Inc. +// SPDX-License-Identifier: GPL-3.0-or-later + +// 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 . #![cfg_attr(not(feature = "std"), no_std)] +#![feature(const_option)] +// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256. +#![recursion_limit = "256"] // Make the WASM binary available. #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); -pub use parachain_template_runtime as execution; -pub use subspace_consensus_runtime as consensus; +use codec::{Compact, CompactLen, Decode, Encode}; +use core::time::Duration; +use frame_support::traits::{ + ConstU128, ConstU16, ConstU32, ConstU64, ConstU8, Currency, ExistenceRequirement, Get, + Imbalance, WithdrawReasons, +}; +use frame_support::weights::{ + constants::{RocksDbWeight, WEIGHT_PER_SECOND}, + IdentityFee, +}; +use frame_support::{construct_runtime, parameter_types}; +use frame_system::limits::{BlockLength, BlockWeights}; +use frame_system::EnsureNever; +use pallet_balances::NegativeImbalance; +use sp_api::{impl_runtime_apis, BlockT, HashT, HeaderT}; +use sp_consensus_subspace::digests::CompatibleDigestItem; +use sp_consensus_subspace::{ + EquivocationProof, FarmerPublicKey, GlobalRandomnesses, Salts, SolutionRanges, +}; +use sp_core::{crypto::KeyTypeId, OpaqueMetadata}; +use sp_executor::{FraudProof, OpaqueBundle}; +use sp_runtime::traits::{AccountIdLookup, BlakeTwo256, DispatchInfoOf, PostDispatchInfoOf, Zero}; +use sp_runtime::transaction_validity::{ + InvalidTransaction, TransactionSource, TransactionValidity, TransactionValidityError, +}; +use sp_runtime::OpaqueExtrinsic; +use sp_runtime::{create_runtime_str, generic, ApplyExtrinsicResult, Perbill}; +use sp_std::prelude::*; +#[cfg(feature = "std")] +use sp_version::NativeVersion; +use sp_version::RuntimeVersion; +use subspace_core_primitives::objects::{BlockObject, BlockObjectMapping}; +use subspace_core_primitives::{Randomness, RootBlock, Sha256Hash, PIECE_SIZE}; +use subspace_runtime_primitives::{ + opaque, AccountId, Balance, BlockNumber, Hash, Index, Moment, Signature, CONFIRMATION_DEPTH_K, + MIN_REPLICATION_FACTOR, RECORDED_HISTORY_SEGMENT_SIZE, RECORD_SIZE, + STORAGE_FEES_ESCROW_BLOCK_REWARD, STORAGE_FEES_ESCROW_BLOCK_TAX, +}; + +sp_runtime::impl_opaque_keys! { + pub struct SessionKeys { + pub subspace: Subspace, + } +} + +// To learn more about runtime versioning and what each of the following value means: +// https://substrate.dev/docs/en/knowledgebase/runtime/upgrades#runtime-versioning +#[sp_version::runtime_version] +pub const VERSION: RuntimeVersion = RuntimeVersion { + spec_name: create_runtime_str!("subspace"), + impl_name: create_runtime_str!("subspace"), + authoring_version: 1, + // The version of the runtime specification. A full node will not attempt to use its native + // runtime in substitute for the on-chain Wasm runtime unless all of `spec_name`, + // `spec_version`, and `authoring_version` are the same between Wasm and native. + // This value is set to 100 to notify Polkadot-JS App (https://polkadot.js.org/apps) to use + // the compatible custom types. + spec_version: 100, + impl_version: 1, + apis: RUNTIME_API_VERSIONS, + transaction_version: 1, + state_version: 1, +}; + +/// 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(), + } +} + +/// The smallest unit of the token is called Shannon. +pub const SHANNON: Balance = 1; +/// Subspace Credits have 18 decimal places. +pub const DECIMAL_PLACES: u8 = 18; +/// One Subspace Credit. +pub const SSC: Balance = (10 * SHANNON).pow(DECIMAL_PLACES as u32); + +// TODO: Many of below constants should probably be updatable but currently they are not + +/// Since Subspace is probabilistic this is the average expected block time that +/// we are targeting. Blocks will be produced at a minimum duration defined +/// by `SLOT_DURATION`, but some slots will not be allocated to any +/// farmer and hence no block will be produced. We expect to have this +/// block time on average following the defined slot duration and the value +/// of `c` configured for Subspace (where `1 - c` represents the probability of +/// a slot being empty). +/// This value is only used indirectly to define the unit constants below +/// that are expressed in blocks. The rest of the code should use +/// `SLOT_DURATION` instead (like the Timestamp pallet for calculating the +/// minimum period). +/// +/// Based on: +/// +pub const MILLISECS_PER_BLOCK: u64 = 6000; + +// NOTE: Currently it is not possible to change the slot duration after the chain has started. +// Attempting to do so will brick block production. +const SLOT_DURATION: u64 = 1000; + +/// 1 in 6 slots (on average, not counting collisions) will have a block. +/// Must match ratio between block and slot duration in constants above. +const SLOT_PROBABILITY: (u64, u64) = (1, 6); + +/// The amount of time, in blocks, between updates of global randomness. +const GLOBAL_RANDOMNESS_UPDATE_INTERVAL: BlockNumber = 100; + +/// Era duration in blocks. +const ERA_DURATION_IN_BLOCKS: BlockNumber = 2016; + +const EQUIVOCATION_REPORT_LONGEVITY: BlockNumber = 256; + +/// Eon duration is 7 days +const EON_DURATION_IN_SLOTS: u64 = 3600 * 24 * 7; +/// Reveal next eon salt 1 day before eon end +const EON_NEXT_SALT_REVEAL: u64 = EON_DURATION_IN_SLOTS + .checked_sub(3600 * 24) + .expect("Offset is smaller than eon duration; qed"); + +// We assume initial plot size starts with the a single recorded history segment (which is erasure +// coded of course, hence `*2`). +const INITIAL_SOLUTION_RANGE: u64 = + u64::MAX / (RECORDED_HISTORY_SEGMENT_SIZE * 2 / RECORD_SIZE as u32) as u64 * SLOT_PROBABILITY.0 + / SLOT_PROBABILITY.1; + +/// A ratio of `Normal` dispatch class within block, for `BlockWeight` and `BlockLength`. +const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75); + +/// Maximum block length for non-`Normal` extrinsic is 5 MiB. +const MAX_BLOCK_LENGTH: u32 = 5 * 1024 * 1024; + +const MAX_OBJECT_MAPPING_RECURSION_DEPTH: u16 = 5; + +parameter_types! { + pub const Version: RuntimeVersion = VERSION; + pub const BlockHashCount: BlockNumber = 2400; + /// We allow for 2 seconds of compute with a 6 second average block time. + pub SubspaceBlockWeights: BlockWeights = BlockWeights::with_sensible_defaults(2 * WEIGHT_PER_SECOND, NORMAL_DISPATCH_RATIO); + /// We allow for 3.75 MiB for `Normal` extrinsic with 5 MiB maximum block length. + pub SubspaceBlockLength: BlockLength = BlockLength::max_with_normal_ratio(MAX_BLOCK_LENGTH, NORMAL_DISPATCH_RATIO); +} + +pub type SS58Prefix = ConstU16<2254>; + +// Configure FRAME pallets to include in runtime. + +impl frame_system::Config for Runtime { + /// The basic call filter to use in dispatchable. + type BaseCallFilter = frame_support::traits::Everything; + /// Block & extrinsics weights: base values and limits. + type BlockWeights = SubspaceBlockWeights; + /// The maximum length of a block (in bytes). + type BlockLength = SubspaceBlockLength; + /// The identifier used to distinguish between accounts. + type AccountId = AccountId; + /// The aggregated dispatch type that is available for extrinsics. + type Call = Call; + /// The lookup mechanism to get account ID from whatever is passed in dispatchers. + type Lookup = AccountIdLookup; + /// The index type for storing how many extrinsics an account has signed. + type Index = Index; + /// The index type for blocks. + type BlockNumber = BlockNumber; + /// The type for hashing blocks and tries. + type Hash = Hash; + /// The hashing algorithm used. + type Hashing = BlakeTwo256; + /// The header type. + type Header = Header; + /// The ubiquitous event type. + type Event = Event; + /// The ubiquitous origin type. + type Origin = Origin; + /// Maximum number of block number to block hash mappings to keep (oldest pruned first). + type BlockHashCount = ConstU32<250>; + /// The weight of database operations that the runtime can invoke. + type DbWeight = RocksDbWeight; + /// Version of the runtime. + type Version = Version; + /// Converts a module to the index of the module in `construct_runtime!`. + /// + /// This type is being generated by `construct_runtime!`. + type PalletInfo = PalletInfo; + /// What to do if a new account is created. + type OnNewAccount = (); + /// What to do if an account is fully reaped from the system. + type OnKilledAccount = (); + /// The data to be stored in an account. + type AccountData = pallet_balances::AccountData; + /// Weight information for the extrinsics of this pallet. + type SystemWeightInfo = (); + /// This is used as an identifier of the chain. + type SS58Prefix = SS58Prefix; + /// The set code logic, just the default since we're not a parachain. + type OnSetCode = (); + type MaxConsumers = ConstU32<16>; +} + +parameter_types! { + pub const SlotProbability: (u64, u64) = SLOT_PROBABILITY; + pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK; +} + +impl pallet_subspace::Config for Runtime { + type Event = Event; + type GlobalRandomnessUpdateInterval = ConstU32; + type EraDuration = ConstU32; + type EonDuration = ConstU64; + type EonNextSaltReveal = ConstU64; + type InitialSolutionRange = ConstU64; + type SlotProbability = SlotProbability; + type ExpectedBlockTime = ExpectedBlockTime; + type ConfirmationDepthK = ConstU32; + type RecordSize = ConstU32; + type RecordedHistorySegmentSize = ConstU32; + type GlobalRandomnessIntervalTrigger = pallet_subspace::NormalGlobalRandomnessInterval; + type EraChangeTrigger = pallet_subspace::NormalEraChange; + type EonChangeTrigger = pallet_subspace::NormalEonChange; + + type HandleEquivocation = pallet_subspace::equivocation::EquivocationHandler< + OffencesSubspace, + ConstU64<{ EQUIVOCATION_REPORT_LONGEVITY as u64 }>, + >; + + type WeightInfo = (); +} + +impl pallet_timestamp::Config for Runtime { + /// A timestamp: milliseconds since the unix epoch. + type Moment = Moment; + type OnTimestampSet = Subspace; + type MinimumPeriod = ConstU64<{ SLOT_DURATION / 2 }>; + type WeightInfo = (); +} + +impl pallet_balances::Config for Runtime { + type MaxLocks = ConstU32<50>; + type MaxReserves = (); + type ReserveIdentifier = [u8; 8]; + /// The type for recording an account's balance. + type Balance = Balance; + /// The ubiquitous event type. + type Event = Event; + type DustRemoval = (); + // TODO: Correct value + type ExistentialDeposit = ConstU128<{ 500 * SHANNON }>; + type AccountStore = System; + type WeightInfo = pallet_balances::weights::SubstrateWeight; +} + +parameter_types! { + pub const StorageFeesEscrowBlockReward: (u64, u64) = STORAGE_FEES_ESCROW_BLOCK_REWARD; + pub const StorageFeesEscrowBlockTax: (u64, u64) = STORAGE_FEES_ESCROW_BLOCK_TAX; +} + +pub struct CreditSupply; + +impl Get for CreditSupply { + fn get() -> Balance { + Balances::total_issuance() + } +} + +pub struct TotalSpacePledged; + +impl Get for TotalSpacePledged { + fn get() -> u64 { + let piece_size = u64::try_from(PIECE_SIZE) + .expect("Piece size is definitely small enough to fit into u64; qed"); + // Operations reordered to avoid u64 overflow, but essentially are: + // u64::MAX * SlotProbability / (solution_range / PIECE_SIZE) + u64::MAX / Subspace::solution_ranges().current * piece_size * SlotProbability::get().0 + / SlotProbability::get().1 + } +} + +pub struct BlockchainHistorySize; + +impl Get for BlockchainHistorySize { + fn get() -> u64 { + Subspace::archived_history_size() + } +} + +impl pallet_transaction_fees::Config for Runtime { + type Event = Event; + type MinReplicationFactor = ConstU16; + type StorageFeesEscrowBlockReward = StorageFeesEscrowBlockReward; + type StorageFeesEscrowBlockTax = StorageFeesEscrowBlockTax; + type CreditSupply = CreditSupply; + type TotalSpacePledged = TotalSpacePledged; + type BlockchainHistorySize = BlockchainHistorySize; + type Currency = Balances; + type FindBlockRewardAddress = Subspace; + type WeightInfo = (); +} + +pub struct TransactionByteFee; + +impl Get for TransactionByteFee { + fn get() -> Balance { + if cfg!(feature = "do-not-enforce-cost-of-storage") { + 1 + } else { + TransactionFees::transaction_byte_fee() + } + } +} + +pub struct LiquidityInfo { + storage_fee: Balance, + imbalance: NegativeImbalance, +} + +/// Implementation of [`pallet_transaction_payment::OnChargeTransaction`] that charges transaction +/// fees and distributes storage/compute fees and tip separately. +pub struct OnChargeTransaction; + +impl pallet_transaction_payment::OnChargeTransaction for OnChargeTransaction { + type LiquidityInfo = Option; + type Balance = Balance; + + fn withdraw_fee( + who: &AccountId, + call: &Call, + _info: &DispatchInfoOf, + fee: Self::Balance, + tip: Self::Balance, + ) -> Result { + if fee.is_zero() { + return Ok(None); + } + + let withdraw_reason = if tip.is_zero() { + WithdrawReasons::TRANSACTION_PAYMENT + } else { + WithdrawReasons::TRANSACTION_PAYMENT | WithdrawReasons::TIP + }; + + let withdraw_result = >::withdraw( + who, + fee, + withdraw_reason, + ExistenceRequirement::KeepAlive, + ); + let imbalance = withdraw_result.map_err(|_error| InvalidTransaction::Payment)?; + + // Separate storage fee while we have access to the call data structure to calculate it. + let storage_fee = TransactionByteFee::get() + * Balance::try_from(call.encoded_size()) + .expect("Size of the call never exceeds balance units; qed"); + + Ok(Some(LiquidityInfo { + storage_fee, + imbalance, + })) + } + + fn correct_and_deposit_fee( + who: &AccountId, + _dispatch_info: &DispatchInfoOf, + _post_info: &PostDispatchInfoOf, + corrected_fee: Self::Balance, + tip: Self::Balance, + liquidity_info: Self::LiquidityInfo, + ) -> Result<(), TransactionValidityError> { + if let Some(LiquidityInfo { + storage_fee, + imbalance, + }) = liquidity_info + { + // Calculate how much refund we should return + let refund_amount = imbalance.peek().saturating_sub(corrected_fee); + // Refund to the the account that paid the fees. If this fails, the account might have + // dropped below the existential balance. In that case we don't refund anything. + let refund_imbalance = Balances::deposit_into_existing(who, refund_amount) + .unwrap_or_else(|_| >::PositiveImbalance::zero()); + // Merge the imbalance caused by paying the fees and refunding parts of it again. + let adjusted_paid = imbalance + .offset(refund_imbalance) + .same() + .map_err(|_| TransactionValidityError::Invalid(InvalidTransaction::Payment))?; + + // Split the tip from the total fee that ended up being paid. + let (tip, fee) = adjusted_paid.split(tip); + // Split paid storage and compute fees so that they can be distributed separately. + let (paid_storage_fee, paid_compute_fee) = fee.split(storage_fee); + + TransactionFees::note_transaction_fees( + paid_storage_fee.peek(), + paid_compute_fee.peek(), + tip.peek(), + ); + } + Ok(()) + } +} + +impl pallet_transaction_payment::Config for Runtime { + type OnChargeTransaction = OnChargeTransaction; + type TransactionByteFee = TransactionByteFee; + type OperationalFeeMultiplier = ConstU8<5>; + type WeightToFee = IdentityFee; + type FeeMultiplierUpdate = (); +} + +impl pallet_utility::Config for Runtime { + type Event = Event; + type Call = Call; + type PalletsOrigin = OriginCaller; + type WeightInfo = pallet_utility::weights::SubstrateWeight; +} + +impl pallet_sudo::Config for Runtime { + type Event = Event; + type Call = Call; +} + +impl frame_system::offchain::SendTransactionTypes for Runtime +where + Call: From, +{ + type Extrinsic = UncheckedExtrinsic; + type OverarchingCall = Call; +} + +impl pallet_offences_subspace::Config for Runtime { + type Event = Event; + type OnOffenceHandler = Subspace; +} + +impl pallet_executor::Config for Runtime { + type Event = Event; +} + +parameter_types! { + pub const BlockReward: Balance = SSC; +} + +impl pallet_rewards::Config for Runtime { + type Event = Event; + type Currency = Balances; + type BlockReward = BlockReward; + type FindBlockRewardAddress = Subspace; + type WeightInfo = (); +} + +impl pallet_feeds::Config for Runtime { + type Event = Event; +} + +impl pallet_object_store::Config for Runtime { + type Event = Event; +} + +parameter_types! { + // This value doesn't matter, we don't use it (`VestedTransferOrigin = EnsureNever` below). + pub const MinVestedTransfer: Balance = 0; +} + +impl orml_vesting::Config for Runtime { + type Event = Event; + type Currency = Balances; + type MinVestedTransfer = MinVestedTransfer; + type VestedTransferOrigin = EnsureNever; + type WeightInfo = (); + type MaxVestingSchedules = ConstU32<2>; + type BlockNumberProvider = System; +} + +construct_runtime!( + pub enum Runtime where + Block = Block, + NodeBlock = opaque::Block, + UncheckedExtrinsic = UncheckedExtrinsic + { + System: frame_system = 0, + Timestamp: pallet_timestamp = 1, + + Subspace: pallet_subspace = 2, + OffencesSubspace: pallet_offences_subspace = 3, + Rewards: pallet_rewards = 9, + + Balances: pallet_balances = 4, + TransactionFees: pallet_transaction_fees = 12, + TransactionPayment: pallet_transaction_payment = 5, + Utility: pallet_utility = 8, + + Feeds: pallet_feeds = 6, + ObjectStore: pallet_object_store = 10, + Executor: pallet_executor = 11, + + Vesting: orml_vesting = 7, + + // Reserve some room for other pallets as we'll remove sudo pallet eventually. + Sudo: pallet_sudo = 100, + } +); + +/// The address format for describing accounts. +pub type Address = sp_runtime::MultiAddress; +/// Block header type as expected by this runtime. +pub type Header = generic::Header; +/// Block type as expected by this runtime. +pub type Block = generic::Block; +/// The SignedExtension to the basic transaction logic. +pub type SignedExtra = ( + frame_system::CheckNonZeroSender, + frame_system::CheckSpecVersion, + frame_system::CheckTxVersion, + frame_system::CheckGenesis, + frame_system::CheckEra, + frame_system::CheckNonce, + frame_system::CheckWeight, + pallet_transaction_payment::ChargeTransactionPayment, +); +/// Unchecked extrinsic type as expected by this runtime. +pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; +/// Executive: handles dispatch to the various modules. +pub type Executive = frame_executive::Executive< + Runtime, + Block, + frame_system::ChainContext, + Runtime, + AllPalletsWithSystem, +>; + +fn extract_root_blocks(ext: &UncheckedExtrinsic) -> Option> { + match &ext.function { + Call::Subspace(pallet_subspace::Call::store_root_blocks { root_blocks }) => { + Some(root_blocks.clone()) + } + _ => None, + } +} + +fn extract_feeds_block_object_mapping( + base_offset: u32, + objects: &mut Vec, + call: &pallet_feeds::Call, +) { + if let Some(call_object) = call.extract_call_object() { + objects.push(BlockObject::V0 { + hash: call_object.hash, + offset: base_offset + call_object.offset, + }); + } +} + +fn extract_object_store_block_object_mapping( + base_offset: u32, + objects: &mut Vec, + call: &pallet_object_store::Call, +) { + if let Some(call_object) = call.extract_call_object() { + objects.push(BlockObject::V0 { + hash: call_object.hash, + offset: base_offset + call_object.offset, + }); + } +} + +fn extract_utility_block_object_mapping( + mut base_offset: u32, + objects: &mut Vec, + call: &pallet_utility::Call, + mut recursion_depth_left: u16, +) { + if recursion_depth_left == 0 { + return; + } + + recursion_depth_left -= 1; + + // Add enum variant to the base offset. + base_offset += 1; + + match call { + pallet_utility::Call::batch { calls } | pallet_utility::Call::batch_all { calls } => { + base_offset += Compact::compact_len(&(calls.len() as u32)) as u32; + + for call in calls { + extract_call_block_object_mapping(base_offset, objects, call, recursion_depth_left); + + base_offset += call.encoded_size() as u32; + } + } + pallet_utility::Call::as_derivative { index, call } => { + base_offset += index.encoded_size() as u32; + + extract_call_block_object_mapping( + base_offset, + objects, + call.as_ref(), + recursion_depth_left, + ); + } + pallet_utility::Call::dispatch_as { as_origin, call } => { + base_offset += as_origin.encoded_size() as u32; + + extract_call_block_object_mapping( + base_offset, + objects, + call.as_ref(), + recursion_depth_left, + ); + } + pallet_utility::Call::__Ignore(_, _) => { + // Ignore. + } + } +} + +fn extract_call_block_object_mapping( + mut base_offset: u32, + objects: &mut Vec, + call: &Call, + recursion_depth_left: u16, +) { + // Add enum variant to the base offset. + base_offset += 1; + + match call { + Call::Feeds(call) => { + extract_feeds_block_object_mapping(base_offset, objects, call); + } + Call::ObjectStore(call) => { + extract_object_store_block_object_mapping(base_offset, objects, call); + } + Call::Utility(call) => { + extract_utility_block_object_mapping(base_offset, objects, call, recursion_depth_left); + } + _ => {} + } +} + +fn extract_block_object_mapping(block: Block) -> BlockObjectMapping { + let mut block_object_mapping = BlockObjectMapping::default(); + let mut base_offset = + block.header.encoded_size() + Compact::compact_len(&(block.extrinsics.len() as u32)); + for extrinsic in block.extrinsics { + let signature_size = extrinsic + .signature + .as_ref() + .map(|s| s.encoded_size()) + .unwrap_or_default(); + // Extrinsic starts with vector length and version byte, followed by optional signature and + // `function` encoding. + let base_extrinsic_offset = base_offset + + Compact::compact_len( + &((1 + signature_size + extrinsic.function.encoded_size()) as u32), + ) + + 1 + + signature_size; + + extract_call_block_object_mapping( + base_extrinsic_offset as u32, + &mut block_object_mapping.objects, + &extrinsic.function, + MAX_OBJECT_MAPPING_RECURSION_DEPTH, + ); + + base_offset += extrinsic.encoded_size(); + } + + block_object_mapping +} + +fn extract_bundles(extrinsics: Vec) -> Vec { + extrinsics + .into_iter() + .filter_map(|opaque_extrinsic| { + match ::decode(&mut opaque_extrinsic.encode().as_slice()) { + Ok(uxt) => { + if let Call::Executor(pallet_executor::Call::submit_transaction_bundle { + opaque_bundle, + }) = uxt.function + { + Some(opaque_bundle) + } else { + None + } + } + Err(_) => None, + } + }) + .collect() +} + +fn extrinsics_shuffling_seed(header: Block::Header) -> Randomness { + if header.number().is_zero() { + Randomness::default() + } else { + let mut pre_digest: Option<_> = None; + for log in header.digest().logs() { + match ( + log.as_subspace_pre_digest::(), + pre_digest.is_some(), + ) { + (Some(_), true) => panic!("Multiple Subspace pre-runtime digests in a header"), + (None, _) => {} + (s, false) => pre_digest = s, + } + } + + let pre_digest = pre_digest.expect("Header must contain one pre-runtime digest; qed"); + + BlakeTwo256::hash_of(&pre_digest.solution.signature).into() + } +} + +impl_runtime_apis! { + impl sp_api::Core for Runtime { + fn version() -> RuntimeVersion { + VERSION + } + + fn execute_block(block: Block) { + Executive::execute_block(block); + } + + fn initialize_block(header: &::Header) { + Executive::initialize_block(header) + } + } + + impl sp_api::Metadata for Runtime { + fn metadata() -> OpaqueMetadata { + OpaqueMetadata::new(Runtime::metadata().into()) + } + } + + impl sp_block_builder::BlockBuilder for Runtime { + fn apply_extrinsic(extrinsic: ::Extrinsic) -> ApplyExtrinsicResult { + Executive::apply_extrinsic(extrinsic) + } + + fn finalize_block() -> ::Header { + Executive::finalize_block() + } + + fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<::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 for Runtime { + fn validate_transaction( + source: TransactionSource, + tx: ::Extrinsic, + block_hash: ::Hash, + ) -> TransactionValidity { + Executive::validate_transaction(source, tx, block_hash) + } + } + + impl sp_offchain::OffchainWorkerApi for Runtime { + fn offchain_worker(header: &::Header) { + Executive::offchain_worker(header) + } + } + + impl sp_consensus_subspace::SubspaceApi for Runtime { + fn confirmation_depth_k() -> <::Header as HeaderT>::Number { + ::ConfirmationDepthK::get() + } + + fn record_size() -> u32 { + ::RecordSize::get() + } + + fn recorded_history_segment_size() -> u32 { + ::RecordedHistorySegmentSize::get() + } + + fn slot_duration() -> Duration { + Duration::from_millis(Subspace::slot_duration()) + } + + fn global_randomnesses() -> GlobalRandomnesses { + Subspace::global_randomnesses() + } + + fn solution_ranges() -> SolutionRanges { + Subspace::solution_ranges() + } + + fn salts() -> Salts { + Subspace::salts() + } + + fn submit_report_equivocation_extrinsic( + equivocation_proof: EquivocationProof<::Header>, + ) -> Option<()> { + Subspace::submit_equivocation_report(equivocation_proof) + } + + fn is_in_block_list(farmer_public_key: &FarmerPublicKey) -> bool { + // TODO: Either check tx pool too for pending equivocations or replace equivocation + // mechanism with an alternative one, so that blocking happens faster + Subspace::is_in_block_list(farmer_public_key) + } + + fn records_root(segment_index: u64) -> Option { + Subspace::records_root(segment_index) + } + + fn extract_root_blocks(ext: &::Extrinsic) -> Option> { + extract_root_blocks(ext) + } + + fn extract_block_object_mapping(block: Block) -> BlockObjectMapping { + extract_block_object_mapping(block) + } + } + + impl sp_executor::ExecutorApi for Runtime { + fn submit_execution_receipt_unsigned( + opaque_execution_receipt: sp_executor::OpaqueExecutionReceipt, + ) -> Option<()> { + ::Hash>>::decode( + &mut opaque_execution_receipt.encode().as_slice(), + ) + .ok() + .and_then(|execution_receipt| { + Executor::submit_execution_receipt_unsigned(execution_receipt).ok() + }) + } + + fn submit_transaction_bundle_unsigned(opaque_bundle: OpaqueBundle) -> Option<()> { + Executor::submit_transaction_bundle_unsigned(opaque_bundle).ok() + } + + fn submit_fraud_proof_unsigned(fraud_proof: FraudProof) -> Option<()> { + Executor::submit_fraud_proof_unsigned(fraud_proof).ok() + } + + fn submit_bundle_equivocation_proof_unsigned( + bundle_equivocation_proof: sp_executor::BundleEquivocationProof, + ) -> Option<()> { + Executor::submit_bundle_equivocation_proof_unsigned(bundle_equivocation_proof).ok() + } + + fn submit_invalid_transaction_proof_unsigned( + invalid_transaction_proof: sp_executor::InvalidTransactionProof, + ) -> Option<()> { + Executor::submit_invalid_transaction_proof_unsigned(invalid_transaction_proof).ok() + } + + fn extract_bundles(extrinsics: Vec) -> Vec { + extract_bundles(extrinsics) + } + + fn extrinsics_shuffling_seed(header: ::Header) -> Randomness { + extrinsics_shuffling_seed::(header) + } + } + + impl sp_session::SessionKeys for Runtime { + fn generate_session_keys(seed: Option>) -> Vec { + SessionKeys::generate(seed) + } + + fn decode_session_keys( + encoded: Vec, + ) -> Option, KeyTypeId)>> { + SessionKeys::decode_into_raw_public_keys(&encoded) + } + } + + impl frame_system_rpc_runtime_api::AccountNonceApi for Runtime { + fn account_nonce(account: AccountId) -> Index { + System::account_nonce(account) + } + } + + impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi for Runtime { + fn query_info( + uxt: ::Extrinsic, + len: u32, + ) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo { + TransactionPayment::query_info(uxt, len) + } + fn query_fee_details( + uxt: ::Extrinsic, + len: u32, + ) -> pallet_transaction_payment::FeeDetails { + TransactionPayment::query_fee_details(uxt, len) + } + } + + #[cfg(feature = "runtime-benchmarks")] + impl frame_benchmarking::Benchmark for Runtime { + fn benchmark_metadata(extra: bool) -> ( + Vec, + Vec, + ) { + use frame_benchmarking::{list_benchmark, baseline, Benchmarking, BenchmarkList}; + use frame_support::traits::StorageInfoTrait; + use frame_system_benchmarking::Pallet as SystemBench; + use baseline::Pallet as BaselineBench; + + let mut list = Vec::::new(); + + list_benchmark!(list, extra, frame_benchmarking, BaselineBench::); + list_benchmark!(list, extra, frame_system, SystemBench::); + list_benchmark!(list, extra, pallet_balances, Balances); + list_benchmark!(list, extra, pallet_timestamp, Timestamp); + list_benchmark!(params, batches, pallet_utility, Utility); + list_benchmark!(list, extra, pallet_template, TemplateModule); + + let storage_info = AllPalletsWithSystem::storage_info(); + + return (list, storage_info) + } + + fn dispatch_benchmark( + config: frame_benchmarking::BenchmarkConfig + ) -> Result, sp_runtime::RuntimeString> { + use frame_benchmarking::{baseline, Benchmarking, BenchmarkBatch, add_benchmark, TrackedStorageKey}; + + use frame_system_benchmarking::Pallet as SystemBench; + use baseline::Pallet as BaselineBench; + + impl frame_system_benchmarking::Config for Runtime {} + impl baseline::Config for Runtime {} + + let whitelist: Vec = 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::::new(); + let params = (&config, &whitelist); + + add_benchmark!(params, batches, frame_benchmarking, BaselineBench::); + add_benchmark!(params, batches, frame_system, SystemBench::); + add_benchmark!(params, batches, pallet_balances, Balances); + add_benchmark!(params, batches, pallet_timestamp, Timestamp); + add_benchmark!(params, batches, pallet_utility, Utility); + add_benchmark!(params, batches, pallet_template, TemplateModule); + + Ok(batches) + } + } +} diff --git a/crates/subspace-consensus-runtime/tests/integration/main.rs b/crates/subspace-runtime/tests/integration/main.rs similarity index 100% rename from crates/subspace-consensus-runtime/tests/integration/main.rs rename to crates/subspace-runtime/tests/integration/main.rs diff --git a/crates/subspace-consensus-runtime/tests/integration/object_mapping.rs b/crates/subspace-runtime/tests/integration/object_mapping.rs similarity index 98% rename from crates/subspace-consensus-runtime/tests/integration/object_mapping.rs rename to crates/subspace-runtime/tests/integration/object_mapping.rs index 1b6924a82fa51..bc30bda3e88eb 100644 --- a/crates/subspace-consensus-runtime/tests/integration/object_mapping.rs +++ b/crates/subspace-runtime/tests/integration/object_mapping.rs @@ -1,8 +1,8 @@ use codec::Encode; use sp_consensus_subspace::runtime_decl_for_SubspaceApi::SubspaceApi; -use subspace_consensus_runtime::{Block, Call, Header, Runtime, UncheckedExtrinsic}; use subspace_core_primitives::crypto; use subspace_core_primitives::objects::BlockObjectMapping; +use subspace_runtime::{Block, Call, Header, Runtime, UncheckedExtrinsic}; #[test] fn object_mapping() { diff --git a/cumulus/parachain-template/node/Cargo.toml b/cumulus/parachain-template/node/Cargo.toml index 4dcdeb4863ab8..03be0033193b0 100644 --- a/cumulus/parachain-template/node/Cargo.toml +++ b/cumulus/parachain-template/node/Cargo.toml @@ -21,7 +21,7 @@ path = "src/main.rs" [features] runtime-benchmarks = [ - "subspace-runtime/runtime-benchmarks", + "parachain-template-runtime/runtime-benchmarks", "subspace-node/runtime-benchmarks", ] @@ -35,6 +35,9 @@ clap = { version = "3.1.6", features = ["derive"] } # RPC related Dependencies jsonrpc-core = "18.0.0" +# Local Dependencies +parachain-template-runtime = { path = "../runtime" } + # Substrate Dependencies frame-benchmarking = { git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998" } frame-benchmarking-cli = { git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998" } diff --git a/cumulus/parachain-template/node/src/chain_spec.rs b/cumulus/parachain-template/node/src/chain_spec.rs index b6c4b788cc968..1dba223129bc5 100644 --- a/cumulus/parachain-template/node/src/chain_spec.rs +++ b/cumulus/parachain-template/node/src/chain_spec.rs @@ -1,13 +1,13 @@ +use parachain_template_runtime::{AccountId, Signature}; use sc_chain_spec::{ChainSpecExtension, ChainSpecGroup}; use sc_service::ChainType; use serde::{Deserialize, Serialize}; use sp_core::{sr25519, Pair, Public}; use sp_runtime::traits::{IdentifyAccount, Verify}; -use subspace_runtime::execution::{AccountId, Signature}; /// Specialized `ChainSpec` for the normal parachain runtime. pub type ChainSpec = - sc_service::GenericChainSpec; + sc_service::GenericChainSpec; /// Helper function to generate a crypto pair from seed pub fn get_pair_from_seed(seed: &str) -> ::Public { @@ -130,14 +130,14 @@ pub fn local_testnet_config() -> ChainSpec { ) } -fn testnet_genesis(endowed_accounts: Vec) -> subspace_runtime::execution::GenesisConfig { - subspace_runtime::execution::GenesisConfig { - system: subspace_runtime::execution::SystemConfig { - code: subspace_runtime::WASM_BINARY +fn testnet_genesis(endowed_accounts: Vec) -> parachain_template_runtime::GenesisConfig { + parachain_template_runtime::GenesisConfig { + system: parachain_template_runtime::SystemConfig { + code: parachain_template_runtime::WASM_BINARY .expect("WASM binary was not build, please build it!") .to_vec(), }, - balances: subspace_runtime::execution::BalancesConfig { + balances: parachain_template_runtime::BalancesConfig { balances: endowed_accounts.iter().cloned().map(|k| (k, 1 << 60)).collect(), }, } diff --git a/cumulus/parachain-template/node/src/command.rs b/cumulus/parachain-template/node/src/command.rs index 19f3f5d42c482..70e6b3e407c7a 100644 --- a/cumulus/parachain-template/node/src/command.rs +++ b/cumulus/parachain-template/node/src/command.rs @@ -6,6 +6,7 @@ use crate::{ use cirrus_client_service::genesis::generate_genesis_block; use codec::Encode; use log::info; +use parachain_template_runtime::{Block, RuntimeApi}; use sc_cli::{ ChainSpec, CliConfiguration, DefaultConfigurationValues, ImportParams, KeystoreParams, NetworkParams, Result, RuntimeVersion, SharedParams, SubstrateCli, @@ -14,7 +15,6 @@ use sc_service::config::{BasePath, PrometheusConfig}; use sp_core::hexdisplay::HexDisplay; use sp_runtime::traits::Block as BlockT; use std::{io::Write, net::SocketAddr}; -use subspace_runtime::execution::{Block, RuntimeApi}; fn load_spec(id: &str) -> std::result::Result, String> { Ok(match id { @@ -61,7 +61,7 @@ impl SubstrateCli for Cli { } fn native_runtime_version(_: &Box) -> &'static RuntimeVersion { - &subspace_runtime::execution::VERSION + ¶chain_template_runtime::VERSION } } diff --git a/cumulus/parachain-template/node/src/rpc.rs b/cumulus/parachain-template/node/src/rpc.rs index 5e14701531b99..5d3dd817c8a4b 100644 --- a/cumulus/parachain-template/node/src/rpc.rs +++ b/cumulus/parachain-template/node/src/rpc.rs @@ -7,7 +7,7 @@ use std::sync::Arc; -use subspace_runtime::execution::{opaque::Block, AccountId, Balance, Index as Nonce}; +use parachain_template_runtime::{opaque::Block, AccountId, Balance, Index as Nonce}; use sc_client_api::AuxStore; pub use sc_rpc::{DenyUnsafe, SubscriptionTaskExecutor}; diff --git a/cumulus/parachain-template/node/src/service.rs b/cumulus/parachain-template/node/src/service.rs index cb8c306895b70..b6ab0f309b5b4 100644 --- a/cumulus/parachain-template/node/src/service.rs +++ b/cumulus/parachain-template/node/src/service.rs @@ -5,7 +5,7 @@ use sc_basic_authorship::ProposerFactory; use std::sync::Arc; // Local Runtime Types -use subspace_runtime::execution::{opaque::Block, AccountId, Balance, Index as Nonce, RuntimeApi}; +use parachain_template_runtime::{opaque::Block, AccountId, Balance, Index as Nonce, RuntimeApi}; // Cumulus Imports use cirrus_client_service::prepare_node_config; @@ -26,11 +26,11 @@ impl NativeExecutionDispatch for TemplateRuntimeExecutor { type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions; fn dispatch(method: &str, data: &[u8]) -> Option> { - subspace_runtime::execution::api::dispatch(method, data) + parachain_template_runtime::api::dispatch(method, data) } fn native_version() -> sc_executor::NativeVersion { - subspace_runtime::execution::native_version() + parachain_template_runtime::native_version() } } @@ -217,10 +217,10 @@ where let span = tracing::info_span!(sc_tracing::logging::PREFIX_LOG_SPAN, name = "Primarychain"); let _enter = span.enter(); - subspace_service::new_full::< - subspace_runtime::consensus::RuntimeApi, - subspace_node::ExecutorDispatch, - >(polkadot_config, false) + subspace_service::new_full::( + polkadot_config, + false, + ) .await .map_err(|_| sc_service::Error::Other("Failed to build a full subspace node".into()))? }; diff --git a/cumulus/parachain-template/runtime/Cargo.toml b/cumulus/parachain-template/runtime/Cargo.toml index 4c2380ba2ed3e..1dd130b6cbd6a 100644 --- a/cumulus/parachain-template/runtime/Cargo.toml +++ b/cumulus/parachain-template/runtime/Cargo.toml @@ -11,6 +11,9 @@ edition = "2021" [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] +[build-dependencies] +substrate-wasm-builder = { git = "https://github.com/paritytech/substrate", rev = "c364008a6c7da8456e17967f55edf51e45146998" } + [dependencies] hex-literal = { version = '0.3.1', optional = true } codec = { package = "parity-scale-codec", version = "3.1.2", default-features = false, features = ["derive"]} diff --git a/cumulus/parachain-template/runtime/build.rs b/cumulus/parachain-template/runtime/build.rs new file mode 100644 index 0000000000000..9b53d2457dffd --- /dev/null +++ b/cumulus/parachain-template/runtime/build.rs @@ -0,0 +1,9 @@ +use substrate_wasm_builder::WasmBuilder; + +fn main() { + WasmBuilder::new() + .with_current_project() + .export_heap_base() + .import_memory() + .build() +} diff --git a/cumulus/parachain-template/runtime/src/lib.rs b/cumulus/parachain-template/runtime/src/lib.rs index a31e9f6ffdf9e..267df33ac8f02 100644 --- a/cumulus/parachain-template/runtime/src/lib.rs +++ b/cumulus/parachain-template/runtime/src/lib.rs @@ -2,6 +2,10 @@ // `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256. #![recursion_limit = "256"] +// Make the WASM binary available. +#[cfg(feature = "std")] +include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); + use smallvec::smallvec; use sp_api::impl_runtime_apis; use sp_core::{crypto::KeyTypeId, OpaqueMetadata};