diff --git a/.github/workflows/unit-tests-suite.yml b/.github/workflows/unit-tests-suite.yml index f1440797..d89d60b6 100644 --- a/.github/workflows/unit-tests-suite.yml +++ b/.github/workflows/unit-tests-suite.yml @@ -9,16 +9,16 @@ on: concurrency: group: ${{ github.ref }}-${{ github.workflow }} - cancel-in-progress: false + cancel-in-progress: true env: CARGO_TERM_COLOR: always +# TODO: refactor common steps into a workflow jobs: - unit-test-suite: + basic-checks: runs-on: ubuntu-latest - steps: - name: Install protoc compiler @@ -37,23 +37,43 @@ jobs: ~/.cargo/registry/index/ ~/.cargo/registry/cache/ ~/.cargo/git/db/ - target/ - key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} + /tmp/academy-pow/target/ + key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}-v1 - name: Install Rust toolchain uses: Cardinal-Cryptography/github-actions/install-rust-toolchain@v1 - name: Run fmt - uses: actions-rs/cargo@v1 - with: - command: fmt - args: --all + run: make fmt - name: Run clippy - uses: actions-rs/cargo@v1 + run: make clippy + + unit-tests: + runs-on: ubuntu-latest + steps: + + - name: Install protoc compiler + shell: bash + run: | + sudo apt-get install -y protobuf-compiler + + - name: Checkout Source code + uses: actions/checkout@v3 + + - name: Cache cargo + uses: actions/cache@v3 with: - command: clippy - args: --all-targets -- --no-deps -D warnings + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + /tmp/academy-pow/target/ + key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}-v1 + + - name: Install Rust toolchain + uses: Cardinal-Cryptography/github-actions/install-rust-toolchain@v1 - name: Run tests - run: cargo test --verbose + run: make test diff --git a/Cargo.lock b/Cargo.lock index 80f6d96d..92b2d1f2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -22,6 +22,7 @@ dependencies = [ "hex", "jsonrpsee", "log", + "pallet-transaction-payment-rpc", "parity-scale-codec", "rand 0.8.5", "sc-basic-authorship", @@ -32,12 +33,15 @@ dependencies = [ "sc-consensus-pow", "sc-executor", "sc-network", + "sc-rpc-api", "sc-service", "sc-telemetry", "sc-transaction-pool", + "sc-transaction-pool-api", "sha3", "sha3pow", "sp-api", + "sp-block-builder", "sp-blockchain", "sp-consensus", "sp-consensus-pow", @@ -47,6 +51,7 @@ dependencies = [ "sp-timestamp", "sp-transaction-pool", "substrate-build-script-utils", + "substrate-frame-rpc-system", ] [[package]] @@ -57,10 +62,16 @@ dependencies = [ "frame-executive", "frame-support", "frame-system", + "frame-system-rpc-runtime-api", "hex-literal", "pallet-balances", + "pallet-contracts", + "pallet-contracts-primitives", + "pallet-insecure-randomness-collective-flip", "pallet-sudo", "pallet-timestamp", + "pallet-transaction-payment", + "pallet-transaction-payment-rpc-runtime-api", "parity-scale-codec", "scale-info", "serde", @@ -2244,6 +2255,15 @@ dependencies = [ "sp-weights", ] +[[package]] +name = "frame-system-rpc-runtime-api" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#569aae5341ea0c1d10426fa1ec13a36c0b64393b" +dependencies = [ + "parity-scale-codec", + "sp-api", +] + [[package]] name = "fs-err" version = "2.9.0" @@ -2885,6 +2905,12 @@ dependencies = [ "serde", ] +[[package]] +name = "indexmap-nostd" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e04e2fd2b8188ea827b32ef11de88377086d690286ab35747ef7f9bf3ccb590" + [[package]] name = "inout" version = "0.1.3" @@ -4427,6 +4453,72 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-contracts" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#569aae5341ea0c1d10426fa1ec13a36c0b64393b" +dependencies = [ + "bitflags", + "environmental", + "frame-benchmarking", + "frame-support", + "frame-system", + "impl-trait-for-tuples", + "log", + "pallet-contracts-primitives", + "pallet-contracts-proc-macro", + "parity-scale-codec", + "rand 0.8.5", + "scale-info", + "serde", + "smallvec", + "sp-api", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", + "wasm-instrument 0.4.0", + "wasmi 0.28.0", + "wasmparser-nostd", +] + +[[package]] +name = "pallet-contracts-primitives" +version = "7.0.0" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#569aae5341ea0c1d10426fa1ec13a36c0b64393b" +dependencies = [ + "bitflags", + "parity-scale-codec", + "scale-info", + "sp-runtime", + "sp-std", + "sp-weights", +] + +[[package]] +name = "pallet-contracts-proc-macro" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#569aae5341ea0c1d10426fa1ec13a36c0b64393b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.18", +] + +[[package]] +name = "pallet-insecure-randomness-collective-flip" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#569aae5341ea0c1d10426fa1ec13a36c0b64393b" +dependencies = [ + "frame-support", + "frame-system", + "parity-scale-codec", + "safe-mix", + "scale-info", + "sp-runtime", + "sp-std", +] + [[package]] name = "pallet-sudo" version = "4.0.0-dev" @@ -4459,6 +4551,50 @@ dependencies = [ "sp-timestamp", ] +[[package]] +name = "pallet-transaction-payment" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#569aae5341ea0c1d10426fa1ec13a36c0b64393b" +dependencies = [ + "frame-support", + "frame-system", + "parity-scale-codec", + "scale-info", + "serde", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "pallet-transaction-payment-rpc" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#569aae5341ea0c1d10426fa1ec13a36c0b64393b" +dependencies = [ + "jsonrpsee", + "pallet-transaction-payment-rpc-runtime-api", + "parity-scale-codec", + "sp-api", + "sp-blockchain", + "sp-core", + "sp-rpc", + "sp-runtime", + "sp-weights", +] + +[[package]] +name = "pallet-transaction-payment-rpc-runtime-api" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#569aae5341ea0c1d10426fa1ec13a36c0b64393b" +dependencies = [ + "pallet-transaction-payment", + "parity-scale-codec", + "sp-api", + "sp-runtime", + "sp-weights", +] + [[package]] name = "parity-db" version = "0.4.8" @@ -5326,7 +5462,7 @@ dependencies = [ "cc", "libc", "once_cell", - "spin", + "spin 0.5.2", "untrusted", "web-sys", "winapi", @@ -5421,6 +5557,15 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver 0.9.0", +] + [[package]] name = "rustc_version" version = "0.4.0" @@ -5536,6 +5681,15 @@ version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" +[[package]] +name = "safe-mix" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d3d055a2582e6b00ed7a31c1524040aa391092bf636328350813f3a0605215c" +dependencies = [ + "rustc_version 0.2.3", +] + [[package]] name = "safe_arch" version = "0.7.0" @@ -5931,7 +6085,7 @@ dependencies = [ "sp-version", "sp-wasm-interface", "tracing", - "wasmi", + "wasmi 0.13.2", ] [[package]] @@ -5943,8 +6097,8 @@ dependencies = [ "sp-maybe-compressed-blob", "sp-wasm-interface", "thiserror", - "wasm-instrument", - "wasmi", + "wasm-instrument 0.3.0", + "wasmi 0.13.2", ] [[package]] @@ -5957,7 +6111,7 @@ dependencies = [ "sc-executor-common", "sp-runtime-interface", "sp-wasm-interface", - "wasmi", + "wasmi 0.13.2", ] [[package]] @@ -6745,6 +6899,15 @@ dependencies = [ "semver-parser", ] +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + [[package]] name = "semver" version = "1.0.17" @@ -6989,7 +7152,7 @@ dependencies = [ "curve25519-dalek 4.0.0-rc.1", "rand_core 0.6.4", "ring", - "rustc_version", + "rustc_version 0.4.0", "sha2 0.10.6", "subtle", ] @@ -7663,7 +7826,7 @@ dependencies = [ "log", "parity-scale-codec", "sp-std", - "wasmi", + "wasmi 0.13.2", "wasmtime", ] @@ -7688,6 +7851,12 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + [[package]] name = "spki" version = "0.6.0" @@ -7831,6 +8000,25 @@ dependencies = [ "platforms 2.0.0", ] +[[package]] +name = "substrate-frame-rpc-system" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#569aae5341ea0c1d10426fa1ec13a36c0b64393b" +dependencies = [ + "frame-system-rpc-runtime-api", + "futures", + "jsonrpsee", + "log", + "parity-scale-codec", + "sc-rpc-api", + "sc-transaction-pool-api", + "sp-api", + "sp-block-builder", + "sp-blockchain", + "sp-core", + "sp-runtime", +] + [[package]] name = "substrate-prometheus-endpoint" version = "0.10.0-dev" @@ -8719,6 +8907,15 @@ dependencies = [ "parity-wasm", ] +[[package]] +name = "wasm-instrument" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a47ecb37b9734d1085eaa5ae1a81e60801fd8c28d4cabdd8aedb982021918bc" +dependencies = [ + "parity-wasm", +] + [[package]] name = "wasm-opt" version = "0.111.0" @@ -8783,7 +8980,19 @@ checksum = "06c326c93fbf86419608361a2c925a31754cf109da1b8b55737070b4d6669422" dependencies = [ "parity-wasm", "wasmi-validation", - "wasmi_core", + "wasmi_core 0.2.1", +] + +[[package]] +name = "wasmi" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e61a7006b0fdf24f6bbe8dcfdad5ca1b350de80061fb2827f31c82fbbb9565a" +dependencies = [ + "spin 0.9.8", + "wasmi_arena", + "wasmi_core 0.12.0", + "wasmparser-nostd", ] [[package]] @@ -8795,6 +9004,12 @@ dependencies = [ "parity-wasm", ] +[[package]] +name = "wasmi_arena" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "401c1f35e413fac1846d4843745589d9ec678977ab35a384db8ae7830525d468" + [[package]] name = "wasmi_core" version = "0.2.1" @@ -8809,6 +9024,18 @@ dependencies = [ "region", ] +[[package]] +name = "wasmi_core" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624e6333e861ef49095d2d678b76ebf30b06bf37effca845be7e5b87c90071b7" +dependencies = [ + "downcast-rs", + "libm 0.2.7", + "num-traits", + "paste", +] + [[package]] name = "wasmparser" version = "0.100.0" @@ -8819,6 +9046,15 @@ dependencies = [ "url", ] +[[package]] +name = "wasmparser-nostd" +version = "0.100.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9157cab83003221bfd385833ab587a039f5d6fa7304854042ba358a3b09e0724" +dependencies = [ + "indexmap-nostd", +] + [[package]] name = "wasmtime" version = "6.0.2" diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..2277e9d6 --- /dev/null +++ b/Makefile @@ -0,0 +1,11 @@ +clippy: + WASM_BUILD_WORKSPACE_HINT=${PWD} CARGO_TARGET_DIR=/tmp/target/ cargo clippy --all-targets -- --no-deps -D warnings + +fmt: + cargo fmt --all + +test: + WASM_BUILD_WORKSPACE_HINT=${PWD} CARGO_TARGET_DIR=/tmp/target/ cargo test --verbose + +watch: + cargo watch -s 'WASM_BUILD_WORKSPACE_HINT=${PWD} CARGO_TARGET_DIR=/tmp/target/ cargo check' -c diff --git a/node/Cargo.toml b/node/Cargo.toml index 79cf24f6..76ff5a63 100644 --- a/node/Cargo.toml +++ b/node/Cargo.toml @@ -19,7 +19,13 @@ clap = { version = "4.3.0", features = ["derive"] } parity-scale-codec = '3.1.2' sha3 = "0.10.1" rand = { version = "0.8.5", features = ["small_rng"] } + +# These dependencies are used for the node template's RPCs jsonrpsee = { version = "0.16.0", features = ["server"] } +pallet-transaction-payment-rpc = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +sc-rpc-api = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +sp-block-builder = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +substrate-frame-rpc-system = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } sc-consensus-pow = {git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } sc-consensus-manual-seal = {git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } @@ -32,6 +38,7 @@ sc-network = {git = "https://github.com/paritytech/substrate.git", branch = "pol sc-service = {git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } sc-telemetry = {git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } sc-transaction-pool = {git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +sc-transaction-pool-api = {git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } sp-api = {git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } sp-blockchain = {git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } sp-consensus = {git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } diff --git a/node/src/chain_spec.rs b/node/src/chain_spec.rs index 2e4fad03..abc274d3 100644 --- a/node/src/chain_spec.rs +++ b/node/src/chain_spec.rs @@ -1,14 +1,10 @@ use academy_pow_runtime::{ - AccountId, BalancesConfig, DifficultyAdjustmentConfig, GenesisConfig, Signature, - /*SudoConfig,*/ SystemConfig, WASM_BINARY, + AccountId, BalancesConfig, DifficultyAdjustmentConfig, GenesisConfig, Signature, SystemConfig, + WASM_BINARY, }; - use sp_core::{sr25519, Pair, Public}; use sp_runtime::traits::{IdentifyAccount, Verify}; -// Note this is the URL for the telemetry server -//const STAGING_TELEMETRY_URL: &str = "wss://telemetry.polkadot.io/submit/"; - /// Specialized `ChainSpec`. This is a specialization of the general Substrate ChainSpec type. pub type ChainSpec = sc_service::GenericChainSpec; @@ -113,10 +109,11 @@ fn testnet_genesis( .collect(), }, // sudo: SudoConfig { - // key: Some(root_key), + // key: Some(root_key), // }, difficulty_adjustment: DifficultyAdjustmentConfig { initial_difficulty: 4_000_000.into(), }, + transaction_payment: Default::default(), } } diff --git a/node/src/cli.rs b/node/src/cli.rs index 0c813142..8ac8376b 100644 --- a/node/src/cli.rs +++ b/node/src/cli.rs @@ -24,7 +24,7 @@ fn parse_sr25519_public_key(i: &str) -> Result .map_err(|e| e.to_string())? .as_slice() .try_into() - .or(Err("invalid length for SR25519 public key".to_string())) + .map_err(|_| "invalid length for SR25519 public key".to_string()) } #[derive(Debug, clap::Subcommand)] diff --git a/node/src/command.rs b/node/src/command.rs index 1c1407c5..2b987e20 100644 --- a/node/src/command.rs +++ b/node/src/command.rs @@ -150,7 +150,7 @@ pub fn run() -> sc_cli::Result<()> { let sr25519_public_key = cli .run .sr25519_public_key - .unwrap_or(sp_core::sr25519::Public::from_raw([0; 32])); + .unwrap_or_else(|| sp_core::sr25519::Public::from_raw([0; 32])); let instant_seal = cli.run.base.is_dev()?; let runner = cli.create_runner(&cli.run.base)?; runner.run_node_until_exit(|config| async move { diff --git a/node/src/main.rs b/node/src/main.rs index 0e4e82f5..a4182cd5 100644 --- a/node/src/main.rs +++ b/node/src/main.rs @@ -6,6 +6,7 @@ mod chain_spec; mod service; mod cli; mod command; +mod rpc; fn main() -> sc_cli::Result<()> { command::run() diff --git a/node/src/rpc.rs b/node/src/rpc.rs new file mode 100644 index 00000000..a07c9a88 --- /dev/null +++ b/node/src/rpc.rs @@ -0,0 +1,56 @@ +//! A collection of node-specific RPC methods. +//! Substrate provides the `sc-rpc` crate, which defines the core RPC layer +//! used by Substrate nodes. This file extends those RPC definitions with +//! capabilities that are specific to this project's runtime configuration. + +#![warn(missing_docs)] + +use std::sync::Arc; + +use academy_pow_runtime::{opaque::Block, AccountId, Balance, Index}; +use jsonrpsee::RpcModule; +use sc_transaction_pool_api::TransactionPool; +use sp_api::ProvideRuntimeApi; +use sp_block_builder::BlockBuilder; +use sp_blockchain::{Error as BlockChainError, HeaderBackend, HeaderMetadata}; + +pub use sc_rpc_api::DenyUnsafe; + +/// Full client dependencies. +pub struct FullDeps { + /// The client instance to use. + pub client: Arc, + /// Transaction pool instance. + pub pool: Arc

, + /// Whether to deny unsafe calls + pub deny_unsafe: DenyUnsafe, +} + +/// Instantiate all full RPC extensions. +pub fn create_full( + deps: FullDeps, +) -> Result, Box> +where + C: ProvideRuntimeApi, + C: HeaderBackend + HeaderMetadata + 'static, + C: Send + Sync + 'static, + C::Api: substrate_frame_rpc_system::AccountNonceApi, + C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi, + C::Api: BlockBuilder, + P: TransactionPool + 'static, +{ + use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApiServer}; + use substrate_frame_rpc_system::{System, SystemApiServer}; + + let mut module = RpcModule::new(()); + let FullDeps { + client, + pool, + deny_unsafe, + } = deps; + + module.merge(System::new(client.clone(), pool, deny_unsafe).into_rpc())?; + module.merge(TransactionPayment::new(client).into_rpc())?; + + Ok(module) +} diff --git a/node/src/service.rs b/node/src/service.rs index d229155a..3b3a1803 100644 --- a/node/src/service.rs +++ b/node/src/service.rs @@ -1,9 +1,7 @@ //! Service and ServiceFactory implementation. Specialized wrapper over substrate service. -use core::clone::Clone; -use std::sync::Arc; - use academy_pow_runtime::{self, opaque::Block, RuntimeApi}; +use core::clone::Clone; use parity_scale_codec::Encode; use sc_consensus::LongestChain; use sc_executor::NativeElseWasmExecutor; @@ -12,6 +10,7 @@ use sc_telemetry::{Telemetry, TelemetryWorker}; use sha3pow::Sha3Algorithm; use sp_api::TransactionFor; use sp_core::sr25519; +use std::sync::Arc; // Our native executor instance. pub struct ExecutorDispatch; @@ -205,13 +204,27 @@ pub fn new_full( let role = config.role.clone(); let prometheus_registry = config.prometheus_registry().cloned(); + let rpc_extensions_builder = { + let client = client.clone(); + let pool = transaction_pool.clone(); + + Box::new(move |deny_unsafe, _| { + let deps = crate::rpc::FullDeps { + client: client.clone(), + pool: pool.clone(), + deny_unsafe, + }; + crate::rpc::create_full(deps).map_err(Into::into) + }) + }; + sc_service::spawn_tasks(sc_service::SpawnTasksParams { network, client: client.clone(), keystore: keystore_container.keystore(), task_manager: &mut task_manager, transaction_pool: transaction_pool.clone(), - rpc_builder: Box::new(|_, _| Ok(jsonrpsee::RpcModule::new(()))), + rpc_builder: rpc_extensions_builder, backend, system_rpc_tx, tx_handler_controller, diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index 61e402b1..fe8f7322 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -31,6 +31,15 @@ sp-transaction-pool = { default-features = false, git = "https://github.com/pari sp-version = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } pallet-timestamp = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } sp-keystore = { optional = true, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +pallet-contracts = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +pallet-contracts-primitives = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +pallet-transaction-payment = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +pallet-insecure-randomness-collective-flip = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } + +# Used for the node's RPCs +pallet-transaction-payment-rpc-runtime-api = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +frame-system-rpc-runtime-api = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } + [dev-dependencies] hex-literal = "0.4.1" @@ -63,4 +72,10 @@ std = [ 'pallet-timestamp/std', 'async-trait', 'sp-keystore', + 'pallet-contracts/std', + "pallet-contracts-primitives/std", + "pallet-transaction-payment/std", + "pallet-transaction-payment-rpc-runtime-api/std", + "pallet-insecure-randomness-collective-flip/std", + "frame-system-rpc-runtime-api/std" ] diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index e3520ea1..83942240 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -8,23 +8,28 @@ #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); -use frame_support::traits::Currency; pub use frame_support::{ - construct_runtime, - dispatch::Callable, - parameter_types, - traits::{ConstU128, ConstU32, IsSubType}, + construct_runtime, log, parameter_types, + traits::{ + Currency, EstimateNextNewSession, Imbalance, KeyOwnerProofSystem, LockIdentifier, Nothing, + OnUnbalanced, Randomness, ValidatorSet, + }, weights::{ constants::{ BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_REF_TIME_PER_SECOND, }, - Weight, + IdentityFee, Weight, }, StorageValue, }; +use frame_support::{ + sp_runtime::Perquintill, + traits::{ConstBool, ConstU128, ConstU32, ConstU8}, +}; use issuance::Issuance; pub use pallet_balances::Call as BalancesCall; pub use pallet_timestamp::Call as TimestampCall; +use pallet_transaction_payment::{ConstFeeMultiplier, CurrencyAdapter, Multiplier}; use sp_api::impl_runtime_apis; use sp_core::{OpaqueMetadata, U256}; // A few exports that help ease life for downstream crates. @@ -32,11 +37,13 @@ use sp_core::{OpaqueMetadata, U256}; pub use sp_runtime::BuildStorage; use sp_runtime::{ create_runtime_str, generic, - traits::{AccountIdLookup, BlakeTwo256, Block as BlockT, IdentifyAccount, Verify}, + traits::{ + AccountIdLookup, BlakeTwo256, Block as BlockT, Bounded, IdentifyAccount, One, Verify, + }, transaction_validity::{TransactionSource, TransactionValidity}, ApplyExtrinsicResult, MultiSignature, }; -pub use sp_runtime::{Perbill, Permill}; +pub use sp_runtime::{FixedPointNumber, Perbill, Permill}; use sp_std::prelude::*; #[cfg(feature = "std")] use sp_version::NativeVersion; @@ -115,6 +122,9 @@ pub fn native_version() -> NativeVersion { } const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75); +// native chain currency +pub const TOKEN_DECIMALS: u32 = 12; +pub const TOKEN: u128 = 10u128.pow(TOKEN_DECIMALS); parameter_types! { pub const BlockHashCount: BlockNumber = 2400; @@ -238,8 +248,8 @@ impl faucet::Config for Runtime { // type Event = Event; type Currency = Balances; - // Each drip of the faucet give 5 tokens (with 12 decimals) - type DripAmount = ConstU128<5_000_000_000_000>; + // Each drip of the faucet gives 5 tokens (with 12 decimals) + type DripAmount = ConstU128<{ 5 * TOKEN }>; } impl block_author::Config for Runtime { @@ -248,15 +258,84 @@ impl block_author::Config for Runtime { let block = System::block_number(); let issuance = >::issuance(block); - // 12 decimals... right? - let issuance = issuance * 1_000_000_000_000; - // sp_std::if_std!{ - // println!("Depositing {issuance} into {author_account}"); - // } + let issuance = issuance * TOKEN; let _ = Balances::deposit_creating(&author_account, issuance); } } +parameter_types! { + // This value increases the priority of `Operational` transactions by adding + // a "virtual tip" that's equal to the `OperationalFeeMultiplier * final_fee`. + // follows polkadot : https://github.com/paritytech/polkadot/blob/9ce5f7ef5abb1a4291454e8c9911b304d80679f9/runtime/polkadot/src/lib.rs#L369 + pub const OperationalFeeMultiplier: u8 = 5; + // We expect that on average 25% of the normal capacity will be occupied with normal txs. + pub const TargetSaturationLevel: Perquintill = Perquintill::from_percent(25); + // During 20 blocks the fee may not change more than by 100%. This, together with the + // `TargetSaturationLevel` value, results in variability ~0.067. For the corresponding + // formulas please refer to Substrate code at `frame/transaction-payment/src/lib.rs`. + pub FeeVariability: Multiplier = Multiplier::saturating_from_rational(67, 1000); + // Fee should never be lower than the computational cost. + pub MinimumMultiplier: Multiplier = Multiplier::one(); + pub MaximumMultiplier: Multiplier = Bounded::max_value(); +} + +impl pallet_insecure_randomness_collective_flip::Config for Runtime {} + +parameter_types! { + pub FeeMultiplier: Multiplier = Multiplier::one(); +} + +impl pallet_transaction_payment::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type OnChargeTransaction = CurrencyAdapter; + type OperationalFeeMultiplier = ConstU8<5>; + type WeightToFee = IdentityFee; + type LengthToFee = IdentityFee; + type FeeMultiplierUpdate = ConstFeeMultiplier; +} + +// Prints debug output of the `contracts` pallet to stdout if the node is started with `-lruntime::contracts=debug`. +const CONTRACTS_DEBUG_OUTPUT: bool = true; +// The storage per one byte of contract storage: 4*10^{-5} AZERO per byte. +pub const CONTRACT_DEPOSIT_PER_BYTE: Balance = 4 * (TOKEN / 100_000); + +parameter_types! { + // Refundable deposit per storage item + pub const DepositPerItem: Balance = 32 * CONTRACT_DEPOSIT_PER_BYTE; + // Refundable deposit per byte of storage + pub const DepositPerByte: Balance = CONTRACT_DEPOSIT_PER_BYTE; + // How much weight of each block can be spent on the lazy deletion queue of terminated contracts + pub DeletionWeightLimit: Weight = Perbill::from_percent(10) * BlockWeights::get().max_block; // 40ms + // Maximum size of the lazy deletion queue of terminated contracts. + pub const DeletionQueueDepth: u32 = 128; + pub Schedule: pallet_contracts::Schedule = Default::default(); + // Fallback value to limit the storage deposit if it's not being set by the caller + pub const DefaultDepositLimit: Balance = CONTRACT_DEPOSIT_PER_BYTE * 128 * 1024; +} + +impl pallet_contracts::Config for Runtime { + type Time = Timestamp; + type Randomness = RandomnessCollectiveFlip; + type Currency = Balances; + type RuntimeEvent = RuntimeEvent; + type RuntimeCall = RuntimeCall; + // The safest default is to allow no calls at all. This is unsafe experimental feature with no support in ink! + type CallFilter = Nothing; + type DepositPerItem = DepositPerItem; + type DepositPerByte = DepositPerByte; + type WeightPrice = pallet_transaction_payment::Pallet; + type WeightInfo = pallet_contracts::weights::SubstrateWeight; + type ChainExtension = (); + type Schedule = Schedule; + type CallStack = [pallet_contracts::Frame; 16]; + type AddressGenerator = pallet_contracts::DefaultAddressGenerator; + type MaxCodeLen = ConstU32<{ 25 * 1024 }>; + type MaxStorageKeyLen = ConstU32<128>; + type UnsafeUnstableInterface = ConstBool; + type MaxDebugBufferLen = ConstU32<{ 2 * 1024 * 1024 }>; + type DefaultDepositLimit = DefaultDepositLimit; +} + construct_runtime!( pub enum Runtime where Block = Block, @@ -264,13 +343,15 @@ construct_runtime!( UncheckedExtrinsic = UncheckedExtrinsic { System: frame_system, - // TODO remove timestamp silly + RandomnessCollectiveFlip: pallet_insecure_randomness_collective_flip, Timestamp: pallet_timestamp, Balances: pallet_balances, - // Sudo: pallet_sudo, + // Sudo: pallet_sudo + TransactionPayment: pallet_transaction_payment, DifficultyAdjustment: difficulty, BlockAuthor: block_author, Faucet: faucet, + Contracts: pallet_contracts, } ); @@ -386,4 +467,120 @@ impl_runtime_apis! { DifficultyAdjustment::difficulty() } } + + 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) + } + fn query_weight_to_fee(weight: Weight) -> Balance { + TransactionPayment::weight_to_fee(weight) + } + fn query_length_to_fee(length: u32) -> Balance { + TransactionPayment::length_to_fee(length) + } + } + +impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentCallApi + for Runtime + { + fn query_call_info( + call: RuntimeCall, + len: u32, + ) -> pallet_transaction_payment::RuntimeDispatchInfo { + TransactionPayment::query_call_info(call, len) + } + fn query_call_fee_details( + call: RuntimeCall, + len: u32, + ) -> pallet_transaction_payment::FeeDetails { + TransactionPayment::query_call_fee_details(call, len) + } + fn query_weight_to_fee(weight: Weight) -> Balance { + TransactionPayment::weight_to_fee(weight) + } + fn query_length_to_fee(length: u32) -> Balance { + TransactionPayment::length_to_fee(length) + } + } + + impl pallet_contracts::ContractsApi + for Runtime + { + fn call( + origin: AccountId, + dest: AccountId, + value: Balance, + gas_limit: Option, + storage_deposit_limit: Option, + input_data: Vec, + ) -> pallet_contracts_primitives::ContractExecResult { + let gas_limit = gas_limit.unwrap_or(BlockWeights::get().max_block); + Contracts::bare_call( + origin, + dest, + value, + gas_limit, + storage_deposit_limit, + input_data, + CONTRACTS_DEBUG_OUTPUT, + pallet_contracts::Determinism::Enforced, + ) + } + + fn instantiate( + origin: AccountId, + value: Balance, + gas_limit: Option, + storage_deposit_limit: Option, + code: pallet_contracts_primitives::Code, + data: Vec, + salt: Vec, + ) -> pallet_contracts_primitives::ContractInstantiateResult + { + let gas_limit = gas_limit.unwrap_or(BlockWeights::get().max_block); + Contracts::bare_instantiate( + origin, + value, + gas_limit, + storage_deposit_limit, + code, + data, + salt, + CONTRACTS_DEBUG_OUTPUT + ) + } + + fn upload_code( + origin: AccountId, + code: Vec, + storage_deposit_limit: Option, + determinism: pallet_contracts::Determinism, + ) -> pallet_contracts_primitives::CodeUploadResult + { + Contracts::bare_upload_code(origin, code, storage_deposit_limit, determinism) + } + + fn get_storage( + address: AccountId, + key: Vec, + ) -> pallet_contracts_primitives::GetStorageResult { + Contracts::get_storage(address, key) + } + } + }