diff --git a/.gitignore b/.gitignore index 6c79bfaf62ed17e608724b1872a9af000f97a079..aadaa13912c19dbc056245784442d8b4c9de2a82 100644 --- a/.gitignore +++ b/.gitignore @@ -2,14 +2,11 @@ **/*.rs.bk *.swp .wasm-binaries -polkadot/runtime/wasm/target/ -core/executor/wasm/target/ -core/test-runtime/wasm/target/ pwasm-alloc/target/ pwasm-libc/target/ pwasm-alloc/Cargo.lock pwasm-libc/Cargo.lock -node/runtime/wasm/target/ +bin/node/runtime/wasm/target/ **/._* **/.criterion/ .vscode diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e4226ee8adb84a3f71f34877afc4dba5e9495e47..7d1debb2fc09bc515c3bf91f1a2142505d35f062 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -15,6 +15,7 @@ stages: variables: GIT_STRATEGY: fetch + GIT_DEPTH: "3" CARGO_HOME: "/ci-cache/${CI_PROJECT_NAME}/cargo/${CI_JOB_NAME}" SCCACHE_DIR: "/ci-cache/${CI_PROJECT_NAME}/sccache" CARGO_INCREMENTAL: 0 @@ -55,6 +56,8 @@ variables: - runner_system_failure - unknown_failure - api_failure + dependencies: [] + interruptible: true tags: - linux-docker @@ -79,6 +82,7 @@ check-runtime: GITHUB_API_PROJECT: "parity%2Finfrastructure%2Fgithub-api" script: - ./.maintain/gitlab/check_runtime.sh + interruptible: true allow_failure: true @@ -90,6 +94,7 @@ check-line-width: - /^[0-9]+$/ script: - ./.maintain/gitlab/check_line_width.sh + interruptible: true allow_failure: true @@ -117,7 +122,7 @@ cargo-check-subkey: except: - /^v[0-9]+\.[0-9]+.*$/ # i.e. v1.0, v2.1rc1 script: - - cd ./bin/subkey + - cd ./bin/utils/subkey - BUILD_DUMMY_WASM_BINARY=1 time cargo check --release - sccache -s @@ -148,7 +153,6 @@ test-linux-stable: &test-linux test-dependency-rules: &test-linux stage: test <<: *docker-env - allow_failure: true except: variables: - $DEPLOY_TAG @@ -219,14 +223,14 @@ check-web-wasm: script: # WASM support is in progress. As more and more crates support WASM, we # should add entries here. See https://github.com/paritytech/substrate/issues/2416 - - time cargo build --target=wasm32-unknown-unknown -p sr-io - - time cargo build --target=wasm32-unknown-unknown -p sr-primitives - - time cargo build --target=wasm32-unknown-unknown -p sr-std - - time cargo build --target=wasm32-unknown-unknown -p substrate-client - - time cargo build --target=wasm32-unknown-unknown -p substrate-consensus-aura - - time cargo build --target=wasm32-unknown-unknown -p substrate-consensus-babe - - time cargo build --target=wasm32-unknown-unknown -p substrate-consensus-common - - time cargo build --target=wasm32-unknown-unknown -p substrate-telemetry + - time cargo build --target=wasm32-unknown-unknown -p sp-io + - time cargo build --target=wasm32-unknown-unknown -p sp-runtime + - time cargo build --target=wasm32-unknown-unknown -p sp-std + - time cargo build --target=wasm32-unknown-unknown -p sc-client + - time cargo build --target=wasm32-unknown-unknown -p sc-consensus-aura + - time cargo build --target=wasm32-unknown-unknown -p sc-consensus-babe + - time cargo build --target=wasm32-unknown-unknown -p sp-consensus + - time cargo build --target=wasm32-unknown-unknown -p sc-telemetry # Note: the command below is a bit weird because several Cargo issues prevent us from compiling the node in a more straight-forward way. - time cargo build --manifest-path=bin/node/cli/Cargo.toml --no-default-features --features "browser" --target=wasm32-unknown-unknown - sccache -s @@ -296,7 +300,7 @@ build-linux-subkey: variables: - $DEPLOY_TAG script: - - cd ./bin/subkey + - cd ./bin/utils/subkey - BUILD_DUMMY_WASM_BINARY=1 time cargo build --release --verbose - cd - - sccache -s @@ -325,7 +329,7 @@ build-rust-doc-release: - rm -f ./crate-docs/index.html # use it as an indicator if the job succeeds - BUILD_DUMMY_WASM_BINARY=1 RUSTDOCFLAGS="--html-in-header $(pwd)/.maintain/rustdoc-header.html" time cargo +nightly doc --release --all --verbose - cp -R ./target/doc ./crate-docs - - echo "" > ./crate-docs/index.html + - echo "" > ./crate-docs/index.html - sccache -s check_warnings: @@ -352,25 +356,18 @@ check_polkadot: stage: build <<: *docker-env allow_failure: true - dependencies: - - test-linux-stable script: - - COMMIT_HASH=$(git rev-parse HEAD) - SUBSTRATE_PATH=$(pwd) # Clone the current Polkadot master branch into ./polkadot. - git clone --depth 1 https://gitlab.parity.io/parity/polkadot.git - cd polkadot - # Within Polkadot 'master' alter each Cargo.toml that references the - # Substrate 'polkadot-master' branch: - # 1. Replace the 'branch = "polkadot-master"' statements with the rev of our - # commit. - # 2. Replace 'git = "https://.*"' with 'git = "file://.*"' (the local - # checked out Substrate repository one folder above). - # 3. Remove any trailing commas. - - git grep -l "polkadot-master" | grep toml | xargs sed -i "s/branch.*=.*\"polkadot-master\"/rev = \"$COMMIT_HASH\"/; s~https://github.com/paritytech/substrate~file://$SUBSTRATE_PATH~; s/,\s*}/ }/" - # Make sure 'Cargo.lock' matches 'Cargo.toml'. It's enough to update one + # Make sure we override the crates in native and wasm build + - mkdir .cargo + - echo "paths = [ \"$SUBSTRATE_PATH\" ]" > .cargo/config + - mkdir -p target/debug/wbuild/.cargo + - echo "paths = [ \"$SUBSTRATE_PATH\" ]" > target/debug/wbuild/.cargo/config # package, others are updated along the way. - - cargo update -p sr-io + - cargo update # Check whether Polkadot 'master' branch builds with this Substrate commit. - time cargo check - cd - diff --git a/.maintain/common.sh b/.maintain/common.sh deleted file mode 100644 index 8aff9acc578ec5c3671e39b269a32c13110a1566..0000000000000000000000000000000000000000 --- a/.maintain/common.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env bash - -ROOT=`dirname "$0"` - -# A list of directories which contain wasm projects. -SRCS=( - "core/executor/wasm" - "node/runtime/wasm" - "node-template/runtime/wasm" - "core/test-runtime/wasm" -) - -# Make pushd/popd silent. - -pushd () { - command pushd "$@" > /dev/null -} - -popd () { - command popd "$@" > /dev/null -} diff --git a/.maintain/ensure-deps.sh b/.maintain/ensure-deps.sh index d8383cd3137726366afc629cd73682e454426db1..7087200cef5185878431a89c013bacbd7417b4fd 100755 --- a/.maintain/ensure-deps.sh +++ b/.maintain/ensure-deps.sh @@ -3,36 +3,41 @@ # The script is meant to check if the rules regarding packages # dependencies are satisfied. # The general format is: -# [top-lvl-dir]<[crate-name-prefix] +# [top-lvl-dir] MESSAGE/[other-top-dir] # For instance no crate within `./client` directory # is allowed to import any crate with a directory path containing `frame`. -# Such rule is just: `client /dev/null +} + +for rule in "${MUST_NOT[@]}" +do + check_rule "$rule"; +done + +# Only the MUST NOT will be counted towards failure +HARD_VIOLATIONS=${#VIOLATIONS[@]} + + +for rule in "${PLEASE_DONT[@]}" +do + check_rule "$rule"; done # Display violations and fail @@ -58,4 +77,4 @@ EOF I=$I+1 done -exit ${#VIOLATIONS[@]} +exit $HARD_VIOLATIONS diff --git a/.maintain/rename-crates-for-2.0.sh b/.maintain/rename-crates-for-2.0.sh new file mode 100644 index 0000000000000000000000000000000000000000..d2bd871f0978075d37f2100ce544640022d3d1e5 --- /dev/null +++ b/.maintain/rename-crates-for-2.0.sh @@ -0,0 +1,123 @@ +#!/bin/bash + +function rust_rename() { + sed -i "s/$1/$2/g" `grep -Rl --include="*.rs" --include="*.stderr" "$1" *` > /dev/null +} + +function cargo_rename() { + find . -name "Cargo.toml" -exec sed -i "s/\(^\|[^\/]\)$1/\1$2/g" {} \; +} + +function rename_gitlabci() { + sed -i "s/$1/$2/g" .gitlab-ci.yml +} + +function rename() { + old=$(echo $1 | cut -f1 -d\ ); + new=$(echo $1 | cut -f2 -d\ ); + + echo "Renaming $old to $new" + # rename in Cargo.tomls + cargo_rename $old $new + rename_gitlabci $old $new + # and it appears, we have the same syntax in rust files + rust_rename $old $new + + # but generally we have the snail case syntax in rust files + old=$(echo $old | sed s/-/_/g ); + new=$(echo $new | sed s/-/_/g ); + + echo " > $old to $new" + rust_rename $old $new +} + +TO_RENAME=( + # OLD-CRATE-NAME NEW-CRATE-NAME + + # post initial rename fixes + "sc-application-crypto sp-application-crypto" + "sp-transaction-pool-api sp-transaction-pool" + "sp-transaction-pool-runtime-api sp-transaction-pool" + "sp-core-storage sp-storage" + "transaction-factory node-transaction-factory" + "sp-finality-granpda sp-finality-grandpa" + "sp-sesssion sp-session" + "sp-tracing-pool sp-transaction-pool" + + # PRIMITIVES + "substrate-application-crypto sp-application-crypto" + "substrate-authority-discovery-primitives sp-authority-discovery" + "substrate-block-builder-runtime-api sp-block-builder" + "substrate-consensus-aura-primitives sp-consensus-aura" + "substrate-consensus-babe-primitives sp-consensus-babe" + "substrate-consensus-common sp-consensus" + "substrate-consensus-pow-primitives sp-consensus-pow" + "substrate-primitives sp-core" + "substrate-debug-derive sp-debug-derive" + "substrate-primitives-storage sp-storage" + "substrate-externalities sp-externalities" + "substrate-finality-grandpa-primitives sp-finality-grandpa" + "substrate-inherents sp-inherents" + "substrate-keyring sp-keyring" + "substrate-offchain-primitives sp-offchain" + "substrate-panic-handler sp-panic-handler" + "substrate-phragmen sp-phragmen" + "substrate-rpc-primitives sp-rpc" + "substrate-runtime-interface sp-runtime-interface" + "substrate-runtime-interface-proc-macro sp-runtime-interface-proc-macro" + "substrate-runtime-interface-test-wasm sp-runtime-interface-test-wasm" + "substrate-serializer sp-serializer" + "substrate-session sp-session" + "sr-api sp-api" + "sr-api-proc-macro sp-api-proc-macro" + "sr-api-test sp-api-test" + "sr-arithmetic sp-arithmetic" + "sr-arithmetic-fuzzer sp-arithmetic-fuzzer" + "sr-io sp-io" + "sr-primitives sp-runtime" + "sr-sandbox sp-sandbox" + "sr-staking-primitives sp-staking" + "sr-std sp-std" + "sr-version sp-version" + "substrate-state-machine sp-state-machine" + "substrate-transaction-pool-runtime-api sp-transaction-pool" + "substrate-trie sp-trie" + "substrate-wasm-interface sp-wasm-interface" + + # # CLIENT + "substrate-client sc-client" + "substrate-client-api sc-api" + "substrate-authority-discovery sc-authority-discovery" + "substrate-basic-authorship sc-basic-authority" + "substrate-block-builder sc-block-builder" + "substrate-chain-spec sc-chain-spec" + "substrate-chain-spec-derive sc-chain-spec-derive" + "substrate-cli sc-cli" + "substrate-consensus-aura sc-consensus-aura" + "substrate-consensus-babe sc-consensus-babe" + "substrate-consensus-pow sc-consensus-pow" + "substrate-consensus-slots sc-consensus-slots" + "substrate-consensus-uncles sc-consensus-uncles" + "substrate-client-db sc-database" + "substrate-executor sc-executor" + "substrate-runtime-test sc-runtime-test" + "substrate-finality-grandpa sc-finality-grandpa" + "substrate-keystore sc-keystore" + "substrate-network sc-network" + "substrate-offchain sc-offchain" + "substrate-peerset sc-peerset" + "substrate-rpc-servers sc-rpc-server" + "substrate-rpc sc-rpc" + "substrate-service sc-service" + "substrate-service-test sc-service-test" + "substrate-state-db sc-state-db" + "substrate-telemetry sc-telemetry" + "substrate-test-primitives sp-test-primitives" + "substrate-tracing sc-tracing" + +); + +for rule in "${TO_RENAME[@]}" +do + rename "$rule"; +done diff --git a/.maintain/sentry-node/docker-compose.yml b/.maintain/sentry-node/docker-compose.yml index dd2aee6995473ad2f4204180568313fe8d271a39..37f0bea6b49856db4da2640742fc12bb2353ea78 100644 --- a/.maintain/sentry-node/docker-compose.yml +++ b/.maintain/sentry-node/docker-compose.yml @@ -38,13 +38,12 @@ services: - "--base-path" - "/tmp/alice" - "--chain=local" - - "--key" - - "//Alice" - "--port" - "30333" - "--validator" - - "--name" - - "AlicesNode" + - "--alice" + - "--sentry-nodes" + - "/dns4/sentry-a/tcp/30333/p2p/QmV7EhW6J6KgmNdr558RH1mPx2xGGznW7At4BhXzntRFsi" - "--reserved-nodes" - "/dns4/sentry-a/tcp/30333/p2p/QmV7EhW6J6KgmNdr558RH1mPx2xGGznW7At4BhXzntRFsi" # Not only bind to localhost. @@ -54,6 +53,8 @@ services: # - "sub-libp2p=trace" # - "--log" # - "afg=trace" + - "--log" + - "sub-authority-discovery=trace" - "--no-telemetry" - "--rpc-cors" - "all" @@ -74,28 +75,24 @@ services: - "--base-path" - "/tmp/sentry" - "--chain=local" - # Don't configure a key, as sentry-a is not a validator. - # - "--key" - # - "//Charlie" - "--port" - "30333" - # sentry-a is not a validator. - # - "--validator" - - "--name" - - "CharliesNode" + - "--charlie" - "--bootnodes" - "/dns4/validator-a/tcp/30333/p2p/QmRpheLN4JWdAnY7HGJfWFNbfkQCb6tFf4vvA6hgjMZKrR" - "--bootnodes" - "/dns4/validator-b/tcp/30333/p2p/QmSVnNf9HwVMT1Y4cK1P6aoJcEZjmoTXpjKBmAABLMnZEk" + - "--reserved-nodes" + - "/dns4/validator-a/tcp/30333/p2p/QmRpheLN4JWdAnY7HGJfWFNbfkQCb6tFf4vvA6hgjMZKrR" - "--no-telemetry" - "--rpc-cors" - "all" # Not only bind to localhost. - "--ws-external" - "--rpc-external" - # Make sure sentry-a still participates as a grandpa voter to forward - # grandpa finality gossip messages. - - "--grandpa-voter" + - "--log" + - "sub-authority-discovery=trace" + - "--sentry" validator-b: image: parity/substrate @@ -112,13 +109,10 @@ services: - "--base-path" - "/tmp/bob" - "--chain=local" - - "--key" - - "//Bob" - "--port" - "30333" - "--validator" - - "--name" - - "BobsNode" + - "--bob" - "--bootnodes" - "/dns4/validator-a/tcp/30333/p2p/QmRpheLN4JWdAnY7HGJfWFNbfkQCb6tFf4vvA6hgjMZKrR" - "--bootnodes" @@ -129,6 +123,8 @@ services: # Not only bind to localhost. - "--ws-external" - "--rpc-external" + - "--log" + - "sub-authority-discovery=trace" ui: image: polkadot-js/apps diff --git a/.maintain/update.sh b/.maintain/update.sh deleted file mode 100755 index a264fab43df306a2384aa15ae8e3a41faf7e33b0..0000000000000000000000000000000000000000 --- a/.maintain/update.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env bash - -# This script assumes that all pre-requisites are installed. - -set -e - -PROJECT_ROOT=`git rev-parse --show-toplevel` -source `dirname "$0"`/common.sh - -export CARGO_INCREMENTAL=0 - -# Save current directory. -pushd . - -cd $ROOT - -for SRC in "${SRCS[@]}" -do - echo "*** Updating and building wasm binaries in $SRC" - cd "$PROJECT_ROOT/$SRC" - - cargo update - ./build.sh "$@" - - cd - >> /dev/null -done - -# Restore initial directory. -popd diff --git a/Cargo.lock b/Cargo.lock index b36e54aba789ecc9230724c38f14af88509e2bb0..46d59553a4e84f8318db103302765e35117bacba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -79,7 +79,7 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.22" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -130,7 +130,7 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -149,7 +149,7 @@ dependencies = [ [[package]] name = "async-std" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "async-macros 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -164,7 +164,7 @@ dependencies = [ "kv-log-macro 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", "once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -186,7 +186,7 @@ name = "atty" version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -202,7 +202,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -211,8 +211,8 @@ name = "backtrace-sys" version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -244,32 +244,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bincode" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "bindgen" -version = "0.47.3" +version = "0.49.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "cexpr 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "clang-sys 0.26.4 (registry+https://github.com/rust-lang/crates.io-index)", + "clang-sys 0.28.1 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "which 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -376,7 +376,7 @@ dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "regex-automata 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -422,6 +422,11 @@ dependencies = [ "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "bytes" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "c2-chacha" version = "0.2.3" @@ -437,13 +442,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "cargo_metadata" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -456,7 +461,7 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.47" +version = "1.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "jobserver 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", @@ -483,30 +488,29 @@ dependencies = [ "ansi_term 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", "node-cli 2.0.0", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "structopt 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "substrate-keystore 2.0.0", - "substrate-primitives 2.0.0", + "sc-keystore 2.0.0", + "sp-core 2.0.0", + "structopt 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "chrono" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "clang-sys" -version = "0.26.4" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "libloading 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -520,7 +524,7 @@ dependencies = [ "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -529,7 +533,7 @@ name = "clear_on_drop" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -545,7 +549,7 @@ name = "cmake" version = "0.1.42" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -595,7 +599,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -622,10 +626,10 @@ dependencies = [ "cranelift-codegen-shared 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)", "cranelift-entity 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "target-lexicon 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "thiserror 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "thiserror 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -647,7 +651,7 @@ name = "cranelift-entity" version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -680,8 +684,8 @@ dependencies = [ "cranelift-entity 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)", "cranelift-frontend 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "thiserror 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "thiserror 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "wasmparser 0.39.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -703,18 +707,18 @@ dependencies = [ "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "criterion-plot 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "csv 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "itertools 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "rand_xoshiro 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "rayon-core 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", "tinytemplate 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -729,16 +733,16 @@ dependencies = [ "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "criterion-plot 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "csv 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "itertools 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_os 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand_xoshiro 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", "tinytemplate 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -750,7 +754,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "cast 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "itertools 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -759,15 +763,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cast 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "itertools 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "crossbeam-channel" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -858,7 +854,7 @@ dependencies = [ "csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -883,7 +879,7 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -922,7 +918,19 @@ dependencies = [ "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "subtle 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "subtle 2.2.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "curve25519-dalek" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "subtle 2.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "zeroize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -932,15 +940,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "derive_more" -version = "0.15.0" +version = "0.99.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -971,7 +976,7 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "redox_users 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -992,25 +997,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "ed25519-dalek" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "curve25519-dalek 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "ed25519-dalek" -version = "1.0.0-pre.2" +version = "1.0.0-pre.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "curve25519-dalek 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "curve25519-dalek 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1021,12 +1013,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "elastic-array" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "enumflags2" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "enumflags2_derive 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "enumflags2_derive" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "env_logger" version = "0.6.2" @@ -1061,7 +1071,7 @@ name = "erased-serde" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1070,7 +1080,7 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "errno-dragonfly 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1080,12 +1090,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "evm" -version = "0.14.0" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "evm-core 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1093,6 +1103,7 @@ dependencies = [ "evm-runtime 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", "primitive-types 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", "sha3 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1126,11 +1137,10 @@ dependencies = [ [[package]] name = "exit-future" -version = "0.1.4" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1138,14 +1148,14 @@ name = "faerie" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "anyhow 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)", - "goblin 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "anyhow 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "goblin 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "scroll 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "string-interner 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "target-lexicon 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "thiserror 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "thiserror 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1164,7 +1174,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", "synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1183,7 +1193,7 @@ name = "fdlimit" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1197,12 +1207,12 @@ dependencies = [ [[package]] name = "finality-grandpa" -version = "0.10.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1213,7 +1223,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "static_assertions 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1232,7 +1242,7 @@ dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", "miniz_oxide 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1263,13 +1273,137 @@ dependencies = [ "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "frame-executive" +version = "2.0.0" +dependencies = [ + "frame-support 2.0.0", + "frame-system 2.0.0", + "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "pallet-balances 2.0.0", + "pallet-indices 2.0.0", + "pallet-transaction-payment 2.0.0", + "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-core 2.0.0", + "sp-io 2.0.0", + "sp-runtime 2.0.0", + "sp-std 2.0.0", +] + +[[package]] +name = "frame-metadata" +version = "2.0.0" +dependencies = [ + "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-core 2.0.0", + "sp-std 2.0.0", +] + +[[package]] +name = "frame-support" +version = "2.0.0" +dependencies = [ + "bitmask 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "frame-metadata 2.0.0", + "frame-support-procedural 2.0.0", + "frame-system 2.0.0", + "impl-trait-for-tuples 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "once_cell 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "paste 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-arithmetic 2.0.0", + "sp-core 2.0.0", + "sp-inherents 2.0.0", + "sp-io 2.0.0", + "sp-runtime 2.0.0", + "sp-state-machine 2.0.0", + "sp-std 2.0.0", + "tracing 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "frame-support-procedural" +version = "2.0.0" +dependencies = [ + "frame-support-procedural-tools 2.0.0", + "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "frame-support-procedural-tools" +version = "2.0.0" +dependencies = [ + "frame-support-procedural-tools-derive 2.0.0", + "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "frame-support-procedural-tools-derive" +version = "2.0.0" +dependencies = [ + "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "frame-support-test" +version = "2.0.0" +dependencies = [ + "frame-support 2.0.0", + "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-core 2.0.0", + "sp-inherents 2.0.0", + "sp-io 2.0.0", + "sp-runtime 2.0.0", + "sp-state-machine 2.0.0", + "trybuild 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "frame-system" +version = "2.0.0" +dependencies = [ + "criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "frame-support 2.0.0", + "impl-trait-for-tuples 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-core 2.0.0", + "sp-io 2.0.0", + "sp-runtime 2.0.0", + "sp-std 2.0.0", + "sp-version 2.0.0", +] + +[[package]] +name = "frame-system-rpc-runtime-api" +version = "2.0.0" +dependencies = [ + "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-api 2.0.0", +] + [[package]] name = "fs-swap" version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "libloading 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1279,7 +1413,7 @@ name = "fs2" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1382,7 +1516,7 @@ dependencies = [ "proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1447,11 +1581,11 @@ dependencies = [ ] [[package]] -name = "futures01" -version = "0.1.29" +name = "fxhash" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1474,7 +1608,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "c_linked_list 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "get_if_addrs-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1484,7 +1618,7 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1493,7 +1627,7 @@ version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1534,7 +1668,7 @@ dependencies = [ [[package]] name = "goblin" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1546,19 +1680,18 @@ dependencies = [ name = "grafana-data-source" version = "2.0.0" dependencies = [ - "async-std 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", - "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "async-std 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", "futures-timer 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.13.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.2.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.2.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1580,7 +1713,7 @@ dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1590,22 +1723,20 @@ dependencies = [ [[package]] name = "h2" -version = "0.2.0-alpha.3" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-sink-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-sink 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "string 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-codec 0.2.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.2.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-sync 0.2.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1630,6 +1761,11 @@ dependencies = [ "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "hashbrown" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "hashbrown" version = "0.6.3" @@ -1660,14 +1796,9 @@ name = "hermit-abi" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "hex" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "hex" version = "0.4.0" @@ -1711,7 +1842,7 @@ dependencies = [ [[package]] name = "http" -version = "0.1.19" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1719,6 +1850,16 @@ dependencies = [ "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "http" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "http-body" version = "0.1.0" @@ -1726,17 +1867,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-buf 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "http-body" -version = "0.2.0-alpha.3" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1779,7 +1920,7 @@ dependencies = [ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "h2 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "http-body 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1790,38 +1931,34 @@ dependencies = [ "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-buf 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-threadpool 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-threadpool 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", "want 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "hyper" -version = "0.13.0-alpha.4" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-channel-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", - "h2 0.2.0-alpha.3 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", - "http-body 0.2.0-alpha.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-channel 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "h2 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "http-body 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.2.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.2.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-sync 0.2.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tower-make 0.3.0-alpha.2a (registry+https://github.com/rust-lang/crates.io-index)", - "tower-service 0.3.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "want 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1860,7 +1997,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-normalization 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-normalization 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1870,7 +2007,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-normalization 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-normalization 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1894,7 +2031,7 @@ name = "impl-serde" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1904,7 +2041,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1930,7 +2067,7 @@ name = "iovec" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1940,7 +2077,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "itertools" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1957,7 +2094,7 @@ version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1971,62 +2108,62 @@ dependencies = [ [[package]] name = "jsonrpc-client-transports" -version = "14.0.3" +version = "14.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)", "hyper-tls 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-pubsub 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-pubsub 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "websocket 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)", + "websocket 0.24.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "jsonrpc-core" -version = "14.0.3" +version = "14.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "jsonrpc-core-client" -version = "14.0.3" +version = "14.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "jsonrpc-client-transports 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-client-transports 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "jsonrpc-derive" -version = "14.0.3" +version = "14.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "jsonrpc-http-server" -version = "14.0.3" +version = "14.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-server-utils 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-server-utils 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2035,23 +2172,23 @@ dependencies = [ [[package]] name = "jsonrpc-pubsub" -version = "14.0.3" +version = "14.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "jsonrpc-core 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "jsonrpc-server-utils" -version = "14.0.3" +version = "14.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "globset 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2061,11 +2198,11 @@ dependencies = [ [[package]] name = "jsonrpc-ws-server" -version = "14.0.3" +version = "14.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "jsonrpc-core 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-server-utils 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-server-utils 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2106,36 +2243,37 @@ dependencies = [ [[package]] name = "kvdb" -version = "0.1.0" -source = "git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d#b0317f649ab2c665b7987b8475878fc4d2e1f81d" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "elastic-array 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-bytes 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)", + "elastic-array 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-bytes 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "kvdb-memorydb" -version = "0.1.0" -source = "git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d#b0317f649ab2c665b7987b8475878fc4d2e1f81d" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "kvdb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)", - "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "kvdb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "kvdb-rocksdb" -version = "0.1.4" -source = "git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d#b0317f649ab2c665b7987b8475878fc4d2e1f81d" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "elastic-array 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", + "elastic-array 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "fs-swap 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "interleaved-ordered 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "kvdb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)", + "kvdb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rocksdb 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rocksdb 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2158,7 +2296,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libc" -version = "0.2.65" +version = "0.2.66" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -2166,7 +2304,7 @@ name = "libloading" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2202,7 +2340,7 @@ dependencies = [ "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-timer 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2215,14 +2353,14 @@ dependencies = [ "asn1_der 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", "bs58 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "ed25519-dalek 1.0.0-pre.2 (registry+https://github.com/rust-lang/crates.io-index)", + "ed25519-dalek 1.0.0-pre.3 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "libsecp256k1 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "multistream-select 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "multistream-select 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-multiaddr 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-multihash 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2233,13 +2371,13 @@ dependencies = [ "rw-stream-sink 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "unsigned-varint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-timer 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "zeroize 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "zeroize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2353,7 +2491,7 @@ dependencies = [ "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-udp 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-timer 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2389,10 +2527,10 @@ dependencies = [ "protobuf 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "ring 0.16.9 (registry+https://github.com/rust-lang/crates.io-index)", - "snow 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "snow 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "x25519-dalek 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "zeroize 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "zeroize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2482,7 +2620,7 @@ dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2542,13 +2680,13 @@ dependencies = [ [[package]] name = "librocksdb-sys" -version = "5.18.3" +version = "6.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bindgen 0.47.3 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)", - "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "bindgen 0.49.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", + "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2561,7 +2699,7 @@ dependencies = [ "hmac-drbg 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "subtle 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "subtle 2.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2570,10 +2708,10 @@ name = "libz-sys" version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)", - "vcpkg 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "vcpkg 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2594,7 +2732,6 @@ name = "lock_api" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2608,7 +2745,7 @@ dependencies = [ [[package]] name = "lock_api" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2632,7 +2769,15 @@ dependencies = [ [[package]] name = "lru" -version = "0.4.0" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "hashbrown 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "lru" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "hashbrown 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2643,7 +2788,7 @@ name = "mach" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2652,7 +2797,7 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", "synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2671,7 +2816,7 @@ name = "memchr" version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2684,9 +2829,10 @@ dependencies = [ [[package]] name = "memory-db" -version = "0.15.2" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "ahash 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "hashbrown 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", "parity-util-mem 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2699,13 +2845,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "merlin" -version = "1.2.1" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "keccak 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "zeroize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2726,14 +2872,15 @@ dependencies = [ [[package]] name = "mio" -version = "0.6.19" +version = "0.6.21" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2743,12 +2890,12 @@ dependencies = [ [[package]] name = "mio-extras" -version = "2.0.5" +version = "2.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2758,8 +2905,8 @@ version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2785,7 +2932,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "multistream-select" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2810,11 +2957,11 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl 0.10.25 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl 0.10.26 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.52 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.53 (registry+https://github.com/rust-lang/crates.io-index)", "schannel 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "security-framework 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "security-framework-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2827,7 +2974,7 @@ version = "0.2.33" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2837,9 +2984,9 @@ version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2851,64 +2998,65 @@ dependencies = [ "console_error_panic_hook 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "console_log 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "ctrlc 3.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "frame-support 2.0.0", + "frame-system 2.0.0", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "js-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "kvdb-memorydb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)", + "jsonrpc-core 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "kvdb-memorydb 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "node-executor 2.0.0", "node-primitives 2.0.0", "node-rpc 2.0.0", "node-runtime 2.0.0", - "frame-support 2.0.0", - "frame-system 2.0.0", - "pallet-authority-discovery 0.1.0", + "node-transaction-factory 2.0.0", + "pallet-authority-discovery 2.0.0", "pallet-balances 2.0.0", "pallet-contracts 2.0.0", - "pallet-im-online 0.1.0", + "pallet-im-online 2.0.0", "pallet-indices 2.0.0", "pallet-timestamp 2.0.0", "pallet-transaction-payment 2.0.0", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "sc-authority-discovery 2.0.0", + "sc-basic-authority 2.0.0", + "sc-chain-spec 2.0.0", + "sc-cli 2.0.0", + "sc-client 2.0.0", + "sc-client-api 2.0.0", + "sc-client-db 2.0.0", + "sc-consensus-babe 0.8.0", + "sc-finality-grandpa 2.0.0", + "sc-keystore 2.0.0", + "sc-network 0.8.0", + "sc-offchain 2.0.0", + "sc-rpc 2.0.0", + "sc-service 2.0.0", + "sc-service-test 2.0.0", + "sc-telemetry 2.0.0", + "sc-transaction-pool 2.0.0", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-authority-discovery 2.0.0", + "sp-consensus 0.8.0", + "sp-consensus-babe 0.8.0", + "sp-core 2.0.0", + "sp-finality-grandpa 2.0.0", "sp-finality-tracker 2.0.0", + "sp-inherents 2.0.0", + "sp-io 2.0.0", + "sp-keyring 2.0.0", + "sp-runtime 2.0.0", "sp-timestamp 2.0.0", - "sr-io 2.0.0", - "sr-primitives 2.0.0", - "structopt 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "substrate-authority-discovery 2.0.0", - "substrate-authority-discovery-primitives 2.0.0", - "substrate-basic-authorship 2.0.0", + "sp-transaction-pool 2.0.0", + "structopt 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "substrate-build-script-utils 2.0.0", - "substrate-chain-spec 2.0.0", - "substrate-cli 2.0.0", - "substrate-client 2.0.0", - "substrate-client-api 2.0.0", - "substrate-client-db 2.0.0", - "substrate-consensus-babe 2.0.0", - "substrate-consensus-babe-primitives 2.0.0", - "substrate-consensus-common 2.0.0", - "substrate-finality-grandpa 2.0.0", - "substrate-finality-grandpa-primitives 2.0.0", - "substrate-inherents 2.0.0", - "substrate-keyring 2.0.0", - "substrate-keystore 2.0.0", - "substrate-network 2.0.0", - "substrate-offchain 2.0.0", - "substrate-primitives 2.0.0", - "substrate-rpc 2.0.0", - "substrate-service 2.0.0", - "substrate-service-test 2.0.0", - "substrate-telemetry 2.0.0", - "substrate-transaction-pool 2.0.0", "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", - "transaction-factory 0.0.1", "vergen 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-futures 0.3.27 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2919,11 +3067,11 @@ name = "node-executor" version = "2.0.0" dependencies = [ "criterion 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "frame-support 2.0.0", + "frame-system 2.0.0", "node-primitives 2.0.0", "node-runtime 2.0.0", "node-testing 2.0.0", - "frame-support 2.0.0", - "frame-system 2.0.0", "pallet-balances 2.0.0", "pallet-contracts 2.0.0", "pallet-grandpa 2.0.0", @@ -2933,13 +3081,13 @@ dependencies = [ "pallet-transaction-payment 2.0.0", "pallet-treasury 2.0.0", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 2.0.0", - "sr-primitives 2.0.0", - "substrate-executor 2.0.0", - "substrate-primitives 2.0.0", - "substrate-state-machine 2.0.0", + "sc-executor 2.0.0", + "sp-core 2.0.0", + "sp-io 2.0.0", + "sp-runtime 2.0.0", + "sp-state-machine 2.0.0", + "sp-trie 2.0.0", "substrate-test-client 2.0.0", - "substrate-trie 2.0.0", "trie-root 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "wabt 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2949,24 +3097,24 @@ name = "node-primitives" version = "2.0.0" dependencies = [ "pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 2.0.0", - "substrate-primitives 2.0.0", - "substrate-serializer 2.0.0", + "sp-core 2.0.0", + "sp-runtime 2.0.0", + "sp-serializer 2.0.0", ] [[package]] name = "node-rpc" version = "2.0.0" dependencies = [ - "jsonrpc-core 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "node-primitives 2.0.0", "node-runtime 2.0.0", - "frame-system-rpc 2.0.0", "pallet-contracts-rpc 2.0.0", "pallet-transaction-payment-rpc 2.0.0", - "sr-primitives 2.0.0", - "substrate-client 2.0.0", - "substrate-transaction-pool 2.0.0", + "sc-client 2.0.0", + "sp-runtime 2.0.0", + "sp-transaction-pool 2.0.0", + "substrate-frame-rpc-system 2.0.0", ] [[package]] @@ -2976,25 +3124,24 @@ dependencies = [ "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core-client 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core-client 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "node-primitives 2.0.0", - "substrate-rpc 2.0.0", + "sc-rpc 2.0.0", ] [[package]] name = "node-runtime" version = "2.0.0" dependencies = [ - "integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "node-primitives 2.0.0", "frame-executive 2.0.0", "frame-support 2.0.0", "frame-system 2.0.0", "frame-system-rpc-runtime-api 2.0.0", - "frame-utility 2.0.0", - "pallet-authority-discovery 0.1.0", - "pallet-authorship 0.1.0", + "integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "node-primitives 2.0.0", + "pallet-authority-discovery 2.0.0", + "pallet-authorship 2.0.0", "pallet-babe 2.0.0", "pallet-balances 2.0.0", "pallet-collective 2.0.0", @@ -3004,11 +3151,11 @@ dependencies = [ "pallet-elections-phragmen 2.0.0", "pallet-finality-tracker 2.0.0", "pallet-grandpa 2.0.0", - "pallet-im-online 0.1.0", + "pallet-im-online 2.0.0", "pallet-indices 2.0.0", "pallet-membership 2.0.0", "pallet-nicks 2.0.0", - "pallet-offences 1.0.0", + "pallet-offences 2.0.0", "pallet-randomness-collective-flip 2.0.0", "pallet-session 2.0.0", "pallet-staking 2.0.0", @@ -3018,25 +3165,26 @@ dependencies = [ "pallet-transaction-payment 2.0.0", "pallet-transaction-payment-rpc-runtime-api 2.0.0", "pallet-treasury 2.0.0", + "pallet-utility 2.0.0", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-api 2.0.0", - "sr-io 2.0.0", - "sr-primitives 2.0.0", - "sr-staking-primitives 2.0.0", - "sr-std 2.0.0", - "sr-version 2.0.0", - "substrate-authority-discovery-primitives 2.0.0", - "substrate-block-builder-runtime-api 2.0.0", - "substrate-consensus-babe-primitives 2.0.0", - "substrate-inherents 2.0.0", - "substrate-keyring 2.0.0", - "substrate-offchain-primitives 2.0.0", - "substrate-primitives 2.0.0", - "substrate-session 2.0.0", - "substrate-transaction-pool-runtime-api 2.0.0", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-api 2.0.0", + "sp-authority-discovery 2.0.0", + "sp-block-builder 2.0.0", + "sp-consensus-babe 0.8.0", + "sp-core 2.0.0", + "sp-inherents 2.0.0", + "sp-io 2.0.0", + "sp-keyring 2.0.0", + "sp-offchain 2.0.0", + "sp-runtime 2.0.0", + "sp-session 2.0.0", + "sp-staking 2.0.0", + "sp-std 2.0.0", + "sp-transaction-pool 2.0.0", + "sp-version 2.0.0", "substrate-wasm-builder-runner 1.0.4", ] @@ -3045,29 +3193,30 @@ name = "node-template" version = "2.0.0" dependencies = [ "ctrlc 3.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "node-template-runtime 2.0.0", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 2.0.0", - "sr-primitives 2.0.0", - "substrate-basic-authorship 2.0.0", + "sc-basic-authority 2.0.0", + "sc-cli 2.0.0", + "sc-client 2.0.0", + "sc-consensus-aura 0.8.0", + "sc-executor 2.0.0", + "sc-finality-grandpa 2.0.0", + "sc-network 0.8.0", + "sc-service 2.0.0", + "sc-transaction-pool 2.0.0", + "sp-consensus 0.8.0", + "sp-consensus-aura 0.8.0", + "sp-core 2.0.0", + "sp-finality-grandpa 2.0.0", + "sp-inherents 2.0.0", + "sp-io 2.0.0", + "sp-runtime 2.0.0", + "sp-transaction-pool 2.0.0", "substrate-build-script-utils 2.0.0", - "substrate-cli 2.0.0", - "substrate-client 2.0.0", - "substrate-consensus-aura 2.0.0", - "substrate-consensus-aura-primitives 2.0.0", - "substrate-executor 2.0.0", - "substrate-finality-grandpa 2.0.0", - "substrate-finality-grandpa-primitives 2.0.0", - "substrate-inherents 2.0.0", - "substrate-network 2.0.0", - "substrate-primitives 2.0.0", - "substrate-service 2.0.0", - "substrate-transaction-pool 2.0.0", "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", "trie-root 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "vergen 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3090,19 +3239,19 @@ dependencies = [ "pallet-transaction-payment 2.0.0", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-api 2.0.0", - "sr-io 2.0.0", - "sr-primitives 2.0.0", - "sr-std 2.0.0", - "sr-version 2.0.0", - "substrate-block-builder-runtime-api 2.0.0", - "substrate-consensus-aura-primitives 2.0.0", - "substrate-inherents 2.0.0", - "substrate-offchain-primitives 2.0.0", - "substrate-primitives 2.0.0", - "substrate-session 2.0.0", - "substrate-transaction-pool-runtime-api 2.0.0", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-api 2.0.0", + "sp-block-builder 2.0.0", + "sp-consensus-aura 0.8.0", + "sp-core 2.0.0", + "sp-inherents 2.0.0", + "sp-io 2.0.0", + "sp-offchain 2.0.0", + "sp-runtime 2.0.0", + "sp-session 2.0.0", + "sp-std 2.0.0", + "sp-transaction-pool 2.0.0", + "sp-version 2.0.0", "substrate-wasm-builder-runner 1.0.4", ] @@ -3110,11 +3259,11 @@ dependencies = [ name = "node-testing" version = "2.0.0" dependencies = [ + "frame-support 2.0.0", + "frame-system 2.0.0", "node-executor 2.0.0", "node-primitives 2.0.0", "node-runtime 2.0.0", - "frame-support 2.0.0", - "frame-system 2.0.0", "pallet-balances 2.0.0", "pallet-contracts 2.0.0", "pallet-grandpa 2.0.0", @@ -3125,16 +3274,34 @@ dependencies = [ "pallet-transaction-payment 2.0.0", "pallet-treasury 2.0.0", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 2.0.0", - "sr-primitives 2.0.0", - "substrate-client 2.0.0", - "substrate-executor 2.0.0", - "substrate-keyring 2.0.0", - "substrate-primitives 2.0.0", + "sc-client 2.0.0", + "sc-executor 2.0.0", + "sp-core 2.0.0", + "sp-io 2.0.0", + "sp-keyring 2.0.0", + "sp-runtime 2.0.0", "substrate-test-client 2.0.0", "wabt 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "node-transaction-factory" +version = "2.0.0" +dependencies = [ + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sc-cli 2.0.0", + "sc-client 2.0.0", + "sc-client-api 2.0.0", + "sc-service 2.0.0", + "sp-api 2.0.0", + "sp-block-builder 2.0.0", + "sp-blockchain 2.0.0", + "sp-consensus 0.8.0", + "sp-core 2.0.0", + "sp-runtime 2.0.0", +] + [[package]] name = "nodrop" version = "0.1.14" @@ -3161,7 +3328,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3170,7 +3337,7 @@ version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3181,12 +3348,12 @@ dependencies = [ "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "num-bigint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "num-traits" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3198,7 +3365,7 @@ version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "hermit-abi 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3235,15 +3402,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "openssl" -version = "0.10.25" +version = "0.10.26" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.52 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.53 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3253,14 +3420,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "openssl-sys" -version = "0.9.52" +version = "0.9.53" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)", - "vcpkg 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "vcpkg 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3279,181 +3446,6 @@ dependencies = [ "stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "frame-executive" -version = "2.0.0" -dependencies = [ - "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "frame-support 2.0.0", - "frame-system 2.0.0", - "pallet-balances 2.0.0", - "pallet-indices 2.0.0", - "pallet-transaction-payment 2.0.0", - "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 2.0.0", - "sr-primitives 2.0.0", - "sr-std 2.0.0", - "substrate-primitives 2.0.0", -] - -[[package]] -name = "frame-metadata" -version = "2.0.0" -dependencies = [ - "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-std 2.0.0", - "substrate-primitives 2.0.0", -] - -[[package]] -name = "frame-support" -version = "2.0.0" -dependencies = [ - "bitmask 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "impl-trait-for-tuples 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "once_cell 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "frame-metadata 2.0.0", - "frame-support-procedural 2.0.0", - "frame-system 2.0.0", - "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "paste 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-arithmetic 2.0.0", - "sr-io 2.0.0", - "sr-primitives 2.0.0", - "sr-std 2.0.0", - "substrate-inherents 2.0.0", - "substrate-primitives 2.0.0", - "substrate-state-machine 2.0.0", - "tracing 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "frame-support-procedural" -version = "2.0.0" -dependencies = [ - "frame-support-procedural-tools 2.0.0", - "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "frame-support-procedural-tools" -version = "2.0.0" -dependencies = [ - "frame-support-procedural-tools-derive 2.0.0", - "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "frame-support-procedural-tools-derive" -version = "2.0.0" -dependencies = [ - "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "frame-support-rpc" -version = "2.0.0" -dependencies = [ - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-client-transports 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "frame-support 2.0.0", - "frame-system 2.0.0", - "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "substrate-primitives-storage 2.0.0", - "substrate-rpc-api 2.0.0", - "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "frame-support-test" -version = "2.0.0" -dependencies = [ - "frame-support 2.0.0", - "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 2.0.0", - "sr-primitives 2.0.0", - "substrate-inherents 2.0.0", - "substrate-primitives 2.0.0", - "substrate-state-machine 2.0.0", - "trybuild 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "frame-system" -version = "2.0.0" -dependencies = [ - "criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "impl-trait-for-tuples 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "frame-support 2.0.0", - "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 2.0.0", - "sr-primitives 2.0.0", - "sr-std 2.0.0", - "sr-version 2.0.0", - "substrate-primitives 2.0.0", -] - -[[package]] -name = "frame-system-rpc" -version = "2.0.0" -dependencies = [ - "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core-client 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-derive 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "frame-system-rpc-runtime-api 2.0.0", - "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 2.0.0", - "substrate-client 2.0.0", - "substrate-primitives 2.0.0", - "substrate-test-runtime-client 2.0.0", - "substrate-transaction-pool 2.0.0", -] - -[[package]] -name = "frame-system-rpc-runtime-api" -version = "2.0.0" -dependencies = [ - "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-api 2.0.0", -] - -[[package]] -name = "frame-utility" -version = "2.0.0" -dependencies = [ - "frame-support 2.0.0", - "frame-system 2.0.0", - "pallet-balances 2.0.0", - "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 2.0.0", - "sr-primitives 2.0.0", - "sr-std 2.0.0", - "substrate-primitives 2.0.0", -] - [[package]] name = "pallet-assets" version = "2.0.0" @@ -3461,91 +3453,91 @@ dependencies = [ "frame-support 2.0.0", "frame-system 2.0.0", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 2.0.0", - "sr-primitives 2.0.0", - "sr-std 2.0.0", - "substrate-primitives 2.0.0", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-core 2.0.0", + "sp-io 2.0.0", + "sp-runtime 2.0.0", + "sp-std 2.0.0", ] [[package]] name = "pallet-aura" version = "2.0.0" dependencies = [ - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "frame-support 2.0.0", "frame-system 2.0.0", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "pallet-session 2.0.0", "pallet-timestamp 2.0.0", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-application-crypto 2.0.0", + "sp-consensus-aura 0.8.0", + "sp-core 2.0.0", + "sp-inherents 2.0.0", + "sp-io 2.0.0", + "sp-runtime 2.0.0", + "sp-std 2.0.0", "sp-timestamp 2.0.0", - "sr-io 2.0.0", - "sr-primitives 2.0.0", - "sr-std 2.0.0", - "substrate-application-crypto 2.0.0", - "substrate-consensus-aura-primitives 2.0.0", - "substrate-inherents 2.0.0", - "substrate-primitives 2.0.0", ] [[package]] name = "pallet-authority-discovery" -version = "0.1.0" +version = "2.0.0" dependencies = [ "frame-support 2.0.0", "frame-system 2.0.0", "pallet-session 2.0.0", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 2.0.0", - "sr-primitives 2.0.0", - "sr-staking-primitives 2.0.0", - "sr-std 2.0.0", - "substrate-application-crypto 2.0.0", - "substrate-authority-discovery-primitives 2.0.0", - "substrate-primitives 2.0.0", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-application-crypto 2.0.0", + "sp-authority-discovery 2.0.0", + "sp-core 2.0.0", + "sp-io 2.0.0", + "sp-runtime 2.0.0", + "sp-staking 2.0.0", + "sp-std 2.0.0", ] [[package]] name = "pallet-authorship" -version = "0.1.0" +version = "2.0.0" dependencies = [ - "impl-trait-for-tuples 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "frame-support 2.0.0", "frame-system 2.0.0", + "impl-trait-for-tuples 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "sp-authorship 2.0.0", - "sr-io 2.0.0", - "sr-primitives 2.0.0", - "sr-std 2.0.0", - "substrate-inherents 2.0.0", - "substrate-primitives 2.0.0", + "sp-core 2.0.0", + "sp-inherents 2.0.0", + "sp-io 2.0.0", + "sp-runtime 2.0.0", + "sp-std 2.0.0", ] [[package]] name = "pallet-babe" version = "2.0.0" dependencies = [ - "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "frame-support 2.0.0", "frame-system 2.0.0", + "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "pallet-session 2.0.0", "pallet-timestamp 2.0.0", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-consensus-babe 0.8.0", + "sp-core 2.0.0", + "sp-inherents 2.0.0", + "sp-io 2.0.0", + "sp-runtime 2.0.0", + "sp-staking 2.0.0", + "sp-std 2.0.0", "sp-timestamp 2.0.0", - "sr-io 2.0.0", - "sr-primitives 2.0.0", - "sr-staking-primitives 2.0.0", - "sr-std 2.0.0", - "sr-version 2.0.0", - "substrate-consensus-babe-primitives 2.0.0", - "substrate-inherents 2.0.0", - "substrate-primitives 2.0.0", + "sp-version 2.0.0", "substrate-test-runtime 2.0.0", ] @@ -3558,28 +3550,28 @@ dependencies = [ "pallet-transaction-payment 2.0.0", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 2.0.0", - "sr-primitives 2.0.0", - "sr-std 2.0.0", - "substrate-primitives 2.0.0", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-core 2.0.0", + "sp-io 2.0.0", + "sp-runtime 2.0.0", + "sp-std 2.0.0", ] [[package]] name = "pallet-collective" version = "2.0.0" dependencies = [ - "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "frame-support 2.0.0", "frame-system 2.0.0", + "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "pallet-balances 2.0.0", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 2.0.0", - "sr-primitives 2.0.0", - "sr-std 2.0.0", - "substrate-primitives 2.0.0", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-core 2.0.0", + "sp-io 2.0.0", + "sp-runtime 2.0.0", + "sp-std 2.0.0", ] [[package]] @@ -3587,40 +3579,40 @@ name = "pallet-contracts" version = "2.0.0" dependencies = [ "assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "frame-support 2.0.0", "frame-system 2.0.0", + "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "pallet-balances 2.0.0", "pallet-randomness-collective-flip 2.0.0", "pallet-timestamp 2.0.0", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-wasm 0.40.3 (registry+https://github.com/rust-lang/crates.io-index)", - "pwasm-utils 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 2.0.0", - "sr-primitives 2.0.0", - "sr-sandbox 2.0.0", - "sr-std 2.0.0", - "substrate-primitives 2.0.0", + "parity-wasm 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pwasm-utils 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-core 2.0.0", + "sp-io 2.0.0", + "sp-runtime 2.0.0", + "sp-sandbox 2.0.0", + "sp-std 2.0.0", "wabt 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmi-validation 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "wasmi-validation 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "pallet-contracts-rpc" version = "2.0.0" dependencies = [ - "jsonrpc-core 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core-client 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-derive 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core-client 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-derive 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "pallet-contracts-rpc-runtime-api 2.0.0", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 2.0.0", - "substrate-client 2.0.0", - "substrate-primitives 2.0.0", - "substrate-rpc-primitives 2.0.0", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-blockchain 2.0.0", + "sp-core 2.0.0", + "sp-rpc 2.0.0", + "sp-runtime 2.0.0", ] [[package]] @@ -3628,10 +3620,9 @@ name = "pallet-contracts-rpc-runtime-api" version = "2.0.0" dependencies = [ "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-api 2.0.0", - "sr-primitives 2.0.0", - "sr-std 2.0.0", + "sp-api 2.0.0", + "sp-runtime 2.0.0", + "sp-std 2.0.0", ] [[package]] @@ -3643,52 +3634,53 @@ dependencies = [ "pallet-balances 2.0.0", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 2.0.0", - "sr-primitives 2.0.0", - "sr-std 2.0.0", - "substrate-primitives 2.0.0", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-core 2.0.0", + "sp-io 2.0.0", + "sp-runtime 2.0.0", + "sp-std 2.0.0", ] [[package]] name = "pallet-elections" version = "2.0.0" dependencies = [ - "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "frame-support 2.0.0", "frame-system 2.0.0", + "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "pallet-balances 2.0.0", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 2.0.0", - "sr-primitives 2.0.0", - "sr-std 2.0.0", - "substrate-primitives 2.0.0", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-core 2.0.0", + "sp-io 2.0.0", + "sp-runtime 2.0.0", + "sp-std 2.0.0", ] [[package]] name = "pallet-elections-phragmen" version = "2.0.0" dependencies = [ - "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "frame-support 2.0.0", "frame-system 2.0.0", + "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "pallet-balances 2.0.0", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 2.0.0", - "sr-primitives 2.0.0", - "sr-std 2.0.0", - "substrate-phragmen 2.0.0", - "substrate-primitives 2.0.0", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-core 2.0.0", + "sp-io 2.0.0", + "sp-phragmen 2.0.0", + "sp-runtime 2.0.0", + "sp-std 2.0.0", + "substrate-test-utils 2.0.0", ] [[package]] name = "pallet-evm" version = "2.0.0" dependencies = [ - "evm 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", + "evm 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", "frame-support 2.0.0", "frame-system 2.0.0", "pallet-balances 2.0.0", @@ -3696,12 +3688,12 @@ dependencies = [ "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "primitive-types 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", "sha3 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 2.0.0", - "sr-primitives 2.0.0", - "sr-std 2.0.0", - "substrate-primitives 2.0.0", + "sp-core 2.0.0", + "sp-io 2.0.0", + "sp-runtime 2.0.0", + "sp-std 2.0.0", ] [[package]] @@ -3712,28 +3704,28 @@ dependencies = [ "frame-system 2.0.0", "pallet-balances 2.0.0", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 2.0.0", - "sr-primitives 2.0.0", - "sr-std 2.0.0", - "substrate-primitives 2.0.0", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-core 2.0.0", + "sp-io 2.0.0", + "sp-runtime 2.0.0", + "sp-std 2.0.0", ] [[package]] name = "pallet-finality-tracker" version = "2.0.0" dependencies = [ - "impl-trait-for-tuples 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "frame-support 2.0.0", "frame-system 2.0.0", + "impl-trait-for-tuples 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-core 2.0.0", "sp-finality-tracker 2.0.0", - "sr-io 2.0.0", - "sr-primitives 2.0.0", - "sr-std 2.0.0", - "substrate-inherents 2.0.0", - "substrate-primitives 2.0.0", + "sp-inherents 2.0.0", + "sp-io 2.0.0", + "sp-runtime 2.0.0", + "sp-std 2.0.0", ] [[package]] @@ -3743,11 +3735,11 @@ dependencies = [ "frame-support 2.0.0", "frame-system 2.0.0", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 2.0.0", - "sr-primitives 2.0.0", - "sr-std 2.0.0", - "substrate-primitives 2.0.0", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-core 2.0.0", + "sp-io 2.0.0", + "sp-runtime 2.0.0", + "sp-std 2.0.0", ] [[package]] @@ -3759,31 +3751,47 @@ dependencies = [ "pallet-finality-tracker 2.0.0", "pallet-session 2.0.0", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 2.0.0", - "sr-primitives 2.0.0", - "sr-staking-primitives 2.0.0", - "sr-std 2.0.0", - "substrate-finality-grandpa-primitives 2.0.0", - "substrate-primitives 2.0.0", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-core 2.0.0", + "sp-finality-grandpa 2.0.0", + "sp-io 2.0.0", + "sp-runtime 2.0.0", + "sp-staking 2.0.0", + "sp-std 2.0.0", +] + +[[package]] +name = "pallet-identity" +version = "2.0.0" +dependencies = [ + "enumflags2 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "frame-support 2.0.0", + "frame-system 2.0.0", + "pallet-balances 2.0.0", + "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-core 2.0.0", + "sp-io 2.0.0", + "sp-runtime 2.0.0", + "sp-std 2.0.0", ] [[package]] name = "pallet-im-online" -version = "0.1.0" +version = "2.0.0" dependencies = [ "frame-support 2.0.0", "frame-system 2.0.0", - "pallet-authorship 0.1.0", + "pallet-authorship 2.0.0", "pallet-session 2.0.0", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 2.0.0", - "sr-primitives 2.0.0", - "sr-staking-primitives 2.0.0", - "sr-std 2.0.0", - "substrate-application-crypto 2.0.0", - "substrate-primitives 2.0.0", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-application-crypto 2.0.0", + "sp-core 2.0.0", + "sp-io 2.0.0", + "sp-runtime 2.0.0", + "sp-staking 2.0.0", + "sp-std 2.0.0", ] [[package]] @@ -3795,12 +3803,12 @@ dependencies = [ "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "ref_thread_local 0.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 2.0.0", - "sr-primitives 2.0.0", - "sr-std 2.0.0", - "substrate-keyring 2.0.0", - "substrate-primitives 2.0.0", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-core 2.0.0", + "sp-io 2.0.0", + "sp-keyring 2.0.0", + "sp-runtime 2.0.0", + "sp-std 2.0.0", ] [[package]] @@ -3810,11 +3818,11 @@ dependencies = [ "frame-support 2.0.0", "frame-system 2.0.0", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 2.0.0", - "sr-primitives 2.0.0", - "sr-std 2.0.0", - "substrate-primitives 2.0.0", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-core 2.0.0", + "sp-io 2.0.0", + "sp-runtime 2.0.0", + "sp-std 2.0.0", ] [[package]] @@ -3825,27 +3833,27 @@ dependencies = [ "frame-system 2.0.0", "pallet-balances 2.0.0", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 2.0.0", - "sr-primitives 2.0.0", - "sr-std 2.0.0", - "substrate-primitives 2.0.0", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-core 2.0.0", + "sp-io 2.0.0", + "sp-runtime 2.0.0", + "sp-std 2.0.0", ] [[package]] name = "pallet-offences" -version = "1.0.0" +version = "2.0.0" dependencies = [ "frame-support 2.0.0", "frame-system 2.0.0", "pallet-balances 2.0.0", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 2.0.0", - "sr-primitives 2.0.0", - "sr-staking-primitives 2.0.0", - "sr-std 2.0.0", - "substrate-primitives 2.0.0", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-core 2.0.0", + "sp-io 2.0.0", + "sp-runtime 2.0.0", + "sp-staking 2.0.0", + "sp-std 2.0.0", ] [[package]] @@ -3856,46 +3864,46 @@ dependencies = [ "frame-system 2.0.0", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 2.0.0", - "sr-primitives 2.0.0", - "sr-std 2.0.0", - "substrate-primitives 2.0.0", + "sp-core 2.0.0", + "sp-io 2.0.0", + "sp-runtime 2.0.0", + "sp-std 2.0.0", ] [[package]] name = "pallet-scored-pool" -version = "1.0.0" +version = "2.0.0" dependencies = [ "frame-support 2.0.0", "frame-system 2.0.0", "pallet-balances 2.0.0", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 2.0.0", - "sr-primitives 2.0.0", - "sr-std 2.0.0", - "substrate-primitives 2.0.0", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-core 2.0.0", + "sp-io 2.0.0", + "sp-runtime 2.0.0", + "sp-std 2.0.0", ] [[package]] name = "pallet-session" version = "2.0.0" dependencies = [ - "impl-trait-for-tuples 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "frame-support 2.0.0", "frame-system 2.0.0", + "impl-trait-for-tuples 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "pallet-timestamp 2.0.0", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 2.0.0", - "sr-primitives 2.0.0", - "sr-staking-primitives 2.0.0", - "sr-std 2.0.0", - "substrate-application-crypto 2.0.0", - "substrate-primitives 2.0.0", - "substrate-trie 2.0.0", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-application-crypto 2.0.0", + "sp-core 2.0.0", + "sp-io 2.0.0", + "sp-runtime 2.0.0", + "sp-staking 2.0.0", + "sp-std 2.0.0", + "sp-trie 2.0.0", ] [[package]] @@ -3904,21 +3912,22 @@ version = "2.0.0" dependencies = [ "frame-support 2.0.0", "frame-system 2.0.0", - "pallet-authorship 0.1.0", + "pallet-authorship 2.0.0", "pallet-balances 2.0.0", "pallet-session 2.0.0", "pallet-staking-reward-curve 2.0.0", "pallet-timestamp 2.0.0", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 2.0.0", - "sr-primitives 2.0.0", - "sr-staking-primitives 2.0.0", - "sr-std 2.0.0", - "substrate-keyring 2.0.0", - "substrate-phragmen 2.0.0", - "substrate-primitives 2.0.0", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-core 2.0.0", + "sp-io 2.0.0", + "sp-keyring 2.0.0", + "sp-phragmen 2.0.0", + "sp-runtime 2.0.0", + "sp-staking 2.0.0", + "sp-std 2.0.0", + "substrate-test-utils 2.0.0", ] [[package]] @@ -3928,8 +3937,8 @@ dependencies = [ "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 2.0.0", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-runtime 2.0.0", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3939,28 +3948,28 @@ dependencies = [ "frame-support 2.0.0", "frame-system 2.0.0", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 2.0.0", - "sr-primitives 2.0.0", - "sr-std 2.0.0", - "substrate-primitives 2.0.0", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-core 2.0.0", + "sp-io 2.0.0", + "sp-runtime 2.0.0", + "sp-std 2.0.0", ] [[package]] name = "pallet-timestamp" version = "2.0.0" dependencies = [ - "impl-trait-for-tuples 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "frame-support 2.0.0", "frame-system 2.0.0", + "impl-trait-for-tuples 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-core 2.0.0", + "sp-inherents 2.0.0", + "sp-io 2.0.0", + "sp-runtime 2.0.0", + "sp-std 2.0.0", "sp-timestamp 2.0.0", - "sr-io 2.0.0", - "sr-primitives 2.0.0", - "sr-std 2.0.0", - "substrate-inherents 2.0.0", - "substrate-primitives 2.0.0", ] [[package]] @@ -3972,26 +3981,26 @@ dependencies = [ "pallet-balances 2.0.0", "pallet-transaction-payment-rpc-runtime-api 2.0.0", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 2.0.0", - "sr-primitives 2.0.0", - "sr-std 2.0.0", - "substrate-primitives 2.0.0", + "sp-core 2.0.0", + "sp-io 2.0.0", + "sp-runtime 2.0.0", + "sp-std 2.0.0", ] [[package]] name = "pallet-transaction-payment-rpc" version = "2.0.0" dependencies = [ - "jsonrpc-core 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core-client 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-derive 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core-client 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-derive 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "pallet-transaction-payment-rpc-runtime-api 2.0.0", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 2.0.0", - "substrate-client 2.0.0", - "substrate-primitives 2.0.0", - "substrate-rpc-primitives 2.0.0", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-blockchain 2.0.0", + "sp-core 2.0.0", + "sp-rpc 2.0.0", + "sp-runtime 2.0.0", ] [[package]] @@ -4000,11 +4009,11 @@ version = "2.0.0" dependencies = [ "frame-support 2.0.0", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-api 2.0.0", - "sr-primitives 2.0.0", - "sr-std 2.0.0", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-api 2.0.0", + "sp-runtime 2.0.0", + "sp-std 2.0.0", ] [[package]] @@ -4015,17 +4024,32 @@ dependencies = [ "frame-system 2.0.0", "pallet-balances 2.0.0", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 2.0.0", - "sr-primitives 2.0.0", - "sr-std 2.0.0", - "substrate-primitives 2.0.0", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-core 2.0.0", + "sp-io 2.0.0", + "sp-runtime 2.0.0", + "sp-std 2.0.0", +] + +[[package]] +name = "pallet-utility" +version = "2.0.0" +dependencies = [ + "frame-support 2.0.0", + "frame-system 2.0.0", + "pallet-balances 2.0.0", + "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-core 2.0.0", + "sp-io 2.0.0", + "sp-runtime 2.0.0", + "sp-std 2.0.0", ] [[package]] name = "parity-bytes" -version = "0.1.0" -source = "git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d#b0317f649ab2c665b7987b8475878fc4d2e1f81d" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "parity-multiaddr" @@ -4039,7 +4063,7 @@ dependencies = [ "data-encoding 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "parity-multihash 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", "unsigned-varint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4056,7 +4080,7 @@ dependencies = [ "data-encoding 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "parity-multihash 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", "unsigned-varint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4098,7 +4122,7 @@ dependencies = [ "bitvec 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "byte-slice-cast 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec-derive 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4109,7 +4133,7 @@ dependencies = [ "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4135,25 +4159,11 @@ dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "parity-wasm" -version = "0.40.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "parity-wasm" version = "0.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "parking_lot" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "parking_lot" version = "0.7.1" @@ -4178,29 +4188,17 @@ name = "parking_lot" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lock_api 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lock_api 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot_core 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "parking_lot_core" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "parking_lot_core" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4214,7 +4212,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4229,7 +4227,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4253,7 +4251,7 @@ dependencies = [ "proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4308,7 +4306,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4374,7 +4372,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4384,7 +4382,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4425,7 +4423,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "itertools 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "multimap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4441,7 +4439,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "itertools 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4463,12 +4461,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "pwasm-utils" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-wasm 0.40.3 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-wasm 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4476,17 +4474,6 @@ name = "quick-error" version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "quickcheck" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "quickcheck" version = "0.9.0" @@ -4519,7 +4506,7 @@ name = "rand" version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4529,31 +4516,19 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "rand" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "rand" version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4571,7 +4546,7 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4645,7 +4620,7 @@ name = "rand_jitter" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4657,7 +4632,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4713,7 +4688,7 @@ version = "7.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4798,7 +4773,7 @@ version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "mach 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4816,9 +4791,9 @@ name = "ring" version = "0.16.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "web-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4835,19 +4810,19 @@ dependencies = [ [[package]] name = "rocksdb" -version = "0.11.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", - "librocksdb-sys 5.18.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "librocksdb-sys 6.2.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rpassword" -version = "4.0.1" +version = "4.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4898,7 +4873,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4938,9 +4913,835 @@ dependencies = [ ] [[package]] -name = "schannel" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" +name = "sc-authority-discovery" +version = "2.0.0" +dependencies = [ + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-timer 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "prost 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "prost-build 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sc-client-api 2.0.0", + "sc-keystore 2.0.0", + "sc-network 0.8.0", + "sc-peerset 2.0.0", + "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-api 2.0.0", + "sp-authority-discovery 2.0.0", + "sp-blockchain 2.0.0", + "sp-core 2.0.0", + "sp-runtime 2.0.0", + "sp-test-primitives 2.0.0", +] + +[[package]] +name = "sc-basic-authority" +version = "2.0.0" +dependencies = [ + "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sc-block-builder 2.0.0", + "sc-client 2.0.0", + "sc-client-api 2.0.0", + "sc-telemetry 2.0.0", + "sc-transaction-pool 2.0.0", + "sp-blockchain 2.0.0", + "sp-consensus 0.8.0", + "sp-core 2.0.0", + "sp-inherents 2.0.0", + "sp-runtime 2.0.0", + "sp-transaction-pool 2.0.0", + "substrate-test-runtime-client 2.0.0", + "tokio-executor 0.2.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "sc-block-builder" +version = "2.0.0" +dependencies = [ + "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-api 2.0.0", + "sp-block-builder 2.0.0", + "sp-blockchain 2.0.0", + "sp-core 2.0.0", + "sp-runtime 2.0.0", + "sp-state-machine 2.0.0", +] + +[[package]] +name = "sc-chain-spec" +version = "2.0.0" +dependencies = [ + "impl-trait-for-tuples 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "sc-chain-spec-derive 2.0.0", + "sc-network 0.8.0", + "sc-telemetry 2.0.0", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-core 2.0.0", + "sp-runtime 2.0.0", +] + +[[package]] +name = "sc-chain-spec-derive" +version = "2.0.0" +dependencies = [ + "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "sc-cli" +version = "2.0.0" +dependencies = [ + "ansi_term 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", + "app_dirs 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "names 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rpassword 4.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "sc-client-api 2.0.0", + "sc-network 0.8.0", + "sc-service 2.0.0", + "sc-telemetry 2.0.0", + "sc-tracing 2.0.0", + "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-blockchain 2.0.0", + "sp-core 2.0.0", + "sp-keyring 2.0.0", + "sp-panic-handler 2.0.0", + "sp-runtime 2.0.0", + "sp-state-machine 2.0.0", + "structopt 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "sc-client" +version = "2.0.0" +dependencies = [ + "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "kvdb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "kvdb-memorydb 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sc-block-builder 2.0.0", + "sc-client-api 2.0.0", + "sc-executor 2.0.0", + "sc-telemetry 2.0.0", + "sp-api 2.0.0", + "sp-blockchain 2.0.0", + "sp-consensus 0.8.0", + "sp-core 2.0.0", + "sp-externalities 2.0.0", + "sp-inherents 2.0.0", + "sp-keyring 2.0.0", + "sp-panic-handler 2.0.0", + "sp-runtime 2.0.0", + "sp-state-machine 2.0.0", + "sp-std 2.0.0", + "sp-trie 2.0.0", + "sp-version 2.0.0", + "substrate-test-runtime-client 2.0.0", + "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tracing 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "sc-client-api" +version = "2.0.0" +dependencies = [ + "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", + "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "kvdb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sc-executor 2.0.0", + "sc-telemetry 2.0.0", + "sp-api 2.0.0", + "sp-blockchain 2.0.0", + "sp-consensus 0.8.0", + "sp-core 2.0.0", + "sp-externalities 2.0.0", + "sp-inherents 2.0.0", + "sp-keyring 2.0.0", + "sp-runtime 2.0.0", + "sp-state-machine 2.0.0", + "sp-std 2.0.0", + "sp-test-primitives 2.0.0", + "sp-transaction-pool 2.0.0", + "sp-trie 2.0.0", + "sp-version 2.0.0", +] + +[[package]] +name = "sc-client-db" +version = "2.0.0" +dependencies = [ + "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", + "kvdb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "kvdb-memorydb 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "kvdb-rocksdb 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "quickcheck 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sc-client 2.0.0", + "sc-client-api 2.0.0", + "sc-executor 2.0.0", + "sc-state-db 2.0.0", + "sp-blockchain 2.0.0", + "sp-consensus 0.8.0", + "sp-core 2.0.0", + "sp-keyring 2.0.0", + "sp-runtime 2.0.0", + "sp-state-machine 2.0.0", + "sp-trie 2.0.0", + "substrate-test-runtime-client 2.0.0", +] + +[[package]] +name = "sc-consensus-aura" +version = "0.8.0" +dependencies = [ + "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-timer 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sc-client 2.0.0", + "sc-client-api 2.0.0", + "sc-consensus-slots 0.8.0", + "sc-executor 2.0.0", + "sc-keystore 2.0.0", + "sc-network 0.8.0", + "sc-network-test 2.0.0", + "sc-service 2.0.0", + "sc-telemetry 2.0.0", + "sp-api 2.0.0", + "sp-application-crypto 2.0.0", + "sp-block-builder 2.0.0", + "sp-blockchain 2.0.0", + "sp-consensus 0.8.0", + "sp-consensus-aura 0.8.0", + "sp-core 2.0.0", + "sp-inherents 2.0.0", + "sp-io 2.0.0", + "sp-keyring 2.0.0", + "sp-runtime 2.0.0", + "sp-timestamp 2.0.0", + "sp-version 2.0.0", + "substrate-test-runtime-client 2.0.0", + "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "sc-consensus-babe" +version = "0.8.0" +dependencies = [ + "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "fork-tree 2.0.0", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-timer 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "merlin 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num-bigint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "num-rational 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pdqselect 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "sc-block-builder 2.0.0", + "sc-client 2.0.0", + "sc-client-api 2.0.0", + "sc-consensus-slots 0.8.0", + "sc-consensus-uncles 0.8.0", + "sc-executor 2.0.0", + "sc-keystore 2.0.0", + "sc-network 0.8.0", + "sc-network-test 2.0.0", + "sc-service 2.0.0", + "sc-telemetry 2.0.0", + "schnorrkel 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-api 2.0.0", + "sp-application-crypto 2.0.0", + "sp-block-builder 2.0.0", + "sp-blockchain 2.0.0", + "sp-consensus 0.8.0", + "sp-consensus-babe 0.8.0", + "sp-core 2.0.0", + "sp-inherents 2.0.0", + "sp-io 2.0.0", + "sp-keyring 2.0.0", + "sp-runtime 2.0.0", + "sp-timestamp 2.0.0", + "sp-version 2.0.0", + "substrate-test-runtime-client 2.0.0", + "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "sc-consensus-pow" +version = "0.8.0" +dependencies = [ + "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sc-client-api 2.0.0", + "sp-block-builder 2.0.0", + "sp-blockchain 2.0.0", + "sp-consensus 0.8.0", + "sp-consensus-pow 0.8.0", + "sp-core 2.0.0", + "sp-inherents 2.0.0", + "sp-runtime 2.0.0", + "sp-timestamp 2.0.0", +] + +[[package]] +name = "sc-consensus-slots" +version = "0.8.0" +dependencies = [ + "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-timer 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sc-client-api 2.0.0", + "sc-telemetry 2.0.0", + "sp-blockchain 2.0.0", + "sp-consensus 0.8.0", + "sp-core 2.0.0", + "sp-inherents 2.0.0", + "sp-runtime 2.0.0", + "substrate-test-runtime-client 2.0.0", +] + +[[package]] +name = "sc-consensus-uncles" +version = "0.8.0" +dependencies = [ + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "sc-client-api 2.0.0", + "sp-authorship 2.0.0", + "sp-consensus 0.8.0", + "sp-core 2.0.0", + "sp-inherents 2.0.0", + "sp-runtime 2.0.0", +] + +[[package]] +name = "sc-executor" +version = "2.0.0" +dependencies = [ + "assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cranelift-codegen 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cranelift-entity 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cranelift-frontend 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cranelift-native 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cranelift-wasm 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libsecp256k1 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-wasm 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sc-runtime-test 2.0.0", + "sp-core 2.0.0", + "sp-externalities 2.0.0", + "sp-io 2.0.0", + "sp-panic-handler 2.0.0", + "sp-runtime-interface 2.0.0", + "sp-serializer 2.0.0", + "sp-state-machine 2.0.0", + "sp-trie 2.0.0", + "sp-version 2.0.0", + "sp-wasm-interface 2.0.0", + "substrate-test-runtime 2.0.0", + "test-case 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "wabt 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", + "wasmi 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "wasmtime-environ 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "wasmtime-jit 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "wasmtime-runtime 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "sc-finality-grandpa" +version = "2.0.0" +dependencies = [ + "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "finality-grandpa 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", + "fork-tree 2.0.0", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-timer 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "sc-client 2.0.0", + "sc-client-api 2.0.0", + "sc-keystore 2.0.0", + "sc-network 0.8.0", + "sc-network-gossip 2.0.0", + "sc-network-test 2.0.0", + "sc-telemetry 2.0.0", + "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-api 2.0.0", + "sp-blockchain 2.0.0", + "sp-consensus 0.8.0", + "sp-consensus-babe 0.8.0", + "sp-core 2.0.0", + "sp-finality-grandpa 2.0.0", + "sp-finality-tracker 2.0.0", + "sp-inherents 2.0.0", + "sp-keyring 2.0.0", + "sp-runtime 2.0.0", + "sp-state-machine 2.0.0", + "substrate-test-runtime-client 2.0.0", + "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "sc-keystore" +version = "2.0.0" +dependencies = [ + "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", + "hex 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-application-crypto 2.0.0", + "sp-core 2.0.0", + "subtle 2.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "sc-network" +version = "0.8.0" +dependencies = [ + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", + "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "erased-serde 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "fork-tree 2.0.0", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-timer 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", + "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "linked_hash_set 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "lru 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "quickcheck 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "sc-block-builder 2.0.0", + "sc-client 2.0.0", + "sc-client-api 2.0.0", + "sc-peerset 2.0.0", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "slog_derive 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-arithmetic 2.0.0", + "sp-blockchain 2.0.0", + "sp-consensus 0.8.0", + "sp-consensus-babe 0.8.0", + "sp-core 2.0.0", + "sp-keyring 2.0.0", + "sp-runtime 2.0.0", + "sp-test-primitives 2.0.0", + "substrate-test-client 2.0.0", + "substrate-test-runtime-client 2.0.0", + "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "unsigned-varint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "zeroize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "sc-network-gossip" +version = "2.0.0" +dependencies = [ + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-timer 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "lru 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sc-network 0.8.0", + "sp-runtime 2.0.0", +] + +[[package]] +name = "sc-network-test" +version = "2.0.0" +dependencies = [ + "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-timer 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "sc-block-builder 2.0.0", + "sc-client 2.0.0", + "sc-client-api 2.0.0", + "sc-network 0.8.0", + "sp-blockchain 2.0.0", + "sp-consensus 0.8.0", + "sp-consensus-babe 0.8.0", + "sp-core 2.0.0", + "sp-runtime 2.0.0", + "substrate-test-runtime 2.0.0", + "substrate-test-runtime-client 2.0.0", + "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "sc-offchain" +version = "2.0.0" +dependencies = [ + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-timer 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper-rustls 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "sc-client-api 2.0.0", + "sc-client-db 2.0.0", + "sc-keystore 2.0.0", + "sc-network 0.8.0", + "sc-transaction-pool 2.0.0", + "sp-api 2.0.0", + "sp-core 2.0.0", + "sp-offchain 2.0.0", + "sp-runtime 2.0.0", + "sp-transaction-pool 2.0.0", + "substrate-test-runtime-client 2.0.0", + "threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "sc-peerset" +version = "2.0.0" +dependencies = [ + "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "sc-rpc" +version = "2.0.0" +dependencies = [ + "assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-pubsub 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "sc-client 2.0.0", + "sc-client-api 2.0.0", + "sc-executor 2.0.0", + "sc-keystore 2.0.0", + "sc-network 0.8.0", + "sc-rpc-api 2.0.0", + "sc-transaction-pool 2.0.0", + "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-api 2.0.0", + "sp-blockchain 2.0.0", + "sp-core 2.0.0", + "sp-io 2.0.0", + "sp-rpc 2.0.0", + "sp-runtime 2.0.0", + "sp-session 2.0.0", + "sp-state-machine 2.0.0", + "sp-transaction-pool 2.0.0", + "sp-version 2.0.0", + "substrate-test-runtime-client 2.0.0", + "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "sc-rpc-api" +version = "2.0.0" +dependencies = [ + "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core-client 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-derive 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-pubsub 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-core 2.0.0", + "sp-rpc 2.0.0", + "sp-transaction-pool 2.0.0", + "sp-version 2.0.0", +] + +[[package]] +name = "sc-rpc-server" +version = "2.0.0" +dependencies = [ + "jsonrpc-core 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-http-server 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-pubsub 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-ws-server 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-runtime 2.0.0", +] + +[[package]] +name = "sc-runtime-test" +version = "2.0.0" +dependencies = [ + "sp-core 2.0.0", + "sp-io 2.0.0", + "sp-runtime 2.0.0", + "sp-sandbox 2.0.0", + "sp-std 2.0.0", + "substrate-wasm-builder-runner 1.0.4", +] + +[[package]] +name = "sc-service" +version = "2.0.0" +dependencies = [ + "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", + "exit-future 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "grafana-data-source 2.0.0", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-multiaddr 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sc-chain-spec 2.0.0", + "sc-client 2.0.0", + "sc-client-api 2.0.0", + "sc-client-db 2.0.0", + "sc-executor 2.0.0", + "sc-finality-grandpa 2.0.0", + "sc-keystore 2.0.0", + "sc-network 0.8.0", + "sc-offchain 2.0.0", + "sc-rpc 2.0.0", + "sc-rpc-server 2.0.0", + "sc-telemetry 2.0.0", + "sc-tracing 2.0.0", + "sc-transaction-pool 2.0.0", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-api 2.0.0", + "sp-application-crypto 2.0.0", + "sp-blockchain 2.0.0", + "sp-consensus 0.8.0", + "sp-consensus-babe 0.8.0", + "sp-core 2.0.0", + "sp-finality-grandpa 2.0.0", + "sp-io 2.0.0", + "sp-runtime 2.0.0", + "sp-session 2.0.0", + "sp-transaction-pool 2.0.0", + "substrate-test-runtime-client 2.0.0", + "sysinfo 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)", + "target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", + "tracing 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "sc-service-test" +version = "2.0.0" +dependencies = [ + "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "sc-client 2.0.0", + "sc-network 0.8.0", + "sc-service 2.0.0", + "sp-consensus 0.8.0", + "sp-core 2.0.0", + "sp-runtime 2.0.0", + "sp-transaction-pool 2.0.0", + "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "sc-state-db" +version = "2.0.0" +dependencies = [ + "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-core 2.0.0", +] + +[[package]] +name = "sc-telemetry" +version = "2.0.0" +dependencies = [ + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-timer 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "slog-json 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slog-scope 4.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "sc-tracing" +version = "2.0.0" +dependencies = [ + "erased-serde 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "grafana-data-source 2.0.0", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sc-telemetry 2.0.0", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tracing 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tracing-core 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "sc-transaction-graph" +version = "2.0.0" +dependencies = [ + "assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "criterion 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-core 2.0.0", + "sp-runtime 2.0.0", + "sp-transaction-pool 2.0.0", + "substrate-test-runtime 2.0.0", +] + +[[package]] +name = "sc-transaction-pool" +version = "2.0.0" +dependencies = [ + "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sc-client-api 2.0.0", + "sc-transaction-graph 2.0.0", + "sp-api 2.0.0", + "sp-blockchain 2.0.0", + "sp-core 2.0.0", + "sp-keyring 2.0.0", + "sp-runtime 2.0.0", + "sp-transaction-pool 2.0.0", + "substrate-test-runtime-client 2.0.0", +] + +[[package]] +name = "schannel" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4953,12 +5754,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "curve25519-dalek 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "merlin 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "merlin 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "subtle 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "subtle 2.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "zeroize 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4987,7 +5788,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5006,7 +5807,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "security-framework-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -5032,7 +5833,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5047,30 +5848,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "1.0.102" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde_derive 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_derive" -version = "1.0.102" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_json" -version = "1.0.41" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5101,1487 +5902,856 @@ dependencies = [ ] [[package]] -name = "sha3" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "keccak 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "shell32-sys" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "slab" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "slog" -version = "2.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "erased-serde 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "slog-async" -version = "2.3.0" -source = "git+https://github.com/paritytech/slog-async#107848e7ded5e80dc43f6296c2b96039eb92c0a5" -dependencies = [ - "crossbeam-channel 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "slog-json" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", - "erased-serde 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", - "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "slog-scope" -version = "4.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "arc-swap 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "slog_derive" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "smallvec" -version = "0.6.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "smallvec" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "snow" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "ring 0.16.9 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "subtle 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "soketto" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "flate2 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", - "httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "sourcefile" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "sp-authorship" -version = "2.0.0" -dependencies = [ - "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-std 2.0.0", - "substrate-inherents 2.0.0", -] - -[[package]] -name = "sp-finality-tracker" -version = "2.0.0" -dependencies = [ - "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-std 2.0.0", - "substrate-inherents 2.0.0", -] - -[[package]] -name = "sp-timestamp" -version = "2.0.0" -dependencies = [ - "impl-trait-for-tuples 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-api 2.0.0", - "sr-primitives 2.0.0", - "sr-std 2.0.0", - "substrate-inherents 2.0.0", -] - -[[package]] -name = "spin" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "sr-api" -version = "2.0.0" -dependencies = [ - "criterion 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-api-proc-macro 2.0.0", - "sr-primitives 2.0.0", - "sr-std 2.0.0", - "sr-version 2.0.0", - "substrate-primitives 2.0.0", - "substrate-state-machine 2.0.0", - "substrate-test-runtime-client 2.0.0", -] - -[[package]] -name = "sr-api-proc-macro" -version = "2.0.0" -dependencies = [ - "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-api 2.0.0", - "sr-primitives 2.0.0", - "sr-version 2.0.0", - "substrate-test-runtime-client 2.0.0", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "sr-api-test" -version = "2.0.0" -dependencies = [ - "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustversion 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-api 2.0.0", - "sr-primitives 2.0.0", - "sr-version 2.0.0", - "substrate-consensus-common 2.0.0", - "substrate-state-machine 2.0.0", - "substrate-test-runtime-client 2.0.0", - "trybuild 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "sr-arithmetic" -version = "2.0.0" -dependencies = [ - "criterion 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "primitive-types 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-std 2.0.0", - "substrate-debug-derive 2.0.0", -] - -[[package]] -name = "sr-io" -version = "2.0.0" -dependencies = [ - "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libsecp256k1 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-std 2.0.0", - "substrate-externalities 2.0.0", - "substrate-primitives 2.0.0", - "substrate-runtime-interface 2.0.0", - "substrate-state-machine 2.0.0", - "substrate-trie 2.0.0", -] - -[[package]] -name = "sr-primitives" -version = "2.0.0" -dependencies = [ - "impl-trait-for-tuples 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "paste 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-arithmetic 2.0.0", - "sr-io 2.0.0", - "sr-std 2.0.0", - "substrate-application-crypto 2.0.0", - "substrate-inherents 2.0.0", - "substrate-primitives 2.0.0", -] - -[[package]] -name = "sr-sandbox" -version = "2.0.0" -dependencies = [ - "assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 2.0.0", - "sr-std 2.0.0", - "substrate-primitives 2.0.0", - "wabt 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmi 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "sr-staking-primitives" -version = "2.0.0" +name = "sha3" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 2.0.0", - "sr-std 2.0.0", + "block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", + "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "keccak 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "sr-std" -version = "2.0.0" - -[[package]] -name = "sr-version" -version = "2.0.0" +name = "shell32-sys" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "impl-serde 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 2.0.0", - "sr-std 2.0.0", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "stable_deref_trait" -version = "1.1.1" +name = "shlex" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "static_assertions" -version = "1.1.0" +name = "slab" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "stream-cipher" -version = "0.3.2" +name = "slog" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", + "erased-serde 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "string" -version = "0.2.1" +name = "slog-json" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "erased-serde 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "string-interner" -version = "0.7.1" +name = "slog-scope" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "arc-swap 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "strsim" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "structopt" -version = "0.3.4" +name = "slog_derive" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", - "structopt-derive 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "structopt-derive" -version = "0.3.4" +name = "smallvec" +version = "0.6.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro-error 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "strum" -version = "0.15.0" +name = "smallvec" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "strum_macros" -version = "0.15.0" +name = "snow" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.16.9 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "subtle 2.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "subkey" -version = "2.0.0" +name = "soketto" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", - "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "node-primitives 2.0.0", - "node-runtime 2.0.0", - "frame-system 2.0.0", - "pallet-balances 2.0.0", - "pallet-transaction-payment 2.0.0", - "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 2.0.0", - "substrate-bip39 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "substrate-primitives 2.0.0", - "tiny-bip39 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "flate2 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "substrate-application-crypto" -version = "2.0.0" -dependencies = [ - "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 2.0.0", - "sr-primitives 2.0.0", - "sr-std 2.0.0", - "substrate-primitives 2.0.0", - "substrate-test-runtime-client 2.0.0", -] +name = "sourcefile" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "substrate-authority-discovery" +name = "sp-api" version = "2.0.0" dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-timer 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "prost 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "prost-build 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-api 2.0.0", - "sr-primitives 2.0.0", - "substrate-authority-discovery-primitives 2.0.0", - "substrate-client-api 2.0.0", - "substrate-keystore 2.0.0", - "substrate-network 2.0.0", - "substrate-peerset 2.0.0", - "substrate-primitives 2.0.0", - "substrate-test-runtime-client 2.0.0", + "sp-api-proc-macro 2.0.0", + "sp-core 2.0.0", + "sp-runtime 2.0.0", + "sp-state-machine 2.0.0", + "sp-std 2.0.0", + "sp-test-primitives 2.0.0", + "sp-version 2.0.0", ] [[package]] -name = "substrate-authority-discovery-primitives" +name = "sp-api-proc-macro" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-api 2.0.0", - "sr-primitives 2.0.0", - "sr-std 2.0.0", - "substrate-application-crypto 2.0.0", + "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "substrate-basic-authorship" +name = "sp-api-test" version = "2.0.0" dependencies = [ - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "criterion 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 2.0.0", - "substrate-block-builder 2.0.0", - "substrate-client 2.0.0", - "substrate-client-api 2.0.0", - "substrate-consensus-common 2.0.0", - "substrate-inherents 2.0.0", - "substrate-primitives 2.0.0", - "substrate-telemetry 2.0.0", + "rustversion 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-api 2.0.0", + "sp-blockchain 2.0.0", + "sp-consensus 0.8.0", + "sp-runtime 2.0.0", + "sp-state-machine 2.0.0", + "sp-version 2.0.0", "substrate-test-runtime-client 2.0.0", - "substrate-transaction-pool 2.0.0", + "trybuild 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "substrate-bip39" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" +name = "sp-application-crypto" +version = "2.0.0" dependencies = [ - "hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "pbkdf2 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "schnorrkel 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-core 2.0.0", + "sp-io 2.0.0", + "sp-std 2.0.0", ] [[package]] -name = "substrate-block-builder" +name = "sp-application-crypto-test" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-api 2.0.0", - "sr-primitives 2.0.0", - "substrate-block-builder-runtime-api 2.0.0", - "substrate-primitives 2.0.0", - "substrate-state-machine 2.0.0", + "sp-application-crypto 2.0.0", + "sp-core 2.0.0", + "sp-runtime 2.0.0", + "substrate-test-runtime-client 2.0.0", ] [[package]] -name = "substrate-block-builder-runtime-api" +name = "sp-arithmetic" version = "2.0.0" dependencies = [ + "criterion 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-api 2.0.0", - "sr-primitives 2.0.0", - "sr-std 2.0.0", - "substrate-inherents 2.0.0", + "primitive-types 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-debug-derive 2.0.0", + "sp-std 2.0.0", ] [[package]] -name = "substrate-build-script-utils" -version = "2.0.0" - -[[package]] -name = "substrate-chain-spec" +name = "sp-authority-discovery" version = "2.0.0" dependencies = [ - "impl-trait-for-tuples 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 2.0.0", - "substrate-chain-spec-derive 2.0.0", - "substrate-network 2.0.0", - "substrate-primitives 2.0.0", - "substrate-telemetry 2.0.0", + "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-api 2.0.0", + "sp-application-crypto 2.0.0", + "sp-runtime 2.0.0", + "sp-std 2.0.0", ] [[package]] -name = "substrate-chain-spec-derive" +name = "sp-authorship" version = "2.0.0" dependencies = [ - "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-inherents 2.0.0", + "sp-runtime 2.0.0", + "sp-std 2.0.0", ] [[package]] -name = "substrate-cli" +name = "sp-block-builder" version = "2.0.0" dependencies = [ - "ansi_term 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", - "app_dirs 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", - "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures01 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "names 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rpassword 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 2.0.0", - "structopt 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "substrate-client-api 2.0.0", - "substrate-header-metadata 2.0.0", - "substrate-keyring 2.0.0", - "substrate-network 2.0.0", - "substrate-panic-handler 2.0.0", - "substrate-primitives 2.0.0", - "substrate-service 2.0.0", - "substrate-state-machine 2.0.0", - "substrate-telemetry 2.0.0", - "substrate-tracing 2.0.0", - "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-api 2.0.0", + "sp-inherents 2.0.0", + "sp-runtime 2.0.0", + "sp-std 2.0.0", ] [[package]] -name = "substrate-client" +name = "sp-blockchain" version = "2.0.0" dependencies = [ - "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "kvdb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)", - "kvdb-memorydb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)", + "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "lru 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-api 2.0.0", - "sr-primitives 2.0.0", - "sr-std 2.0.0", - "sr-version 2.0.0", - "substrate-block-builder 2.0.0", - "substrate-client-api 2.0.0", - "substrate-client-db 2.0.0", - "substrate-consensus-common 2.0.0", - "substrate-executor 2.0.0", - "substrate-externalities 2.0.0", - "substrate-header-metadata 2.0.0", - "substrate-inherents 2.0.0", - "substrate-keyring 2.0.0", - "substrate-panic-handler 2.0.0", - "substrate-primitives 2.0.0", - "substrate-state-machine 2.0.0", - "substrate-telemetry 2.0.0", - "substrate-test-runtime-client 2.0.0", - "substrate-trie 2.0.0", - "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-block-builder 2.0.0", + "sp-consensus 0.8.0", + "sp-runtime 2.0.0", + "sp-state-machine 2.0.0", ] [[package]] -name = "substrate-client-api" -version = "2.0.0" +name = "sp-consensus" +version = "0.8.0" dependencies = [ - "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "kvdb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)", - "kvdb-memorydb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)", + "futures-timer 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-api 2.0.0", - "sr-primitives 2.0.0", - "sr-std 2.0.0", - "sr-version 2.0.0", - "substrate-block-builder 2.0.0", - "substrate-client-db 2.0.0", - "substrate-consensus-common 2.0.0", - "substrate-executor 2.0.0", - "substrate-externalities 2.0.0", - "substrate-header-metadata 2.0.0", - "substrate-inherents 2.0.0", - "substrate-keyring 2.0.0", - "substrate-panic-handler 2.0.0", - "substrate-primitives 2.0.0", - "substrate-state-machine 2.0.0", - "substrate-telemetry 2.0.0", - "substrate-test-primitives 2.0.0", - "substrate-test-runtime-client 2.0.0", - "substrate-trie 2.0.0", - "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-core 2.0.0", + "sp-inherents 2.0.0", + "sp-runtime 2.0.0", + "sp-std 2.0.0", + "sp-test-primitives 2.0.0", + "sp-version 2.0.0", ] [[package]] -name = "substrate-client-db" -version = "2.0.0" +name = "sp-consensus-aura" +version = "0.8.0" dependencies = [ - "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", - "kvdb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)", - "kvdb-memorydb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)", - "kvdb-rocksdb 0.1.4 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)", - "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "quickcheck 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 2.0.0", - "substrate-client 2.0.0", - "substrate-client-api 2.0.0", - "substrate-consensus-common 2.0.0", - "substrate-executor 2.0.0", - "substrate-header-metadata 2.0.0", - "substrate-keyring 2.0.0", - "substrate-primitives 2.0.0", - "substrate-state-db 2.0.0", - "substrate-state-machine 2.0.0", - "substrate-test-runtime-client 2.0.0", - "substrate-trie 2.0.0", + "sp-api 2.0.0", + "sp-application-crypto 2.0.0", + "sp-inherents 2.0.0", + "sp-runtime 2.0.0", + "sp-std 2.0.0", + "sp-timestamp 2.0.0", ] [[package]] -name = "substrate-consensus-aura" -version = "2.0.0" +name = "sp-consensus-babe" +version = "0.8.0" dependencies = [ - "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-timer 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "schnorrkel 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-api 2.0.0", + "sp-application-crypto 2.0.0", + "sp-consensus 0.8.0", + "sp-inherents 2.0.0", + "sp-runtime 2.0.0", + "sp-std 2.0.0", "sp-timestamp 2.0.0", - "sr-api 2.0.0", - "sr-io 2.0.0", - "sr-primitives 2.0.0", - "sr-version 2.0.0", - "substrate-application-crypto 2.0.0", - "substrate-block-builder-runtime-api 2.0.0", - "substrate-client 2.0.0", - "substrate-client-api 2.0.0", - "substrate-consensus-aura-primitives 2.0.0", - "substrate-consensus-common 2.0.0", - "substrate-consensus-slots 2.0.0", - "substrate-executor 2.0.0", - "substrate-inherents 2.0.0", - "substrate-keyring 2.0.0", - "substrate-keystore 2.0.0", - "substrate-network 2.0.0", - "substrate-primitives 2.0.0", - "substrate-service 2.0.0", - "substrate-telemetry 2.0.0", - "substrate-test-runtime-client 2.0.0", - "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "substrate-consensus-aura-primitives" -version = "2.0.0" +name = "sp-consensus-pow" +version = "0.8.0" dependencies = [ "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sp-timestamp 2.0.0", - "sr-api 2.0.0", - "sr-primitives 2.0.0", - "sr-std 2.0.0", - "substrate-application-crypto 2.0.0", - "substrate-inherents 2.0.0", + "sp-api 2.0.0", + "sp-core 2.0.0", + "sp-runtime 2.0.0", + "sp-std 2.0.0", ] [[package]] -name = "substrate-consensus-babe" +name = "sp-core" version = "2.0.0" dependencies = [ - "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "fork-tree 2.0.0", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-timer 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "ed25519-dalek 1.0.0-pre.3 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", + "hash256-std-hasher 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", + "hex 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-serde 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libsecp256k1 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "merlin 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "num-bigint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "num-rational 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "pdqselect 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "primitive-types 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "schnorrkel 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)", - "sp-timestamp 2.0.0", - "sr-api 2.0.0", - "sr-io 2.0.0", - "sr-primitives 2.0.0", - "sr-version 2.0.0", - "substrate-application-crypto 2.0.0", - "substrate-block-builder 2.0.0", - "substrate-block-builder-runtime-api 2.0.0", - "substrate-client 2.0.0", - "substrate-client-api 2.0.0", - "substrate-consensus-babe-primitives 2.0.0", - "substrate-consensus-common 2.0.0", - "substrate-consensus-slots 2.0.0", - "substrate-consensus-uncles 2.0.0", - "substrate-executor 2.0.0", - "substrate-header-metadata 2.0.0", - "substrate-inherents 2.0.0", - "substrate-keyring 2.0.0", - "substrate-keystore 2.0.0", - "substrate-network 2.0.0", - "substrate-primitives 2.0.0", - "substrate-service 2.0.0", - "substrate-telemetry 2.0.0", - "substrate-test-runtime-client 2.0.0", - "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-debug-derive 2.0.0", + "sp-externalities 2.0.0", + "sp-runtime-interface 2.0.0", + "sp-serializer 2.0.0", + "sp-std 2.0.0", + "sp-storage 2.0.0", + "substrate-bip39 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tiny-bip39 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tiny-keccak 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "twox-hash 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "wasmi 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "zeroize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "substrate-consensus-babe-primitives" +name = "sp-debug-derive" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "schnorrkel 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)", - "sp-timestamp 2.0.0", - "sr-api 2.0.0", - "sr-primitives 2.0.0", - "sr-std 2.0.0", - "substrate-application-crypto 2.0.0", - "substrate-consensus-slots 2.0.0", - "substrate-inherents 2.0.0", + "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "substrate-consensus-common" +name = "sp-externalities" version = "2.0.0" dependencies = [ - "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-timer 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 2.0.0", - "sr-std 2.0.0", - "sr-version 2.0.0", - "substrate-inherents 2.0.0", - "substrate-primitives 2.0.0", - "substrate-test-runtime-client 2.0.0", + "environmental 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-std 2.0.0", + "sp-storage 2.0.0", ] [[package]] -name = "substrate-consensus-pow" +name = "sp-finality-grandpa" version = "2.0.0" dependencies = [ - "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sp-timestamp 2.0.0", - "sr-primitives 2.0.0", - "substrate-block-builder-runtime-api 2.0.0", - "substrate-client-api 2.0.0", - "substrate-consensus-common 2.0.0", - "substrate-consensus-pow-primitives 2.0.0", - "substrate-inherents 2.0.0", - "substrate-primitives 2.0.0", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-api 2.0.0", + "sp-application-crypto 2.0.0", + "sp-runtime 2.0.0", + "sp-std 2.0.0", ] [[package]] -name = "substrate-consensus-pow-primitives" +name = "sp-finality-tracker" version = "2.0.0" dependencies = [ "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-api 2.0.0", - "sr-primitives 2.0.0", - "sr-std 2.0.0", - "substrate-primitives 2.0.0", + "sp-inherents 2.0.0", + "sp-std 2.0.0", ] [[package]] -name = "substrate-consensus-slots" +name = "sp-inherents" version = "2.0.0" dependencies = [ - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-timer 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 2.0.0", - "substrate-client-api 2.0.0", - "substrate-consensus-common 2.0.0", - "substrate-inherents 2.0.0", - "substrate-primitives 2.0.0", - "substrate-telemetry 2.0.0", - "substrate-test-runtime-client 2.0.0", + "sp-core 2.0.0", + "sp-std 2.0.0", ] [[package]] -name = "substrate-consensus-uncles" +name = "sp-io" version = "2.0.0" dependencies = [ + "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libsecp256k1 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "sp-authorship 2.0.0", - "sr-primitives 2.0.0", - "substrate-client-api 2.0.0", - "substrate-consensus-common 2.0.0", - "substrate-inherents 2.0.0", - "substrate-primitives 2.0.0", -] - -[[package]] -name = "substrate-debug-derive" -version = "2.0.0" -dependencies = [ - "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-core 2.0.0", + "sp-externalities 2.0.0", + "sp-runtime-interface 2.0.0", + "sp-state-machine 2.0.0", + "sp-std 2.0.0", + "sp-trie 2.0.0", ] [[package]] -name = "substrate-executor" +name = "sp-keyring" version = "2.0.0" dependencies = [ - "assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cranelift-codegen 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cranelift-entity 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cranelift-frontend 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cranelift-native 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cranelift-wasm 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)", - "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libsecp256k1 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-wasm 0.40.3 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 2.0.0", - "sr-version 2.0.0", - "substrate-client-api 2.0.0", - "substrate-externalities 2.0.0", - "substrate-offchain 2.0.0", - "substrate-panic-handler 2.0.0", - "substrate-primitives 2.0.0", - "substrate-runtime-interface 2.0.0", - "substrate-runtime-test 2.0.0", - "substrate-serializer 2.0.0", - "substrate-state-machine 2.0.0", - "substrate-test-runtime 2.0.0", - "substrate-trie 2.0.0", - "substrate-wasm-interface 2.0.0", - "test-case 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "wabt 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmi 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmtime-environ 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmtime-jit 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmtime-runtime 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-core 2.0.0", + "sp-runtime 2.0.0", + "strum 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "substrate-externalities" +name = "sp-offchain" version = "2.0.0" dependencies = [ - "environmental 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "primitive-types 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-std 2.0.0", - "substrate-primitives-storage 2.0.0", + "sp-api 2.0.0", + "sp-runtime 2.0.0", ] [[package]] -name = "substrate-finality-grandpa" +name = "sp-panic-handler" version = "2.0.0" dependencies = [ - "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "finality-grandpa 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "fork-tree 2.0.0", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", - "sp-finality-tracker 2.0.0", - "sr-api 2.0.0", - "sr-primitives 2.0.0", - "substrate-client 2.0.0", - "substrate-client-api 2.0.0", - "substrate-consensus-babe-primitives 2.0.0", - "substrate-consensus-common 2.0.0", - "substrate-finality-grandpa-primitives 2.0.0", - "substrate-header-metadata 2.0.0", - "substrate-inherents 2.0.0", - "substrate-keyring 2.0.0", - "substrate-keystore 2.0.0", - "substrate-network 2.0.0", - "substrate-primitives 2.0.0", - "substrate-state-machine 2.0.0", - "substrate-telemetry 2.0.0", - "substrate-test-runtime-client 2.0.0", - "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "substrate-finality-grandpa-primitives" +name = "sp-phragmen" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-api 2.0.0", - "sr-primitives 2.0.0", - "sr-std 2.0.0", - "substrate-application-crypto 2.0.0", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-io 2.0.0", + "sp-runtime 2.0.0", + "sp-std 2.0.0", + "substrate-test-utils 2.0.0", ] [[package]] -name = "substrate-header-metadata" +name = "sp-rpc" version = "2.0.0" dependencies = [ - "lru 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 2.0.0", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-core 2.0.0", ] [[package]] -name = "substrate-inherents" +name = "sp-runtime" version = "2.0.0" dependencies = [ - "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-trait-for-tuples 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-std 2.0.0", - "substrate-primitives 2.0.0", + "paste 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-application-crypto 2.0.0", + "sp-arithmetic 2.0.0", + "sp-core 2.0.0", + "sp-inherents 2.0.0", + "sp-io 2.0.0", + "sp-std 2.0.0", ] [[package]] -name = "substrate-keyring" +name = "sp-runtime-interface" version = "2.0.0" dependencies = [ - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 2.0.0", - "strum 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "strum_macros 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "substrate-primitives 2.0.0", + "environmental 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "primitive-types 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rustversion 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-core 2.0.0", + "sp-externalities 2.0.0", + "sp-io 2.0.0", + "sp-runtime-interface-proc-macro 2.0.0", + "sp-runtime-interface-test-wasm 2.0.0", + "sp-state-machine 2.0.0", + "sp-std 2.0.0", + "sp-wasm-interface 2.0.0", + "static_assertions 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "trybuild 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "substrate-keystore" +name = "sp-runtime-interface-proc-macro" version = "2.0.0" dependencies = [ - "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", - "substrate-application-crypto 2.0.0", - "substrate-primitives 2.0.0", - "subtle 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "Inflector 0.11.4 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "substrate-network" +name = "sp-runtime-interface-test" version = "2.0.0" dependencies = [ - "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "erased-serde 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "fork-tree 2.0.0", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-timer 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", - "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "linked_hash_set 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "lru 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "quickcheck 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", - "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "slog_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-arithmetic 2.0.0", - "sr-primitives 2.0.0", - "substrate-block-builder 2.0.0", - "substrate-client 2.0.0", - "substrate-client-api 2.0.0", - "substrate-consensus-babe-primitives 2.0.0", - "substrate-consensus-common 2.0.0", - "substrate-header-metadata 2.0.0", - "substrate-keyring 2.0.0", - "substrate-peerset 2.0.0", - "substrate-primitives 2.0.0", - "substrate-test-client 2.0.0", - "substrate-test-runtime 2.0.0", - "substrate-test-runtime-client 2.0.0", - "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "unsigned-varint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "zeroize 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sc-executor 2.0.0", + "sp-core 2.0.0", + "sp-io 2.0.0", + "sp-runtime-interface 2.0.0", + "sp-runtime-interface-test-wasm 2.0.0", + "sp-state-machine 2.0.0", ] [[package]] -name = "substrate-offchain" +name = "sp-runtime-interface-test-wasm" version = "2.0.0" dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-timer 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper-rustls 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-api 2.0.0", - "sr-primitives 2.0.0", - "substrate-client-api 2.0.0", - "substrate-client-db 2.0.0", - "substrate-keystore 2.0.0", - "substrate-network 2.0.0", - "substrate-offchain-primitives 2.0.0", - "substrate-primitives 2.0.0", - "substrate-test-runtime-client 2.0.0", - "substrate-transaction-pool 2.0.0", - "threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-core 2.0.0", + "sp-io 2.0.0", + "sp-runtime-interface 2.0.0", + "sp-std 2.0.0", + "substrate-wasm-builder-runner 1.0.4", ] [[package]] -name = "substrate-offchain-primitives" +name = "sp-sandbox" version = "2.0.0" dependencies = [ - "sr-api 2.0.0", - "sr-primitives 2.0.0", + "assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-core 2.0.0", + "sp-io 2.0.0", + "sp-std 2.0.0", + "wabt 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", + "wasmi 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "substrate-panic-handler" +name = "sp-serializer" version = "2.0.0" dependencies = [ - "backtrace 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "substrate-peerset" +name = "sp-session" version = "2.0.0" dependencies = [ - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-api 2.0.0", + "sp-runtime 2.0.0", + "sp-std 2.0.0", ] [[package]] -name = "substrate-phragmen" +name = "sp-staking" version = "2.0.0" dependencies = [ - "frame-support 2.0.0", - "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 2.0.0", - "sr-primitives 2.0.0", - "sr-std 2.0.0", + "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-runtime 2.0.0", + "sp-std 2.0.0", ] [[package]] -name = "substrate-primitives" +name = "sp-state-machine" version = "2.0.0" dependencies = [ - "base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "ed25519-dalek 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hash256-std-hasher 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hex 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "impl-serde 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libsecp256k1 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "primitive-types 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "schnorrkel 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-std 2.0.0", - "substrate-bip39 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "substrate-debug-derive 2.0.0", - "substrate-externalities 2.0.0", - "substrate-primitives-storage 2.0.0", - "substrate-runtime-interface 2.0.0", - "substrate-serializer 2.0.0", - "tiny-bip39 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tiny-keccak 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "twox-hash 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmi 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "zeroize 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-core 2.0.0", + "sp-externalities 2.0.0", + "sp-panic-handler 2.0.0", + "sp-trie 2.0.0", + "trie-db 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", + "trie-root 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "substrate-primitives-storage" +name = "sp-std" version = "2.0.0" -dependencies = [ - "impl-serde 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-std 2.0.0", - "substrate-debug-derive 2.0.0", -] [[package]] -name = "substrate-rpc" +name = "sp-storage" version = "2.0.0" dependencies = [ - "assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-pubsub 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-api 2.0.0", - "sr-io 2.0.0", - "sr-primitives 2.0.0", - "sr-version 2.0.0", - "substrate-client 2.0.0", - "substrate-client-api 2.0.0", - "substrate-executor 2.0.0", - "substrate-keystore 2.0.0", - "substrate-network 2.0.0", - "substrate-primitives 2.0.0", - "substrate-rpc-api 2.0.0", - "substrate-rpc-primitives 2.0.0", - "substrate-session 2.0.0", - "substrate-state-machine 2.0.0", - "substrate-test-runtime-client 2.0.0", - "substrate-transaction-pool 2.0.0", - "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-serde 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-debug-derive 2.0.0", + "sp-std 2.0.0", ] [[package]] -name = "substrate-rpc-api" +name = "sp-test-primitives" version = "2.0.0" dependencies = [ - "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core-client 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-derive 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-pubsub 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-version 2.0.0", - "substrate-primitives 2.0.0", - "substrate-rpc-primitives 2.0.0", - "substrate-transaction-graph 2.0.0", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-application-crypto 2.0.0", + "sp-core 2.0.0", + "sp-runtime 2.0.0", ] [[package]] -name = "substrate-rpc-primitives" +name = "sp-timestamp" version = "2.0.0" dependencies = [ - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "substrate-primitives 2.0.0", + "impl-trait-for-tuples 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-api 2.0.0", + "sp-inherents 2.0.0", + "sp-runtime 2.0.0", + "sp-std 2.0.0", ] [[package]] -name = "substrate-rpc-servers" +name = "sp-transaction-pool" version = "2.0.0" dependencies = [ - "jsonrpc-core 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-http-server 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-pubsub 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-ws-server 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 2.0.0", + "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-api 2.0.0", + "sp-runtime 2.0.0", ] [[package]] -name = "substrate-runtime-interface" +name = "sp-trie" version = "2.0.0" dependencies = [ - "environmental 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "memory-db 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "primitive-types 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-io 2.0.0", - "sr-std 2.0.0", - "static_assertions 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "substrate-executor 2.0.0", - "substrate-externalities 2.0.0", - "substrate-primitives 2.0.0", - "substrate-runtime-interface-proc-macro 2.0.0", - "substrate-runtime-interface-test-wasm 2.0.0", - "substrate-state-machine 2.0.0", - "substrate-wasm-interface 2.0.0", + "sp-core 2.0.0", + "sp-std 2.0.0", + "trie-bench 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", + "trie-db 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", + "trie-root 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", + "trie-standardmap 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "substrate-runtime-interface-proc-macro" +name = "sp-version" version = "2.0.0" dependencies = [ - "Inflector 0.11.4 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-serde 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rustversion 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "substrate-externalities 2.0.0", - "substrate-runtime-interface 2.0.0", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", - "trybuild 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-runtime 2.0.0", + "sp-std 2.0.0", ] [[package]] -name = "substrate-runtime-interface-test-wasm" +name = "sp-wasm-interface" version = "2.0.0" dependencies = [ - "sr-io 2.0.0", - "sr-std 2.0.0", - "substrate-primitives 2.0.0", - "substrate-runtime-interface 2.0.0", - "substrate-wasm-builder-runner 1.0.4", + "impl-trait-for-tuples 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "wasmi 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "substrate-runtime-test" -version = "2.0.0" +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "stable_deref_trait" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "stream-cipher" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "sr-io 2.0.0", - "sr-primitives 2.0.0", - "sr-sandbox 2.0.0", - "sr-std 2.0.0", - "substrate-primitives 2.0.0", - "substrate-wasm-builder-runner 1.0.4", + "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "substrate-serializer" -version = "2.0.0" +name = "string" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "substrate-service" -version = "2.0.0" +name = "string-interner" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "exit-future 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "grafana-data-source 2.0.0", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "node-executor 2.0.0", - "node-primitives 2.0.0", - "node-runtime 2.0.0", - "parity-multiaddr 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", - "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-api 2.0.0", - "sr-io 2.0.0", - "sr-primitives 2.0.0", - "substrate-application-crypto 2.0.0", - "substrate-chain-spec 2.0.0", - "substrate-client 2.0.0", - "substrate-client-api 2.0.0", - "substrate-client-db 2.0.0", - "substrate-consensus-babe-primitives 2.0.0", - "substrate-consensus-common 2.0.0", - "substrate-executor 2.0.0", - "substrate-finality-grandpa 2.0.0", - "substrate-finality-grandpa-primitives 2.0.0", - "substrate-keystore 2.0.0", - "substrate-network 2.0.0", - "substrate-offchain 2.0.0", - "substrate-primitives 2.0.0", - "substrate-rpc 2.0.0", - "substrate-rpc-servers 2.0.0", - "substrate-session 2.0.0", - "substrate-telemetry 2.0.0", - "substrate-test-runtime-client 2.0.0", - "substrate-tracing 2.0.0", - "substrate-transaction-pool 2.0.0", - "substrate-transaction-pool-runtime-api 2.0.0", - "sysinfo 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)", - "target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "tracing 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "strsim" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "structopt" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", + "structopt-derive 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "substrate-service-test" -version = "2.0.0" +name = "structopt-derive" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 2.0.0", - "substrate-client 2.0.0", - "substrate-consensus-common 2.0.0", - "substrate-network 2.0.0", - "substrate-primitives 2.0.0", - "substrate-service 2.0.0", - "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", + "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-error 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "substrate-session" -version = "2.0.0" +name = "strum" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "sr-api 2.0.0", - "sr-primitives 2.0.0", - "sr-std 2.0.0", + "strum_macros 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "substrate-state-db" -version = "2.0.0" +name = "strum_macros" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "substrate-primitives 2.0.0", + "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "substrate-state-machine" +name = "subkey" version = "2.0.0" dependencies = [ - "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", + "frame-system 2.0.0", + "hex 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "node-primitives 2.0.0", + "node-runtime 2.0.0", + "pallet-balances 2.0.0", + "pallet-transaction-payment 2.0.0", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "substrate-externalities 2.0.0", - "substrate-panic-handler 2.0.0", - "substrate-primitives 2.0.0", - "substrate-trie 2.0.0", - "trie-db 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", - "trie-root 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-core 2.0.0", + "sp-runtime 2.0.0", + "substrate-bip39 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tiny-bip39 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "substrate-telemetry" +name = "substrate-bip39" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "pbkdf2 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "schnorrkel 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)", + "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "substrate-build-script-utils" +version = "2.0.0" + +[[package]] +name = "substrate-frame-rpc-support" version = "2.0.0" dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "frame-support 2.0.0", + "frame-system 2.0.0", "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-timer 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "slog-async 2.3.0 (git+https://github.com/paritytech/slog-async)", - "slog-json 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slog-scope 4.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-client-transports 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sc-rpc-api 2.0.0", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-storage 2.0.0", + "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "substrate-test-client" +name = "substrate-frame-rpc-system" version = "2.0.0" dependencies = [ + "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "frame-system-rpc-runtime-api 2.0.0", "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core-client 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-derive 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 2.0.0", - "substrate-client 2.0.0", - "substrate-client-api 2.0.0", - "substrate-client-db 2.0.0", - "substrate-consensus-common 2.0.0", - "substrate-executor 2.0.0", - "substrate-keyring 2.0.0", - "substrate-primitives 2.0.0", - "substrate-state-machine 2.0.0", + "sc-client 2.0.0", + "sc-transaction-pool 2.0.0", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-blockchain 2.0.0", + "sp-core 2.0.0", + "sp-runtime 2.0.0", + "sp-transaction-pool 2.0.0", + "substrate-test-runtime-client 2.0.0", ] [[package]] -name = "substrate-test-primitives" +name = "substrate-test-client" version = "2.0.0" dependencies = [ + "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 2.0.0", - "substrate-application-crypto 2.0.0", - "substrate-primitives 2.0.0", + "sc-client 2.0.0", + "sc-client-api 2.0.0", + "sc-client-db 2.0.0", + "sc-executor 2.0.0", + "sp-blockchain 2.0.0", + "sp-consensus 0.8.0", + "sp-core 2.0.0", + "sp-keyring 2.0.0", + "sp-runtime 2.0.0", + "sp-state-machine 2.0.0", ] [[package]] @@ -6589,37 +6759,37 @@ name = "substrate-test-runtime" version = "2.0.0" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "memory-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "frame-executive 2.0.0", "frame-support 2.0.0", "frame-system 2.0.0", "frame-system-rpc-runtime-api 2.0.0", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "memory-db 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)", "pallet-babe 2.0.0", "pallet-timestamp 2.0.0", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-api 2.0.0", - "sr-io 2.0.0", - "sr-primitives 2.0.0", - "sr-std 2.0.0", - "sr-version 2.0.0", - "substrate-application-crypto 2.0.0", - "substrate-block-builder-runtime-api 2.0.0", - "substrate-client 2.0.0", - "substrate-consensus-aura-primitives 2.0.0", - "substrate-consensus-babe-primitives 2.0.0", - "substrate-executor 2.0.0", - "substrate-inherents 2.0.0", - "substrate-keyring 2.0.0", - "substrate-offchain-primitives 2.0.0", - "substrate-primitives 2.0.0", - "substrate-runtime-interface 2.0.0", - "substrate-session 2.0.0", - "substrate-state-machine 2.0.0", + "sc-client 2.0.0", + "sc-executor 2.0.0", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-api 2.0.0", + "sp-application-crypto 2.0.0", + "sp-block-builder 2.0.0", + "sp-consensus-aura 0.8.0", + "sp-consensus-babe 0.8.0", + "sp-core 2.0.0", + "sp-inherents 2.0.0", + "sp-io 2.0.0", + "sp-keyring 2.0.0", + "sp-offchain 2.0.0", + "sp-runtime 2.0.0", + "sp-runtime-interface 2.0.0", + "sp-session 2.0.0", + "sp-state-machine 2.0.0", + "sp-std 2.0.0", + "sp-transaction-pool 2.0.0", + "sp-trie 2.0.0", + "sp-version 2.0.0", "substrate-test-runtime-client 2.0.0", - "substrate-transaction-pool-runtime-api 2.0.0", - "substrate-trie 2.0.0", "substrate-wasm-builder-runner 1.0.4", "trie-db 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -6628,88 +6798,21 @@ dependencies = [ name = "substrate-test-runtime-client" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 2.0.0", - "substrate-block-builder 2.0.0", - "substrate-client 2.0.0", - "substrate-client-api 2.0.0", - "substrate-primitives 2.0.0", - "substrate-test-client 2.0.0", - "substrate-test-runtime 2.0.0", -] - -[[package]] -name = "substrate-tracing" -version = "2.0.0" -dependencies = [ - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "substrate-telemetry 2.0.0", - "tracing 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "tracing-core 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "substrate-transaction-graph" -version = "2.0.0" -dependencies = [ - "assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "criterion 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 2.0.0", - "substrate-primitives 2.0.0", + "sc-block-builder 2.0.0", + "sc-client 2.0.0", + "sc-client-api 2.0.0", + "sp-blockchain 2.0.0", + "sp-core 2.0.0", + "sp-runtime 2.0.0", + "substrate-test-client 2.0.0", "substrate-test-runtime 2.0.0", ] [[package]] -name = "substrate-transaction-pool" -version = "2.0.0" -dependencies = [ - "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-api 2.0.0", - "sr-primitives 2.0.0", - "substrate-keyring 2.0.0", - "substrate-primitives 2.0.0", - "substrate-test-runtime-client 2.0.0", - "substrate-transaction-graph 2.0.0", - "substrate-transaction-pool-runtime-api 2.0.0", -] - -[[package]] -name = "substrate-transaction-pool-runtime-api" -version = "2.0.0" -dependencies = [ - "sr-api 2.0.0", - "sr-primitives 2.0.0", - "substrate-primitives 2.0.0", -] - -[[package]] -name = "substrate-trie" +name = "substrate-test-utils" version = "2.0.0" -dependencies = [ - "criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "memory-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-std 2.0.0", - "substrate-primitives 2.0.0", - "trie-bench 0.16.3 (registry+https://github.com/rust-lang/crates.io-index)", - "trie-db 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", - "trie-root 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", - "trie-standardmap 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "substrate-wasm-builder" @@ -6717,7 +6820,7 @@ version = "1.0.8" dependencies = [ "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", "build-helper 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "cargo_metadata 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cargo_metadata 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6729,14 +6832,6 @@ dependencies = [ name = "substrate-wasm-builder-runner" version = "1.0.4" -[[package]] -name = "substrate-wasm-interface" -version = "2.0.0" -dependencies = [ - "impl-trait-for-tuples 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmi 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "subtle" version = "1.0.0" @@ -6744,7 +6839,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "subtle" -version = "2.2.1" +version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -6759,7 +6854,7 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.8" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6774,7 +6869,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -6785,7 +6880,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "doc-comment 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -6805,22 +6900,13 @@ name = "target_info" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "tempdir" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "tempfile" version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", "remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6843,7 +6929,7 @@ dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", "version_check 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -6852,25 +6938,25 @@ name = "textwrap" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "thiserror" -version = "1.0.6" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "thiserror-impl 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "thiserror-impl 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "thiserror-impl" -version = "1.0.6" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -6894,7 +6980,7 @@ name = "time" version = "0.1.42" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -6934,8 +7020,8 @@ name = "tinytemplate" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -6945,52 +7031,51 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-fs 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-sync 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-threadpool 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-threadpool 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-udp 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "tokio-buf" -version = "0.1.1" +name = "tokio" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project-lite 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "tokio-codec" +name = "tokio-buf" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-codec" -version = "0.2.0-alpha.6" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-sink-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.2.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -6999,7 +7084,7 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -7015,7 +7100,7 @@ dependencies = [ [[package]] name = "tokio-executor" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -7028,6 +7113,8 @@ version = "0.2.0-alpha.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures-util-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-sync 0.2.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -7037,7 +7124,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-threadpool 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-threadpool 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -7050,32 +7137,20 @@ dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "tokio-io" -version = "0.2.0-alpha.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "tokio-reactor" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-sync 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -7120,14 +7195,14 @@ dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-threadpool" -version = "0.1.16" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -7138,18 +7213,18 @@ dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-timer" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -7170,10 +7245,10 @@ dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -7184,35 +7259,39 @@ dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "toml" -version = "0.5.5" +name = "tokio-util" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-sink 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project-lite 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "tower-make" -version = "0.3.0-alpha.2a" +name = "toml" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "tokio-io 0.2.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tower-service 0.3.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tower-service" -version = "0.3.0-alpha.2" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -7232,7 +7311,7 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -7249,32 +7328,15 @@ name = "traitobject" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "transaction-factory" -version = "0.0.1" -dependencies = [ - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-api 2.0.0", - "sr-primitives 2.0.0", - "substrate-block-builder-runtime-api 2.0.0", - "substrate-cli 2.0.0", - "substrate-client 2.0.0", - "substrate-client-api 2.0.0", - "substrate-consensus-common 2.0.0", - "substrate-primitives 2.0.0", - "substrate-service 2.0.0", -] - [[package]] name = "trie-bench" -version = "0.16.3" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "keccak-hasher 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", - "memory-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", + "memory-db 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "trie-db 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", "trie-root 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -7286,7 +7348,7 @@ name = "trie-db" version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "elastic-array 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", + "elastic-array 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "hashbrown 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -7317,13 +7379,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "trybuild" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", "termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -7393,7 +7455,7 @@ dependencies = [ [[package]] name = "unicode-normalization" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -7406,7 +7468,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "unicode-width" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -7455,7 +7517,7 @@ dependencies = [ [[package]] name = "vcpkg" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -7469,7 +7531,7 @@ version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -7493,9 +7555,9 @@ name = "wabt" version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", "wabt-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -7504,7 +7566,7 @@ name = "wabt-sys" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", "cmake 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -7562,7 +7624,7 @@ dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-shared 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -7594,7 +7656,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-backend 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-shared 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -7609,12 +7671,12 @@ name = "wasm-bindgen-webidl" version = "0.2.55" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "anyhow 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)", + "anyhow 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-backend 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)", "weedle 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -7637,7 +7699,7 @@ dependencies = [ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "js-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)", "send_wrapper 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)", "web-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -7648,22 +7710,14 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "errno 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "memory_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "num-rational 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "parity-wasm 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)", "wasmi-validation 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "wasmi-validation" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "parity-wasm 0.40.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "wasmi-validation" version = "0.3.0" @@ -7682,7 +7736,7 @@ name = "wasmtime-debug" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "anyhow 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)", + "anyhow 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", "cranelift-codegen 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)", "cranelift-entity 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)", "cranelift-wasm 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -7690,7 +7744,7 @@ dependencies = [ "gimli 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)", "more-asserts 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "target-lexicon 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "thiserror 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "thiserror 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "wasmparser 0.39.3 (registry+https://github.com/rust-lang/crates.io-index)", "wasmtime-environ 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -7701,7 +7755,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "bincode 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "cranelift-codegen 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)", "cranelift-entity 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)", "cranelift-wasm 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -7710,14 +7764,14 @@ dependencies = [ "file-per-thread-logger 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "more-asserts 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "thiserror 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "thiserror 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "wasmparser 0.39.3 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -7729,7 +7783,7 @@ name = "wasmtime-jit" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "anyhow 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)", + "anyhow 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", "cranelift-codegen 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)", "cranelift-entity 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)", "cranelift-frontend 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -7737,7 +7791,7 @@ dependencies = [ "more-asserts 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "region 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "target-lexicon 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "thiserror 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "thiserror 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "wasmparser 0.39.3 (registry+https://github.com/rust-lang/crates.io-index)", "wasmtime-debug 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "wasmtime-environ 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -7750,17 +7804,17 @@ name = "wasmtime-runtime" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", "cranelift-codegen 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)", "cranelift-entity 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)", "cranelift-wasm 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)", "indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "more-asserts 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "region 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "thiserror 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "thiserror 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "wasmtime-environ 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -7770,7 +7824,7 @@ name = "web-sys" version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "anyhow 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)", + "anyhow 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", "js-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)", "sourcefile 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)", @@ -7804,7 +7858,27 @@ dependencies = [ [[package]] name = "websocket" -version = "0.23.0" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.10.16 (registry+https://github.com/rust-lang/crates.io-index)", + "native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-tls 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "websocket-base 0.24.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "websocket-base" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -7812,17 +7886,13 @@ dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.10.16 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tls 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -7839,7 +7909,7 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -7897,8 +7967,8 @@ dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", - "mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", + "mio-extras 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -7952,8 +8022,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "zeroize" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "zeroize_derive 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "zeroize_derive" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", + "synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "zstd" @@ -7968,7 +8052,7 @@ name = "zstd-safe" version = "2.0.3+zstd.1.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "zstd-sys 1.4.15+zstd.1.4.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -7977,9 +8061,9 @@ name = "zstd-sys" version = "1.4.15+zstd.1.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", ] [metadata] @@ -7992,7 +8076,7 @@ dependencies = [ "checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d" "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" "checksum ansi_term 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" -"checksum anyhow 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)" = "e19f23ab207147bbdbcdfa7f7e4ca5e84963d79bae3937074682177ab9150968" +"checksum anyhow 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "9267dff192e68f3399525901e709a48c1d3982c9c072fa32f2127a0cb0babf14" "checksum app_dirs 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e73a24bad9bd6a94d6395382a6c69fe071708ae4409f763c5475e14ee896313d" "checksum arc-swap 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d7b8a9123b8027467bce0099fe556c628a53c8d83df0507084c31e9ba2e39aff" "checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee" @@ -8002,7 +8086,7 @@ dependencies = [ "checksum asn1_der_derive 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0d0864d84b8e07b145449be9a8537db86bf9de5ce03b913214694643b4743502" "checksum assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7deb0a829ca7bcfaf5da70b073a8d128619259a7be8216a355e23f00763059e5" "checksum async-macros 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "644a5a8de80f2085a1e7e57cd1544a2a7438f6e003c0790999bd43b92a77cdb2" -"checksum async-std 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "56933da6903b273923d13f4746d829f66ff9b444173f6743d831e80f4da15446" +"checksum async-std 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "513ee3c49800679a319912340f5601afda9e72848d7dea3a48bab489e8c1a46f" "checksum async-task 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de6bd58f7b9cc49032559422595c81cbfcf04db2f2133592f70af19e258a1ced" "checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90" "checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" @@ -8012,8 +8096,8 @@ dependencies = [ "checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" "checksum base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" "checksum base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643" -"checksum bincode 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b8ab639324e3ee8774d296864fbc0dbbb256cf1a41c490b94cba90c082915f92" -"checksum bindgen 0.47.3 (registry+https://github.com/rust-lang/crates.io-index)" = "df683a55b54b41d5ea8ebfaebb5aa7e6b84e3f3006a78f010dadc9ca88469260" +"checksum bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5753e2a71534719bf3f4e57006c3a4f0d2c672a4b676eec84161f763eca87dbf" +"checksum bindgen 0.49.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4c07087f3d5731bf3fb375a81841b99597e25dc11bd3bc72d16d43adf6624a6e" "checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" "checksum bitmask 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5da9b3d9f6f585199287a473f4f8dfab6566cf827d15c00c219f53c645687ead" "checksum bitvec 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a993f74b4c99c1908d156b8d2e0fb6277736b0ecbd833982fd1241d39b2766a6" @@ -8034,15 +8118,16 @@ dependencies = [ "checksum byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0fc10e8cc6b2580fda3f36eb6dc5316657f812a3df879a44a66fc9f0fdbc4855" "checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" "checksum bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" +"checksum bytes 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1c85319f157e4e26c703678e68e26ab71a46c0199286fa670b21cc9fec13d895" "checksum c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb" "checksum c_linked_list 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4964518bd3b4a8190e832886cdc0da9794f12e8e6c1613a9e90ff331c4c8724b" -"checksum cargo_metadata 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8d2d1617e838936c0d2323a65cc151e03ae19a7678dd24f72bccf27119b90a5d" +"checksum cargo_metadata 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "46e3374c604fb39d1a2f35ed5e4a4e30e60d01fab49446e08f1b3e9a90aef202" "checksum cast 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4b9434b9a5aa1450faa3f9cb14ea0e8c53bb5d2b3c1bfd1ab4fc03e9f33fbfb0" -"checksum cc 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)" = "aa87058dce70a3ff5621797f1506cb837edd02ac4c0ae642b4542dce802908b8" +"checksum cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)" = "f52a465a666ca3d838ebbf08b241383421412fe7ebb463527bba275526d89f76" "checksum cexpr 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fce5b5fb86b0c57c20c834c1b412fd09c77c8a59b9473f86272709e78874cd1d" "checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" -"checksum chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e8493056968583b0193c1bb04d6f7684586f3726992d6c573261941a895dbd68" -"checksum clang-sys 0.26.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6ef0c1bcf2e99c649104bd7a7012d8f8802684400e03db0ec0af48583c6fa0e4" +"checksum chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "31850b4a4d6bae316f7a09e691c944c28299298837edc0a03f755618c23cbc01" +"checksum clang-sys 0.28.1 (registry+https://github.com/rust-lang/crates.io-index)" = "81de550971c976f176130da4b2978d3b524eaa0fd9ac31f3ceb5ae1231fb4853" "checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" "checksum clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "97276801e127ffb46b66ce23f35cc96bd454fa311294bced4bbace7baa8b1d17" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" @@ -8067,7 +8152,6 @@ dependencies = [ "checksum criterion 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "938703e165481c8d612ea3479ac8342e5615185db37765162e762ec3523e2fc6" "checksum criterion-plot 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "76f9212ddf2f4a9eb2d401635190600656a1f88a932ef53d06e7fa4c7e02fb8e" "checksum criterion-plot 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eccdc6ce8bbe352ca89025bee672aa6d24f4eb8c53e3a8b5d1bc58011da072a2" -"checksum crossbeam-channel 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c8ec7fcd21571dc78f96cc96243cab8d8f035247c3efd16c687be154c3fa9efa" "checksum crossbeam-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "acec9a3b0b3559f15aee4f90746c4e5e293b701c0f7d3925d24e01645267b68c" "checksum crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3aa945d63861bfe624b55d153a39684da1e8c0bc8fba932f7ee3a3c16cea3ca" "checksum crossbeam-epoch 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5064ebdbf05ce3cb95e45c8b086f72263f4166b29b97f6baff7ef7fe047b55ac" @@ -8085,29 +8169,31 @@ dependencies = [ "checksum ctrlc 3.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c7dfd2d8b4c82121dfdff120f818e09fc4380b0b7e17a742081a89b94853e87f" "checksum cuckoofilter 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8dd43f7cfaffe0a386636a10baea2ee05cc50df3b77bea4a456c9572a939bf1f" "checksum curve25519-dalek 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8b7dcd30ba50cdf88b55b033456138b7c0ac4afdc436d82e1b79f370f24cc66d" +"checksum curve25519-dalek 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "26778518a7f6cffa1d25a44b602b62b979bd88adb9e99ffec546998cf3404839" "checksum data-encoding 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f4f47ca1860a761136924ddd2422ba77b2ea54fe8cc75b9040804a0d9d32ad97" -"checksum derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a141330240c921ec6d074a3e188a7c7ef95668bb95e7d44fa0e5778ec2a7afe" +"checksum derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2159be042979966de68315bce7034bb000c775f22e3e834e1c52ff78f041cae8" "checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" "checksum digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" "checksum directories 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "551a778172a450d7fc12e629ca3b0428d00f6afa9a43da1b630d54604e97371c" "checksum dirs-sys 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "afa0b23de8fd801745c471deffa6e12d248f962c9fd4b4c33787b055599bde7b" "checksum dns-parser 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c4d33be9473d06f75f58220f71f7a9317aca647dc061dbd3c361b0bef505fbea" "checksum doc-comment 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "923dea538cea0aa3025e8685b20d6ee21ef99c4f77e954a30febbaac5ec73a97" -"checksum ed25519-dalek 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d07e8b8a8386c3b89a7a4b329fdfa4cb545de2545e9e2ebbc3dd3929253e426" -"checksum ed25519-dalek 1.0.0-pre.2 (registry+https://github.com/rust-lang/crates.io-index)" = "845aaacc16f01178f33349e7c992ecd0cee095aa5e577f0f4dee35971bd36455" +"checksum ed25519-dalek 1.0.0-pre.3 (registry+https://github.com/rust-lang/crates.io-index)" = "978710b352437433c97b2bff193f2fb1dfd58a093f863dd95e225a19baa599a2" "checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" -"checksum elastic-array 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "073be79b6538296faf81c631872676600616073817dd9a440c477ad09b408983" +"checksum elastic-array 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)" = "580f3768bd6465780d063f5b8213a2ebd506e139b345e4a81eb301ceae3d61e1" +"checksum enumflags2 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "33121c8782ba948ba332dab29311b026a8716dc65a1599e5b88f392d38496af8" +"checksum enumflags2_derive 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ecf634c5213044b8d54a46dd282cf5dd1f86bb5cb53e92c409cb4680a7fb9894" "checksum env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "aafcde04e90a5226a6443b7aabdb016ba2f8307c847d524724bd9b346dd1a2d3" "checksum env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" "checksum environmental 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "34f8467a0284de039e6bd0e25c14519538462ba5beb548bb1f03e645097837a8" "checksum erased-serde 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3beee4bc16478a1b26f2e80ad819a52d24745e292f521a63c16eea5f74b7eb60" "checksum errno 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2a071601ed01b988f896ab14b95e67335d1eeb50190932a1320f7fe3cadc84e" "checksum errno-dragonfly 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "14ca354e36190500e1e1fb267c647932382b54053c50b14970856c0b00a35067" -"checksum evm 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1138816a9b7f9a9d1fcabb1b8a7afed2687d035692baf297bd3fea122acdc96f" +"checksum evm 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "32a2c6961fdc9952371fc5f0416f03a9d90378a9dfb6862f6a7a9a3b8986b8dd" "checksum evm-core 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3bcde5af3d542874ddeb53de0919302d57586ea04b3f76f54d865f8a6cdc70ae" "checksum evm-gasometer 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b82bc9f275cb59d2bcc05d85c98736ddfaba003a7ef7b73893fa7c1c1fab29dc" "checksum evm-runtime 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0dbbc89d29618c3722c17ba78ddf432d40ace8ee27e3f8b28b52a85921112e4b" -"checksum exit-future 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d8013f441e38e31c670e7f34ec8f1d5d3a2bd9d303c1ff83976ca886005e8f48" +"checksum exit-future 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e43f2f1833d64e33f15592464d6fdd70f349dda7b1a53088eb83cd94014008c5" "checksum faerie 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f902f2af041f6c7177a2a04f805687cdc71e69c7cbef059a2755d8923f4cd7a8" "checksum failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f8273f13c977665c5db7eb2b99ae520952fe5ac831ae4cd09d80c4c7042b5ed9" "checksum failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0bc225b78e0391e4b8683440bf2e63c2deeeb2ce5189eab46e2b68c6d3725d08" @@ -8115,7 +8201,7 @@ dependencies = [ "checksum fallible-iterator 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" "checksum fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b1ee15a7050e5580b3712877157068ea713b245b080ff302ae2ca973cfcd9baa" "checksum file-per-thread-logger 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8505b75b31ef7285168dd237c4a7db3c1f3e0927e7d314e670bc98e854272fe9" -"checksum finality-grandpa 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b36ece7dc398ce17438d815f3202d2cdba8fd930452a68b616965662742b7e10" +"checksum finality-grandpa 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4106eb29c7e092f4a6ce6e7632abbbfdf85d94e63035d3790d2d16eeae83d3f4" "checksum fixed-hash 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "72fe7539e2c5692c6989f2f9c0457e42f1e5768f96b85c87d273574670ae459f" "checksum fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33" "checksum flate2 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6bd6d6f4752952feb71363cffc9ebac9411b75b87c6ab6058c40c8900cf43c0f" @@ -8144,7 +8230,7 @@ dependencies = [ "checksum futures-timer 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a1de7508b218029b0f01662ed8f61b1c964b3ae99d6f25462d0f55a595109df6" "checksum futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c0d66274fb76985d3c62c886d1da7ac4c0903a8c9f754e8fe0f35a6a6cc39e76" "checksum futures-util-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)" = "5ce968633c17e5f97936bd2797b6e38fb56cf16a7422319f7ec2e30d3c470e8d" -"checksum futures01 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)" = "7ef8cbbf52909170053540c6c05a62433ddb60662dabee714e2a882caa864f22" +"checksum fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" "checksum gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" "checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" "checksum get_if_addrs 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "abddb55a898d32925f3148bd281174a68eeb68bbfd9a5938a57b18f506ee4ef7" @@ -8154,30 +8240,31 @@ dependencies = [ "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" "checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" "checksum globset 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "925aa2cac82d8834e2b2a4415b6f6879757fb5c0928fc445ae76461a12eed8f2" -"checksum goblin 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5e6040506480da04a63de51a478e8021892d65d8411f29b2a422c2648bdd8bcb" +"checksum goblin 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "88a79ef1f0dad46fd78075b6f80f92d97710eddf87b3e18a15a66761e8942672" "checksum h2 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b34c246847f938a410a03c5458c7fee2274436675e76d8b903c08efc29c462" -"checksum h2 0.2.0-alpha.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0f107db1419ef8271686187b1a5d47c6431af4a7f4d98b495e7b7fc249bb0a78" +"checksum h2 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b9433d71e471c1736fd5a61b671fc0b148d7a2992f666c958d03cd8feb3b88d1" "checksum hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d23bd4e7b5eda0d0f3a307e8b381fdc8ba9000f26fbe912250c0a4cc3956364a" "checksum hash256-std-hasher 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "92c171d55b98633f4ed3860808f004099b36c1cc29c42cfc53aa8591b21efcf2" "checksum hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3bae29b6653b3412c2e71e9d486db9f9df5d701941d86683005efb9f2d28e3da" +"checksum hashbrown 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e1de41fb8dba9714efd92241565cdff73f78508c95697dd56787d3cba27e2353" "checksum hashbrown 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8e6073d0ca812575946eb5f35ff68dbe519907b25c42530389ff946dc84c6ead" "checksum heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1679e6ea370dee694f91f1dc469bf94cf8f52051d147aec3e1f9497c6fc22461" "checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" "checksum hermit-abi 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "307c3c9f937f38e3534b1d6447ecf090cafcc9744e4a6360e8b037b2cf5af120" -"checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77" "checksum hex 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "023b39be39e3a2da62a94feb433e91e8bcd37676fbc8bea371daf52b7a769a3e" "checksum hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "961de220ec9a91af2e1e5bd80d02109155695e516771762381ef8581317066e0" "checksum hex-literal-impl 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9d4c5c844e2fee0bf673d54c2c177f1713b3d2af2ff6e666b49cb7572e6cf42d" "checksum hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695" "checksum hmac-drbg 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c6e570451493f10f6581b48cdd530413b63ea9e780f544bfd3bdcaa0d89d1a7b" -"checksum http 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)" = "d7e06e336150b178206af098a055e3621e8336027e2b4d126bda0bc64824baaf" +"checksum http 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "d6ccf5ede3a895d8856620237b2f02972c1bbc78d2965ad7fe8838d4a0ed41f0" +"checksum http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b708cc7f06493459026f53b9a61a7a121a5d1ec6238dee58ea4941132b30156b" "checksum http-body 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d" -"checksum http-body 0.2.0-alpha.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1f3aef6f3de2bd8585f5b366f3f550b5774500b4764d00cf00f903c95749eec3" +"checksum http-body 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "13d5ff830006f7646652e057693569bfe0d51760c0085a071769d142a205111b" "checksum httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" "checksum humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" "checksum hyper 0.10.16 (registry+https://github.com/rust-lang/crates.io-index)" = "0a0652d9a2609a968c14be1a9ea00bf4b1d64e2e1f53a1b51b6fff3a6e829273" "checksum hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)" = "9dbe6ed1438e1f8ad955a4701e9a944938e9519f6888d12d8558b645e247d5f6" -"checksum hyper 0.13.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "2d05aa523087ac0b9d8b93dd80d5d482a697308ed3b0dca7b0667511a7fa7cdc" +"checksum hyper 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8bf49cfb32edee45d890537d9057d1b02ed55f53b7b6a30bae83a38c9231749e" "checksum hyper-rustls 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)" = "719d85c7df4a7f309a77d145340a063ea929dcb2e025bae46a80345cffec2952" "checksum hyper-tls 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3a800d6aa50af4b5850b2b0f659625ce9504df908e9733b635720483be26174f" "checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" @@ -8191,29 +8278,29 @@ dependencies = [ "checksum interleaved-ordered 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "141340095b15ed7491bd3d4ced9d20cebfb826174b6bb03386381f62b01e3d77" "checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" "checksum ipnet 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f2f4b06b21db0228860c8dfd17d2106c49c7c6bd07477a4036985347d84def04" -"checksum itertools 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "87fa75c9dea7b07be3138c49abbb83fd4bea199b5cdc76f9804458edc5da0d6e" +"checksum itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484" "checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" "checksum jobserver 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "f2b1d42ef453b30b7387e113da1c83ab1605d90c5b4e0eb8e96d016ed3b8c160" "checksum js-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)" = "1c840fdb2167497b0bd0db43d6dfe61e91637fa72f9d061f8bd17ddc44ba6414" -"checksum jsonrpc-client-transports 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d389a085cb2184604dff060390cadb8cba1f063c7fd0ad710272c163c88b9f20" -"checksum jsonrpc-core 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "34651edf3417637cc45e70ed0182ecfa9ced0b7e8131805fccf7400d989845ca" -"checksum jsonrpc-core-client 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9dbaec1d57271ff952f24ca79d37d716cfd749c855b058d9aa5f053a6b8ae4ef" -"checksum jsonrpc-derive 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d5d5c31575cc70a8b21542599028472c80a9248394aeea4d8918a045a0ab08a3" -"checksum jsonrpc-http-server 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "aa54c4c2d88cb5e04b251a5031ba0f2ee8c6ef30970e31228955b89a80c3b611" -"checksum jsonrpc-pubsub 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3ee1b8da0b9219a231c4b7cbc7110bfdb457cbcd8d90a6224d0b3cab8aae8443" -"checksum jsonrpc-server-utils 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "87bc3c0a9a282211b2ec14abb3e977de33016bbec495332e9f7be858de7c5117" -"checksum jsonrpc-ws-server 14.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "af36a129cef77a9db8028ac7552d927e1bb7b6928cd96b23dd25cc38bff974ab" +"checksum jsonrpc-client-transports 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0a9ae166c4d1f702d297cd76d4b55758ace80272ffc6dbb139fdc1bf810de40b" +"checksum jsonrpc-core 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fe3b688648f1ef5d5072229e2d672ecb92cbff7d1c79bcf3fd5898f3f3df0970" +"checksum jsonrpc-core-client 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "080dc110be17701097df238fad3c816d4a478a1899dfbcf8ec8957dd40ec7304" +"checksum jsonrpc-derive 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "8609af8f63b626e8e211f52441fcdb6ec54f1a446606b10d5c89ae9bf8a20058" +"checksum jsonrpc-http-server 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2d83d348120edee487c560b7cdd2565055d61cda053aa0d0ef0f8b6a18429048" +"checksum jsonrpc-pubsub 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3453625f0f0f5cd6d6776d389d73b7d70fcc98620b7cbb1cbbb1f6a36e95f39a" +"checksum jsonrpc-server-utils 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "95b7635e618a0edbbe0d2a2bbbc69874277c49383fcf6c3c0414491cfb517d22" +"checksum jsonrpc-ws-server 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b34faa167c3ac9705aeecb986c0da6056529f348425dbe0441db60a2c4cc41d1" "checksum keccak 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" "checksum keccak-hasher 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3468207deea1359a0e921591ae9b4c928733d94eb9d6a2eeda994cfd59f42cf8" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum kv-log-macro 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c54d9f465d530a752e6ebdc217e081a7a614b48cb200f6f0aee21ba6bc9aabb" -"checksum kvdb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)" = "" -"checksum kvdb-memorydb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)" = "" -"checksum kvdb-rocksdb 0.1.4 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)" = "" +"checksum kvdb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c1b2f251f01a7224426abdb2563707d856f7de995d821744fd8fa8e2874f69e3" +"checksum kvdb-memorydb 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "296c12309ed36cb74d59206406adbf1971c3baa56d5410efdb508d8f1c60a351" +"checksum kvdb-rocksdb 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d3f82177237c1ae67d6ab208a6f790cab569a1d81c1ba02348e0736a99510be3" "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" "checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" -"checksum libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)" = "1a31a0627fdf1f6a39ec0dd577e101440b7db22672c0901fe00a9a6fbb5c24e8" +"checksum libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)" = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558" "checksum libloading 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753" "checksum libp2p 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fab3090cd3af0f0ff5e6c2cc0f6fe6607e9f9282680cf7cd3bdd4cda38ea722" "checksum libp2p-core 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4a3def059145c191b6975e51784d5edc59e77e1ed5b25402fccac704dd7731f3" @@ -8235,35 +8322,36 @@ dependencies = [ "checksum libp2p-wasm-ext 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3f7b8f2bd81fb356e81352d4513856bc21215ecf91502aa1f55b6449642a9acf" "checksum libp2p-websocket 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0d74d4fc229ad7e8d1a973178786bdcd5dadbdd7b9822c4477c8687df6f82f66" "checksum libp2p-yamux 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1913eb7dd6eb5515957b6f1770296f6921968db87bc9b985f0e974b6657e1003" -"checksum librocksdb-sys 5.18.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d19778314deaa7048f2ea7d07b8aa12e1c227acebe975a37eeab6d2f8c74e41b" +"checksum librocksdb-sys 6.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0a0785e816e1e11e7599388a492c61ef80ddc2afc91e313e61662cce537809be" "checksum libsecp256k1 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2bd9a7c16c9487e710536b699c962f022266347c94201174aa0a7eb0546051aa" "checksum libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "2eb5e43362e38e2bca2fd5f5134c4d4564a23a5c28e9b95411652021a8675ebe" "checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83" "checksum linked_hash_set 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3c7c91c4c7bbeb4f2f7c4e5be11e6a05bd6830bc37249c47ce1ad86ad453ff9c" "checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c" "checksum lock_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed946d4529956a20f2d63ebe1b69996d5a2137c91913fe3ebbeff957f5bca7ff" -"checksum lock_api 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f8912e782533a93a167888781b836336a6ca5da6175c05944c86cf28c31104dc" +"checksum lock_api 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e57b3997725d2b60dbec1297f6c2e2957cc383db1cebd6be812163f969c7d586" "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" "checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" -"checksum lru 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "26b0dca4ac5b5083c5169ab12205e6473df1c7659940e4978b94f363c6b54b22" +"checksum lru 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "5d8f669d42c72d18514dfca8115689c5f6370a17d980cb5bd777a67f404594c8" +"checksum lru 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0609345ddee5badacf857d4f547e0e5a2e987db77085c24cd887f73573a04237" "checksum mach 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "86dd2487cdfea56def77b88438a2c915fb45113c5319bfe7e14306ca4cd0b0e1" "checksum malloc_size_of_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e37c5d4cd9473c5f4c9c111f033f15d4df9bd378fdf615944e360a4f55a05f0b" "checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" "checksum maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" "checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" "checksum memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9" -"checksum memory-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ef49315991403ba5fa225a70399df5e115f57b274cb0b1b4bcd6e734fa5bd783" +"checksum memory-db 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5dabfe0a8c69954ae3bcfc5fc14260a85fb80e1bf9f86a155f668d10a67e93dd" "checksum memory_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882" -"checksum merlin 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "de2d16d3b15fec5943d1144f861f61f279d165fdd60998ca262913b9bf1c8adb" +"checksum merlin 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2b0942b357c1b4d0dc43ba724674ec89c3218e6ca2b3e8269e7cb53bcecd2f6e" "checksum mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0" "checksum miniz_oxide 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6f3f74f726ae935c3f514300cc6773a0c9492abc5e972d42ba0c0ebb88757625" -"checksum mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)" = "83f51996a3ed004ef184e16818edc51fadffe8e7ca68be67f9dee67d84d0ff23" -"checksum mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "46e73a04c2fa6250b8d802134d56d554a9ec2922bf977777c805ea5def61ce40" +"checksum mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)" = "302dec22bcf6bae6dfb69c647187f4b4d0fb6f535521f7bc022430ce8e12008f" +"checksum mio-extras 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19" "checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" "checksum more-asserts 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0debeb9fcf88823ea64d64e4a815ab1643f33127d995978e099942ce38f25238" "checksum multimap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2eb04b9f127583ed176e163fb9ec6f3e793b87e21deedd5734a69386a18a0151" -"checksum multistream-select 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1242e4ecf2060b35fb58002988e4720fbb3a2cbd4c136d369c420fa028f69efe" +"checksum multistream-select 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fc3ef54aab1b2e37e911bcb99e376dbe4c1e0710afcdb8428608e4f993b39c47" "checksum names 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef320dab323286b50fb5cdda23f61c796a72a89998ab565ca32525c5c556f2da" "checksum native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4b2df1a4c22fd44a62147fd8f13dd0f95c9d8ca7b2610299b2a2f9cf8964274e" "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" @@ -8274,19 +8362,19 @@ dependencies = [ "checksum num-bigint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f9c3f34cdd24f334cb265d9bf8bfa8a241920d026916785747a92f0e55541a1a" "checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09" "checksum num-rational 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f2885278d5fe2adc2f75ced642d52d879bffaceb5a2e0b1d4309ffdfb239b454" -"checksum num-traits 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "443c53b3c3531dfcbfa499d8893944db78474ad7a1d87fa2d94d1a2231693ac6" +"checksum num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c81ffc11c212fa327657cb19dd85eb7419e163b5b076bede2bdb5c974c07e4" "checksum num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "76dac5ed2a876980778b8b85f75a71b6cbf0db0b1232ee12f826bccb00d09d72" "checksum ole32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d2c49021782e5233cd243168edfa8037574afed4eba4bbaf538b3d8d1789d8c" "checksum once_cell 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "532c29a261168a45ce28948f9537ddd7a5dd272cc513b3017b1e82a88f962c37" "checksum once_cell 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d584f08c2d717d5c23a6414fc2822b71c651560713e54fa7eace675f758a355e" "checksum once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "891f486f630e5c5a4916c7e16c4b24a53e78c860b646e9f8e005e4f16847bfed" "checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" -"checksum openssl 0.10.25 (registry+https://github.com/rust-lang/crates.io-index)" = "2f372b2b53ce10fb823a337aaa674e3a7d072b957c6264d0f4ff0bd86e657449" +"checksum openssl 0.10.26 (registry+https://github.com/rust-lang/crates.io-index)" = "3a3cc5799d98e1088141b8e01ff760112bbd9f19d850c124500566ca6901a585" "checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" -"checksum openssl-sys 0.9.52 (registry+https://github.com/rust-lang/crates.io-index)" = "c977d08e1312e2f7e4b86f9ebaa0ed3b19d1daff75fae88bbb88108afbd801fc" +"checksum openssl-sys 0.9.53 (registry+https://github.com/rust-lang/crates.io-index)" = "465d16ae7fc0e313318f7de5cecf57b2fbe7511fd213978b457e1c96ff46736f" "checksum output_vt100 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "53cdc5b785b7a58c5aad8216b3dfa114df64b0b06ae6e1501cef91df2fbdf8f9" "checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13" -"checksum parity-bytes 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)" = "" +"checksum parity-bytes 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0c276d76c5333b8c2579e02d49a06733a55b8282d2d9b13e8d53b6406bd7e30a" "checksum parity-multiaddr 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "045b3c7af871285146300da35b1932bb6e4639b66c7c98e85d06a32cbc4e8fa7" "checksum parity-multiaddr 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "82afcb7461eae5d122543d8be1c57d306ed89af2d6ff7f8b0f5a3cc8f7e511bc" "checksum parity-multihash 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "df3a17dc27848fd99e4f87eb0f8c9baba6ede0a6d555400c850ca45254ef4ce3" @@ -8296,13 +8384,10 @@ dependencies = [ "checksum parity-send-wrapper 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aa9777aa91b8ad9dd5aaa04a9b6bcb02c7f1deb952fca5a66034d5e63afc5c6f" "checksum parity-util-mem 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "570093f39f786beea92dcc09e45d8aae7841516ac19a50431953ac82a0e8f85c" "checksum parity-wasm 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "16ad52817c4d343339b3bc2e26861bd21478eda0b7509acf83505727000512ac" -"checksum parity-wasm 0.40.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1e39faaa292a687ea15120b1ac31899b13586446521df6c149e46f1584671e0f" "checksum parity-wasm 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc878dac00da22f8f61e7af3157988424567ab01d9920b962ef7dcbd7cd865" -"checksum parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5" "checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337" "checksum parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fa7767817701cce701d5585b9c4db3cdd02086398322c1d7e8bf5094a96a2ce7" "checksum parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252" -"checksum parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad7f7e6ebdc79edff6fdcb87a55b620174f7a989e3eb31b65231f4af57f00b8c" "checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9" "checksum parking_lot_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cb88cb1cb3790baa6776844f968fea3be44956cf184fa1be5a03341f5491278c" "checksum parking_lot_core 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b" @@ -8334,15 +8419,13 @@ dependencies = [ "checksum prost-derive 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5e7dc378b94ac374644181a2247cebf59a6ec1c88b49ac77f3a94b86b79d0e11" "checksum prost-types 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1de482a366941c8d56d19b650fac09ca08508f2a696119ee7513ad590c8bac6f" "checksum protobuf 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "40361836defdd5871ff7e84096c6f6444af7fc157f8ef1789f54f147687caa20" -"checksum pwasm-utils 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d473123ba135028544926f7aa6f34058d8bc6f120c4fcd3777f84af724280b3" +"checksum pwasm-utils 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4f7a12f176deee919f4ba55326ee17491c8b707d0987aed822682c821b660192" "checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" -"checksum quickcheck 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)" = "9c35d9c36a562f37eca96e79f66d5fd56eefbc22560dacc4a864cabd2d277456" "checksum quickcheck 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d5ca504a2fdaa08d3517f442fbbba91ac24d1ec4c51ea68688a038765e3b2662" "checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" "checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" "checksum rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)" = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c" "checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" -"checksum rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9" "checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" "checksum rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3ae1b169243eaf61759b8475a998f0a385e42042370f3a7dbaf35246eacc8412" "checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" @@ -8374,8 +8457,8 @@ dependencies = [ "checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e" "checksum ring 0.16.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6747f8da1f2b1fabbee1aaa4eb8a11abf9adef0bf58a41cee45db5d59cecdfac" "checksum rlp 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3a44d5ae8afcb238af8b75640907edc6c931efcfab2c854e81ed35fa080f84cd" -"checksum rocksdb 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f1651697fefd273bfb4fd69466cc2a9d20de557a0213b97233b22b5e95924b5e" -"checksum rpassword 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f072d931f11a96546efd97642e1e75e807345aced86b947f9239102f262d0fcd" +"checksum rocksdb 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "12069b106981c6103d3eab7dd1c86751482d0779a520b7c14954c8b586c1e643" +"checksum rpassword 4.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d59f0e97173c514b9036cd450c195a6483ba81055c6fa0f1bff3ab563f47d44a" "checksum rust-argon2 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4ca4eaef519b494d1f2848fc602d18816fed808a981aedf4f1f00ceb7c9d32cf" "checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" "checksum rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "403bb3a286107a04825a5f82e1270acc1e14028d3d554d7a1e08914549575ab8" @@ -8400,23 +8483,23 @@ dependencies = [ "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" "checksum send_wrapper 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a0eddf2e8f50ced781f288c19f18621fa72a3779e3cb58dbf23b07469b0abeb4" -"checksum serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4b39bd9b0b087684013a792c59e3e07a46a01d2322518d8a1104641a0b1be0" -"checksum serde_derive 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)" = "ca13fc1a832f793322228923fbb3aba9f3f44444898f835d31ad1b74fa0a2bf8" -"checksum serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)" = "2f72eb2a68a7dc3f9a691bfda9305a1c017a6215e5a4545c258500d2099a37c2" +"checksum serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)" = "1217f97ab8e8904b57dd22eb61cde455fa7446a9c1cf43966066da047c1f3702" +"checksum serde_derive 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)" = "a8c6faef9a2e64b0064f48570289b4bf8823b7581f1d6157c1b52152306651d0" +"checksum serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)" = "48c575e0cc52bdd09b47f330f646cf59afc586e9c4e3ccd6fc1f625b8ea1dad7" "checksum sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "23962131a91661d643c98940b20fcaffe62d776a823247be80a48fcb8b6fce68" "checksum sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" "checksum sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b4d8bfd0e469f417657573d8451fb33d16cfe0989359b93baf3a1ffc639543d" "checksum sha3 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd26bc0e7a2e3a7c959bc494caf58b72ee0c71d67704e9520f736ca7e4853ecf" "checksum shell32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9ee04b46101f57121c9da2b151988283b6beb79b34f5bb29a58ee48cb695122c" +"checksum shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2" "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" "checksum slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1cc9c640a4adbfbcc11ffb95efe5aa7af7309e002adab54b185507dbf2377b99" -"checksum slog-async 2.3.0 (git+https://github.com/paritytech/slog-async)" = "" "checksum slog-json 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ddc0d2aff1f8f325ef660d9a0eb6e6dcd20b30b3f581a5897f58bf42d061c37a" "checksum slog-scope 4.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c44c89dd8b0ae4537d1ae318353eaf7840b4869c536e31c41e963d1ea523ee6" -"checksum slog_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9eff3b513cf2e0d1a60e1aba152dc72bedc5b05585722bb3cebd7bcb1e31b98f" +"checksum slog_derive 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a945ec7f7ce853e89ffa36be1e27dce9a43e82ff9093bf3461c30d5da74ed11b" "checksum smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" "checksum smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ecf3b85f68e8abaa7555aa5abdb1153079387e60b718283d732f03897fcfc86" -"checksum snow 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "91eecae35b461ed26bda7a76bea2cc5bda2bf4b8dd06761879f19e6fdd50c2dd" +"checksum snow 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "afb767eee7d257ba202f0b9b08673bc13b22281632ef45267b19f13100accd2f" "checksum soketto 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bceb1a3a15232d013d9a3b7cac9e5ce8e2313f348f01d4bc1097e5e53aa07095" "checksum sourcefile 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4bf77cb82ba8453b42b6ae1d692e4cdc92f9a47beaf89a847c8be83f4e328ad3" "checksum spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" @@ -8426,27 +8509,26 @@ dependencies = [ "checksum string 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d24114bfcceb867ca7f71a0d3fe45d45619ec47a6fbfa98cb14e14250bfa5d6d" "checksum string-interner 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd710eadff449a1531351b0e43eb81ea404336fa2f56c777427ab0e32a4cf183" "checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" -"checksum structopt 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c167b61c7d4c126927f5346a4327ce20abf8a186b8041bbeb1ce49e5db49587b" -"checksum structopt-derive 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "519621841414165d2ad0d4c92be8f41844203f2b67e245f9345a5a12d40c69d7" -"checksum strum 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e5d1c33039533f051704951680f1adfd468fd37ac46816ded0d9ee068e60f05f" -"checksum strum_macros 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "47cd23f5c7dee395a00fa20135e2ec0fffcdfa151c56182966d7a3261343432e" +"checksum structopt 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "30b3a3e93f5ad553c38b3301c8a0a0cec829a36783f6a0c467fc4bf553a5f5bf" +"checksum structopt-derive 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea692d40005b3ceba90a9fe7a78fa8d4b82b0ce627eebbffc329aab850f3410e" +"checksum strum 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6138f8f88a16d90134763314e3fc76fa3ed6a7db4725d6acf9a3ef95a3188d22" +"checksum strum_macros 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0054a7df764039a6cd8592b9de84be4bec368ff081d203a7d5371cbfa8e65c81" "checksum substrate-bip39 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3be511be555a3633e71739a79e4ddff6a6aaa6579fa6114182a51d72c3eb93c5" "checksum subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" -"checksum subtle 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab3af2eb31c42e8f0ccf43548232556c42737e01a96db6e1777b0be108e79799" +"checksum subtle 2.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c65d530b10ccaeac294f349038a597e435b18fb456aadd0840a623f83b9e941" "checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" -"checksum syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "661641ea2aa15845cddeb97dad000d22070bb5c1fb456b96c1cba883ec691e92" +"checksum syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)" = "dff0acdb207ae2fe6d5976617f887eb1e35a2ba52c13c7234c790960cdad9238" "checksum synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" "checksum sysinfo 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)" = "6f4b2468c629cffba39c0a4425849ab3cdb03d9dfacba69684609aea04d08ff9" "checksum take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60" "checksum target-lexicon 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6f4c118a7a38378f305a9e111fcb2f7f838c0be324bfb31a77ea04f7f6e684b4" "checksum target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c63f48baada5c52e65a29eef93ab4f8982681b67f9e8d29c7b05abcfec2b9ffe" -"checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" "checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" "checksum termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "96d6098003bde162e4277c70665bd87c326f5a0c3f3fbfb285787fa482d54e6e" "checksum test-case 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a605baa797821796a751f4a959e1206079b24a4b7e1ed302b7d785d81a9276c9" "checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -"checksum thiserror 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "cc6b305ec0e323c7b6cfff6098a22516e0063d0bb7c3d88660a890217dca099a" -"checksum thiserror-impl 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45ba8d810d9c48fc456b7ad54574e8bfb7c7918a57ad7a6e6a0985d7959e8597" +"checksum thiserror 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6f357d1814b33bc2dc221243f8424104bfe72dbe911d5b71b3816a2dff1c977e" +"checksum thiserror-impl 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "eb2e25d25307eb8436894f727aba8f65d07adf02e5b35a13cebed48bd282bfef" "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" "checksum threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e2f0c90a5f3459330ac8bc0d2f879c693bb7a2f59689c1083fc4ef83834da865" "checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" @@ -8455,39 +8537,38 @@ dependencies = [ "checksum tiny-keccak 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2953ca5148619bc99695c1274cb54c5275bbb913c6adad87e72eaf8db9787f69" "checksum tinytemplate 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4574b75faccaacddb9b284faecdf0b544b80b6b294f3d062d325c5726a209c20" "checksum tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)" = "5a09c0b5bb588872ab2f09afa13ee6e9dac11e10a0ec9e8e3ba39a5a5d530af6" +"checksum tokio 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bcced6bb623d4bff3739c176c415f13c418f426395c169c9c3cd9a492c715b16" "checksum tokio-buf 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fb220f46c53859a4b7ec083e41dec9778ff0b1851c0942b211edb89e0ccdc46" "checksum tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5c501eceaf96f0e1793cf26beb63da3d11c738c4a943fdf3746d81d64684c39f" -"checksum tokio-codec 0.2.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9f5d22fd1e84bd4045d28813491cb7d7caae34d45c80517c2213f09a85e8787a" "checksum tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "d16217cad7f1b840c5a97dfb3c43b0c871fef423a6e8d2118c604e843662a443" "checksum tokio-dns-unofficial 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "82c65483db54eb91b4ef3a9389a3364558590faf30ce473141707c0e16fda975" -"checksum tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "0f27ee0e6db01c5f0b2973824547ce7e637b2ed79b891a9677b0de9bd532b6ac" +"checksum tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "ca6df436c42b0c3330a82d855d2ef017cd793090ad550a6bc2184f4b933532ab" "checksum tokio-executor 0.2.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9ee9ceecf69145923834ea73f32ba40c790fd877b74a7817dd0b089f1eb9c7c8" "checksum tokio-fs 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "3fe6dc22b08d6993916647d108a1a7d15b9cd29c4f4496c62b92c45b5041b7af" "checksum tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "5090db468dad16e1a7a54c8c67280c5e4b544f3d3e018f0b913b400261f85926" -"checksum tokio-io 0.2.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)" = "112784d5543df30660b04a72ca423bfbd90e8bb32f94dcf610f15401218b22c5" -"checksum tokio-reactor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "c56391be9805bc80163151c0b9e5164ee64f4b0200962c346fea12773158f22d" +"checksum tokio-reactor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "6732fe6b53c8d11178dcb77ac6d9682af27fc6d4cb87789449152e5377377146" "checksum tokio-rustls 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1df2fa53ac211c136832f530ccb081af9af891af22d685a9493e232c7a359bc2" "checksum tokio-sync 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "d06554cce1ae4a50f42fba8023918afa931413aded705b560e29600ccf7c6d76" "checksum tokio-sync 0.2.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4f1aaeb685540f7407ea0e27f1c9757d258c7c6bf4e3eb19da6fc59b747239d2" "checksum tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1d14b10654be682ac43efee27401d792507e30fd8d26389e1da3b185de2e4119" -"checksum tokio-threadpool 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "2bd2c6a3885302581f4401c82af70d792bb9df1700e7437b0aeb4ada94d5388c" -"checksum tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "f2106812d500ed25a4f38235b9cae8f78a09edf43203e16e59c3b769a342a60e" +"checksum tokio-threadpool 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "f0c32ffea4827978e9aa392d2f743d973c1dfa3730a2ed3f22ce1e6984da848c" +"checksum tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "1739638e364e558128461fc1ad84d997702c8e31c2e6b18fb99842268199e827" "checksum tokio-tls 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "354b8cd83825b3c20217a9dc174d6a0c67441a2fae5c41bcb1ea6679f6ae0f7c" "checksum tokio-udp 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f02298505547f73e60f568359ef0d016d5acd6e830ab9bc7c4a5b3403440121b" "checksum tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "037ffc3ba0e12a0ab4aca92e5234e0dedeb48fddf6ccd260f1f150a36a9f2445" +"checksum tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "571da51182ec208780505a32528fc5512a8fe1443ab960b3f2f3ef093cd16930" "checksum toml 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "01d1404644c8b12b16bfcffa4322403a91a451584daaaa7c28d3152e6cbc98cf" -"checksum tower-make 0.3.0-alpha.2a (registry+https://github.com/rust-lang/crates.io-index)" = "316d47dd40cde4ac5d88110eaf9a10a4e2a68612d9c056cd2aa24e37dcb484cd" -"checksum tower-service 0.3.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)" = "63ff37396cd966ce43bea418bfa339f802857495f797dafa00bea5b7221ebdfa" +"checksum tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e987b6bf443f4b5b3b6f38704195592cca41c5bb7aedd3c3693c7081f8289860" "checksum tracing 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ff4e4f59e752cb3beb5b61c6d5e11191c7946231ba84faec2902c9efdd8691c5" "checksum tracing-attributes 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a4263b12c3d3c403274493eb805966093b53214124796552d674ca1dd5d27c2b" "checksum tracing-core 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "bc913647c520c959b6d21e35ed8fa6984971deca9f0a2fcb8c51207e0c56af1d" "checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" -"checksum trie-bench 0.16.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d14da20d0549737c88299aee9e7b46098c30dd2af7cbca0518bdd420f3766191" +"checksum trie-bench 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "403d8ec7dbc4b46781ef18cd96b371bb9ce6ec394fe83ece75eb3bc755dfa69f" "checksum trie-db 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "784a9813d23f18bccab728ab039c39b8a87d0d6956dcdece39e92f5cffe5076e" "checksum trie-root 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0b779f7c1c8fe9276365d9d5be5c4b5adeacf545117bb3f64c974305789c5c0b" "checksum trie-standardmap 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3161ba520ab28cd8e6b68e1126f1009f6e335339d1a73b978139011703264c8" "checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" -"checksum trybuild 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)" = "e6851bf8351876984fbab8a2391de6378947b898410d8714edd12164d2137127" +"checksum trybuild 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "b75e31d624df08744532e935f1d4bfedd319a277d5a162c5b15f6ced59307575" "checksum twofish 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712d261e83e727c8e2dbb75dacac67c36e35db36a958ee504f2164fc052434e1" "checksum twox-hash 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3bfd5b7557925ce778ff9b9ef90e3ade34c524b5ff10e239c69a42d546d2af56" "checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887" @@ -8496,16 +8577,16 @@ dependencies = [ "checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33" "checksum unicase 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" -"checksum unicode-normalization 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "f0d98d53dfd9509a7c7f36fa8857b8f1fb699edbddd7dc2fb688db2ae5d0b2c1" +"checksum unicode-normalization 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b561e267b2326bb4cebfc0ef9e68355c7abe6c6f522aeac2f5bf95d56c59bdcf" "checksum unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" -"checksum unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7007dbd421b92cc6e28410fe7362e2e0a2503394908f417b68ec8d1c364c4e20" +"checksum unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" "checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" "checksum unsigned-varint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a7f0023a96687fe169081e8adce3f65e3874426b7886e9234d490af2dc077959" "checksum untrusted 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60369ef7a31de49bcb3f6ca728d4ba7300d9a1658f94c727d4cab8c8d9f4aece" "checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" "checksum url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75b414f6c464c879d7f9babf951f23bc3743fb7313c081b2e6ca719067ea9d61" -"checksum vcpkg 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "33dd455d0f96e90a75803cfeb7f948768c08d70a6de9a8d2362461935698bf95" +"checksum vcpkg 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3fc439f2794e98976c88a2a2dafce96b930fe8010b0a256b3c2199a773933168" "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" "checksum vergen 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6aba5e34f93dc7051dfad05b98a18e9156f27e7b431fe1d2398cb6061c0a1dba" "checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" @@ -8527,7 +8608,6 @@ dependencies = [ "checksum wasm-gc-api 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c32691b6c7e6c14e7f8fd55361a9088b507aa49620fcd06c09b3a1082186b9" "checksum wasm-timer 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "aa3e01d234bb71760e685cfafa5e2c96f8ad877c161a721646356651069e26ac" "checksum wasmi 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bf617d864d25af3587aa745529f7aaa541066c876d57e050c0d0c85c61c92aff" -"checksum wasmi-validation 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6bc0356e3df56e639fc7f7d8a99741915531e27ed735d911ed83d7e1339c8188" "checksum wasmi-validation 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ea78c597064ba73596099281e2f4cfc019075122a65cdda3205af94f0b264d93" "checksum wasmparser 0.39.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c702914acda5feeeffbc29e4d953e5b9ce79d8b98da4dbf18a77086e116c5470" "checksum wasmtime-debug 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5008729ad53f75020f28fa0d682269335d6f0eac0b3ffafe31f185b2f33aca74" @@ -8538,7 +8618,8 @@ dependencies = [ "checksum webpki 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d7e664e770ac0110e2384769bcc59ed19e329d81f555916a6e072714957b81b4" "checksum webpki-roots 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a262ae37dd9d60f60dd473d1158f9fbebf110ba7b6a5051c8160460f6043718b" "checksum webpki-roots 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)" = "91cd5736df7f12a964a5067a12c62fa38e1bd8080aff1f80bc29be7c80d19ab4" -"checksum websocket 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b255b190f412e45000c35be7fe9b48b39a2ac5eb90d093d421694e5dae8b335c" +"checksum websocket 0.24.0 (registry+https://github.com/rust-lang/crates.io-index)" = "413b37840b9e27b340ce91b319ede10731de8c72f5bc4cb0206ec1ca4ce581d0" +"checksum websocket-base 0.24.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5e3810f0d00c4dccb54c30a4eee815e703232819dec7b007db115791c42aa374" "checksum weedle 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3bb43f70885151e629e2a19ce9e50bd730fd436cfd4b666894c9ce4de9141164" "checksum which 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b57acb10231b9493c8472b20cb57317d0679a49e0bdbee44b3b803a6473af164" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" @@ -8554,7 +8635,8 @@ dependencies = [ "checksum xdg 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57" "checksum yamux 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2758f29014c1cb7a6e74c1b1160ac8c8203be342d35b73462fc6a13cc6385423" "checksum zeroize 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "45af6a010d13e4cf5b54c94ba5a2b2eba5596b9e46bf5875612d332a1f2b3f86" -"checksum zeroize 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cdc979d9b5ead18184c357c4d8a3f81b579aae264e32507223032e64715462d3" +"checksum zeroize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3cbac2ed2ba24cc90f5e06485ac8c7c1e5449fe8911aef4d8877218af021a5b8" +"checksum zeroize_derive 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de251eec69fc7c1bc3923403d18ececb929380e016afe103da75f396704f8ca2" "checksum zstd 0.5.1+zstd.1.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5c5d978b793ae64375b80baf652919b148f6a496ac8802922d9999f5a553194f" "checksum zstd-safe 2.0.3+zstd.1.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bee25eac9753cfedd48133fa1736cbd23b774e253d89badbeac7d12b23848d3f" "checksum zstd-sys 1.4.15+zstd.1.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "89719b034dc22d240d5b407fb0a3fe6d29952c181cff9a9f95c0bd40b4f8f7d8" diff --git a/Cargo.toml b/Cargo.toml index d398fd78b28b69c74f62a0e6723316213aff7609..4aabe5916f4117357330652ecd8741b8c94050c6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,9 @@ members = [ "bin/node/rpc", "bin/node/runtime", "bin/node/testing", - "bin/subkey", + "bin/node/transaction-factory", + "bin/utils/subkey", + "bin/utils/chain-spec-builder", "client", "client/api", "client/authority-discovery", @@ -27,23 +29,25 @@ members = [ "client/executor", "client/executor/runtime-test", "client/finality-grandpa", - "client/header-metadata", "client/tracing", "client/keystore", "client/network", + "client/network/test", + "client/network-gossip", "client/offchain", + "client/peerset", "client/rpc-servers", "client/rpc", - "client/rpc/api", + "client/rpc-api", "client/service", "client/service/test", "client/state-db", "client/telemetry", "client/transaction-pool", "client/transaction-pool/graph", - "client/utils/wasm-builder-runner", - "client/grafana-data-source", - "client/grafana-data-source/test", + "utils/wasm-builder-runner", + "utils/grafana-data-source", + "utils/grafana-data-source/test", "frame/assets", "frame/aura", "frame/authority-discovery", @@ -63,6 +67,7 @@ members = [ "frame/finality-tracker", "frame/generic-asset", "frame/grandpa", + "frame/identity", "frame/im-online", "frame/indices", "frame/membership", @@ -79,10 +84,8 @@ members = [ "frame/support/procedural", "frame/support/procedural/tools", "frame/support/procedural/tools/derive", - "frame/support/rpc", "frame/support/test", "frame/system", - "frame/system/rpc", "frame/system/rpc/runtime-api", "frame/timestamp", "frame/transaction-payment", @@ -91,16 +94,18 @@ members = [ "frame/treasury", "frame/utility", "primitives/application-crypto", + "primitives/application-crypto/test", "primitives/authority-discovery", "primitives/authorship", - "primitives/block-builder/runtime-api", + "primitives/block-builder", + "primitives/blockchain", "primitives/consensus/aura", "primitives/consensus/babe", "primitives/consensus/common", "primitives/consensus/pow", "primitives/core", - "primitives/core/debug-derive", - "primitives/core/storage", + "primitives/debug-derive", + "primitives/storage", "primitives/externalities", "primitives/finality-tracker", "primitives/finality-grandpa", @@ -108,37 +113,37 @@ members = [ "primitives/keyring", "primitives/offchain", "primitives/panic-handler", - "primitives/peerset", "primitives/phragmen", "primitives/rpc", "primitives/runtime-interface", "primitives/runtime-interface/proc-macro", "primitives/runtime-interface/test-wasm", + "primitives/runtime-interface/test", "primitives/serializer", "primitives/session", - "primitives/sr-api", - "primitives/sr-api/proc-macro", - "primitives/sr-api/test", - "primitives/sr-arithmetic", - "primitives/sr-io", - "primitives/sr-primitives", - "primitives/sr-sandbox", - "primitives/sr-staking-primitives", - "primitives/sr-std", - "primitives/sr-version", + "primitives/api", + "primitives/api/proc-macro", + "primitives/api/test", + "primitives/arithmetic", + "primitives/io", + "primitives/runtime", + "primitives/sandbox", + "primitives/staking", + "primitives/std", + "primitives/version", "primitives/state-machine", "primitives/timestamp", - "primitives/transaction-pool/runtime-api", + "primitives/test-primitives", + "primitives/transaction-pool", "primitives/trie", "primitives/wasm-interface", - "test/utils/chain-spec-builder", - "test/utils/client", - "test/utils/primitives", - "test/utils/runtime", - "test/utils/runtime/client", - "test/utils/transaction-factory", + "test-utils/client", + "test-utils/runtime", + "test-utils/runtime/client", "utils/build-script-utils", "utils/fork-tree", + "utils/frame/rpc/support", + "utils/frame/rpc/system", "utils/wasm-builder", ] diff --git a/bin/node-template/Cargo.toml b/bin/node-template/Cargo.toml index ff393730761bb5326f80cc2b1c06c730627bb4dc..aaaae647cf564767fdbcc6c218cd15d08104a0dc 100644 --- a/bin/node-template/Cargo.toml +++ b/bin/node-template/Cargo.toml @@ -10,7 +10,6 @@ name = "node-template" path = "src/main.rs" [dependencies] -derive_more = "0.15.0" futures = "0.3.1" futures01 = { package = "futures", version = "0.1.29" } ctrlc = { version = "3.1.3", features = ["termination"] } @@ -19,23 +18,25 @@ tokio = "0.1.22" parking_lot = "0.9.0" codec = { package = "parity-scale-codec", version = "1.0.0" } trie-root = "0.15.2" -sr-io = { path = "../../primitives/sr-io" } -substrate-cli = { path = "../../client/cli" } -primitives = { package = "substrate-primitives", path = "../../primitives/core" } -substrate-executor = { path = "../../client/executor" } -substrate-service = { path = "../../client/service" } -inherents = { package = "substrate-inherents", path = "../../primitives/inherents" } -transaction-pool = { package = "substrate-transaction-pool", path = "../../client/transaction-pool" } -network = { package = "substrate-network", path = "../../client/network" } -aura = { package = "substrate-consensus-aura", path = "../../client/consensus/aura" } -aura-primitives = { package = "substrate-consensus-aura-primitives", path = "../../primitives/consensus/aura" } -grandpa = { package = "substrate-finality-grandpa", path = "../../client/finality-grandpa" } -grandpa-primitives = { package = "substrate-finality-grandpa-primitives", path = "../../primitives/finality-grandpa" } -substrate-client = { path = "../../client/" } -runtime = { package = "node-template-runtime", path = "runtime" } -sr-primitives = { path = "../../primitives/sr-primitives" } -basic-authorship = { package = "substrate-basic-authorship", path = "../../client/basic-authorship"} +sp-io = { version = "2.0.0", path = "../../primitives/io" } +sc-cli = { version = "2.0.0", path = "../../client/cli" } +sp-core = { version = "2.0.0", path = "../../primitives/core" } +sc-executor = { version = "2.0.0", path = "../../client/executor" } +sc-service = { version = "2.0.0", path = "../../client/service" } +sp-inherents = { version = "2.0.0", path = "../../primitives/inherents" } +sc-transaction-pool = { version = "2.0.0", path = "../../client/transaction-pool" } +sp-transaction-pool = { version = "2.0.0", path = "../../primitives/transaction-pool" } +sc-network = { version = "0.8", path = "../../client/network" } +sc-consensus-aura = { version = "0.8", path = "../../client/consensus/aura" } +sp-consensus-aura = { version = "0.8", path = "../../primitives/consensus/aura" } +sp-consensus = { version = "0.8", path = "../../primitives/consensus/common" } +grandpa = { version = "2.0.0", package = "sc-finality-grandpa", path = "../../client/finality-grandpa" } +grandpa-primitives = { version = "2.0.0", package = "sp-finality-grandpa", path = "../../primitives/finality-grandpa" } +sc-client = { version = "2.0.0", path = "../../client/" } +node-template-runtime = { version = "2.0.0", path = "runtime" } +sp-runtime = { version = "2.0.0", path = "../../primitives/runtime" } +sc-basic-authority = { path = "../../client/basic-authorship" } [build-dependencies] vergen = "3.0.4" -build-script-utils = { package = "substrate-build-script-utils", path = "../../utils/build-script-utils" } +build-script-utils = { version = "2.0.0", package = "substrate-build-script-utils", path = "../../utils/build-script-utils" } diff --git a/bin/node-template/runtime/Cargo.toml b/bin/node-template/runtime/Cargo.toml index f71c238d4c524671f3e3b0e879c82dce472a94a0..b61ad25f466a45cf158ff7f1494d60df1c809040 100644 --- a/bin/node-template/runtime/Cargo.toml +++ b/bin/node-template/runtime/Cargo.toml @@ -5,63 +5,64 @@ authors = ["Anonymous"] edition = "2018" [dependencies] -aura = { package = "pallet-aura", path = "../../../frame/aura", default-features = false } -aura-primitives = { package = "substrate-consensus-aura-primitives", path = "../../../primitives/consensus/aura", default-features = false } -balances = { package = "pallet-balances", path = "../../../frame/balances", default-features = false } -block-builder-api = { package = "substrate-block-builder-runtime-api", path = "../../../primitives/block-builder/runtime-api", default-features = false} +aura = { version = "2.0.0", default-features = false, package = "pallet-aura", path = "../../../frame/aura" } +balances = { version = "2.0.0", default-features = false, package = "pallet-balances", path = "../../../frame/balances" } +frame-support = { version = "2.0.0", default-features = false, path = "../../../frame/support" } +grandpa = { version = "2.0.0", default-features = false, package = "pallet-grandpa", path = "../../../frame/grandpa" } +indices = { version = "2.0.0", default-features = false, package = "pallet-indices", path = "../../../frame/indices" } +randomness-collective-flip = { version = "2.0.0", default-features = false, package = "pallet-randomness-collective-flip", path = "../../../frame/randomness-collective-flip" } +sudo = { version = "2.0.0", default-features = false, package = "pallet-sudo", path = "../../../frame/sudo" } +system = { version = "2.0.0", default-features = false, package = "frame-system", path = "../../../frame/system" } +timestamp = { version = "2.0.0", default-features = false, package = "pallet-timestamp", path = "../../../frame/timestamp" } +transaction-payment = { version = "2.0.0", default-features = false, package = "pallet-transaction-payment", path = "../../../frame/transaction-payment" } + codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -executive = { package = "frame-executive", path = "../../../frame/executive", default-features = false } -grandpa = { package = "pallet-grandpa", path = "../../../frame/grandpa", default-features = false } -indices = { package = "pallet-indices", path = "../../../frame/indices", default-features = false } -inherents = { package = "substrate-inherents", path = "../../../primitives/inherents", default-features = false} -offchain-primitives = { package = "substrate-offchain-primitives", path = "../../../primitives/offchain", default-features = false } -primitives = { package = "substrate-primitives", path = "../../../primitives/core", default-features = false } -randomness-collective-flip = { package = "pallet-randomness-collective-flip", path = "../../../frame/randomness-collective-flip", default-features = false } -rstd = { package = "sr-std", path = "../../../primitives/sr-std", default-features = false } -runtime-io = { package = "sr-io", path = "../../../primitives/sr-io", default-features = false } +frame-executive = { version = "2.0.0", default-features = false, path = "../../../frame/executive" } safe-mix = { version = "1.0.0", default-features = false } serde = { version = "1.0.101", optional = true, features = ["derive"] } -sr-api = { path = "../../../primitives/sr-api", default-features = false } -sr-primitives = { path = "../../../primitives/sr-primitives", default-features = false } -substrate-session = { path = "../../../primitives/session", default-features = false } -sudo = { package = "pallet-sudo", path = "../../../frame/sudo", default-features = false } -support = { package = "frame-support", path = "../../../frame/support", default-features = false } -system = { package = "frame-system", path = "../../../frame/system", default-features = false } -timestamp = { package = "pallet-timestamp", path = "../../../frame/timestamp", default-features = false } -transaction-payment = { package = "pallet-transaction-payment", path = "../../../frame/transaction-payment", default-features = false } -tx-pool-api = { package = "substrate-transaction-pool-runtime-api", path = "../../../primitives/transaction-pool/runtime-api", default-features = false } -version = { package = "sr-version", path = "../../../primitives/sr-version", default-features = false } +sp-api = { version = "2.0.0", default-features = false, path = "../../../primitives/api" } +sp-block-builder = { path = "../../../primitives/block-builder", default-features = false} +sp-consensus-aura = { version = "0.8", default-features = false, path = "../../../primitives/consensus/aura" } +sp-core = { version = "2.0.0", default-features = false, path = "../../../primitives/core" } +sp-inherents = { path = "../../../primitives/inherents", default-features = false} +sp-io = { version = "2.0.0", default-features = false, path = "../../../primitives/io" } +sp-offchain = { version = "2.0.0", default-features = false, path = "../../../primitives/offchain" } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../../primitives/runtime" } +sp-session = { version = "2.0.0", default-features = false, path = "../../../primitives/session" } +sp-std = { version = "2.0.0", default-features = false, path = "../../../primitives/std" } +sp-transaction-pool = { version = "2.0.0", default-features = false, path = "../../../primitives/transaction-pool" } +sp-version = { version = "2.0.0", default-features = false, path = "../../../primitives/version" } [build-dependencies] -wasm-builder-runner = { package = "substrate-wasm-builder-runner", path = "../../../client/utils/wasm-builder-runner", version = "1.0.4" } +wasm-builder-runner = { version = "1.0.4", package = "substrate-wasm-builder-runner", path = "../../../utils/wasm-builder-runner" } [features] default = ["std"] std = [ - "aura-primitives/std", "aura/std", "balances/std", - "block-builder-api/std", "codec/std", - "executive/std", + "frame-executive/std", + "frame-support/std", "grandpa/std", "indices/std", - "inherents/std", - "offchain-primitives/std", - "primitives/std", "randomness-collective-flip/std", - "rstd/std", - "runtime-io/std", "safe-mix/std", "serde", - "sr-api/std", - "sr-primitives/std", - "substrate-session/std", + "sp-api/std", + "sp-block-builder/std", + "sp-consensus-aura/std", + "sp-core/std", + "sp-inherents/std", + "sp-io/std", + "sp-offchain/std", + "sp-runtime/std", + "sp-session/std", + "sp-std/std", + "sp-transaction-pool/std", + "sp-version/std", "sudo/std", - "support/std", "system/std", "timestamp/std", "transaction-payment/std", - "tx-pool-api/std", - "version/std", ] diff --git a/bin/node-template/runtime/src/lib.rs b/bin/node-template/runtime/src/lib.rs index 170874bfcbd54ae5a4f76412ce6924d93d3de16e..60d8b7485d503865fb15d0e32ddcc02c98ae4119 100644 --- a/bin/node-template/runtime/src/lib.rs +++ b/bin/node-template/runtime/src/lib.rs @@ -8,30 +8,30 @@ #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); -use rstd::prelude::*; -use primitives::OpaqueMetadata; -use sr_primitives::{ +use sp_std::prelude::*; +use sp_core::OpaqueMetadata; +use sp_runtime::{ ApplyExtrinsicResult, transaction_validity::TransactionValidity, generic, create_runtime_str, impl_opaque_keys, MultiSignature }; -use sr_primitives::traits::{ +use sp_runtime::traits::{ NumberFor, BlakeTwo256, Block as BlockT, StaticLookup, Verify, ConvertInto, IdentifyAccount }; -use sr_api::impl_runtime_apis; -use aura_primitives::sr25519::AuthorityId as AuraId; +use sp_api::impl_runtime_apis; +use sp_consensus_aura::sr25519::AuthorityId as AuraId; use grandpa::AuthorityList as GrandpaAuthorityList; use grandpa::fg_primitives; -use version::RuntimeVersion; +use sp_version::RuntimeVersion; #[cfg(feature = "std")] -use version::NativeVersion; +use sp_version::NativeVersion; // A few exports that help ease life for downstream crates. #[cfg(any(feature = "std", test))] -pub use sr_primitives::BuildStorage; +pub use sp_runtime::BuildStorage; pub use timestamp::Call as TimestampCall; pub use balances::Call as BalancesCall; -pub use sr_primitives::{Permill, Perbill}; -pub use support::{ +pub use sp_runtime::{Permill, Perbill}; +pub use frame_support::{ StorageValue, construct_runtime, parameter_types, traits::Randomness, weights::Weight, @@ -58,7 +58,7 @@ pub type Balance = u128; pub type Index = u32; /// A hash of some data used by the chain. -pub type Hash = primitives::H256; +pub type Hash = sp_core::H256; /// Digest item type. pub type DigestItem = generic::DigestItem; @@ -73,7 +73,7 @@ mod template; pub mod opaque { use super::*; - pub use sr_primitives::OpaqueExtrinsic as UncheckedExtrinsic; + pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic; /// Opaque block header type. pub type Header = generic::Header; @@ -157,6 +157,10 @@ impl system::Trait for Runtime { type AvailableBlockRatio = AvailableBlockRatio; /// 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 ModuleToIndex = ModuleToIndex; } impl aura::Trait for Runtime { @@ -246,7 +250,7 @@ construct_runtime!( Timestamp: timestamp::{Module, Call, Storage, Inherent}, Aura: aura::{Module, Config, Inherent(Timestamp)}, Grandpa: grandpa::{Module, Call, Storage, Config, Event}, - Indices: indices::{default, Config}, + Indices: indices, Balances: balances::{default, Error}, TransactionPayment: transaction_payment::{Module, Storage}, Sudo: sudo, @@ -280,10 +284,10 @@ pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; /// Executive: handles dispatch to the various modules. -pub type Executive = executive::Executive, Runtime, AllModules>; +pub type Executive = frame_executive::Executive, Runtime, AllModules>; impl_runtime_apis! { - impl sr_api::Core for Runtime { + impl sp_api::Core for Runtime { fn version() -> RuntimeVersion { VERSION } @@ -297,13 +301,13 @@ impl_runtime_apis! { } } - impl sr_api::Metadata for Runtime { + impl sp_api::Metadata for Runtime { fn metadata() -> OpaqueMetadata { Runtime::metadata().into() } } - impl block_builder_api::BlockBuilder for Runtime { + impl sp_block_builder::BlockBuilder for Runtime { fn apply_extrinsic(extrinsic: ::Extrinsic) -> ApplyExtrinsicResult { Executive::apply_extrinsic(extrinsic) } @@ -312,14 +316,14 @@ impl_runtime_apis! { Executive::finalize_block() } - fn inherent_extrinsics(data: inherents::InherentData) -> Vec<::Extrinsic> { + fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<::Extrinsic> { data.create_extrinsics() } fn check_inherents( block: Block, - data: inherents::InherentData, - ) -> inherents::CheckInherentsResult { + data: sp_inherents::InherentData, + ) -> sp_inherents::CheckInherentsResult { data.check_extrinsics(&block) } @@ -328,19 +332,19 @@ impl_runtime_apis! { } } - impl tx_pool_api::TaggedTransactionQueue for Runtime { + impl sp_transaction_pool::runtime_api::TaggedTransactionQueue for Runtime { fn validate_transaction(tx: ::Extrinsic) -> TransactionValidity { Executive::validate_transaction(tx) } } - impl offchain_primitives::OffchainWorkerApi for Runtime { + impl sp_offchain::OffchainWorkerApi for Runtime { fn offchain_worker(number: NumberFor) { Executive::offchain_worker(number) } } - impl aura_primitives::AuraApi for Runtime { + impl sp_consensus_aura::AuraApi for Runtime { fn slot_duration() -> u64 { Aura::slot_duration() } @@ -350,7 +354,7 @@ impl_runtime_apis! { } } - impl substrate_session::SessionKeys for Runtime { + impl sp_session::SessionKeys for Runtime { fn generate_session_keys(seed: Option>) -> Vec { opaque::SessionKeys::generate(seed) } diff --git a/bin/node-template/runtime/src/template.rs b/bin/node-template/runtime/src/template.rs index 33f0b6af7ebe0c5f4d8426c5f41329ac7fb3b81d..a64a4c3216fe6b408181fc20c22255764beff8fd 100644 --- a/bin/node-template/runtime/src/template.rs +++ b/bin/node-template/runtime/src/template.rs @@ -8,7 +8,7 @@ /// For more guidance on Substrate modules, see the example module /// https://github.com/paritytech/substrate/blob/master/frame/example/src/lib.rs -use support::{decl_module, decl_storage, decl_event, dispatch::Result}; +use frame_support::{decl_module, decl_storage, decl_event, dispatch}; use system::ensure_signed; /// The module's configuration trait. @@ -40,7 +40,7 @@ decl_module! { // Just a dummy entry point. // function that can be called by the external world as an extrinsics call // takes a parameter of the type `AccountId`, stores it and emits an event - pub fn do_something(origin, something: u32) -> Result { + pub fn do_something(origin, something: u32) -> dispatch::DispatchResult { // TODO: You only need this if you want to check it was signed. let who = ensure_signed(origin)?; @@ -69,9 +69,9 @@ decl_event!( mod tests { use super::*; - use primitives::H256; - use support::{impl_outer_origin, assert_ok, parameter_types, weights::Weight}; - use sr_primitives::{ + use sp_core::H256; + use frame_support::{impl_outer_origin, assert_ok, parameter_types, weights::Weight}; + use sp_runtime::{ traits::{BlakeTwo256, IdentityLookup}, testing::Header, Perbill, }; @@ -106,6 +106,7 @@ mod tests { type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); + type ModuleToIndex = (); } impl Trait for Test { type Event = (); @@ -114,7 +115,7 @@ mod tests { // This function basically just builds a genesis storage key/value store according to // our desired mockup. - fn new_test_ext() -> runtime_io::TestExternalities { + fn new_test_ext() -> sp_io::TestExternalities { system::GenesisConfig::default().build_storage::().unwrap().into() } diff --git a/bin/node-template/src/chain_spec.rs b/bin/node-template/src/chain_spec.rs index 8d43e67304c795b510777e3de154d75513f16eb1..fae9feaf5113b04aab3d52def1353295fe31e3d6 100644 --- a/bin/node-template/src/chain_spec.rs +++ b/bin/node-template/src/chain_spec.rs @@ -1,18 +1,18 @@ -use primitives::{Pair, Public, sr25519}; -use runtime::{ +use sp_core::{Pair, Public, sr25519}; +use node_template_runtime::{ AccountId, AuraConfig, BalancesConfig, GenesisConfig, GrandpaConfig, SudoConfig, IndicesConfig, SystemConfig, WASM_BINARY, Signature }; -use aura_primitives::sr25519::{AuthorityId as AuraId}; +use sp_consensus_aura::sr25519::{AuthorityId as AuraId}; use grandpa_primitives::{AuthorityId as GrandpaId}; -use substrate_service; -use sr_primitives::traits::{Verify, IdentifyAccount}; +use sc_service; +use sp_runtime::traits::{Verify, IdentifyAccount}; // 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 = substrate_service::ChainSpec; +pub type ChainSpec = sc_service::ChainSpec; /// The chain specification option. This is expected to come in from the CLI and /// is little more than one of a number of alternatives which can easily be converted diff --git a/bin/node-template/src/cli.rs b/bin/node-template/src/cli.rs index 1171a906549357fc2e9373b9a9c026edaeee1c5b..16638c4af955d5481662141a132088f6610c7edb 100644 --- a/bin/node-template/src/cli.rs +++ b/bin/node-template/src/cli.rs @@ -2,10 +2,10 @@ use crate::service; use futures::{future::{select, Map}, FutureExt, TryFutureExt, channel::oneshot, compat::Future01CompatExt}; use std::cell::RefCell; use tokio::runtime::Runtime; -pub use substrate_cli::{VersionInfo, IntoExit, error}; -use substrate_cli::{display_role, informant, parse_and_prepare, ParseAndPrepare, NoCustom}; -use substrate_service::{AbstractService, Roles as ServiceRoles, Configuration}; -use aura_primitives::sr25519::{AuthorityPair as AuraPair}; +pub use sc_cli::{VersionInfo, IntoExit, error}; +use sc_cli::{display_role, informant, parse_and_prepare, ParseAndPrepare, NoCustom}; +use sc_service::{AbstractService, Roles as ServiceRoles, Configuration}; +use sp_consensus_aura::sr25519::{AuthorityPair as AuraPair}; use crate::chain_spec; use log::info; @@ -44,6 +44,8 @@ pub fn run(args: I, exit: E, version: VersionInfo) -> error::Result<()> Ok(new_full_start!(config).0), load_spec, exit), ParseAndPrepare::ImportBlocks(cmd) => cmd.run_with_builder(|config: Config<_>| Ok(new_full_start!(config).0), load_spec, exit), + ParseAndPrepare::CheckBlock(cmd) => cmd.run_with_builder(|config: Config<_>| + Ok(new_full_start!(config).0), load_spec, exit), ParseAndPrepare::PurgeChain(cmd) => cmd.run(load_spec), ParseAndPrepare::RevertChain(cmd) => cmd.run_with_builder(|config: Config<_>| Ok(new_full_start!(config).0), load_spec), diff --git a/bin/node-template/src/main.rs b/bin/node-template/src/main.rs index 1f286a2237548dfc84a9c9ccce7c9f78a3eb38d4..2942bb68a37aac14bbef3e85fa5d340bb15f7d48 100644 --- a/bin/node-template/src/main.rs +++ b/bin/node-template/src/main.rs @@ -8,7 +8,7 @@ mod chain_spec; mod service; mod cli; -pub use substrate_cli::{VersionInfo, IntoExit, error}; +pub use sc_cli::{VersionInfo, IntoExit, error}; fn main() -> Result<(), cli::error::Error> { let version = VersionInfo { diff --git a/bin/node-template/src/service.rs b/bin/node-template/src/service.rs index ad517d956b4c72482d75d17a8aeff19bfe7d58e7..e1379d2200354becdb62adce9e7e9c97a11acf24 100644 --- a/bin/node-template/src/service.rs +++ b/bin/node-template/src/service.rs @@ -2,23 +2,22 @@ use std::sync::Arc; use std::time::Duration; -use substrate_client::LongestChain; -use runtime::{self, GenesisConfig, opaque::Block, RuntimeApi}; -use substrate_service::{error::{Error as ServiceError}, AbstractService, Configuration, ServiceBuilder}; -use transaction_pool::{self, txpool::{Pool as TransactionPool}}; -use inherents::InherentDataProviders; -use network::{construct_simple_protocol}; -use substrate_executor::native_executor_instance; -pub use substrate_executor::NativeExecutor; -use aura_primitives::sr25519::{AuthorityPair as AuraPair}; +use sc_client::LongestChain; +use node_template_runtime::{self, GenesisConfig, opaque::Block, RuntimeApi}; +use sc_service::{error::{Error as ServiceError}, AbstractService, Configuration, ServiceBuilder}; +use sp_inherents::InherentDataProviders; +use sc_network::{construct_simple_protocol}; +use sc_executor::native_executor_instance; +pub use sc_executor::NativeExecutor; +use sp_consensus_aura::sr25519::{AuthorityPair as AuraPair}; use grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider}; -use basic_authorship; +use sc_basic_authority; // Our native executor instance. native_executor_instance!( pub Executor, - runtime::api::dispatch, - runtime::native_version, + node_template_runtime::api::dispatch, + node_template_runtime::native_version, ); construct_simple_protocol! { @@ -33,28 +32,32 @@ construct_simple_protocol! { macro_rules! new_full_start { ($config:expr) => {{ let mut import_setup = None; - let inherent_data_providers = inherents::InherentDataProviders::new(); + let inherent_data_providers = sp_inherents::InherentDataProviders::new(); - let builder = substrate_service::ServiceBuilder::new_full::< - runtime::opaque::Block, runtime::RuntimeApi, crate::service::Executor + let builder = sc_service::ServiceBuilder::new_full::< + node_template_runtime::opaque::Block, node_template_runtime::RuntimeApi, crate::service::Executor >($config)? .with_select_chain(|_config, backend| { - Ok(substrate_client::LongestChain::new(backend.clone())) + Ok(sc_client::LongestChain::new(backend.clone())) + })? + .with_transaction_pool(|config, client, _fetcher| { + let pool_api = sc_transaction_pool::FullChainApi::new(client.clone()); + let pool = sc_transaction_pool::BasicPool::new(config, pool_api); + let maintainer = sc_transaction_pool::FullBasicPoolMaintainer::new(pool.pool().clone(), client); + let maintainable_pool = sp_transaction_pool::MaintainableTransactionPool::new(pool, maintainer); + Ok(maintainable_pool) })? - .with_transaction_pool(|config, client| - Ok(transaction_pool::txpool::Pool::new(config, transaction_pool::FullChainApi::new(client))) - )? .with_import_queue(|_config, client, mut select_chain, transaction_pool| { let select_chain = select_chain.take() - .ok_or_else(|| substrate_service::Error::SelectChainRequired)?; + .ok_or_else(|| sc_service::Error::SelectChainRequired)?; let (grandpa_block_import, grandpa_link) = - grandpa::block_import::<_, _, _, runtime::RuntimeApi, _>( + grandpa::block_import::<_, _, _, node_template_runtime::RuntimeApi, _>( client.clone(), &*client, select_chain )?; - let import_queue = aura::import_queue::<_, _, AuraPair, _>( - aura::SlotDuration::get_or_compute(&*client)?, + let import_queue = sc_consensus_aura::import_queue::<_, _, AuraPair, _>( + sc_consensus_aura::SlotDuration::get_or_compute(&*client)?, Box::new(grandpa_block_import.clone()), Some(Box::new(grandpa_block_import.clone())), None, @@ -99,7 +102,7 @@ pub fn new_full(config: Configuration(config: Configuration( - aura::SlotDuration::get_or_compute(&*client)?, + let can_author_with = + sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone()); + + let aura = sc_consensus_aura::start_aura::<_, _, _, _, _, AuraPair, _, _, _, _>( + sc_consensus_aura::SlotDuration::get_or_compute(&*client)?, client, select_chain, block_import, @@ -118,6 +124,7 @@ pub fn new_full(config: Configuration(config: Configuration { @@ -163,6 +171,7 @@ pub fn new_full(config: Configuration(config: Configuration(config: Configuration( - aura::SlotDuration::get_or_compute(&*client)?, + let import_queue = sc_consensus_aura::import_queue::<_, _, AuraPair, ()>( + sc_consensus_aura::SlotDuration::get_or_compute(&*client)?, Box::new(grandpa_block_import), None, Some(Box::new(finality_proof_import)), diff --git a/bin/node/cli/Cargo.toml b/bin/node/cli/Cargo.toml index b6bc00c90c0f8ad0108b413626a491b9cff67991..0ce5115831a287c2b04d94db8b0f5ff6e2dfb7ea 100644 --- a/bin/node/cli/Cargo.toml +++ b/bin/node/cli/Cargo.toml @@ -24,7 +24,7 @@ crate-type = ["cdylib", "rlib"] [dependencies] # third-party dependencies codec = { package = "parity-scale-codec", version = "1.0.6" } -serde = { version = "1.0.102", features = [ "derive" ] } +serde = { version = "1.0.102", features = ["derive"] } futures01 = { package = "futures", version = "0.1.29" } futures = { version = "0.3.1", features = ["compat"] } hex-literal = "0.2.1" @@ -34,55 +34,57 @@ rand = "0.7.2" structopt = "0.3.3" # primitives -authority-discovery-primitives = { package = "substrate-authority-discovery-primitives", path = "../../../primitives/authority-discovery"} -babe-primitives = { package = "substrate-consensus-babe-primitives", path = "../../../primitives/consensus/babe" } -grandpa_primitives = { package = "substrate-finality-grandpa-primitives", path = "../../../primitives/finality-grandpa" } -primitives = { package = "substrate-primitives", path = "../../../primitives/core" } -sr-primitives = { path = "../../../primitives/sr-primitives" } -sp-timestamp = { path = "../../../primitives/timestamp", default-features = false } +sp-authority-discovery = { version = "2.0.0", path = "../../../primitives/authority-discovery" } +sp-consensus-babe = { version = "0.8", path = "../../../primitives/consensus/babe" } +grandpa-primitives = { version = "2.0.0", package = "sp-finality-grandpa", path = "../../../primitives/finality-grandpa" } +sp-core = { version = "2.0.0", path = "../../../primitives/core" } +sp-runtime = { version = "2.0.0", path = "../../../primitives/runtime" } +sp-timestamp = { version = "2.0.0", default-features = false, path = "../../../primitives/timestamp" } +sp-finality-tracker = { version = "2.0.0", default-features = false, path = "../../../primitives/finality-tracker" } +sp-inherents = { version = "2.0.0", path = "../../../primitives/inherents" } +sp-keyring = { version = "2.0.0", path = "../../../primitives/keyring" } +sp-io = { version = "2.0.0", path = "../../../primitives/io" } +sp-consensus = { version = "0.8", path = "../../../primitives/consensus/common" } -# core dependencies -runtime-io = { package = "sr-io", path = "../../../primitives/sr-io" } -client-api = { package = "substrate-client-api", path = "../../../client/api" } -client = { package = "substrate-client", path = "../../../client/" } -inherents = { package = "substrate-inherents", path = "../../../primitives/inherents" } -chain-spec = { package = "substrate-chain-spec", path = "../../../client/chain-spec" } -transaction_pool = { package = "substrate-transaction-pool", path = "../../../client/transaction-pool" } -network = { package = "substrate-network", path = "../../../client/network" } -babe = { package = "substrate-consensus-babe", path = "../../../client/consensus/babe" } -grandpa = { package = "substrate-finality-grandpa", path = "../../../client/finality-grandpa" } -keyring = { package = "substrate-keyring", path = "../../../primitives/keyring" } -client_db = { package = "substrate-client-db", path = "../../../client/db", default-features = false } -offchain = { package = "substrate-offchain", path = "../../../client/offchain" } -substrate-rpc = { package = "substrate-rpc", path = "../../../client/rpc" } -substrate-basic-authorship = { path = "../../../client/basic-authorship" } -substrate-service = { path = "../../../client/service", default-features = false } -substrate-telemetry = { package = "substrate-telemetry", path = "../../../client/telemetry" } -authority-discovery = { package = "substrate-authority-discovery", path = "../../../client/authority-discovery"} +# client dependencies +sc-client-api = { version = "2.0.0", path = "../../../client/api" } +sc-client = { version = "2.0.0", path = "../../../client/" } +sc-chain-spec = { version = "2.0.0", path = "../../../client/chain-spec" } +sc-transaction-pool = { version = "2.0.0", path = "../../../client/transaction-pool" } +sp-transaction-pool = { version = "2.0.0", path = "../../../primitives/transaction-pool" } +sc-network = { version = "0.8", path = "../../../client/network" } +sc-consensus-babe = { version = "0.8", path = "../../../client/consensus/babe" } +grandpa = { version = "2.0.0", package = "sc-finality-grandpa", path = "../../../client/finality-grandpa" } +sc-client-db = { version = "2.0.0", default-features = false, path = "../../../client/db" } +sc-offchain = { version = "2.0.0", path = "../../../client/offchain" } +sc-rpc = { version = "2.0.0", path = "../../../client/rpc" } +sc-basic-authority = { version = "2.0.0", path = "../../../client/basic-authorship" } +sc-service = { version = "2.0.0", default-features = false, path = "../../../client/service" } +sc-telemetry = { version = "2.0.0", path = "../../../client/telemetry" } +sc-authority-discovery = { version = "2.0.0", path = "../../../client/authority-discovery" } # frame dependencies -indices = { package = "pallet-indices", path = "../../../frame/indices" } -timestamp = { package = "pallet-timestamp", path = "../../../frame/timestamp", default-features = false } -sp-finality-tracker = { path = "../../../primitives/finality-tracker", default-features = false } -contracts = { package = "pallet-contracts", path = "../../../frame/contracts" } -system = { package = "frame-system", path = "../../../frame/system" } -balances = { package = "pallet-balances", path = "../../../frame/balances" } -transaction-payment = { package = "pallet-transaction-payment", path = "../../../frame/transaction-payment" } -support = { package = "frame-support", path = "../../../frame/support", default-features = false } -im_online = { package = "pallet-im-online", path = "../../../frame/im-online", default-features = false } -sr-authority-discovery = { package = "pallet-authority-discovery", path = "../../../frame/authority-discovery"} +pallet-indices = { version = "2.0.0", path = "../../../frame/indices" } +pallet-timestamp = { version = "2.0.0", default-features = false, path = "../../../frame/timestamp" } +pallet-contracts = { version = "2.0.0", path = "../../../frame/contracts" } +frame-system = { version = "2.0.0", path = "../../../frame/system" } +pallet-balances = { version = "2.0.0", path = "../../../frame/balances" } +pallet-transaction-payment = { version = "2.0.0", path = "../../../frame/transaction-payment" } +frame-support = { version = "2.0.0", default-features = false, path = "../../../frame/support" } +pallet-im-online = { version = "2.0.0", default-features = false, path = "../../../frame/im-online" } +pallet-authority-discovery = { version = "2.0.0", path = "../../../frame/authority-discovery" } # node-specific dependencies -node-runtime = { path = "../runtime" } -node-rpc = { path = "../rpc" } -node-primitives = { path = "../primitives" } -node-executor = { path = "../executor" } +node-runtime = { version = "2.0.0", path = "../runtime" } +node-rpc = { version = "2.0.0", path = "../rpc" } +node-primitives = { version = "2.0.0", path = "../primitives" } +node-executor = { version = "2.0.0", path = "../executor" } # CLI-specific dependencies tokio = { version = "0.1.22", optional = true } -substrate-cli = { path = "../../../client/cli", optional = true } -transaction-factory = { path = "../../../test/utils/transaction-factory", optional = true } +sc-cli = { version = "2.0.0", optional = true, path = "../../../client/cli" } ctrlc = { version = "3.1.3", features = ["termination"], optional = true } +node-transaction-factory = { version = "2.0.0", optional = true, path = "../transaction-factory" } # WASM-specific dependencies libp2p = { version = "0.13.0", default-features = false, optional = true } @@ -92,20 +94,19 @@ console_log = { version = "0.1.2", optional = true } js-sys = { version = "0.3.22", optional = true } wasm-bindgen = { version = "0.2.45", optional = true } wasm-bindgen-futures = { version = "0.3.22", optional = true } -kvdb-memorydb = { git = "https://github.com/paritytech/parity-common", rev="b0317f649ab2c665b7987b8475878fc4d2e1f81d", optional = true } +kvdb-memorydb = { version = "0.1.1", optional = true } rand6 = { package = "rand", version = "0.6", features = ["wasm-bindgen"], optional = true } # Imported just for the `wasm-bindgen` feature [dev-dependencies] -keystore = { package = "substrate-keystore", path = "../../../client/keystore" } -babe = { package = "substrate-consensus-babe", path = "../../../client/consensus/babe", features = ["test-helpers"] } -consensus-common = { package = "substrate-consensus-common", path = "../../../primitives/consensus/common" } -service-test = { package = "substrate-service-test", path = "../../../client/service/test" } +sc-keystore = { version = "2.0.0", path = "../../../client/keystore" } +sc-consensus-babe = { version = "0.8", features = ["test-helpers"], path = "../../../client/consensus/babe" } +sc-service-test = { version = "2.0.0", path = "../../../client/service/test" } futures = "0.3.1" tempfile = "3.1.0" [build-dependencies] -substrate-cli = { package = "substrate-cli", path = "../../../client/cli" } -build-script-utils = { package = "substrate-build-script-utils", path = "../../../utils/build-script-utils" } +sc-cli = { version = "2.0.0", package = "sc-cli", path = "../../../client/cli" } +build-script-utils = { version = "2.0.0", package = "substrate-build-script-utils", path = "../../../utils/build-script-utils" } structopt = "0.3.3" vergen = "3.0.4" @@ -124,16 +125,16 @@ browser = [ "rand6" ] cli = [ - "substrate-cli", - "transaction-factory", + "sc-cli", + "node-transaction-factory", "tokio", "ctrlc", - "substrate-service/rocksdb", + "sc-service/rocksdb", "node-executor/wasmi-errno", ] wasmtime = [ "cli", "node-executor/wasmtime", - "substrate-cli/wasmtime", - "substrate-service/wasmtime", + "sc-cli/wasmtime", + "sc-service/wasmtime", ] diff --git a/bin/node/cli/bin/main.rs b/bin/node/cli/bin/main.rs index 45cf173efb3e94095d910427a6b6c2f2b328b151..338fbd081e7200e4ef788182eadfb7cb6f2ade61 100644 --- a/bin/node/cli/bin/main.rs +++ b/bin/node/cli/bin/main.rs @@ -20,13 +20,13 @@ use futures::channel::oneshot; use futures::{future, FutureExt}; -use substrate_cli::VersionInfo; +use sc_cli::VersionInfo; use std::cell::RefCell; // handles ctrl-c struct Exit; -impl substrate_cli::IntoExit for Exit { +impl sc_cli::IntoExit for Exit { type Exit = future::Map, fn(Result<(), oneshot::Canceled>) -> ()>; fn into_exit(self) -> Self::Exit { // can't use signal directly here because CtrlC takes only `Fn`. @@ -43,7 +43,7 @@ impl substrate_cli::IntoExit for Exit { } } -fn main() -> Result<(), substrate_cli::error::Error> { +fn main() -> Result<(), sc_cli::error::Error> { let version = VersionInfo { name: "Substrate Node", commit: env!("VERGEN_SHA_SHORT"), diff --git a/bin/node/cli/build.rs b/bin/node/cli/build.rs index ae936ce4fbacef2b32e8bec34e2286997448035d..44bbe8c5dbb8b5fc4195c574f2beb54669632f67 100644 --- a/bin/node/cli/build.rs +++ b/bin/node/cli/build.rs @@ -16,7 +16,7 @@ use std::{fs, env, path::Path}; use structopt::{StructOpt, clap::Shell}; -use substrate_cli::{NoCustom, CoreParams}; +use sc_cli::{NoCustom, CoreParams}; use vergen::{ConstantsFlags, generate_cargo_keys}; fn main() { diff --git a/bin/node/cli/res/flaming-fir.json b/bin/node/cli/res/flaming-fir.json index 5cd11eb97fa008d124b4d51322520610538d6d8c..1e7d4424b5fc429ece50085769c54aa5856f317b 100644 --- a/bin/node/cli/res/flaming-fir.json +++ b/bin/node/cli/res/flaming-fir.json @@ -18,7 +18,7 @@ "telemetryEndpoints": [ ["wss://telemetry.polkadot.io/submit/", 0] ], - "protocolId": "fir", + "protocolId": "fir2", "consensusEngine": null, "genesis": { "raw": [ diff --git a/bin/node/cli/src/browser.rs b/bin/node/cli/src/browser.rs index 93df41402b9f2c4fbc210644fd5dd17d4278614a..cd1d453d8b2665a681d7d193b12e5e8eb1c7fa45 100644 --- a/bin/node/cli/src/browser.rs +++ b/bin/node/cli/src/browser.rs @@ -19,7 +19,7 @@ use futures01::{prelude::*, sync::oneshot, sync::mpsc}; use libp2p::wasm_ext; use log::{debug, info}; use std::sync::Arc; -use substrate_service::{AbstractService, RpcSession, Roles as ServiceRoles, Configuration, config::DatabaseConfig}; +use sc_service::{AbstractService, RpcSession, Roles as ServiceRoles, Configuration, config::DatabaseConfig}; use wasm_bindgen::prelude::*; /// Starts the client. @@ -40,7 +40,7 @@ fn start_inner(wasm_ext: wasm_ext::ffi::Transport) -> Result::default_with_spec_and_base_path(chain_spec, None); - config.network.transport = network::config::TransportConfig::Normal { + config.network.transport = sc_network::config::TransportConfig::Normal { wasm_external_transport: Some(wasm_ext.clone()), allow_private_ipv4: true, enable_mdns: false, diff --git a/bin/node/cli/src/chain_spec.rs b/bin/node/cli/src/chain_spec.rs index 792dd237ac4dcdf611b9da5ca588a11e9cea504a..bfab71b553bf6f75dc28eaf6237d1158bf8ae552 100644 --- a/bin/node/cli/src/chain_spec.rs +++ b/bin/node/cli/src/chain_spec.rs @@ -16,8 +16,8 @@ //! Substrate chain configurations. -use chain_spec::ChainSpecExtension; -use primitives::{Pair, Public, crypto::UncheckedInto, sr25519}; +use sc_chain_spec::ChainSpecExtension; +use sp_core::{Pair, Public, crypto::UncheckedInto, sr25519}; use serde::{Serialize, Deserialize}; use node_runtime::{ AuthorityDiscoveryConfig, BabeConfig, BalancesConfig, ContractsConfig, CouncilConfig, DemocracyConfig, @@ -26,14 +26,14 @@ use node_runtime::{ }; use node_runtime::Block; use node_runtime::constants::currency::*; -use substrate_service; +use sc_service; use hex_literal::hex; -use substrate_telemetry::TelemetryEndpoints; +use sc_telemetry::TelemetryEndpoints; use grandpa_primitives::{AuthorityId as GrandpaId}; -use babe_primitives::{AuthorityId as BabeId}; -use im_online::sr25519::{AuthorityId as ImOnlineId}; -use authority_discovery_primitives::AuthorityId as AuthorityDiscoveryId; -use sr_primitives::{Perbill, traits::{Verify, IdentifyAccount}}; +use sp_consensus_babe::{AuthorityId as BabeId}; +use pallet_im_online::sr25519::{AuthorityId as ImOnlineId}; +use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId; +use sp_runtime::{Perbill, traits::{Verify, IdentifyAccount}}; pub use node_primitives::{AccountId, Balance, Signature}; pub use node_runtime::GenesisConfig; @@ -49,11 +49,11 @@ const STAGING_TELEMETRY_URL: &str = "wss://telemetry.polkadot.io/submit/"; #[derive(Default, Clone, Serialize, Deserialize, ChainSpecExtension)] pub struct Extensions { /// Block numbers with known hashes. - pub fork_blocks: client::ForkBlocks, + pub fork_blocks: sc_client::ForkBlocks, } /// Specialized `ChainSpec`. -pub type ChainSpec = substrate_service::ChainSpec< +pub type ChainSpec = sc_service::ChainSpec< GenesisConfig, Extensions, >; @@ -219,33 +219,34 @@ pub fn testnet_genesis( get_account_id_from_seed::("Ferdie//stash"), ] }); + let num_endowed_accounts = endowed_accounts.len(); const ENDOWMENT: Balance = 10_000_000 * DOLLARS; const STASH: Balance = 100 * DOLLARS; GenesisConfig { - system: Some(SystemConfig { + frame_system: Some(SystemConfig { code: WASM_BINARY.to_vec(), changes_trie_config: Default::default(), }), - balances: Some(BalancesConfig { + pallet_balances: Some(BalancesConfig { balances: endowed_accounts.iter().cloned() .map(|k| (k, ENDOWMENT)) .chain(initial_authorities.iter().map(|x| (x.0.clone(), STASH))) .collect(), vesting: vec![], }), - indices: Some(IndicesConfig { + pallet_indices: Some(IndicesConfig { ids: endowed_accounts.iter().cloned() .chain(initial_authorities.iter().map(|x| x.0.clone())) .collect::>(), }), - session: Some(SessionConfig { + pallet_session: Some(SessionConfig { keys: initial_authorities.iter().map(|x| { (x.0.clone(), session_keys(x.2.clone(), x.3.clone(), x.4.clone(), x.5.clone())) }).collect::>(), }), - staking: Some(StakingConfig { + pallet_staking: Some(StakingConfig { current_era: 0, validator_count: initial_authorities.len() as u32 * 2, minimum_validator_count: initial_authorities.len() as u32, @@ -256,39 +257,41 @@ pub fn testnet_genesis( slash_reward_fraction: Perbill::from_percent(10), .. Default::default() }), - democracy: Some(DemocracyConfig::default()), - collective_Instance1: Some(CouncilConfig { - members: vec![], + pallet_democracy: Some(DemocracyConfig::default()), + pallet_collective_Instance1: Some(CouncilConfig { + members: endowed_accounts.iter().cloned() + .collect::>()[..(num_endowed_accounts + 1) / 2].to_vec(), phantom: Default::default(), }), - collective_Instance2: Some(TechnicalCommitteeConfig { - members: vec![], + pallet_collective_Instance2: Some(TechnicalCommitteeConfig { + members: endowed_accounts.iter().cloned() + .collect::>()[..(num_endowed_accounts + 1) / 2].to_vec(), phantom: Default::default(), }), - contracts: Some(ContractsConfig { - current_schedule: contracts::Schedule { + pallet_contracts: Some(ContractsConfig { + current_schedule: pallet_contracts::Schedule { enable_println, // this should only be enabled on development chains ..Default::default() }, gas_price: 1 * MILLICENTS, }), - sudo: Some(SudoConfig { + pallet_sudo: Some(SudoConfig { key: root_key, }), - babe: Some(BabeConfig { + pallet_babe: Some(BabeConfig { authorities: vec![], }), - im_online: Some(ImOnlineConfig { + pallet_im_online: Some(ImOnlineConfig { keys: vec![], }), - authority_discovery: Some(AuthorityDiscoveryConfig { + pallet_authority_discovery: Some(AuthorityDiscoveryConfig { keys: vec![], }), - grandpa: Some(GrandpaConfig { + pallet_grandpa: Some(GrandpaConfig { authorities: vec![], }), - membership_Instance1: Some(Default::default()), - treasury: Some(Default::default()), + pallet_membership_Instance1: Some(Default::default()), + pallet_treasury: Some(Default::default()), } } @@ -346,9 +349,8 @@ pub fn local_testnet_config() -> ChainSpec { #[cfg(test)] pub(crate) mod tests { use super::*; - use crate::service::new_full; - use substrate_service::Roles; - use service_test; + use crate::service::{new_full, new_light}; + use sc_service_test; fn local_testnet_genesis_instant_single() -> GenesisConfig { testnet_genesis( @@ -392,15 +394,10 @@ pub(crate) mod tests { #[test] #[ignore] fn test_connectivity() { - service_test::connectivity( + sc_service_test::connectivity( integration_test_config_with_two_authorities(), |config| new_full(config), - |mut config| { - // light nodes are unsupported - config.roles = Roles::FULL; - new_full(config) - }, - true, + |config| new_light(config), ); } } diff --git a/bin/node/cli/src/cli.rs b/bin/node/cli/src/cli.rs index f648038d82cb5eefd3207a1d87d8edfe4d14b68d..6e8afc613336ae3d48faed3a99e3255f0b022995 100644 --- a/bin/node/cli/src/cli.rs +++ b/bin/node/cli/src/cli.rs @@ -14,18 +14,17 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -pub use substrate_cli::error; +pub use sc_cli::VersionInfo; use tokio::prelude::Future; use tokio::runtime::{Builder as RuntimeBuilder, Runtime}; -pub use substrate_cli::{VersionInfo, IntoExit, NoCustom, SharedParams, ExecutionStrategyParam}; -use substrate_service::{AbstractService, Roles as ServiceRoles, Configuration}; +use sc_cli::{IntoExit, NoCustom, SharedParams, ImportParams, error}; +use sc_service::{AbstractService, Roles as ServiceRoles, Configuration}; use log::info; use structopt::{StructOpt, clap::App}; -use substrate_cli::{display_role, parse_and_prepare, AugmentClap, GetLogFilter, ParseAndPrepare}; +use sc_cli::{display_role, parse_and_prepare, AugmentClap, GetLogFilter, ParseAndPrepare}; use crate::{service, ChainSpec, load_spec}; use crate::factory_impl::FactoryState; -use transaction_factory::RuntimeAdapter; -use client::ExecutionStrategies; +use node_transaction_factory::RuntimeAdapter; /// Custom subcommands. #[derive(Clone, Debug, StructOpt)] @@ -71,7 +70,7 @@ pub struct FactoryCmd { /// /// These three modes control manufacturing. #[structopt(long="mode", default_value = "MasterToN")] - pub mode: transaction_factory::Mode, + pub mode: node_transaction_factory::Mode, /// Number of transactions to generate. In mode `MasterNToNToM` this is /// the number of transactions per round. @@ -82,15 +81,9 @@ pub struct FactoryCmd { #[structopt(flatten)] pub shared_params: SharedParams, - /// The means of execution used when calling into the runtime while importing blocks. - #[structopt( - long = "execution", - value_name = "STRATEGY", - possible_values = &ExecutionStrategyParam::variants(), - case_insensitive = true, - default_value = "NativeElseWasm" - )] - pub execution: ExecutionStrategyParam, + #[allow(missing_docs)] + #[structopt(flatten)] + pub import_params: ImportParams, } impl AugmentClap for FactoryCmd { @@ -100,7 +93,7 @@ impl AugmentClap for FactoryCmd { } /// Parse command line arguments into service configuration. -pub fn run(args: I, exit: E, version: substrate_cli::VersionInfo) -> error::Result<()> where +pub fn run(args: I, exit: E, version: sc_cli::VersionInfo) -> error::Result<()> where I: IntoIterator, T: Into + Clone, E: IntoExit, @@ -136,21 +129,19 @@ pub fn run(args: I, exit: E, version: substrate_cli::VersionInfo) -> er Ok(new_full_start!(config).0), load_spec, exit), ParseAndPrepare::ImportBlocks(cmd) => cmd.run_with_builder(|config: Config<_, _>| Ok(new_full_start!(config).0), load_spec, exit), + ParseAndPrepare::CheckBlock(cmd) => cmd.run_with_builder(|config: Config<_, _>| + Ok(new_full_start!(config).0), load_spec, exit), ParseAndPrepare::PurgeChain(cmd) => cmd.run(load_spec), ParseAndPrepare::RevertChain(cmd) => cmd.run_with_builder(|config: Config<_, _>| Ok(new_full_start!(config).0), load_spec), ParseAndPrepare::CustomCommand(CustomSubcommands::Factory(cli_args)) => { - let mut config: Config<_, _> = substrate_cli::create_config_with_db_path( + let mut config: Config<_, _> = sc_cli::create_config_with_db_path( load_spec, &cli_args.shared_params, &version, )?; - config.execution_strategies = ExecutionStrategies { - importing: cli_args.execution.into(), - block_construction: cli_args.execution.into(), - other: cli_args.execution.into(), - ..Default::default() - }; + + sc_cli::fill_import_params(&mut config, &cli_args.import_params, ServiceRoles::FULL)?; match ChainSpec::from(config.chain_spec.id()) { Some(ref c) if c == &ChainSpec::Development || c == &ChainSpec::LocalTestnet => {}, @@ -164,7 +155,7 @@ pub fn run(args: I, exit: E, version: substrate_cli::VersionInfo) -> er ); let service_builder = new_full_start!(config).0; - transaction_factory::factory::, _, _, _, _, _>( + node_transaction_factory::factory::, _, _, _, _, _>( factory_state, service_builder.client(), service_builder.select_chain() @@ -189,7 +180,7 @@ where let (exit_send, exit) = oneshot::channel(); - let informant = substrate_cli::informant::build(&service); + let informant = sc_cli::informant::build(&service); let future = select(informant, exit) .map(|_| Ok(())) diff --git a/bin/node/cli/src/factory_impl.rs b/bin/node/cli/src/factory_impl.rs index b47710b733f48fd10cf8c6261f1bd08fd225cd10..2a77bb5caaa39e6b21ee1dfc0b7eac7030aa0252 100644 --- a/bin/node/cli/src/factory_impl.rs +++ b/bin/node/cli/src/factory_impl.rs @@ -22,19 +22,19 @@ use rand::{Rng, SeedableRng}; use rand::rngs::StdRng; use codec::{Encode, Decode}; -use keyring::sr25519::Keyring; +use sp_keyring::sr25519::Keyring; use node_runtime::{ Call, CheckedExtrinsic, UncheckedExtrinsic, SignedExtra, BalancesCall, ExistentialDeposit, MinimumPeriod }; use node_primitives::Signature; -use primitives::{sr25519, crypto::Pair}; -use sr_primitives::{ +use sp_core::{sr25519, crypto::Pair}; +use sp_runtime::{ generic::Era, traits::{Block as BlockT, Header as HeaderT, SignedExtension, Verify, IdentifyAccount} }; -use transaction_factory::RuntimeAdapter; -use transaction_factory::modes::Mode; -use inherents::InherentData; +use node_transaction_factory::RuntimeAdapter; +use node_transaction_factory::modes::Mode; +use sp_inherents::InherentData; use sp_timestamp; use sp_finality_tracker; @@ -56,12 +56,12 @@ type Number = <::Header as HeaderT>::Number; impl FactoryState { fn build_extra(index: node_primitives::Index, phase: u64) -> node_runtime::SignedExtra { ( - system::CheckVersion::new(), - system::CheckGenesis::new(), - system::CheckEra::from(Era::mortal(256, phase)), - system::CheckNonce::from(index), - system::CheckWeight::new(), - transaction_payment::ChargeTransactionPayment::from(0), + frame_system::CheckVersion::new(), + frame_system::CheckGenesis::new(), + frame_system::CheckEra::from(Era::mortal(256, phase)), + frame_system::CheckNonce::from(index), + frame_system::CheckWeight::new(), + pallet_transaction_payment::ChargeTransactionPayment::from(0), Default::default(), ) } @@ -71,7 +71,7 @@ impl RuntimeAdapter for FactoryState { type AccountId = node_primitives::AccountId; type Balance = node_primitives::Balance; type Block = node_primitives::Block; - type Phase = sr_primitives::generic::Phase; + type Phase = sp_runtime::generic::Phase; type Secret = sr25519::Pair; type Index = node_primitives::Index; @@ -149,7 +149,7 @@ impl RuntimeAdapter for FactoryState { signed: Some((sender.clone(), Self::build_extra(index, phase))), function: Call::Balances( BalancesCall::transfer( - indices::address::Address::Id(destination.clone().into()), + pallet_indices::address::Address::Id(destination.clone().into()), (*amount).into() ) ) @@ -247,13 +247,13 @@ fn sign( let payload = (xt.function, extra.clone(), additional_signed); let signature = payload.using_encoded(|b| { if b.len() > 256 { - key.sign(&runtime_io::hashing::blake2_256(b)) + key.sign(&sp_io::hashing::blake2_256(b)) } else { key.sign(b) } }).into(); UncheckedExtrinsic { - signature: Some((indices::address::Address::Id(signed), signature, extra)), + signature: Some((pallet_indices::address::Address::Id(signed), signature, extra)), function: payload.0, } } diff --git a/bin/node/cli/src/service.rs b/bin/node/cli/src/service.rs index 93422bd3b4eaad2ce84039c8180c1a24912ab67e..1403393866fdda0d423edea2f6446fa05124a555 100644 --- a/bin/node/cli/src/service.rs +++ b/bin/node/cli/src/service.rs @@ -20,27 +20,26 @@ use std::sync::Arc; -use babe; -use client::{self, LongestChain}; +use sc_consensus_babe; +use sc_client::{self, LongestChain}; use grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider}; use node_executor; use node_primitives::Block; use node_runtime::{GenesisConfig, RuntimeApi}; -use substrate_service::{ +use sc_service::{ AbstractService, ServiceBuilder, config::Configuration, error::{Error as ServiceError}, }; -use transaction_pool::{self, txpool::{Pool as TransactionPool}}; -use inherents::InherentDataProviders; -use network::construct_simple_protocol; - -use substrate_service::{Service, NetworkStatus}; -use client::{Client, LocalCallExecutor}; -use client_db::Backend; -use sr_primitives::traits::Block as BlockT; +use sp_inherents::InherentDataProviders; +use sc_network::construct_simple_protocol; + +use sc_service::{Service, NetworkStatus}; +use sc_client::{Client, LocalCallExecutor}; +use sc_client_db::Backend; +use sp_runtime::traits::Block as BlockT; use node_executor::NativeExecutor; -use network::NetworkService; -use offchain::OffchainWorkers; -use primitives::Blake2Hasher; +use sc_network::NetworkService; +use sc_offchain::OffchainWorkers; +use sp_core::Blake2Hasher; construct_simple_protocol! { /// Demo protocol attachment for substrate. @@ -53,22 +52,26 @@ construct_simple_protocol! { /// be able to perform chain operations. macro_rules! new_full_start { ($config:expr) => {{ - type RpcExtension = jsonrpc_core::IoHandler; + type RpcExtension = jsonrpc_core::IoHandler; let mut import_setup = None; - let inherent_data_providers = inherents::InherentDataProviders::new(); + let inherent_data_providers = sp_inherents::InherentDataProviders::new(); - let builder = substrate_service::ServiceBuilder::new_full::< + let builder = sc_service::ServiceBuilder::new_full::< node_primitives::Block, node_runtime::RuntimeApi, node_executor::Executor >($config)? .with_select_chain(|_config, backend| { - Ok(client::LongestChain::new(backend.clone())) + Ok(sc_client::LongestChain::new(backend.clone())) + })? + .with_transaction_pool(|config, client, _fetcher| { + let pool_api = sc_transaction_pool::FullChainApi::new(client.clone()); + let pool = sc_transaction_pool::BasicPool::new(config, pool_api); + let maintainer = sc_transaction_pool::FullBasicPoolMaintainer::new(pool.pool().clone(), client); + let maintainable_pool = sp_transaction_pool::MaintainableTransactionPool::new(pool, maintainer); + Ok(maintainable_pool) })? - .with_transaction_pool(|config, client| - Ok(transaction_pool::txpool::Pool::new(config, transaction_pool::FullChainApi::new(client))) - )? .with_import_queue(|_config, client, mut select_chain, _transaction_pool| { let select_chain = select_chain.take() - .ok_or_else(|| substrate_service::Error::SelectChainRequired)?; + .ok_or_else(|| sc_service::Error::SelectChainRequired)?; let (grandpa_block_import, grandpa_link) = grandpa::block_import( client.clone(), &*client, @@ -76,14 +79,14 @@ macro_rules! new_full_start { )?; let justification_import = grandpa_block_import.clone(); - let (block_import, babe_link) = babe::block_import( - babe::Config::get_or_compute(&*client)?, + let (block_import, babe_link) = sc_consensus_babe::block_import( + sc_consensus_babe::Config::get_or_compute(&*client)?, grandpa_block_import, client.clone(), client.clone(), )?; - let import_queue = babe::import_queue( + let import_queue = sc_consensus_babe::import_queue( babe_link.clone(), block_import.clone(), Some(Box::new(justification_import)), @@ -96,8 +99,8 @@ macro_rules! new_full_start { import_setup = Some((block_import, grandpa_link, babe_link)); Ok(import_queue) })? - .with_rpc_extensions(|client, pool, _backend| -> RpcExtension { - node_rpc::create(client, pool) + .with_rpc_extensions(|client, pool, _backend, fetcher, _remote_blockchain| -> Result { + Ok(node_rpc::create(client, pool, node_rpc::LightDeps::none(fetcher))) })?; (builder, import_setup, inherent_data_providers) @@ -111,7 +114,7 @@ macro_rules! new_full_start { macro_rules! new_full { ($config:expr, $with_startup_data: expr) => {{ use futures01::sync::mpsc; - use network::DhtEvent; + use sc_network::DhtEvent; use futures::{ compat::Stream01CompatExt, stream::StreamExt, @@ -122,12 +125,14 @@ macro_rules! new_full { is_authority, force_authoring, name, - disable_grandpa + disable_grandpa, + sentry_nodes, ) = ( $config.roles.is_authority(), $config.force_authoring, $config.name.clone(), - $config.disable_grandpa + $config.disable_grandpa, + $config.network.sentry_nodes.clone(), ); // sentry nodes announce themselves as authorities to the network @@ -157,16 +162,19 @@ macro_rules! new_full { ($with_startup_data)(&block_import, &babe_link); if participates_in_consensus { - let proposer = substrate_basic_authorship::ProposerFactory { + let proposer = sc_basic_authority::ProposerFactory { client: service.client(), transaction_pool: service.transaction_pool(), }; let client = service.client(); let select_chain = service.select_chain() - .ok_or(substrate_service::Error::SelectChainRequired)?; + .ok_or(sc_service::Error::SelectChainRequired)?; - let babe_config = babe::BabeParams { + let can_author_with = + sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone()); + + let babe_config = sc_consensus_babe::BabeParams { keystore: service.keystore(), client, select_chain, @@ -176,17 +184,19 @@ macro_rules! new_full { inherent_data_providers: inherent_data_providers.clone(), force_authoring, babe_link, + can_author_with, }; - let babe = babe::start_babe(babe_config)?; + let babe = sc_consensus_babe::start_babe(babe_config)?; service.spawn_essential_task(babe); let future03_dht_event_rx = dht_event_rx.compat() .map(|x| x.expect(" never returns an error; qed")) .boxed(); - let authority_discovery = authority_discovery::AuthorityDiscovery::new( + let authority_discovery = sc_authority_discovery::AuthorityDiscovery::new( service.client(), service.network(), + sentry_nodes, service.keystore(), future03_dht_event_rx, ); @@ -221,6 +231,7 @@ macro_rules! new_full { grandpa_link, service.network(), service.on_exit(), + service.spawn_task_handle(), )?); }, (true, false) => { @@ -233,6 +244,7 @@ macro_rules! new_full { on_exit: service.on_exit(), telemetry_on_connect: Some(service.telemetry_on_connect_stream()), voting_rule: grandpa::VotingRulesBuilder::default().build(), + executor: service.spawn_task_handle(), }; // the GRANDPA voter task is considered infallible, i.e. // if it fails we take down the service with it. @@ -267,6 +279,17 @@ type ConcreteClient = >; #[allow(dead_code)] type ConcreteBackend = Backend; +#[allow(dead_code)] +type ConcreteTransactionPool = sp_transaction_pool::MaintainableTransactionPool< + sc_transaction_pool::BasicPool< + sc_transaction_pool::FullChainApi, + ConcreteBlock + >, + sc_transaction_pool::FullBasicPoolMaintainer< + ConcreteClient, + sc_transaction_pool::FullChainApi + > +>; /// A specialized configuration object for setting up the node.. pub type NodeConfiguration = Configuration; @@ -280,10 +303,10 @@ pub fn new_full(config: NodeConfiguration) LongestChain, NetworkStatus, NetworkService::Hash>, - TransactionPool>, + ConcreteTransactionPool, OffchainWorkers< ConcreteClient, - >::OffchainStorage, + >::OffchainStorage, ConcreteBlock, > >, @@ -296,16 +319,22 @@ pub fn new_full(config: NodeConfiguration) /// Builds a new service for a light client. pub fn new_light(config: NodeConfiguration) -> Result { - type RpcExtension = jsonrpc_core::IoHandler; + type RpcExtension = jsonrpc_core::IoHandler; let inherent_data_providers = InherentDataProviders::new(); let service = ServiceBuilder::new_light::(config)? .with_select_chain(|_config, backend| { Ok(LongestChain::new(backend.clone())) })? - .with_transaction_pool(|config, client| - Ok(TransactionPool::new(config, transaction_pool::FullChainApi::new(client))) - )? + .with_transaction_pool(|config, client, fetcher| { + let fetcher = fetcher + .ok_or_else(|| "Trying to start light transaction pool without active fetcher")?; + let pool_api = sc_transaction_pool::LightChainApi::new(client.clone(), fetcher.clone()); + let pool = sc_transaction_pool::BasicPool::new(config, pool_api); + let maintainer = sc_transaction_pool::LightBasicPoolMaintainer::with_defaults(pool.pool().clone(), client, fetcher); + let maintainable_pool = sp_transaction_pool::MaintainableTransactionPool::new(pool, maintainer); + Ok(maintainable_pool) + })? .with_import_queue_and_fprb(|_config, client, backend, fetcher, _select_chain, _tx_pool| { let fetch_checker = fetcher .map(|fetcher| fetcher.checker().clone()) @@ -321,14 +350,14 @@ pub fn new_light(config: NodeConfiguration) let finality_proof_request_builder = finality_proof_import.create_finality_proof_request_builder(); - let (babe_block_import, babe_link) = babe::block_import( - babe::Config::get_or_compute(&*client)?, + let (babe_block_import, babe_link) = sc_consensus_babe::block_import( + sc_consensus_babe::Config::get_or_compute(&*client)?, grandpa_block_import, client.clone(), client.clone(), )?; - let import_queue = babe::import_queue( + let import_queue = sc_consensus_babe::import_queue( babe_link, babe_block_import, None, @@ -344,8 +373,14 @@ pub fn new_light(config: NodeConfiguration) .with_finality_proof_provider(|client, backend| Ok(Arc::new(GrandpaFinalityProofProvider::new(backend, client)) as _) )? - .with_rpc_extensions(|client, pool, _backend| -> RpcExtension { - node_rpc::create(client, pool) + .with_rpc_extensions(|client, pool, _backend, fetcher, remote_blockchain| -> Result { + let fetcher = fetcher + .ok_or_else(|| "Trying to start node RPC without active fetcher")?; + let remote_blockchain = remote_blockchain + .ok_or_else(|| "Trying to start node RPC without active remote blockchain")?; + + let light_deps = node_rpc::LightDeps { remote_blockchain, fetcher }; + Ok(node_rpc::create(client, pool, Some(light_deps))) })? .build()?; @@ -355,16 +390,16 @@ pub fn new_light(config: NodeConfiguration) #[cfg(test)] mod tests { use std::sync::Arc; - use babe::CompatibleDigestItem; - use consensus_common::{ + use sc_consensus_babe::CompatibleDigestItem; + use sp_consensus::{ Environment, Proposer, BlockImportParams, BlockOrigin, ForkChoiceStrategy, BlockImport, }; use node_primitives::{Block, DigestItem, Signature}; use node_runtime::{BalancesCall, Call, UncheckedExtrinsic, Address}; use node_runtime::constants::{currency::CENTS, time::SLOT_DURATION}; use codec::{Encode, Decode}; - use primitives::{crypto::Pair as CryptoPair, H256}; - use sr_primitives::{ + use sp_core::{crypto::Pair as CryptoPair, H256}; + use sp_runtime::{ generic::{BlockId, Era, Digest, SignedPayload}, traits::Block as BlockT, traits::Verify, @@ -372,19 +407,19 @@ mod tests { }; use sp_timestamp; use sp_finality_tracker; - use keyring::AccountKeyring; - use substrate_service::{AbstractService, Roles}; - use crate::service::new_full; - use sr_primitives::traits::IdentifyAccount; + use sp_keyring::AccountKeyring; + use sc_service::AbstractService; + use crate::service::{new_full, new_light}; + use sp_runtime::traits::IdentifyAccount; type AccountPublic = ::Signer; #[cfg(feature = "rhd")] fn test_sync() { - use primitives::ed25519::Pair; + use sp_core::ed25519::Pair; use {service_test, Factory}; - use client::{BlockImportParams, BlockOrigin}; + use sc_client::{BlockImportParams, BlockOrigin}; let alice: Arc = Arc::new(Keyring::Alice.into()); let bob: Arc = Arc::new(Keyring::Bob.into()); @@ -432,14 +467,10 @@ mod tests { let v: Vec = Decode::decode(&mut xt.as_slice()).unwrap(); OpaqueExtrinsic(v) }; - service_test::sync( - chain_spec::integration_test_config(), + sc_service_test::sync( + sc_chain_spec::integration_test_config(), |config| new_full(config), - |mut config| { - // light nodes are unsupported - config.roles = Roles::FULL; - new_full(config) - }, + |mut config| new_light(config), block_factory, extrinsic_factory, ); @@ -449,9 +480,9 @@ mod tests { #[ignore] fn test_sync() { let keystore_path = tempfile::tempdir().expect("Creates keystore path"); - let keystore = keystore::Store::open(keystore_path.path(), None) + let keystore = sc_keystore::Store::open(keystore_path.path(), None) .expect("Creates keystore"); - let alice = keystore.write().insert_ephemeral_from_seed::("//Alice") + let alice = keystore.write().insert_ephemeral_from_seed::("//Alice") .expect("Creates authority pair"); let chain_spec = crate::chain_spec::tests::integration_test_config_with_single_authority(); @@ -464,22 +495,18 @@ mod tests { let charlie = Arc::new(AccountKeyring::Charlie.pair()); let mut index = 0; - service_test::sync( + sc_service_test::sync( chain_spec, |config| { let mut setup_handles = None; new_full!(config, | - block_import: &babe::BabeBlockImport<_, _, Block, _, _, _>, - babe_link: &babe::BabeLink, + block_import: &sc_consensus_babe::BabeBlockImport<_, _, Block, _, _, _>, + babe_link: &sc_consensus_babe::BabeLink, | { setup_handles = Some((block_import.clone(), babe_link.clone())); }).map(move |(node, x)| (node, (x, setup_handles.unwrap()))) }, - |mut config| { - // light nodes are unsupported - config.roles = Roles::FULL; - new_full(config) - }, + |config| new_light(config), |service, &mut (ref inherent_data_providers, (ref mut block_import, ref babe_link))| { let mut inherent_data = inherent_data_providers .create_inherent_data() @@ -488,7 +515,7 @@ mod tests { let parent_id = BlockId::number(service.client().info().chain.best_number); let parent_header = service.client().header(&parent_id).unwrap().unwrap(); - let mut proposer_factory = substrate_basic_authorship::ProposerFactory { + let mut proposer_factory = sc_basic_authority::ProposerFactory { client: service.client(), transaction_pool: service.transaction_pool(), }; @@ -499,7 +526,7 @@ mod tests { // so we must keep trying the next slots until we can claim one. let babe_pre_digest = loop { inherent_data.replace_data(sp_timestamp::INHERENT_IDENTIFIER, &(slot_num * SLOT_DURATION)); - if let Some(babe_pre_digest) = babe::test_helpers::claim_slot( + if let Some(babe_pre_digest) = sc_consensus_babe::test_helpers::claim_slot( slot_num, &parent_header, &*service.client(), @@ -542,6 +569,7 @@ mod tests { auxiliary: Vec::new(), fork_choice: ForkChoiceStrategy::LongestChain, allow_missing_state: false, + import_existing: false, }; block_import.import_block(params, Default::default()) @@ -558,12 +586,12 @@ mod tests { let function = Call::Balances(BalancesCall::transfer(to.into(), amount)); - let check_version = system::CheckVersion::new(); - let check_genesis = system::CheckGenesis::new(); - let check_era = system::CheckEra::from(Era::Immortal); - let check_nonce = system::CheckNonce::from(index); - let check_weight = system::CheckWeight::new(); - let payment = transaction_payment::ChargeTransactionPayment::from(0); + let check_version = frame_system::CheckVersion::new(); + let check_genesis = frame_system::CheckGenesis::new(); + let check_era = frame_system::CheckEra::from(Era::Immortal); + let check_nonce = frame_system::CheckNonce::from(index); + let check_weight = frame_system::CheckWeight::new(); + let payment = pallet_transaction_payment::ChargeTransactionPayment::from(0); let extra = ( check_version, check_genesis, @@ -599,14 +627,10 @@ mod tests { #[test] #[ignore] fn test_consensus() { - service_test::consensus( + sc_service_test::consensus( crate::chain_spec::tests::integration_test_config_with_two_authorities(), |config| new_full(config), - |mut config| { - // light nodes are unsupported - config.roles = Roles::FULL; - new_full(config) - }, + |config| new_light(config), vec![ "//Alice".into(), "//Bob".into(), diff --git a/bin/node/executor/Cargo.toml b/bin/node/executor/Cargo.toml index aad3351e91451b2a8eb4a26be162cf325fa03cc3..24f593d1ce8bb9be1b1b314b1fe7ee8e081682e7 100644 --- a/bin/node/executor/Cargo.toml +++ b/bin/node/executor/Cargo.toml @@ -8,41 +8,40 @@ edition = "2018" [dependencies] trie-root = "0.15.2" codec = { package = "parity-scale-codec", version = "1.0.0" } -runtime_io = { package = "sr-io", path = "../../../primitives/sr-io" } -state_machine = { package = "substrate-state-machine", path = "../../../primitives/state-machine" } -substrate-executor = { path = "../../../client/executor" } -primitives = { package = "substrate-primitives", path = "../../../primitives/core" } -trie = { package = "substrate-trie", path = "../../../primitives/trie" } -node-primitives = { path = "../primitives" } -node-runtime = { path = "../runtime" } +sp-io = { version = "2.0.0", path = "../../../primitives/io" } +sp-state-machine = { version = "2.0.0", path = "../../../primitives/state-machine" } +sc-executor = { version = "2.0.0", path = "../../../client/executor" } +sp-core = { version = "2.0.0", path = "../../../primitives/core" } +sp-trie = { version = "2.0.0", path = "../../../primitives/trie" } +node-primitives = { version = "2.0.0", path = "../primitives" } +node-runtime = { version = "2.0.0", path = "../runtime" } [dev-dependencies] -node-testing = { path = "../testing" } -test-client = { package = "substrate-test-client", path = "../../../test/utils/client" } -sr-primitives = { path = "../../../primitives/sr-primitives" } -runtime_support = { package = "frame-support", path = "../../../frame/support" } -balances = { package = "pallet-balances", path = "../../../frame/balances" } -transaction-payment = { package = "pallet-transaction-payment", path = "../../../frame/transaction-payment" } -session = { package = "pallet-session", path = "../../../frame/session" } -system = { package = "frame-system", path = "../../../frame/system" } -timestamp = { package = "pallet-timestamp", path = "../../../frame/timestamp" } -treasury = { package = "pallet-treasury", path = "../../../frame/treasury" } -contracts = { package = "pallet-contracts", path = "../../../frame/contracts" } -grandpa = { package = "pallet-grandpa", path = "../../../frame/grandpa" } -indices = { package = "pallet-indices", path = "../../../frame/indices" } +node-testing = { version = "2.0.0", path = "../testing" } +substrate-test-client = { version = "2.0.0", path = "../../../test-utils/client" } +sp-runtime = { version = "2.0.0", path = "../../../primitives/runtime" } +frame-support = { version = "2.0.0", path = "../../../frame/support" } +pallet-balances = { version = "2.0.0", path = "../../../frame/balances" } +pallet-transaction-payment = { version = "2.0.0", path = "../../../frame/transaction-payment" } +pallet-session = { version = "2.0.0", path = "../../../frame/session" } +frame-system = { version = "2.0.0", path = "../../../frame/system" } +pallet-timestamp = { version = "2.0.0", path = "../../../frame/timestamp" } +pallet-treasury = { version = "2.0.0", path = "../../../frame/treasury" } +pallet-contracts = { version = "2.0.0", path = "../../../frame/contracts" } +pallet-grandpa = { version = "2.0.0", path = "../../../frame/grandpa" } +pallet-indices = { version = "2.0.0", path = "../../../frame/indices" } wabt = "0.9.2" criterion = "0.3.0" [features] wasmtime = [ - "substrate-executor/wasmtime", + "sc-executor/wasmtime", ] wasmi-errno = [ - "substrate-executor/wasmi-errno", + "sc-executor/wasmi-errno", ] stress-test = [] [[bench]] name = "bench" harness = false - diff --git a/bin/node/executor/benches/bench.rs b/bin/node/executor/benches/bench.rs index e72c28467fa7f6fe624ba3514ebe00ca91a33ebe..74999a404e8dd96c1762da76497e1c387a0ab6b4 100644 --- a/bin/node/executor/benches/bench.rs +++ b/bin/node/executor/benches/bench.rs @@ -23,12 +23,12 @@ use node_runtime::{ }; use node_runtime::constants::currency::*; use node_testing::keyring::*; -use primitives::{Blake2Hasher, NativeOrEncoded, NeverNativeValue}; -use primitives::storage::well_known_keys; -use primitives::traits::CodeExecutor; -use runtime_support::Hashable; -use state_machine::TestExternalities as CoreTestExternalities; -use substrate_executor::{NativeExecutor, RuntimeInfo, WasmExecutionMethod, Externalities}; +use sp_core::{Blake2Hasher, NativeOrEncoded, NeverNativeValue}; +use sp_core::storage::well_known_keys; +use sp_core::traits::CodeExecutor; +use frame_support::Hashable; +use sp_state_machine::TestExternalities as CoreTestExternalities; +use sc_executor::{NativeExecutor, RuntimeInfo, WasmExecutionMethod, Externalities}; criterion_group!(benches, bench_execute_block); criterion_main!(benches); @@ -70,7 +70,7 @@ fn construct_block( parent_hash: Hash, extrinsics: Vec, ) -> (Vec, Hash) { - use trie::{TrieConfiguration, trie_types::Layout}; + use sp_trie::{TrieConfiguration, trie_types::Layout}; // sign extrinsics. let extrinsics = extrinsics.into_iter().map(sign).collect::>(); @@ -131,13 +131,13 @@ fn test_blocks(genesis_config: &GenesisConfig, executor: &NativeExecutor(extrinsic: &E, fee_multiplier: Fixed64) -> Balance { - let length_fee = TransactionBaseFee::get() + - TransactionByteFee::get() * - (extrinsic.encode().len() as Balance); + let length_fee = TransactionByteFee::get() * (extrinsic.encode().len() as Balance); let weight = default_transfer_call().get_dispatch_info().weight; - let weight_fee = ::WeightToFee::convert(weight); + let weight_fee = ::WeightToFee::convert(weight); - fee_multiplier.saturated_multiply_accumulate(length_fee + weight_fee) + TransferFee::get() + let base_fee = TransactionBaseFee::get(); + + base_fee + fee_multiplier.saturated_multiply_accumulate(length_fee + weight_fee) + TransferFee::get() } - fn default_transfer_call() -> balances::Call { - balances::Call::transfer::(bob().into(), 69 * DOLLARS) + fn default_transfer_call() -> pallet_balances::Call { + pallet_balances::Call::transfer::(bob().into(), 69 * DOLLARS) } fn xt() -> UncheckedExtrinsic { @@ -143,20 +142,23 @@ mod tests { #[test] fn panic_execution_with_foreign_code_gives_error() { - let mut t = TestExternalities::::new_with_code(BLOATY_CODE, (map![ - >::hashed_key_for(alice()) => { - 69_u128.encode() - }, - >::hashed_key().to_vec() => { - 69_u128.encode() - }, - >::hashed_key().to_vec() => { - 0_u128.encode() - }, - >::hashed_key_for(0) => { - vec![0u8; 32] - } - ], map![])); + let mut t = TestExternalities::::new_with_code(BLOATY_CODE, Storage { + top: map![ + >::hashed_key_for(alice()) => { + 69_u128.encode() + }, + >::hashed_key().to_vec() => { + 69_u128.encode() + }, + >::hashed_key().to_vec() => { + 0_u128.encode() + }, + >::hashed_key_for(0) => { + vec![0u8; 32] + } + ], + children: map![], + }); let r = executor_call:: _>( &mut t, @@ -179,20 +181,23 @@ mod tests { #[test] fn bad_extrinsic_with_native_equivalent_code_gives_error() { - let mut t = TestExternalities::::new_with_code(COMPACT_CODE, (map![ - >::hashed_key_for(alice()) => { - 69_u128.encode() - }, - >::hashed_key().to_vec() => { - 69_u128.encode() - }, - >::hashed_key().to_vec() => { - 0_u128.encode() - }, - >::hashed_key_for(0) => { - vec![0u8; 32] - } - ], map![])); + let mut t = TestExternalities::::new_with_code(COMPACT_CODE, Storage { + top: map![ + >::hashed_key_for(alice()) => { + 69_u128.encode() + }, + >::hashed_key().to_vec() => { + 69_u128.encode() + }, + >::hashed_key().to_vec() => { + 0_u128.encode() + }, + >::hashed_key_for(0) => { + vec![0u8; 32] + } + ], + children: map![], + }); let r = executor_call:: _>( &mut t, @@ -215,16 +220,19 @@ mod tests { #[test] fn successful_execution_with_native_equivalent_code_gives_ok() { - let mut t = TestExternalities::::new_with_code(COMPACT_CODE, (map![ - >::hashed_key_for(alice()) => { - (111 * DOLLARS).encode() - }, - >::hashed_key().to_vec() => { - (111 * DOLLARS).encode() - }, - >::hashed_key().to_vec() => vec![0u8; 16], - >::hashed_key_for(0) => vec![0u8; 32] - ], map![])); + let mut t = TestExternalities::::new_with_code(COMPACT_CODE, Storage { + top: map![ + >::hashed_key_for(alice()) => { + (111 * DOLLARS).encode() + }, + >::hashed_key().to_vec() => { + (111 * DOLLARS).encode() + }, + >::hashed_key().to_vec() => vec![0u8; 16], + >::hashed_key_for(0) => vec![0u8; 32] + ], + children: map![], + }); let r = executor_call:: _>( &mut t, @@ -254,16 +262,19 @@ mod tests { #[test] fn successful_execution_with_foreign_code_gives_ok() { - let mut t = TestExternalities::::new_with_code(BLOATY_CODE, (map![ - >::hashed_key_for(alice()) => { - (111 * DOLLARS).encode() - }, - >::hashed_key().to_vec() => { - (111 * DOLLARS).encode() - }, - >::hashed_key().to_vec() => vec![0u8; 16], - >::hashed_key_for(0) => vec![0u8; 32] - ], map![])); + let mut t = TestExternalities::::new_with_code(BLOATY_CODE, Storage { + top: map![ + >::hashed_key_for(alice()) => { + (111 * DOLLARS).encode() + }, + >::hashed_key().to_vec() => { + (111 * DOLLARS).encode() + }, + >::hashed_key().to_vec() => vec![0u8; 16], + >::hashed_key_for(0) => vec![0u8; 32] + ], + children: map![], + }); let r = executor_call:: _>( &mut t, @@ -306,7 +317,7 @@ mod tests { parent_hash: Hash, extrinsics: Vec, ) -> (Vec, Hash) { - use trie::{TrieConfiguration, trie_types::Layout}; + use sp_trie::{TrieConfiguration, trie_types::Layout}; // sign extrinsics. let extrinsics = extrinsics.into_iter().map(sign).collect::>(); @@ -367,11 +378,11 @@ mod tests { vec![ CheckedExtrinsic { signed: None, - function: Call::Timestamp(timestamp::Call::set(42 * 1000)), + function: Call::Timestamp(pallet_timestamp::Call::set(42 * 1000)), }, CheckedExtrinsic { signed: Some((alice(), signed_extra(0, 0))), - function: Call::Balances(balances::Call::transfer(bob().into(), 69 * DOLLARS)), + function: Call::Balances(pallet_balances::Call::transfer(bob().into(), 69 * DOLLARS)), }, ] ) @@ -389,11 +400,11 @@ mod tests { vec![ CheckedExtrinsic { signed: None, - function: Call::Timestamp(timestamp::Call::set(42 * 1000)), + function: Call::Timestamp(pallet_timestamp::Call::set(42 * 1000)), }, CheckedExtrinsic { signed: Some((alice(), signed_extra(0, 0))), - function: Call::Balances(balances::Call::transfer(bob().into(), 69 * DOLLARS)), + function: Call::Balances(pallet_balances::Call::transfer(bob().into(), 69 * DOLLARS)), }, ] ); @@ -404,15 +415,15 @@ mod tests { vec![ CheckedExtrinsic { signed: None, - function: Call::Timestamp(timestamp::Call::set(52 * 1000)), + function: Call::Timestamp(pallet_timestamp::Call::set(52 * 1000)), }, CheckedExtrinsic { signed: Some((bob(), signed_extra(0, 0))), - function: Call::Balances(balances::Call::transfer(alice().into(), 5 * DOLLARS)), + function: Call::Balances(pallet_balances::Call::transfer(alice().into(), 5 * DOLLARS)), }, CheckedExtrinsic { signed: Some((alice(), signed_extra(1, 0))), - function: Call::Balances(balances::Call::transfer(bob().into(), 15 * DOLLARS)), + function: Call::Balances(pallet_balances::Call::transfer(bob().into(), 15 * DOLLARS)), } ] ); @@ -432,11 +443,11 @@ mod tests { vec![ CheckedExtrinsic { signed: None, - function: Call::Timestamp(timestamp::Call::set(time * 1000)), + function: Call::Timestamp(pallet_timestamp::Call::set(time * 1000)), }, CheckedExtrinsic { signed: Some((alice(), signed_extra(nonce, 0))), - function: Call::System(system::Call::remark(vec![0; size])), + function: Call::System(frame_system::Call::remark(vec![0; size])), } ] ) @@ -466,19 +477,19 @@ mod tests { let events = vec![ EventRecord { phase: Phase::ApplyExtrinsic(0), - event: Event::system(system::Event::ExtrinsicSuccess( - DispatchInfo { weight: 10000, class: DispatchClass::Operational } + event: Event::system(frame_system::Event::ExtrinsicSuccess( + DispatchInfo { weight: 10000, class: DispatchClass::Operational, pays_fee: true } )), topics: vec![], }, EventRecord { phase: Phase::ApplyExtrinsic(1), - event: Event::treasury(treasury::RawEvent::Deposit(1984800000000)), + event: Event::pallet_treasury(pallet_treasury::RawEvent::Deposit(1984800000000)), topics: vec![], }, EventRecord { phase: Phase::ApplyExtrinsic(1), - event: Event::balances(balances::RawEvent::Transfer( + event: Event::pallet_balances(pallet_balances::RawEvent::Transfer( alice().into(), bob().into(), 69 * DOLLARS, @@ -488,8 +499,8 @@ mod tests { }, EventRecord { phase: Phase::ApplyExtrinsic(1), - event: Event::system(system::Event::ExtrinsicSuccess( - DispatchInfo { weight: 1000000, class: DispatchClass::Normal } + event: Event::system(frame_system::Event::ExtrinsicSuccess( + DispatchInfo { weight: 1000000, class: DispatchClass::Normal, pays_fee: true } )), topics: vec![], }, @@ -519,20 +530,20 @@ mod tests { let events = vec![ EventRecord { phase: Phase::ApplyExtrinsic(0), - event: Event::system(system::Event::ExtrinsicSuccess( - DispatchInfo { weight: 10000, class: DispatchClass::Operational } + event: Event::system(frame_system::Event::ExtrinsicSuccess( + DispatchInfo { weight: 10000, class: DispatchClass::Operational, pays_fee: true } )), topics: vec![], }, EventRecord { phase: Phase::ApplyExtrinsic(1), - event: Event::treasury(treasury::RawEvent::Deposit(1984780231392)), + event: Event::pallet_treasury(pallet_treasury::RawEvent::Deposit(1984788199392)), topics: vec![], }, EventRecord { phase: Phase::ApplyExtrinsic(1), - event: Event::balances( - balances::RawEvent::Transfer( + event: Event::pallet_balances( + pallet_balances::RawEvent::Transfer( bob().into(), alice().into(), 5 * DOLLARS, @@ -543,20 +554,20 @@ mod tests { }, EventRecord { phase: Phase::ApplyExtrinsic(1), - event: Event::system(system::Event::ExtrinsicSuccess( - DispatchInfo { weight: 1000000, class: DispatchClass::Normal } + event: Event::system(frame_system::Event::ExtrinsicSuccess( + DispatchInfo { weight: 1000000, class: DispatchClass::Normal, pays_fee: true } )), topics: vec![], }, EventRecord { phase: Phase::ApplyExtrinsic(2), - event: Event::treasury(treasury::RawEvent::Deposit(1984780231392)), + event: Event::pallet_treasury(pallet_treasury::RawEvent::Deposit(1984788199392)), topics: vec![], }, EventRecord { phase: Phase::ApplyExtrinsic(2), - event: Event::balances( - balances::RawEvent::Transfer( + event: Event::pallet_balances( + pallet_balances::RawEvent::Transfer( alice().into(), bob().into(), 15 * DOLLARS, @@ -567,8 +578,8 @@ mod tests { }, EventRecord { phase: Phase::ApplyExtrinsic(2), - event: Event::system(system::Event::ExtrinsicSuccess( - DispatchInfo { weight: 1000000, class: DispatchClass::Normal } + event: Event::system(frame_system::Event::ExtrinsicSuccess( + DispatchInfo { weight: 1000000, class: DispatchClass::Normal, pays_fee: true } )), topics: vec![], }, @@ -717,9 +728,9 @@ mod tests { #[test] fn deploying_wasm_contract_should_work() { let transfer_code = wabt::wat2wasm(CODE_TRANSFER).unwrap(); - let transfer_ch = ::Hashing::hash(&transfer_code); + let transfer_ch = ::Hashing::hash(&transfer_code); - let addr = ::DetermineContractAddress::contract_address_for( + let addr = ::DetermineContractAddress::contract_address_for( &transfer_ch, &[], &charlie(), @@ -732,25 +743,25 @@ mod tests { vec![ CheckedExtrinsic { signed: None, - function: Call::Timestamp(timestamp::Call::set(42 * 1000)), + function: Call::Timestamp(pallet_timestamp::Call::set(42 * 1000)), }, CheckedExtrinsic { signed: Some((charlie(), signed_extra(0, 0))), function: Call::Contracts( - contracts::Call::put_code::(10_000, transfer_code) + pallet_contracts::Call::put_code::(10_000, transfer_code) ), }, CheckedExtrinsic { signed: Some((charlie(), signed_extra(1, 0))), function: Call::Contracts( - contracts::Call::instantiate::(1 * DOLLARS, 10_000, transfer_ch, Vec::new()) + pallet_contracts::Call::instantiate::(1 * DOLLARS, 10_000, transfer_ch, Vec::new()) ), }, CheckedExtrinsic { signed: Some((charlie(), signed_extra(2, 0))), function: Call::Contracts( - contracts::Call::call::( - indices::address::Address::Id(addr.clone()), + pallet_contracts::Call::call::( + pallet_indices::address::Address::Id(addr.clone()), 10, 10_000, vec![0x00, 0x01, 0x02, 0x03] @@ -773,7 +784,7 @@ mod tests { t.execute_with(|| { // Verify that the contract constructor worked well and code of TRANSFER contract is actually deployed. assert_eq!( - &contracts::ContractInfoOf::::get(addr) + &pallet_contracts::ContractInfoOf::::get(addr) .and_then(|c| c.get_alive()) .unwrap() .code_hash, @@ -828,16 +839,19 @@ mod tests { #[test] fn panic_execution_gives_error() { - let mut t = TestExternalities::::new_with_code(BLOATY_CODE, (map![ - >::hashed_key_for(alice()) => { - 0_u128.encode() - }, - >::hashed_key().to_vec() => { - 0_u128.encode() - }, - >::hashed_key().to_vec() => vec![0u8; 16], - >::hashed_key_for(0) => vec![0u8; 32] - ], map![])); + let mut t = TestExternalities::::new_with_code(BLOATY_CODE, Storage { + top: map![ + >::hashed_key_for(alice()) => { + 0_u128.encode() + }, + >::hashed_key().to_vec() => { + 0_u128.encode() + }, + >::hashed_key().to_vec() => vec![0u8; 16], + >::hashed_key_for(0) => vec![0u8; 32] + ], + children: map![], + }); let r = executor_call:: _>( &mut t, @@ -860,16 +874,19 @@ mod tests { #[test] fn successful_execution_gives_ok() { - let mut t = TestExternalities::::new_with_code(COMPACT_CODE, (map![ - >::hashed_key_for(alice()) => { - (111 * DOLLARS).encode() - }, - >::hashed_key().to_vec() => { - (111 * DOLLARS).encode() - }, - >::hashed_key().to_vec() => vec![0u8; 16], - >::hashed_key_for(0) => vec![0u8; 32] - ], map![])); + let mut t = TestExternalities::::new_with_code(COMPACT_CODE, Storage { + top: map![ + >::hashed_key_for(alice()) => { + (111 * DOLLARS).encode() + }, + >::hashed_key().to_vec() => { + (111 * DOLLARS).encode() + }, + >::hashed_key().to_vec() => vec![0u8; 16], + >::hashed_key_for(0) => vec![0u8; 32] + ], + children: map![], + }); let r = executor_call:: _>( &mut t, @@ -913,7 +930,7 @@ mod tests { None, ).0.unwrap(); - assert!(t.ext().storage_changes_root(GENESIS_HASH.into()).unwrap().is_some()); + assert!(t.ext().storage_changes_root(&GENESIS_HASH.encode()).unwrap().is_some()); } #[test] @@ -929,12 +946,14 @@ mod tests { None, ).0.unwrap(); - assert!(t.ext().storage_changes_root(GENESIS_HASH.into()).unwrap().is_some()); + assert!(t.ext().storage_changes_root(&GENESIS_HASH.encode()).unwrap().is_some()); } #[test] fn should_import_block_with_test_client() { - use node_testing::client::{ClientExt, TestClientBuilderExt, TestClientBuilder, consensus::BlockOrigin}; + use node_testing::client::{ + ClientExt, TestClientBuilderExt, TestClientBuilder, sp_consensus::BlockOrigin + }; let client = TestClientBuilder::new().build(); let block1 = changes_trie_block(); @@ -966,11 +985,11 @@ mod tests { vec![ CheckedExtrinsic { signed: None, - function: Call::Timestamp(timestamp::Call::set(42 * 1000)), + function: Call::Timestamp(pallet_timestamp::Call::set(42 * 1000)), }, CheckedExtrinsic { signed: Some((charlie(), signed_extra(0, 0))), - function: Call::System(system::Call::fill_block()), + function: Call::System(frame_system::Call::fill_block()), } ] ); @@ -983,11 +1002,11 @@ mod tests { vec![ CheckedExtrinsic { signed: None, - function: Call::Timestamp(timestamp::Call::set(52 * 1000)), + function: Call::Timestamp(pallet_timestamp::Call::set(52 * 1000)), }, CheckedExtrinsic { signed: Some((charlie(), signed_extra(1, 0))), - function: Call::System(system::Call::remark(vec![0; 1])), + function: Call::System(frame_system::Call::remark(vec![0; 1])), } ] ); @@ -1037,19 +1056,22 @@ mod tests { // - 1 MILLICENTS in substrate node. // - 1 milli-dot based on current polkadot runtime. // (this baed on assigning 0.1 CENT to the cheapest tx with `weight = 100`) - let mut t = TestExternalities::::new_with_code(COMPACT_CODE, (map![ - >::hashed_key_for(alice()) => { - (100 * DOLLARS).encode() - }, - >::hashed_key_for(bob()) => { - (10 * DOLLARS).encode() - }, - >::hashed_key().to_vec() => { - (110 * DOLLARS).encode() - }, - >::hashed_key().to_vec() => vec![0u8; 16], - >::hashed_key_for(0) => vec![0u8; 32] - ], map![])); + let mut t = TestExternalities::::new_with_code(COMPACT_CODE, Storage { + top: map![ + >::hashed_key_for(alice()) => { + (100 * DOLLARS).encode() + }, + >::hashed_key_for(bob()) => { + (10 * DOLLARS).encode() + }, + >::hashed_key().to_vec() => { + (110 * DOLLARS).encode() + }, + >::hashed_key().to_vec() => vec![0u8; 16], + >::hashed_key_for(0) => vec![0u8; 32] + ], + children: map![], + }); let tip = 1_000_000; let xt = sign(CheckedExtrinsic { @@ -1126,12 +1148,12 @@ mod tests { let num_transfers = block_number * factor; let mut xts = (0..num_transfers).map(|i| CheckedExtrinsic { signed: Some((charlie(), signed_extra(nonce + i as Index, 0))), - function: Call::Balances(balances::Call::transfer(bob().into(), 0)), + function: Call::Balances(pallet_balances::Call::transfer(bob().into(), 0)), }).collect::>(); xts.insert(0, CheckedExtrinsic { signed: None, - function: Call::Timestamp(timestamp::Call::set(time * 1000)), + function: Call::Timestamp(pallet_timestamp::Call::set(time * 1000)), }); // NOTE: this is super slow. Can probably be improved. @@ -1198,11 +1220,11 @@ mod tests { vec![ CheckedExtrinsic { signed: None, - function: Call::Timestamp(timestamp::Call::set(time * 1000)), + function: Call::Timestamp(pallet_timestamp::Call::set(time * 1000)), }, CheckedExtrinsic { signed: Some((charlie(), signed_extra(nonce, 0))), - function: Call::System(system::Call::remark(vec![0u8; (block_number * factor) as usize])), + function: Call::System(frame_system::Call::remark(vec![0u8; (block_number * factor) as usize])), }, ] ); diff --git a/bin/node/primitives/Cargo.toml b/bin/node/primitives/Cargo.toml index 1f632dda8dd5cba1694efef5ab36035be1839874..1ecfd76792cc628f8c1040c8b0f29901886a18ee 100644 --- a/bin/node/primitives/Cargo.toml +++ b/bin/node/primitives/Cargo.toml @@ -5,16 +5,16 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -primitives = { package = "substrate-primitives", path = "../../../primitives/core", default-features = false } -sr-primitives = { path = "../../../primitives/sr-primitives", default-features = false } +sp-core = { version = "2.0.0", default-features = false, path = "../../../primitives/core" } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../../primitives/runtime" } [dev-dependencies] -substrate-serializer = { path = "../../../primitives/serializer" } +sp-serializer = { version = "2.0.0", path = "../../../primitives/serializer" } pretty_assertions = "0.6.1" [features] default = ["std"] std = [ - "primitives/std", - "sr-primitives/std", + "sp-core/std", + "sp-runtime/std", ] diff --git a/bin/node/primitives/src/lib.rs b/bin/node/primitives/src/lib.rs index b6a5ec05655c5ff90cf4e9180ecb90b52dcd020b..9cd9c047c94ee33b4e6640bb53bc29eda6a91d80 100644 --- a/bin/node/primitives/src/lib.rs +++ b/bin/node/primitives/src/lib.rs @@ -20,7 +20,7 @@ #![cfg_attr(not(feature = "std"), no_std)] -use sr_primitives::{ +use sp_runtime::{ generic, traits::{Verify, BlakeTwo256, IdentifyAccount}, OpaqueExtrinsic, MultiSignature }; @@ -47,7 +47,7 @@ pub type Moment = u64; pub type Index = u32; /// A hash of some data used by the chain. -pub type Hash = primitives::H256; +pub type Hash = sp_core::H256; /// A timestamp: milliseconds since the unix epoch. /// `u64` is enough to represent a duration of half a billion years, when the diff --git a/bin/node/rpc-client/Cargo.toml b/bin/node/rpc-client/Cargo.toml index 882dd7ee2b629680b950e63facf01afdbc65f831..5ef9d1e99d16c1189d8b89be507e38589cd977fa 100644 --- a/bin/node/rpc-client/Cargo.toml +++ b/bin/node/rpc-client/Cargo.toml @@ -10,5 +10,5 @@ futures = "0.1.29" hyper = "0.12.35" jsonrpc-core-client = { version = "14.0.3", features = ["http", "ws"] } log = "0.4.8" -node-primitives = { path = "../primitives" } -substrate-rpc = { path = "../../../client/rpc", version = "2.0.0" } +node-primitives = { version = "2.0.0", path = "../primitives" } +sc-rpc = { version = "2.0.0", path = "../../../client/rpc" } diff --git a/bin/node/rpc-client/src/main.rs b/bin/node/rpc-client/src/main.rs index fe057bcbeaf4236661d5109513138a93a7e894f7..3874556ef621763f3b53cd12f0ec4911f23e0d2c 100644 --- a/bin/node/rpc-client/src/main.rs +++ b/bin/node/rpc-client/src/main.rs @@ -24,7 +24,7 @@ use futures::Future; use hyper::rt; use node_primitives::Hash; -use substrate_rpc::author::{ +use sc_rpc::author::{ AuthorClient, hash::ExtrinsicOrHash, }; diff --git a/bin/node/rpc/Cargo.toml b/bin/node/rpc/Cargo.toml index e9889854ee45913d4a21d4babe60d66eb645c83a..634a946bb713fb343d9a7f990aba17bd6cce8221 100644 --- a/bin/node/rpc/Cargo.toml +++ b/bin/node/rpc/Cargo.toml @@ -5,12 +5,12 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -client = { package = "substrate-client", path = "../../../client/" } +sc-client = { version = "2.0.0", path = "../../../client/" } jsonrpc-core = "14.0.3" -node-primitives = { path = "../primitives" } -node-runtime = { path = "../runtime" } -sr-primitives = { path = "../../../primitives/sr-primitives" } -pallet-contracts-rpc = { path = "../../../frame/contracts/rpc/" } -pallet-transaction-payment-rpc = { path = "../../../frame/transaction-payment/rpc/" } -frame-system-rpc = { path = "../../../frame/system/rpc/" } -transaction_pool = { package = "substrate-transaction-pool", path = "../../../client/transaction-pool" } +node-primitives = { version = "2.0.0", path = "../primitives" } +node-runtime = { version = "2.0.0", path = "../runtime" } +sp-runtime = { version = "2.0.0", path = "../../../primitives/runtime" } +pallet-contracts-rpc = { version = "2.0.0", path = "../../../frame/contracts/rpc/" } +pallet-transaction-payment-rpc = { version = "2.0.0", path = "../../../frame/transaction-payment/rpc/" } +substrate-frame-rpc-system = { version = "2.0.0", path = "../../../utils/frame/rpc/system" } +sp-transaction-pool = { version = "2.0.0", path = "../../../primitives/transaction-pool" } diff --git a/bin/node/rpc/src/lib.rs b/bin/node/rpc/src/lib.rs index 7f19af45e47ca5b3b0dc4496caef99fa0dc6b2f8..67a349598ff4278d438b0c4477b5127cafbcbe5b 100644 --- a/bin/node/rpc/src/lib.rs +++ b/bin/node/rpc/src/lib.rs @@ -18,7 +18,7 @@ //! //! Since `substrate` core functionality makes no assumptions //! about the modules used inside the runtime, so do -//! RPC methods defined in `substrate-rpc` crate. +//! RPC methods defined in `sc-rpc` crate. //! It means that `client/rpc` can't have any methods that //! need some strong assumptions about the particular runtime. //! @@ -33,33 +33,69 @@ use std::sync::Arc; use node_primitives::{Block, AccountId, Index, Balance}; use node_runtime::UncheckedExtrinsic; -use sr_primitives::traits::ProvideRuntimeApi; -use transaction_pool::txpool::{ChainApi, Pool}; +use sp_runtime::traits::ProvideRuntimeApi; +use sp_transaction_pool::TransactionPool; + +/// Light client extra dependencies. +pub struct LightDeps { + /// Remote access to the blockchain (async). + pub remote_blockchain: Arc>, + /// Fetcher instance. + pub fetcher: Arc, +} + +impl LightDeps { + /// Create empty `LightDeps` with given `F` type. + /// + /// This is a convenience method to be used in the service builder, + /// to make sure the type of the `LightDeps` is matching. + pub fn none(_: Option>) -> Option { + None + } +} /// Instantiate all RPC extensions. -pub fn create(client: Arc, pool: Arc>) -> jsonrpc_core::IoHandler where +/// +/// If you provide `LightDeps`, the system is configured for light client. +pub fn create( + client: Arc, + pool: Arc

, + light_deps: Option>, +) -> jsonrpc_core::IoHandler where C: ProvideRuntimeApi, - C: client::blockchain::HeaderBackend, + C: sc_client::blockchain::HeaderBackend, C: Send + Sync + 'static, - C::Api: frame_system_rpc::AccountNonceApi, + C::Api: substrate_frame_rpc_system::AccountNonceApi, C::Api: pallet_contracts_rpc::ContractsRuntimeApi, C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi, - P: ChainApi + Sync + Send + 'static, + F: sc_client::light::fetcher::Fetcher + 'static, + P: TransactionPool + 'static, M: jsonrpc_core::Metadata + Default, { - use frame_system_rpc::{System, SystemApi}; + use substrate_frame_rpc_system::{FullSystem, LightSystem, SystemApi}; use pallet_contracts_rpc::{Contracts, ContractsApi}; use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApi}; let mut io = jsonrpc_core::IoHandler::default(); - io.extend_with( - SystemApi::to_delegate(System::new(client.clone(), pool)) - ); - io.extend_with( - ContractsApi::to_delegate(Contracts::new(client.clone())) - ); - io.extend_with( - TransactionPaymentApi::to_delegate(TransactionPayment::new(client)) - ); + + if let Some(LightDeps { remote_blockchain, fetcher }) = light_deps { + io.extend_with( + SystemApi::::to_delegate(LightSystem::new(client, remote_blockchain, fetcher, pool)) + ); + } else { + io.extend_with( + SystemApi::to_delegate(FullSystem::new(client.clone(), pool)) + ); + + // Making synchronous calls in light client freezes the browser currently, + // more context: https://github.com/paritytech/substrate/pull/3480 + // These RPCs should use an asynchronous caller instead. + io.extend_with( + ContractsApi::to_delegate(Contracts::new(client.clone())) + ); + io.extend_with( + TransactionPaymentApi::to_delegate(TransactionPayment::new(client)) + ); + } io } diff --git a/bin/node/runtime/Cargo.toml b/bin/node/runtime/Cargo.toml index 3844fa336fd698b7cffdc20275827eae5c78a7fc..33cb7b61dbd5cb7ffd203d540ad0e73c3f4466f1 100644 --- a/bin/node/runtime/Cargo.toml +++ b/bin/node/runtime/Cargo.toml @@ -14,109 +14,109 @@ rustc-hex = { version = "2.0", optional = true } serde = { version = "1.0.102", optional = true } # primitives -authority-discovery-primitives = { package = "substrate-authority-discovery-primitives", path = "../../../primitives/authority-discovery", default-features = false } -babe-primitives = { package = "substrate-consensus-babe-primitives", path = "../../../primitives/consensus/babe", default-features = false } -block-builder-api = { package = "substrate-block-builder-runtime-api", path = "../../../primitives/block-builder/runtime-api", default-features = false} -inherents = { package = "substrate-inherents", path = "../../../primitives/inherents", default-features = false } -node-primitives = { path = "../primitives", default-features = false } -offchain-primitives = { package = "substrate-offchain-primitives", path = "../../../primitives/offchain", default-features = false } -primitives = { package = "substrate-primitives", path = "../../../primitives/core", default-features = false } -rstd = { package = "sr-std", path = "../../../primitives/sr-std", default-features = false } -sr-api = { path = "../../../primitives/sr-api", default-features = false } -sr-primitives = { path = "../../../primitives/sr-primitives", default-features = false } -sr-staking-primitives = { path = "../../../primitives/sr-staking-primitives", default-features = false } -substrate-keyring = { path = "../../../primitives/keyring", optional = true } -substrate-session = { path = "../../../primitives/session", default-features = false } -tx-pool-api = { package = "substrate-transaction-pool-runtime-api", path = "../../../primitives/transaction-pool/runtime-api", default-features = false } -version = { package = "sr-version", path = "../../../primitives/sr-version", default-features = false } +sp-authority-discovery = { version = "2.0.0", default-features = false, path = "../../../primitives/authority-discovery" } +sp-consensus-babe = { version = "0.8", default-features = false, path = "../../../primitives/consensus/babe" } +sp-block-builder = { path = "../../../primitives/block-builder", default-features = false} +sp-inherents = { version = "2.0.0", default-features = false, path = "../../../primitives/inherents" } +node-primitives = { version = "2.0.0", default-features = false, path = "../primitives" } +sp-offchain = { version = "2.0.0", default-features = false, path = "../../../primitives/offchain" } +sp-core = { version = "2.0.0", default-features = false, path = "../../../primitives/core" } +sp-std = { version = "2.0.0", default-features = false, path = "../../../primitives/std" } +sp-api = { version = "2.0.0", default-features = false, path = "../../../primitives/api" } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../../primitives/runtime" } +sp-staking = { version = "2.0.0", default-features = false, path = "../../../primitives/staking" } +sp-keyring = { version = "2.0.0", optional = true, path = "../../../primitives/keyring" } +sp-session = { version = "2.0.0", default-features = false, path = "../../../primitives/session" } +sp-transaction-pool = { version = "2.0.0", default-features = false, path = "../../../primitives/transaction-pool" } +sp-version = { version = "2.0.0", default-features = false, path = "../../../primitives/version" } # frame dependencies -authority-discovery = { package = "pallet-authority-discovery", path = "../../../frame/authority-discovery", default-features = false } -authorship = { package = "pallet-authorship", path = "../../../frame/authorship", default-features = false } -babe = { package = "pallet-babe", path = "../../../frame/babe", default-features = false } -balances = { package = "pallet-balances", path = "../../../frame/balances", default-features = false } -collective = { package = "pallet-collective", path = "../../../frame/collective", default-features = false } -contracts = { package = "pallet-contracts", path = "../../../frame/contracts", default-features = false } -contracts-rpc-runtime-api = { package = "pallet-contracts-rpc-runtime-api", path = "../../../frame/contracts/rpc/runtime-api/", default-features = false } -democracy = { package = "pallet-democracy", path = "../../../frame/democracy", default-features = false } -elections-phragmen = { package = "pallet-elections-phragmen", path = "../../../frame/elections-phragmen", default-features = false } -executive = { package = "frame-executive", path = "../../../frame/executive", default-features = false } -finality-tracker = { package = "pallet-finality-tracker", path = "../../../frame/finality-tracker", default-features = false } -grandpa = { package = "pallet-grandpa", path = "../../../frame/grandpa", default-features = false } -im-online = { package = "pallet-im-online", path = "../../../frame/im-online", default-features = false } -indices = { package = "pallet-indices", path = "../../../frame/indices", default-features = false } -membership = { package = "pallet-membership", path = "../../../frame/membership", default-features = false } -nicks = { package = "pallet-nicks", path = "../../../frame/nicks", default-features = false } -offences = { package = "pallet-offences", path = "../../../frame/offences", default-features = false } -randomness-collective-flip = { package = "pallet-randomness-collective-flip", path = "../../../frame/randomness-collective-flip", default-features = false } -session = { package = "pallet-session", path = "../../../frame/session", default-features = false, features = ["historical"] } -staking = { package = "pallet-staking", path = "../../../frame/staking", default-features = false } -pallet-staking-reward-curve = { path = "../../../frame/staking/reward-curve"} -sudo = { package = "pallet-sudo", path = "../../../frame/sudo", default-features = false } -support = { package = "frame-support", path = "../../../frame/support", default-features = false } -system = { package = "frame-system", path = "../../../frame/system", default-features = false } -system-rpc-runtime-api = { package = "frame-system-rpc-runtime-api", path = "../../../frame/system/rpc/runtime-api/", default-features = false } -timestamp = { package = "pallet-timestamp", path = "../../../frame/timestamp", default-features = false } -treasury = { package = "pallet-treasury", path = "../../../frame/treasury", default-features = false } -utility = { package = "frame-utility", path = "../../../frame/utility", default-features = false } -transaction-payment = { package = "pallet-transaction-payment", path = "../../../frame/transaction-payment", default-features = false } -transaction-payment-rpc-runtime-api = { package = "pallet-transaction-payment-rpc-runtime-api", path = "../../../frame/transaction-payment/rpc/runtime-api/", default-features = false } +pallet-authority-discovery = { version = "2.0.0", default-features = false, path = "../../../frame/authority-discovery" } +pallet-authorship = { version = "2.0.0", default-features = false, path = "../../../frame/authorship" } +pallet-babe = { version = "2.0.0", default-features = false, path = "../../../frame/babe" } +pallet-balances = { version = "2.0.0", default-features = false, path = "../../../frame/balances" } +pallet-collective = { version = "2.0.0", default-features = false, path = "../../../frame/collective" } +pallet-contracts = { version = "2.0.0", default-features = false, path = "../../../frame/contracts" } +pallet-contracts-rpc-runtime-api = { version = "2.0.0", default-features = false, path = "../../../frame/contracts/rpc/runtime-api/" } +pallet-democracy = { version = "2.0.0", default-features = false, path = "../../../frame/democracy" } +pallet-elections-phragmen = { version = "2.0.0", default-features = false, path = "../../../frame/elections-phragmen" } +frame-executive = { version = "2.0.0", default-features = false, path = "../../../frame/executive" } +pallet-finality-tracker = { version = "2.0.0", default-features = false, path = "../../../frame/finality-tracker" } +pallet-grandpa = { version = "2.0.0", default-features = false, path = "../../../frame/grandpa" } +pallet-im-online = { version = "2.0.0", default-features = false, path = "../../../frame/im-online" } +pallet-indices = { version = "2.0.0", default-features = false, path = "../../../frame/indices" } +pallet-membership = { version = "2.0.0", default-features = false, path = "../../../frame/membership" } +pallet-nicks = { version = "2.0.0", default-features = false, path = "../../../frame/nicks" } +pallet-offences = { version = "2.0.0", default-features = false, path = "../../../frame/offences" } +pallet-randomness-collective-flip = { version = "2.0.0", default-features = false, path = "../../../frame/randomness-collective-flip" } +pallet-session = { version = "2.0.0", features = ["historical"], path = "../../../frame/session", default-features = false } +pallet-staking = { version = "2.0.0", features = ["migrate"], path = "../../../frame/staking", default-features = false } +pallet-staking-reward-curve = { version = "2.0.0", path = "../../../frame/staking/reward-curve" } +pallet-sudo = { version = "2.0.0", default-features = false, path = "../../../frame/sudo" } +frame-support = { version = "2.0.0", default-features = false, path = "../../../frame/support" } +frame-system = { version = "2.0.0", default-features = false, path = "../../../frame/system" } +frame-system-rpc-runtime-api = { version = "2.0.0", default-features = false, path = "../../../frame/system/rpc/runtime-api/" } +pallet-timestamp = { version = "2.0.0", default-features = false, path = "../../../frame/timestamp" } +pallet-treasury = { version = "2.0.0", default-features = false, path = "../../../frame/treasury" } +pallet-utility = { version = "2.0.0", default-features = false, path = "../../../frame/utility" } +pallet-transaction-payment = { version = "2.0.0", default-features = false, path = "../../../frame/transaction-payment" } +pallet-transaction-payment-rpc-runtime-api = { version = "2.0.0", default-features = false, path = "../../../frame/transaction-payment/rpc/runtime-api/" } [build-dependencies] -wasm-builder-runner = { package = "substrate-wasm-builder-runner", path = "../../../client/utils/wasm-builder-runner", version = "1.0.4" } +wasm-builder-runner = { version = "1.0.4", package = "substrate-wasm-builder-runner", path = "../../../utils/wasm-builder-runner" } [dev-dependencies] -runtime_io = { package = "sr-io", path = "../../../primitives/sr-io" } +sp-io = { version = "2.0.0", path = "../../../primitives/io" } [features] default = ["std"] std = [ - "authority-discovery-primitives/std", - "authority-discovery/std", - "authorship/std", - "babe-primitives/std", - "babe/std", - "balances/std", - "block-builder-api/std", + "sp-authority-discovery/std", + "pallet-authority-discovery/std", + "pallet-authorship/std", + "sp-consensus-babe/std", + "pallet-babe/std", + "pallet-balances/std", + "sp-block-builder/std", "codec/std", - "collective/std", - "contracts-rpc-runtime-api/std", - "contracts/std", - "democracy/std", - "elections-phragmen/std", - "executive/std", - "finality-tracker/std", - "grandpa/std", - "im-online/std", - "indices/std", - "inherents/std", - "membership/std", - "nicks/std", + "pallet-collective/std", + "pallet-contracts-rpc-runtime-api/std", + "pallet-contracts/std", + "pallet-democracy/std", + "pallet-elections-phragmen/std", + "frame-executive/std", + "pallet-finality-tracker/std", + "pallet-grandpa/std", + "pallet-im-online/std", + "pallet-indices/std", + "sp-inherents/std", + "pallet-membership/std", + "pallet-nicks/std", "node-primitives/std", - "offchain-primitives/std", - "offences/std", - "primitives/std", - "randomness-collective-flip/std", - "rstd/std", + "sp-offchain/std", + "pallet-offences/std", + "sp-core/std", + "pallet-randomness-collective-flip/std", + "sp-std/std", "rustc-hex", "safe-mix/std", "serde", - "session/std", - "sr-api/std", - "sr-primitives/std", - "sr-staking-primitives/std", - "staking/std", - "substrate-keyring", - "substrate-session/std", - "sudo/std", - "support/std", - "system-rpc-runtime-api/std", - "system/std", - "timestamp/std", - "transaction-payment-rpc-runtime-api/std", - "transaction-payment/std", - "treasury/std", - "tx-pool-api/std", - "utility/std", - "version/std", + "pallet-session/std", + "sp-api/std", + "sp-runtime/std", + "sp-staking/std", + "pallet-staking/std", + "sp-keyring", + "sp-session/std", + "pallet-sudo/std", + "frame-support/std", + "frame-system-rpc-runtime-api/std", + "frame-system/std", + "pallet-timestamp/std", + "pallet-transaction-payment-rpc-runtime-api/std", + "pallet-transaction-payment/std", + "pallet-treasury/std", + "sp-transaction-pool/std", + "pallet-utility/std", + "sp-version/std", ] diff --git a/bin/node/runtime/src/impls.rs b/bin/node/runtime/src/impls.rs index de2efdae4af2ead5541c8f48b2d671ab1184fbb1..75aba8b7075ae8076f23656889c1cf9db56f60d5 100644 --- a/bin/node/runtime/src/impls.rs +++ b/bin/node/runtime/src/impls.rs @@ -17,9 +17,9 @@ //! Some configurable implementations as associated type for the substrate runtime. use node_primitives::Balance; -use sr_primitives::traits::{Convert, Saturating}; -use sr_primitives::{Fixed64, Perbill}; -use support::{traits::{OnUnbalanced, Currency, Get}, weights::Weight}; +use sp_runtime::traits::{Convert, Saturating}; +use sp_runtime::{Fixed64, Perbill}; +use frame_support::{traits::{OnUnbalanced, Currency, Get}, weights::Weight}; use crate::{Balances, System, Authorship, MaximumBlockWeight, NegativeImbalance}; pub struct Author; @@ -47,7 +47,7 @@ impl Convert for CurrencyToVoteHandler { /// Convert from weight to balance via a simple coefficient multiplication /// The associated type C encapsulates a constant in units of balance per weight -pub struct LinearWeightToFee(rstd::marker::PhantomData); +pub struct LinearWeightToFee(sp_std::marker::PhantomData); impl> Convert for LinearWeightToFee { fn convert(w: Weight) -> Balance { @@ -66,7 +66,7 @@ impl> Convert for LinearWeightToFee { /// /// Where `target_weight` must be given as the `Get` implementation of the `T` generic type. /// https://research.web3.foundation/en/latest/polkadot/Token%20Economics/#relay-chain-transaction-fees -pub struct TargetedFeeAdjustment(rstd::marker::PhantomData); +pub struct TargetedFeeAdjustment(sp_std::marker::PhantomData); impl> Convert for TargetedFeeAdjustment { fn convert(multiplier: Fixed64) -> Fixed64 { @@ -115,10 +115,10 @@ impl> Convert for TargetedFeeAdjustment { #[cfg(test)] mod tests { use super::*; - use sr_primitives::assert_eq_error_rate; + use sp_runtime::assert_eq_error_rate; use crate::{MaximumBlockWeight, AvailableBlockRatio, Runtime}; use crate::{constants::currency::*, TransactionPayment, TargetBlockFullness}; - use support::weights::Weight; + use frame_support::weights::Weight; fn max() -> Weight { MaximumBlockWeight::get() @@ -150,8 +150,8 @@ mod tests { } fn run_with_system_weight(w: Weight, assertions: F) where F: Fn() -> () { - let mut t: runtime_io::TestExternalities = - system::GenesisConfig::default().build_storage::().unwrap().into(); + let mut t: sp_io::TestExternalities = + frame_system::GenesisConfig::default().build_storage::().unwrap().into(); t.execute_with(|| { System::set_block_limits(w, 0); assertions() @@ -227,7 +227,7 @@ mod tests { if fm == next { panic!("The fee should ever increase"); } fm = next; iterations += 1; - let fee = ::WeightToFee::convert(tx_weight); + let fee = ::WeightToFee::convert(tx_weight); let adjusted_fee = fm.saturated_multiply_accumulate(fee); println!( "iteration {}, new fm = {:?}. Fee at this point is: {} units / {} millicents, \ @@ -340,7 +340,7 @@ mod tests { mb, 10 * mb, Weight::max_value() / 2, - Weight::max_value() + Weight::max_value(), ].into_iter().for_each(|i| { run_with_system_weight(i, || { let next = TargetedFeeAdjustment::::convert(Fixed64::default()); diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index c4752bae06d46d8e3cd9983e3027a819476a88db..488b29aa2aab9fac760d43ce1bd91f90b902beb0 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -20,42 +20,42 @@ // `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256. #![recursion_limit="256"] -use rstd::prelude::*; -use support::{ +use sp_std::prelude::*; +use frame_support::{ construct_runtime, parameter_types, weights::Weight, traits::{SplitTwoWays, Currency, Randomness}, }; -use primitives::u32_trait::{_1, _2, _3, _4}; +use sp_core::u32_trait::{_1, _2, _3, _4}; use node_primitives::{AccountId, AccountIndex, Balance, BlockNumber, Hash, Index, Moment, Signature}; -use sr_api::impl_runtime_apis; -use sr_primitives::{Permill, Perbill, ApplyExtrinsicResult, impl_opaque_keys, generic, create_runtime_str}; -use sr_primitives::curve::PiecewiseLinear; -use sr_primitives::transaction_validity::TransactionValidity; -use sr_primitives::traits::{ +use sp_api::impl_runtime_apis; +use sp_runtime::{Permill, Perbill, ApplyExtrinsicResult, impl_opaque_keys, generic, create_runtime_str}; +use sp_runtime::curve::PiecewiseLinear; +use sp_runtime::transaction_validity::TransactionValidity; +use sp_runtime::traits::{ self, BlakeTwo256, Block as BlockT, NumberFor, StaticLookup, SaturatedConversion, OpaqueKeys, }; -use version::RuntimeVersion; +use sp_version::RuntimeVersion; #[cfg(any(feature = "std", test))] -use version::NativeVersion; -use primitives::OpaqueMetadata; -use grandpa::AuthorityList as GrandpaAuthorityList; -use grandpa::fg_primitives; -use im_online::sr25519::{AuthorityId as ImOnlineId}; -use authority_discovery_primitives::AuthorityId as AuthorityDiscoveryId; -use transaction_payment_rpc_runtime_api::RuntimeDispatchInfo; -use contracts_rpc_runtime_api::ContractExecResult; -use system::offchain::TransactionSubmitter; -use inherents::{InherentData, CheckInherentsResult}; +use sp_version::NativeVersion; +use sp_core::OpaqueMetadata; +use pallet_grandpa::AuthorityList as GrandpaAuthorityList; +use pallet_grandpa::fg_primitives; +use pallet_im_online::sr25519::{AuthorityId as ImOnlineId}; +use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId; +use pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo; +use pallet_contracts_rpc_runtime_api::ContractExecResult; +use frame_system::offchain::TransactionSubmitter; +use sp_inherents::{InherentData, CheckInherentsResult}; #[cfg(any(feature = "std", test))] -pub use sr_primitives::BuildStorage; -pub use timestamp::Call as TimestampCall; -pub use balances::Call as BalancesCall; -pub use contracts::Gas; -pub use support::StorageValue; -pub use staking::StakerStatus; +pub use sp_runtime::BuildStorage; +pub use pallet_timestamp::Call as TimestampCall; +pub use pallet_balances::Call as BalancesCall; +pub use pallet_contracts::Gas; +pub use frame_support::StorageValue; +pub use pallet_staking::StakerStatus; /// Implementations of some helper traits passed into runtime modules as associated types. pub mod impls; @@ -78,8 +78,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to equal spec_version. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 195, - impl_version: 195, + spec_version: 198, + impl_version: 198, apis: RUNTIME_API_VERSIONS, }; @@ -109,7 +109,7 @@ parameter_types! { pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); } -impl system::Trait for Runtime { +impl frame_system::Trait for Runtime { type Origin = Origin; type Call = Call; type Index = Index; @@ -125,9 +125,10 @@ impl system::Trait for Runtime { type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = Version; + type ModuleToIndex = (); } -impl utility::Trait for Runtime { +impl pallet_utility::Trait for Runtime { type Event = Event; type Call = Call; } @@ -137,16 +138,16 @@ parameter_types! { pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK; } -impl babe::Trait for Runtime { +impl pallet_babe::Trait for Runtime { type EpochDuration = EpochDuration; type ExpectedBlockTime = ExpectedBlockTime; - type EpochChangeTrigger = babe::ExternalTrigger; + type EpochChangeTrigger = pallet_babe::ExternalTrigger; } -impl indices::Trait for Runtime { +impl pallet_indices::Trait for Runtime { type AccountIndex = AccountIndex; type IsDeadAccount = Balances; - type ResolveHint = indices::SimpleResolveHint; + type ResolveHint = pallet_indices::SimpleResolveHint; type Event = Event; } @@ -156,7 +157,7 @@ parameter_types! { pub const CreationFee: Balance = 1 * CENTS; } -impl balances::Trait for Runtime { +impl pallet_balances::Trait for Runtime { type Balance = Balance; type OnFreeBalanceZero = ((Staking, Contracts), Session); type OnNewAccount = Indices; @@ -177,7 +178,7 @@ parameter_types! { pub const TargetBlockFullness: Perbill = Perbill::from_percent(25); } -impl transaction_payment::Trait for Runtime { +impl pallet_transaction_payment::Trait for Runtime { type Currency = Balances; type OnTransactionPayment = DealWithFees; type TransactionBaseFee = TransactionBaseFee; @@ -189,7 +190,7 @@ impl transaction_payment::Trait for Runtime { parameter_types! { pub const MinimumPeriod: Moment = SLOT_DURATION / 2; } -impl timestamp::Trait for Runtime { +impl pallet_timestamp::Trait for Runtime { type Moment = Moment; type OnTimestampSet = Babe; type MinimumPeriod = MinimumPeriod; @@ -199,8 +200,8 @@ parameter_types! { pub const UncleGenerations: BlockNumber = 5; } -impl authorship::Trait for Runtime { - type FindAuthor = session::FindAccountFromAuthorIndex; +impl pallet_authorship::Trait for Runtime { + type FindAuthor = pallet_session::FindAccountFromAuthorIndex; type UncleGenerations = UncleGenerations; type FilterUncle = (); type EventHandler = (Staking, ImOnline); @@ -219,21 +220,21 @@ parameter_types! { pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(17); } -impl session::Trait for Runtime { +impl pallet_session::Trait for Runtime { type OnSessionEnding = Staking; type SessionHandler = ::KeyTypeIdProviders; type ShouldEndSession = Babe; type Event = Event; type Keys = SessionKeys; - type ValidatorId = ::AccountId; - type ValidatorIdOf = staking::StashOf; + type ValidatorId = ::AccountId; + type ValidatorIdOf = pallet_staking::StashOf; type SelectInitialValidators = Staking; type DisabledValidatorsThreshold = DisabledValidatorsThreshold; } -impl session::historical::Trait for Runtime { - type FullIdentification = staking::Exposure; - type FullIdentificationOf = staking::ExposureOf; +impl pallet_session::historical::Trait for Runtime { + type FullIdentification = pallet_staking::Exposure; + type FullIdentificationOf = pallet_staking::ExposureOf; } pallet_staking_reward_curve::build! { @@ -248,12 +249,13 @@ pallet_staking_reward_curve::build! { } parameter_types! { - pub const SessionsPerEra: sr_staking_primitives::SessionIndex = 6; - pub const BondingDuration: staking::EraIndex = 24 * 28; + pub const SessionsPerEra: sp_staking::SessionIndex = 6; + pub const BondingDuration: pallet_staking::EraIndex = 24 * 28; + pub const SlashDeferDuration: pallet_staking::EraIndex = 24 * 7; // 1/4 the bonding duration. pub const RewardCurve: &'static PiecewiseLinear<'static> = &REWARD_CURVE; } -impl staking::Trait for Runtime { +impl pallet_staking::Trait for Runtime { type Currency = Balances; type Time = Timestamp; type CurrencyToVote = CurrencyToVoteHandler; @@ -263,6 +265,9 @@ impl staking::Trait for Runtime { type Reward = (); // rewards are minted from the void type SessionsPerEra = SessionsPerEra; type BondingDuration = BondingDuration; + type SlashDeferDuration = SlashDeferDuration; + /// A super-majority of the council can cancel the slash. + type SlashCancelOrigin = pallet_collective::EnsureProportionAtLeast<_3, _4, AccountId, CouncilCollective>; type SessionInterface = Self; type RewardCurve = RewardCurve; } @@ -274,9 +279,11 @@ parameter_types! { pub const MinimumDeposit: Balance = 100 * DOLLARS; pub const EnactmentPeriod: BlockNumber = 30 * 24 * 60 * MINUTES; pub const CooloffPeriod: BlockNumber = 28 * 24 * 60 * MINUTES; + // One cent: $10,000 / MB + pub const PreimageByteDeposit: Balance = 1 * CENTS; } -impl democracy::Trait for Runtime { +impl pallet_democracy::Trait for Runtime { type Proposal = Call; type Event = Event; type Currency = Balances; @@ -286,25 +293,27 @@ impl democracy::Trait for Runtime { type EmergencyVotingPeriod = EmergencyVotingPeriod; type MinimumDeposit = MinimumDeposit; /// A straight majority of the council can decide what their next motion is. - type ExternalOrigin = collective::EnsureProportionAtLeast<_1, _2, AccountId, CouncilCollective>; + type ExternalOrigin = pallet_collective::EnsureProportionAtLeast<_1, _2, AccountId, CouncilCollective>; /// A super-majority can have the next scheduled referendum be a straight majority-carries vote. - type ExternalMajorityOrigin = collective::EnsureProportionAtLeast<_3, _4, AccountId, CouncilCollective>; + type ExternalMajorityOrigin = pallet_collective::EnsureProportionAtLeast<_3, _4, AccountId, CouncilCollective>; /// A unanimous council can have the next scheduled referendum be a straight default-carries /// (NTB) vote. - type ExternalDefaultOrigin = collective::EnsureProportionAtLeast<_1, _1, AccountId, CouncilCollective>; + type ExternalDefaultOrigin = pallet_collective::EnsureProportionAtLeast<_1, _1, AccountId, CouncilCollective>; /// Two thirds of the technical committee can have an ExternalMajority/ExternalDefault vote /// be tabled immediately and with a shorter voting/enactment period. - type FastTrackOrigin = collective::EnsureProportionAtLeast<_2, _3, AccountId, TechnicalCollective>; + type FastTrackOrigin = pallet_collective::EnsureProportionAtLeast<_2, _3, AccountId, TechnicalCollective>; // To cancel a proposal which has been passed, 2/3 of the council must agree to it. - type CancellationOrigin = collective::EnsureProportionAtLeast<_2, _3, AccountId, CouncilCollective>; + type CancellationOrigin = pallet_collective::EnsureProportionAtLeast<_2, _3, AccountId, CouncilCollective>; // Any single technical committee member may veto a coming council proposal, however they can // only do it once and it lasts only for the cooloff period. - type VetoOrigin = collective::EnsureMember; + type VetoOrigin = pallet_collective::EnsureMember; type CooloffPeriod = CooloffPeriod; + type PreimageByteDeposit = PreimageByteDeposit; + type Slash = Treasury; } -type CouncilCollective = collective::Instance1; -impl collective::Trait for Runtime { +type CouncilCollective = pallet_collective::Instance1; +impl pallet_collective::Trait for Runtime { type Origin = Origin; type Proposal = Call; type Event = Event; @@ -318,7 +327,7 @@ parameter_types! { pub const DesiredRunnersUp: u32 = 7; } -impl elections_phragmen::Trait for Runtime { +impl pallet_elections_phragmen::Trait for Runtime { type Event = Event; type Currency = Balances; type CurrencyToVote = CurrencyToVoteHandler; @@ -333,19 +342,19 @@ impl elections_phragmen::Trait for Runtime { type ChangeMembers = Council; } -type TechnicalCollective = collective::Instance2; -impl collective::Trait for Runtime { +type TechnicalCollective = pallet_collective::Instance2; +impl pallet_collective::Trait for Runtime { type Origin = Origin; type Proposal = Call; type Event = Event; } -impl membership::Trait for Runtime { +impl pallet_membership::Trait for Runtime { type Event = Event; - type AddOrigin = collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>; - type RemoveOrigin = collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>; - type SwapOrigin = collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>; - type ResetOrigin = collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>; + type AddOrigin = pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>; + type RemoveOrigin = pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>; + type SwapOrigin = pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>; + type ResetOrigin = pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>; type MembershipInitialized = TechnicalCommittee; type MembershipChanged = TechnicalCommittee; } @@ -357,10 +366,10 @@ parameter_types! { pub const Burn: Permill = Permill::from_percent(50); } -impl treasury::Trait for Runtime { +impl pallet_treasury::Trait for Runtime { type Currency = Balances; - type ApproveOrigin = collective::EnsureMembers<_4, AccountId, CouncilCollective>; - type RejectOrigin = collective::EnsureMembers<_2, AccountId, CouncilCollective>; + type ApproveOrigin = pallet_collective::EnsureMembers<_4, AccountId, CouncilCollective>; + type RejectOrigin = pallet_collective::EnsureMembers<_2, AccountId, CouncilCollective>; type Event = Event; type ProposalRejection = (); type ProposalBond = ProposalBond; @@ -381,20 +390,20 @@ parameter_types! { pub const SurchargeReward: Balance = 150 * DOLLARS; } -impl contracts::Trait for Runtime { +impl pallet_contracts::Trait for Runtime { type Currency = Balances; type Time = Timestamp; type Randomness = RandomnessCollectiveFlip; type Call = Call; type Event = Event; - type DetermineContractAddress = contracts::SimpleAddressDeterminator; - type ComputeDispatchFee = contracts::DefaultDispatchFeeComputor; - type TrieIdGenerator = contracts::TrieIdFromParentCounter; + type DetermineContractAddress = pallet_contracts::SimpleAddressDeterminator; + type ComputeDispatchFee = pallet_contracts::DefaultDispatchFeeComputor; + type TrieIdGenerator = pallet_contracts::TrieIdFromParentCounter; type GasPayment = (); type RentPayment = (); - type SignedClaimHandicap = contracts::DefaultSignedClaimHandicap; + type SignedClaimHandicap = pallet_contracts::DefaultSignedClaimHandicap; type TombstoneDeposit = TombstoneDeposit; - type StorageSizeOffset = contracts::DefaultStorageSizeOffset; + type StorageSizeOffset = pallet_contracts::DefaultStorageSizeOffset; type RentByteFee = RentByteFee; type RentDepositOffset = RentDepositOffset; type SurchargeReward = SurchargeReward; @@ -403,14 +412,14 @@ impl contracts::Trait for Runtime { type TransactionBaseFee = ContractTransactionBaseFee; type TransactionByteFee = ContractTransactionByteFee; type ContractFee = ContractFee; - type CallBaseFee = contracts::DefaultCallBaseFee; - type InstantiateBaseFee = contracts::DefaultInstantiateBaseFee; - type MaxDepth = contracts::DefaultMaxDepth; - type MaxValueSize = contracts::DefaultMaxValueSize; - type BlockGasLimit = contracts::DefaultBlockGasLimit; + type CallBaseFee = pallet_contracts::DefaultCallBaseFee; + type InstantiateBaseFee = pallet_contracts::DefaultInstantiateBaseFee; + type MaxDepth = pallet_contracts::DefaultMaxDepth; + type MaxValueSize = pallet_contracts::DefaultMaxValueSize; + type BlockGasLimit = pallet_contracts::DefaultBlockGasLimit; } -impl sudo::Trait for Runtime { +impl pallet_sudo::Trait for Runtime { type Event = Event; type Proposal = Call; } @@ -421,7 +430,7 @@ parameter_types! { pub const SessionDuration: BlockNumber = EPOCH_DURATION_IN_SLOTS as _; } -impl im_online::Trait for Runtime { +impl pallet_im_online::Trait for Runtime { type AuthorityId = ImOnlineId; type Call = Call; type Event = Event; @@ -430,15 +439,15 @@ impl im_online::Trait for Runtime { type SessionDuration = SessionDuration; } -impl offences::Trait for Runtime { +impl pallet_offences::Trait for Runtime { type Event = Event; - type IdentificationTuple = session::historical::IdentificationTuple; + type IdentificationTuple = pallet_session::historical::IdentificationTuple; type OnOffenceHandler = Staking; } -impl authority_discovery::Trait for Runtime {} +impl pallet_authority_discovery::Trait for Runtime {} -impl grandpa::Trait for Runtime { +impl pallet_grandpa::Trait for Runtime { type Event = Event; } @@ -447,7 +456,7 @@ parameter_types! { pub const ReportLatency: BlockNumber = 1000; } -impl finality_tracker::Trait for Runtime { +impl pallet_finality_tracker::Trait for Runtime { type OnFinalizationStalled = Grandpa; type WindowSize = WindowSize; type ReportLatency = ReportLatency; @@ -459,21 +468,21 @@ parameter_types! { pub const MaxLength: usize = 16; } -impl nicks::Trait for Runtime { +impl pallet_nicks::Trait for Runtime { type Event = Event; type Currency = Balances; type ReservationFee = ReservationFee; type Slashed = Treasury; - type ForceOrigin = collective::EnsureMember; + type ForceOrigin = pallet_collective::EnsureMember; type MinLength = MinLength; type MaxLength = MaxLength; } -impl system::offchain::CreateTransaction for Runtime { +impl frame_system::offchain::CreateTransaction for Runtime { type Public = ::Signer; type Signature = Signature; - fn create_transaction>( + fn create_transaction>( call: Call, public: Self::Public, account: AccountId, @@ -483,12 +492,12 @@ impl system::offchain::CreateTransaction for Runtim let current_block = System::block_number().saturated_into::(); let tip = 0; let extra: SignedExtra = ( - system::CheckVersion::::new(), - system::CheckGenesis::::new(), - system::CheckEra::::from(generic::Era::mortal(period, current_block)), - system::CheckNonce::::from(index), - system::CheckWeight::::new(), - transaction_payment::ChargeTransactionPayment::::from(tip), + frame_system::CheckVersion::::new(), + frame_system::CheckGenesis::::new(), + frame_system::CheckEra::::from(generic::Era::mortal(period, current_block)), + frame_system::CheckNonce::::from(index), + frame_system::CheckWeight::::new(), + pallet_transaction_payment::ChargeTransactionPayment::::from(tip), Default::default(), ); let raw_payload = SignedPayload::new(call, extra).ok()?; @@ -505,31 +514,31 @@ construct_runtime!( NodeBlock = node_primitives::Block, UncheckedExtrinsic = UncheckedExtrinsic { - System: system::{Module, Call, Storage, Config, Event}, - Utility: utility::{Module, Call, Event}, - Babe: babe::{Module, Call, Storage, Config, Inherent(Timestamp)}, - Timestamp: timestamp::{Module, Call, Storage, Inherent}, - Authorship: authorship::{Module, Call, Storage, Inherent}, - Indices: indices, - Balances: balances::{default, Error}, - TransactionPayment: transaction_payment::{Module, Storage}, - Staking: staking::{default, OfflineWorker}, - Session: session::{Module, Call, Storage, Event, Config}, - Democracy: democracy::{Module, Call, Storage, Config, Event}, - Council: collective::::{Module, Call, Storage, Origin, Event, Config}, - TechnicalCommittee: collective::::{Module, Call, Storage, Origin, Event, Config}, - Elections: elections_phragmen::{Module, Call, Storage, Event}, - TechnicalMembership: membership::::{Module, Call, Storage, Event, Config}, - FinalityTracker: finality_tracker::{Module, Call, Inherent}, - Grandpa: grandpa::{Module, Call, Storage, Config, Event}, - Treasury: treasury::{Module, Call, Storage, Config, Event}, - Contracts: contracts, - Sudo: sudo, - ImOnline: im_online::{Module, Call, Storage, Event, ValidateUnsigned, Config}, - AuthorityDiscovery: authority_discovery::{Module, Call, Config}, - Offences: offences::{Module, Call, Storage, Event}, - RandomnessCollectiveFlip: randomness_collective_flip::{Module, Call, Storage}, - Nicks: nicks::{Module, Call, Storage, Event}, + System: frame_system::{Module, Call, Storage, Config, Event}, + Utility: pallet_utility::{Module, Call, Event}, + Babe: pallet_babe::{Module, Call, Storage, Config, Inherent(Timestamp)}, + Timestamp: pallet_timestamp::{Module, Call, Storage, Inherent}, + Authorship: pallet_authorship::{Module, Call, Storage, Inherent}, + Indices: pallet_indices, + Balances: pallet_balances::{default, Error}, + TransactionPayment: pallet_transaction_payment::{Module, Storage}, + Staking: pallet_staking::{default, OfflineWorker}, + Session: pallet_session::{Module, Call, Storage, Event, Config}, + Democracy: pallet_democracy::{Module, Call, Storage, Config, Event}, + Council: pallet_collective::::{Module, Call, Storage, Origin, Event, Config}, + TechnicalCommittee: pallet_collective::::{Module, Call, Storage, Origin, Event, Config}, + Elections: pallet_elections_phragmen::{Module, Call, Storage, Event}, + TechnicalMembership: pallet_membership::::{Module, Call, Storage, Event, Config}, + FinalityTracker: pallet_finality_tracker::{Module, Call, Inherent}, + Grandpa: pallet_grandpa::{Module, Call, Storage, Config, Event}, + Treasury: pallet_treasury::{Module, Call, Storage, Config, Event}, + Contracts: pallet_contracts, + Sudo: pallet_sudo, + ImOnline: pallet_im_online::{Module, Call, Storage, Event, ValidateUnsigned, Config}, + AuthorityDiscovery: pallet_authority_discovery::{Module, Call, Config}, + Offences: pallet_offences::{Module, Call, Storage, Event}, + RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Module, Call, Storage}, + Nicks: pallet_nicks::{Module, Call, Storage, Event}, } ); @@ -545,13 +554,13 @@ pub type SignedBlock = generic::SignedBlock; pub type BlockId = generic::BlockId; /// The SignedExtension to the basic transaction logic. pub type SignedExtra = ( - system::CheckVersion, - system::CheckGenesis, - system::CheckEra, - system::CheckNonce, - system::CheckWeight, - transaction_payment::ChargeTransactionPayment, - contracts::CheckBlockGasLimit, + frame_system::CheckVersion, + frame_system::CheckGenesis, + frame_system::CheckEra, + frame_system::CheckNonce, + frame_system::CheckWeight, + pallet_transaction_payment::ChargeTransactionPayment, + pallet_contracts::CheckBlockGasLimit, ); /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; @@ -560,10 +569,10 @@ pub type SignedPayload = generic::SignedPayload; /// Extrinsic type that has already been checked. pub type CheckedExtrinsic = generic::CheckedExtrinsic; /// Executive: handles dispatch to the various modules. -pub type Executive = executive::Executive, Runtime, AllModules>; +pub type Executive = frame_executive::Executive, Runtime, AllModules>; impl_runtime_apis! { - impl sr_api::Core for Runtime { + impl sp_api::Core for Runtime { fn version() -> RuntimeVersion { VERSION } @@ -577,13 +586,13 @@ impl_runtime_apis! { } } - impl sr_api::Metadata for Runtime { + impl sp_api::Metadata for Runtime { fn metadata() -> OpaqueMetadata { Runtime::metadata().into() } } - impl block_builder_api::BlockBuilder for Runtime { + impl sp_block_builder::BlockBuilder for Runtime { fn apply_extrinsic(extrinsic: ::Extrinsic) -> ApplyExtrinsicResult { Executive::apply_extrinsic(extrinsic) } @@ -605,13 +614,13 @@ impl_runtime_apis! { } } - impl tx_pool_api::TaggedTransactionQueue for Runtime { + impl sp_transaction_pool::runtime_api::TaggedTransactionQueue for Runtime { fn validate_transaction(tx: ::Extrinsic) -> TransactionValidity { Executive::validate_transaction(tx) } } - impl offchain_primitives::OffchainWorkerApi for Runtime { + impl sp_offchain::OffchainWorkerApi for Runtime { fn offchain_worker(number: NumberFor) { Executive::offchain_worker(number) } @@ -623,14 +632,14 @@ impl_runtime_apis! { } } - impl babe_primitives::BabeApi for Runtime { - fn configuration() -> babe_primitives::BabeConfiguration { + impl sp_consensus_babe::BabeApi for Runtime { + fn configuration() -> sp_consensus_babe::BabeConfiguration { // The choice of `c` parameter (where `1 - c` represents the // probability of a slot being empty), is done in accordance to the // slot duration and expected target block time, for safely // resisting network delays of maximum two seconds. // - babe_primitives::BabeConfiguration { + sp_consensus_babe::BabeConfiguration { slot_duration: Babe::slot_duration(), epoch_length: EpochDuration::get(), c: PRIMARY_PROBABILITY, @@ -641,19 +650,19 @@ impl_runtime_apis! { } } - impl authority_discovery_primitives::AuthorityDiscoveryApi for Runtime { + impl sp_authority_discovery::AuthorityDiscoveryApi for Runtime { fn authorities() -> Vec { AuthorityDiscovery::authorities() } } - impl system_rpc_runtime_api::AccountNonceApi for Runtime { + impl frame_system_rpc_runtime_api::AccountNonceApi for Runtime { fn account_nonce(account: AccountId) -> Index { System::account_nonce(account) } } - impl contracts_rpc_runtime_api::ContractsApi for Runtime { + impl pallet_contracts_rpc_runtime_api::ContractsApi for Runtime { fn call( origin: AccountId, dest: AccountId, @@ -680,10 +689,10 @@ impl_runtime_apis! { fn get_storage( address: AccountId, key: [u8; 32], - ) -> contracts_rpc_runtime_api::GetStorageResult { + ) -> pallet_contracts_rpc_runtime_api::GetStorageResult { Contracts::get_storage(address, key).map_err(|rpc_err| { - use contracts::GetStorageError; - use contracts_rpc_runtime_api::{GetStorageError as RpcGetStorageError}; + use pallet_contracts::GetStorageError; + use pallet_contracts_rpc_runtime_api::{GetStorageError as RpcGetStorageError}; /// Map the contract error into the RPC layer error. match rpc_err { GetStorageError::ContractDoesntExist => RpcGetStorageError::ContractDoesntExist, @@ -693,7 +702,7 @@ impl_runtime_apis! { } } - impl transaction_payment_rpc_runtime_api::TransactionPaymentApi< + impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi< Block, Balance, UncheckedExtrinsic, @@ -703,7 +712,7 @@ impl_runtime_apis! { } } - impl substrate_session::SessionKeys for Runtime { + impl sp_session::SessionKeys for Runtime { fn generate_session_keys(seed: Option>) -> Vec { SessionKeys::generate(seed) } @@ -713,7 +722,7 @@ impl_runtime_apis! { #[cfg(test)] mod tests { use super::*; - use system::offchain::SubmitSignedTransaction; + use frame_system::offchain::SubmitSignedTransaction; fn is_submit_signed_transaction(_arg: T) where T: SubmitSignedTransaction< @@ -733,7 +742,7 @@ mod tests { #[test] fn block_hooks_weight_should_not_exceed_limits() { - use support::weights::WeighBlock; + use frame_support::weights::WeighBlock; let check_for_block = |b| { let block_hooks_weight = >::on_initialize(b) + diff --git a/bin/node/testing/Cargo.toml b/bin/node/testing/Cargo.toml index 2bfdd58a65b921f19df02c9002b600b5d1681cc0..4449c7bd22d473faa45d8d6b5acbf00668e46771 100644 --- a/bin/node/testing/Cargo.toml +++ b/bin/node/testing/Cargo.toml @@ -6,26 +6,26 @@ description = "Test utilities for Substrate node." edition = "2018" [dependencies] -balances = { package = "pallet-balances", path = "../../../frame/balances" } -client = { package = "substrate-client", path = "../../../client/" } +pallet-balances = { version = "2.0.0", path = "../../../frame/balances" } +sc-client = { version = "2.0.0", path = "../../../client/" } codec = { package = "parity-scale-codec", version = "1.0.0" } -contracts = { package = "pallet-contracts", path = "../../../frame/contracts" } -grandpa = { package = "pallet-grandpa", path = "../../../frame/grandpa" } -indices = { package = "pallet-indices", path = "../../../frame/indices" } -keyring = { package = "substrate-keyring", path = "../../../primitives/keyring" } -node-executor = { path = "../executor" } -node-primitives = { path = "../primitives" } -node-runtime = { path = "../runtime" } -primitives = { package = "substrate-primitives", path = "../../../primitives/core" } -runtime-io = { package = "sr-io", path = "../../../primitives/sr-io" } -runtime_support = { package = "frame-support", path = "../../../frame/support" } -session = { package = "pallet-session", path = "../../../frame/session" } -sr-primitives = { path = "../../../primitives/sr-primitives" } -staking = { package = "pallet-staking", path = "../../../frame/staking" } -substrate-executor = { path = "../../../client/executor" } -system = { package = "frame-system", path = "../../../frame/system" } -test-client = { package = "substrate-test-client", path = "../../../test/utils/client" } -timestamp = { package = "pallet-timestamp", path = "../../../frame/timestamp" } -transaction-payment = { package = "pallet-transaction-payment", path = "../../../frame/transaction-payment" } -treasury = { package = "pallet-treasury", path = "../../../frame/treasury" } +pallet-contracts = { version = "2.0.0", path = "../../../frame/contracts" } +pallet-grandpa = { version = "2.0.0", path = "../../../frame/grandpa" } +pallet-indices = { version = "2.0.0", path = "../../../frame/indices" } +sp-keyring = { version = "2.0.0", path = "../../../primitives/keyring" } +node-executor = { version = "2.0.0", path = "../executor" } +node-primitives = { version = "2.0.0", path = "../primitives" } +node-runtime = { version = "2.0.0", path = "../runtime" } +sp-core = { version = "2.0.0", path = "../../../primitives/core" } +sp-io = { version = "2.0.0", path = "../../../primitives/io" } +frame-support = { version = "2.0.0", path = "../../../frame/support" } +pallet-session = { version = "2.0.0", path = "../../../frame/session" } +sp-runtime = { version = "2.0.0", path = "../../../primitives/runtime" } +pallet-staking = { version = "2.0.0", path = "../../../frame/staking" } +sc-executor = { version = "2.0.0", path = "../../../client/executor" } +frame-system = { version = "2.0.0", path = "../../../frame/system" } +substrate-test-client = { version = "2.0.0", path = "../../../test-utils/client" } +pallet-timestamp = { version = "2.0.0", path = "../../../frame/timestamp" } +pallet-transaction-payment = { version = "2.0.0", path = "../../../frame/transaction-payment" } +pallet-treasury = { version = "2.0.0", path = "../../../frame/treasury" } wabt = "0.9.2" diff --git a/bin/node/testing/src/client.rs b/bin/node/testing/src/client.rs index 3b16f2cbcb97d801500e1bb8ffbef3f2e0c9bb9c..4cd193a69e1324bacdb921b2b32934b538746df8 100644 --- a/bin/node/testing/src/client.rs +++ b/bin/node/testing/src/client.rs @@ -16,21 +16,21 @@ //! Utilites to build a `TestClient` for `node-runtime`. -use sr_primitives::BuildStorage; +use sp_runtime::BuildStorage; /// Re-export test-client utilities. -pub use test_client::*; +pub use substrate_test_client::*; /// Call executor for `node-runtime` `TestClient`. -pub type Executor = substrate_executor::NativeExecutor; +pub type Executor = sc_executor::NativeExecutor; /// Default backend type. -pub type Backend = client_db::Backend; +pub type Backend = sc_client_db::Backend; /// Test client type. -pub type Client = client::Client< +pub type Client = sc_client::Client< Backend, - client::LocalCallExecutor, + sc_client::LocalCallExecutor, node_primitives::Block, node_runtime::RuntimeApi, >; @@ -41,8 +41,8 @@ pub struct GenesisParameters { support_changes_trie: bool, } -impl test_client::GenesisInit for GenesisParameters { - fn genesis_storage(&self) -> (StorageOverlay, ChildrenStorageOverlay) { +impl substrate_test_client::GenesisInit for GenesisParameters { + fn genesis_storage(&self) -> Storage { crate::genesis::config(self.support_changes_trie, None).build_storage().unwrap() } } @@ -56,8 +56,8 @@ pub trait TestClientBuilderExt: Sized { fn build(self) -> Client; } -impl TestClientBuilderExt for test_client::TestClientBuilder< - client::LocalCallExecutor, +impl TestClientBuilderExt for substrate_test_client::TestClientBuilder< + sc_client::LocalCallExecutor, Backend, GenesisParameters, > { diff --git a/bin/node/testing/src/genesis.rs b/bin/node/testing/src/genesis.rs index 1531ba134892afabfc74c29c86129bedc413f8b7..3a7e597ed5e07a46f4962519bc0e372f82b52a87 100644 --- a/bin/node/testing/src/genesis.rs +++ b/bin/node/testing/src/genesis.rs @@ -17,30 +17,30 @@ //! Genesis Configuration. use crate::keyring::*; -use keyring::{Ed25519Keyring, Sr25519Keyring}; +use sp_keyring::{Ed25519Keyring, Sr25519Keyring}; use node_runtime::{ GenesisConfig, BalancesConfig, SessionConfig, StakingConfig, SystemConfig, GrandpaConfig, IndicesConfig, ContractsConfig, WASM_BINARY, }; use node_runtime::constants::currency::*; -use primitives::ChangesTrieConfiguration; -use sr_primitives::Perbill; +use sp_core::ChangesTrieConfiguration; +use sp_runtime::Perbill; /// Create genesis runtime configuration for tests. pub fn config(support_changes_trie: bool, code: Option<&[u8]>) -> GenesisConfig { GenesisConfig { - system: Some(SystemConfig { + frame_system: Some(SystemConfig { changes_trie_config: if support_changes_trie { Some(ChangesTrieConfiguration { digest_interval: 2, digest_levels: 2, }) } else { None }, code: code.map(|x| x.to_vec()).unwrap_or_else(|| WASM_BINARY.to_vec()), }), - indices: Some(IndicesConfig { + pallet_indices: Some(IndicesConfig { ids: vec![alice(), bob(), charlie(), dave(), eve(), ferdie()], }), - balances: Some(BalancesConfig { + pallet_balances: Some(BalancesConfig { balances: vec![ (alice(), 111 * DOLLARS), (bob(), 100 * DOLLARS), @@ -51,7 +51,7 @@ pub fn config(support_changes_trie: bool, code: Option<&[u8]>) -> GenesisConfig ], vesting: vec![], }), - session: Some(SessionConfig { + pallet_session: Some(SessionConfig { keys: vec![ (alice(), to_session_keys( &Ed25519Keyring::Alice, @@ -67,12 +67,12 @@ pub fn config(support_changes_trie: bool, code: Option<&[u8]>) -> GenesisConfig )), ] }), - staking: Some(StakingConfig { + pallet_staking: Some(StakingConfig { current_era: 0, stakers: vec![ - (dave(), alice(), 111 * DOLLARS, staking::StakerStatus::Validator), - (eve(), bob(), 100 * DOLLARS, staking::StakerStatus::Validator), - (ferdie(), charlie(), 100 * DOLLARS, staking::StakerStatus::Validator) + (dave(), alice(), 111 * DOLLARS, pallet_staking::StakerStatus::Validator), + (eve(), bob(), 100 * DOLLARS, pallet_staking::StakerStatus::Validator), + (ferdie(), charlie(), 100 * DOLLARS, pallet_staking::StakerStatus::Validator) ], validator_count: 3, minimum_validator_count: 0, @@ -80,21 +80,21 @@ pub fn config(support_changes_trie: bool, code: Option<&[u8]>) -> GenesisConfig invulnerables: vec![alice(), bob(), charlie()], .. Default::default() }), - contracts: Some(ContractsConfig { + pallet_contracts: Some(ContractsConfig { current_schedule: Default::default(), gas_price: 1 * MILLICENTS, }), - babe: Some(Default::default()), - grandpa: Some(GrandpaConfig { + pallet_babe: Some(Default::default()), + pallet_grandpa: Some(GrandpaConfig { authorities: vec![], }), - im_online: Some(Default::default()), - authority_discovery: Some(Default::default()), - democracy: Some(Default::default()), - collective_Instance1: Some(Default::default()), - collective_Instance2: Some(Default::default()), - membership_Instance1: Some(Default::default()), - sudo: Some(Default::default()), - treasury: Some(Default::default()), + pallet_im_online: Some(Default::default()), + pallet_authority_discovery: Some(Default::default()), + pallet_democracy: Some(Default::default()), + pallet_collective_Instance1: Some(Default::default()), + pallet_collective_Instance2: Some(Default::default()), + pallet_membership_Instance1: Some(Default::default()), + pallet_sudo: Some(Default::default()), + pallet_treasury: Some(Default::default()), } } diff --git a/bin/node/testing/src/keyring.rs b/bin/node/testing/src/keyring.rs index 9c4f11fcf31102ad843954173dc2ed28bf4ee603..b3dd18b5395df584e59046463363121a0cef71bb 100644 --- a/bin/node/testing/src/keyring.rs +++ b/bin/node/testing/src/keyring.rs @@ -16,10 +16,10 @@ //! Test accounts. -use keyring::{AccountKeyring, Sr25519Keyring, Ed25519Keyring}; +use sp_keyring::{AccountKeyring, Sr25519Keyring, Ed25519Keyring}; use node_primitives::{AccountId, Balance, Index}; use node_runtime::{CheckedExtrinsic, UncheckedExtrinsic, SessionKeys, SignedExtra}; -use sr_primitives::generic::Era; +use sp_runtime::generic::Era; use codec::Encode; /// Alice's account id. @@ -66,12 +66,12 @@ pub fn to_session_keys( /// Returns transaction extra. pub fn signed_extra(nonce: Index, extra_fee: Balance) -> SignedExtra { ( - system::CheckVersion::new(), - system::CheckGenesis::new(), - system::CheckEra::from(Era::mortal(256, 0)), - system::CheckNonce::from(nonce), - system::CheckWeight::new(), - transaction_payment::ChargeTransactionPayment::from(extra_fee), + frame_system::CheckVersion::new(), + frame_system::CheckGenesis::new(), + frame_system::CheckEra::from(Era::mortal(256, 0)), + frame_system::CheckNonce::from(nonce), + frame_system::CheckWeight::new(), + pallet_transaction_payment::ChargeTransactionPayment::from(extra_fee), Default::default(), ) } @@ -84,13 +84,13 @@ pub fn sign(xt: CheckedExtrinsic, version: u32, genesis_hash: [u8; 32]) -> Unche let key = AccountKeyring::from_account_id(&signed).unwrap(); let signature = payload.using_encoded(|b| { if b.len() > 256 { - key.sign(&runtime_io::hashing::blake2_256(b)) + key.sign(&sp_io::hashing::blake2_256(b)) } else { key.sign(b) } }).into(); UncheckedExtrinsic { - signature: Some((indices::address::Address::Id(signed), signature, extra)), + signature: Some((pallet_indices::address::Address::Id(signed), signature, extra)), function: payload.0, } } diff --git a/bin/node/transaction-factory/Cargo.toml b/bin/node/transaction-factory/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..8b10e10f41f8189f6d6e1bc2d7699ea2589b4d24 --- /dev/null +++ b/bin/node/transaction-factory/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "node-transaction-factory" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +sp-block-builder = { version = "2.0.0", path = "../../../primitives/block-builder" } +sc-cli = { version = "2.0.0", path = "../../../client/cli" } +sc-client-api = { version = "2.0.0", path = "../../../client/api" } +sc-client = { version = "2.0.0", path = "../../../client" } +codec = { package = "parity-scale-codec", version = "1.0.0", features = ["derive"] } +sp-consensus = { version = "0.8", path = "../../../primitives/consensus/common" } +log = "0.4.8" +sp-core = { version = "2.0.0", path = "../../../primitives/core" } +sp-api = { version = "2.0.0", path = "../../../primitives/api" } +sp-runtime = { version = "2.0.0", path = "../../../primitives/runtime" } +sc-service = { version = "2.0.0", path = "../../../client/service" } +sp-blockchain = { version = "2.0.0", path = "../../../primitives/blockchain" } diff --git a/test/utils/transaction-factory/src/complex_mode.rs b/bin/node/transaction-factory/src/complex_mode.rs similarity index 91% rename from test/utils/transaction-factory/src/complex_mode.rs rename to bin/node/transaction-factory/src/complex_mode.rs index 086698ffc3ac9f76b2db66ae731c326b886a7d9d..61be2ab98756e2f67777a56b61ff1d32d4a56d2d 100644 --- a/test/utils/transaction-factory/src/complex_mode.rs +++ b/bin/node/transaction-factory/src/complex_mode.rs @@ -41,12 +41,12 @@ use std::sync::Arc; use log::info; -use client::Client; -use block_builder_api::BlockBuilder; -use sr_api::ConstructRuntimeApi; -use primitives::{Blake2Hasher, Hasher}; -use sr_primitives::generic::BlockId; -use sr_primitives::traits::{Block as BlockT, ProvideRuntimeApi, One, Zero}; +use sc_client::Client; +use sp_block_builder::BlockBuilder; +use sp_api::ConstructRuntimeApi; +use sp_core::{Blake2Hasher, Hasher}; +use sp_runtime::generic::BlockId; +use sp_runtime::traits::{Block as BlockT, ProvideRuntimeApi, One, Zero}; use crate::{RuntimeAdapter, create_block}; @@ -60,11 +60,11 @@ pub fn next( ) -> Option where Block: BlockT::Out>, - Exec: client::CallExecutor + Send + Sync + Clone, - Backend: client_api::backend::Backend + Send, + Exec: sc_client::CallExecutor + Send + Sync + Clone, + Backend: sc_client_api::backend::Backend + Send, Client: ProvideRuntimeApi, as ProvideRuntimeApi>::Api: - BlockBuilder, + BlockBuilder, RtApi: ConstructRuntimeApi> + Send + Sync, RA: RuntimeAdapter, { diff --git a/test/utils/transaction-factory/src/lib.rs b/bin/node/transaction-factory/src/lib.rs similarity index 85% rename from test/utils/transaction-factory/src/lib.rs rename to bin/node/transaction-factory/src/lib.rs index 357e8067f37b9dd4d454d83b0c42bbc864e59eed..effb9c6d80313a6602dc81d7fb4cd9d9e96f0660 100644 --- a/test/utils/transaction-factory/src/lib.rs +++ b/bin/node/transaction-factory/src/lib.rs @@ -26,18 +26,18 @@ use std::fmt::Display; use log::info; -use client::Client; -use block_builder_api::BlockBuilder; -use sr_api::ConstructRuntimeApi; -use consensus_common::{ +use sc_client::Client; +use sp_block_builder::BlockBuilder; +use sp_api::ConstructRuntimeApi; +use sp_consensus::{ BlockOrigin, BlockImportParams, InherentData, ForkChoiceStrategy, SelectChain }; -use consensus_common::block_import::BlockImport; +use sp_consensus::block_import::BlockImport; use codec::{Decode, Encode}; -use primitives::{Blake2Hasher, Hasher}; -use sr_primitives::generic::BlockId; -use sr_primitives::traits::{ +use sp_core::{Blake2Hasher, Hasher}; +use sp_runtime::generic::BlockId; +use sp_runtime::traits::{ Block as BlockT, Header as HeaderT, ProvideRuntimeApi, SimpleArithmetic, One, Zero, }; @@ -98,25 +98,25 @@ pub fn factory( mut factory_state: RA, client: &Arc>, select_chain: &Sc, -) -> cli::error::Result<()> +) -> sc_cli::error::Result<()> where Block: BlockT::Out>, - Exec: client::CallExecutor + Send + Sync + Clone, - Backend: client_api::backend::Backend + Send, + Exec: sc_client::CallExecutor + Send + Sync + Clone, + Backend: sc_client_api::backend::Backend + Send, Client: ProvideRuntimeApi, as ProvideRuntimeApi>::Api: - BlockBuilder, + BlockBuilder, RtApi: ConstructRuntimeApi> + Send + Sync, Sc: SelectChain, RA: RuntimeAdapter, - <::Block as BlockT>::Hash: From, + <::Block as BlockT>::Hash: From, { if *factory_state.mode() != Mode::MasterToNToM && factory_state.rounds() > RA::Number::one() { let msg = "The factory can only be used with rounds set to 1 in this mode.".into(); - return Err(cli::error::Error::Input(msg)); + return Err(sc_cli::error::Error::Input(msg)); } - let best_header: Result<::Header, cli::error::Error> = + let best_header: Result<::Header, sc_cli::error::Error> = select_chain.best_chain().map_err(|e| format!("{:?}", e).into()); let mut best_hash = best_header?.hash(); let mut best_block_id = BlockId::::hash(best_hash); @@ -160,12 +160,12 @@ pub fn create_block( ) -> Block where Block: BlockT::Out>, - Exec: client::CallExecutor + Send + Sync + Clone, - Backend: client_api::backend::Backend + Send, + Exec: sc_client::CallExecutor + Send + Sync + Clone, + Backend: sc_client_api::backend::Backend + Send, Client: ProvideRuntimeApi, RtApi: ConstructRuntimeApi> + Send + Sync, as ProvideRuntimeApi>::Api: - BlockBuilder, + BlockBuilder, RA: RuntimeAdapter, { let mut block = client.new_block(Default::default()).expect("Failed to create new block"); @@ -186,8 +186,8 @@ fn import_block( block: Block ) -> () where Block: BlockT::Out>, - Exec: client::CallExecutor + Send + Sync + Clone, - Backend: client_api::backend::Backend + Send, + Exec: sc_client::CallExecutor + Send + Sync + Clone, + Backend: sc_client_api::backend::Backend + Send, { let import = BlockImportParams { origin: BlockOrigin::File, @@ -199,6 +199,7 @@ fn import_block( auxiliary: Vec::new(), fork_choice: ForkChoiceStrategy::LongestChain, allow_missing_state: false, + import_existing: false, }; (&**client).import_block(import, HashMap::new()).expect("Failed to import block"); } diff --git a/test/utils/transaction-factory/src/modes.rs b/bin/node/transaction-factory/src/modes.rs similarity index 100% rename from test/utils/transaction-factory/src/modes.rs rename to bin/node/transaction-factory/src/modes.rs diff --git a/test/utils/transaction-factory/src/simple_modes.rs b/bin/node/transaction-factory/src/simple_modes.rs similarity index 87% rename from test/utils/transaction-factory/src/simple_modes.rs rename to bin/node/transaction-factory/src/simple_modes.rs index f869201b46cd6c8d7fd094ade3bb2652dbbd00da..c8ea77f5fea9ca5567c036c76ab0b96223d2bc18 100644 --- a/test/utils/transaction-factory/src/simple_modes.rs +++ b/bin/node/transaction-factory/src/simple_modes.rs @@ -36,12 +36,12 @@ use std::sync::Arc; use log::info; -use client::Client; -use block_builder_api::BlockBuilder; -use sr_api::ConstructRuntimeApi; -use primitives::{Blake2Hasher, Hasher}; -use sr_primitives::traits::{Block as BlockT, ProvideRuntimeApi, One}; -use sr_primitives::generic::BlockId; +use sc_client::Client; +use sp_block_builder::BlockBuilder; +use sp_api::ConstructRuntimeApi; +use sp_core::{Blake2Hasher, Hasher}; +use sp_runtime::traits::{Block as BlockT, ProvideRuntimeApi, One}; +use sp_runtime::generic::BlockId; use crate::{Mode, RuntimeAdapter, create_block}; @@ -55,11 +55,11 @@ pub fn next( ) -> Option where Block: BlockT::Out>, - Exec: client::CallExecutor + Send + Sync + Clone, - Backend: client_api::backend::Backend + Send, + Exec: sc_client::CallExecutor + Send + Sync + Clone, + Backend: sc_client_api::backend::Backend + Send, Client: ProvideRuntimeApi, as ProvideRuntimeApi>::Api: - BlockBuilder, + BlockBuilder, RtApi: ConstructRuntimeApi> + Send + Sync, RA: RuntimeAdapter, { diff --git a/bin/subkey/Cargo.toml b/bin/subkey/Cargo.toml deleted file mode 100644 index 978ecc709fcb568e68dd02fe253b6d7fe31c6bb7..0000000000000000000000000000000000000000 --- a/bin/subkey/Cargo.toml +++ /dev/null @@ -1,25 +0,0 @@ -[package] -name = "subkey" -version = "2.0.0" -authors = ["Parity Technologies "] -edition = "2018" - -[dependencies] -primitives = { package = "substrate-primitives", version = "*", path = "../../primitives/core" } -node-runtime = { version = "*", path = "../node/runtime" } -node-primitives = { version = "*", path = "../node/primitives" } -sr-primitives = { version = "*", path = "../../primitives/sr-primitives" } -rand = "0.7.2" -clap = "2.33.0" -tiny-bip39 = "0.6.2" -rustc-hex = "2.0.1" -substrate-bip39 = "0.3.1" -hex = "0.3.2" -hex-literal = "0.2.1" -codec = { package = "parity-scale-codec", version = "1.0.0" } -system = { package = "frame-system", path = "../../frame/system" } -balances = { package = "pallet-balances", path = "../../frame/balances" } -transaction-payment = { package = "pallet-transaction-payment", path = "../../frame/transaction-payment" } - -[features] -bench = [] diff --git a/test/utils/chain-spec-builder/Cargo.toml b/bin/utils/chain-spec-builder/Cargo.toml similarity index 50% rename from test/utils/chain-spec-builder/Cargo.toml rename to bin/utils/chain-spec-builder/Cargo.toml index 7498880e0f5660e35adf555f63b29e60aa01cbf7..e31419d3b9f2e1abedc8992322b7058896c904fa 100644 --- a/test/utils/chain-spec-builder/Cargo.toml +++ b/bin/utils/chain-spec-builder/Cargo.toml @@ -7,8 +7,8 @@ build = "build.rs" [dependencies] ansi_term = "0.12.1" -keystore = { package = "substrate-keystore", path = "../../../client/keystore" } -node-cli = { path = "../../../bin/node/cli" } -primitives = { package = "substrate-primitives", path = "../../../primitives/core" } +sc-keystore = { version = "2.0.0", path = "../../../client/keystore" } +node-cli = { version = "2.0.0", path = "../../node/cli" } +sp-core = { version = "2.0.0", path = "../../../primitives/core" } rand = "0.7.2" structopt = "0.3.3" diff --git a/test/utils/chain-spec-builder/build.rs b/bin/utils/chain-spec-builder/build.rs similarity index 100% rename from test/utils/chain-spec-builder/build.rs rename to bin/utils/chain-spec-builder/build.rs diff --git a/test/utils/chain-spec-builder/src/main.rs b/bin/utils/chain-spec-builder/src/main.rs similarity index 96% rename from test/utils/chain-spec-builder/src/main.rs rename to bin/utils/chain-spec-builder/src/main.rs index b277987e1ea5efca8fa285f7a357bc4bd13bd67f..c370469d6490114172f8d9e7fe9bfd8bbff6177b 100644 --- a/test/utils/chain-spec-builder/src/main.rs +++ b/bin/utils/chain-spec-builder/src/main.rs @@ -20,9 +20,9 @@ use ansi_term::Style; use rand::{Rng, distributions::Alphanumeric, rngs::OsRng}; use structopt::StructOpt; -use keystore::{Store as Keystore}; +use sc_keystore::{Store as Keystore}; use node_cli::chain_spec::{self, AccountId}; -use primitives::{sr25519, crypto::{Public, Ss58Codec}, traits::BareCryptoStore}; +use sp_core::{sr25519, crypto::{Public, Ss58Codec}, traits::BareCryptoStore}; /// A utility to easily create a testnet chain spec definition with a given set /// of authorities and endowed accounts and/or generate random accounts. @@ -153,22 +153,22 @@ fn generate_authority_keys_and_store( }; insert_key( - primitives::crypto::key_types::BABE, + sp_core::crypto::key_types::BABE, babe.as_slice(), )?; insert_key( - primitives::crypto::key_types::GRANDPA, + sp_core::crypto::key_types::GRANDPA, grandpa.as_slice(), )?; insert_key( - primitives::crypto::key_types::IM_ONLINE, + sp_core::crypto::key_types::IM_ONLINE, im_online.as_slice(), )?; insert_key( - primitives::crypto::key_types::AUTHORITY_DISCOVERY, + sp_core::crypto::key_types::AUTHORITY_DISCOVERY, authority_discovery.as_slice(), )?; } diff --git a/bin/utils/subkey/Cargo.toml b/bin/utils/subkey/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..ca3519ae2758e41af52bda337be7687d502ef1df --- /dev/null +++ b/bin/utils/subkey/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "subkey" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +sp-core = { version = "*", path = "../../../primitives/core" } +node-runtime = { version = "*", path = "../../node/runtime" } +node-primitives = { version = "*", path = "../../node/primitives" } +sp-runtime = { version = "*", path = "../../../primitives/runtime" } +rand = "0.7.2" +clap = "2.33.0" +tiny-bip39 = "0.6.2" +rustc-hex = "2.0.1" +substrate-bip39 = "0.3.1" +hex = "0.4.0" +hex-literal = "0.2.1" +codec = { package = "parity-scale-codec", version = "1.0.0" } +frame-system = { version = "2.0.0", path = "../../../frame/system" } +pallet-balances = { version = "2.0.0", path = "../../../frame/balances" } +pallet-transaction-payment = { version = "2.0.0", path = "../../../frame/transaction-payment" } + +[features] +bench = [] diff --git a/bin/subkey/README.adoc b/bin/utils/subkey/README.adoc similarity index 100% rename from bin/subkey/README.adoc rename to bin/utils/subkey/README.adoc diff --git a/bin/subkey/src/main.rs b/bin/utils/subkey/src/main.rs similarity index 95% rename from bin/subkey/src/main.rs rename to bin/utils/subkey/src/main.rs index b1dce363146fde5ea8340ebadf9ffc86cde71712..10a2e131706faacc3936e29cfd27b3c1010d820a 100644 --- a/bin/subkey/src/main.rs +++ b/bin/utils/subkey/src/main.rs @@ -24,11 +24,11 @@ use codec::{Decode, Encode}; use hex_literal::hex; use node_primitives::{Balance, Hash, Index, AccountId, Signature}; use node_runtime::{BalancesCall, Call, Runtime, SignedPayload, UncheckedExtrinsic, VERSION}; -use primitives::{ +use sp_core::{ crypto::{set_default_ss58_version, Ss58AddressFormat, Ss58Codec}, ed25519, sr25519, ecdsa, Pair, Public, H256, hexdisplay::HexDisplay, }; -use sr_primitives::{traits::{IdentifyAccount, Verify}, generic::Era}; +use sp_runtime::{traits::{IdentifyAccount, Verify}, generic::Era}; use std::{ convert::{TryInto, TryFrom}, io::{stdin, Read}, @@ -165,7 +165,7 @@ fn get_app<'a, 'b>() -> App<'a, 'b> { -k, --secp256k1 'Use SECP256k1/ECDSA/BIP39 cryptography' -s, --sr25519 'Use Schnorr/Ristretto x25519/BIP39 cryptography' [network] -n, --network 'Specify a network. One of substrate \ - (default), polkadot, kusama, or dothereum.' + (default), polkadot, kusama, dothereum, edgeware, or kulupu' [password] -p, --password 'The password for the key' ") .subcommands(vec![ @@ -197,7 +197,7 @@ fn get_app<'a, 'b>() -> App<'a, 'b> { -s, --suri 'The secret key URI.' "), SubCommand::with_name("transfer") - .about("Author and sign a Node balances::Transfer transaction with a given (secret) key") + .about("Author and sign a Node pallet_balances::Transfer transaction with a given (secret) key") .args_from_usage(" -g, --genesis 'The genesis hash or a recognised \ chain identifier (dev, elm, alex).' @@ -244,7 +244,7 @@ where let maybe_network: Option = matches.value_of("network").map(|network| { network .try_into() - .expect("Invalid network name: must be polkadot/substrate/kusama/dothereum") + .expect("Invalid network name: must be polkadot/substrate/kusama/dothereum/edgeware") }); if let Some(network) = maybe_network { set_default_ss58_version(network); @@ -362,14 +362,15 @@ fn read_message_from_stdin(should_decode: bool) -> Vec { message } -fn read_required_parameter(matches: &ArgMatches, name: &str) -> T -where +fn read_required_parameter(matches: &ArgMatches, name: &str) -> T where ::Err: std::fmt::Debug, { let str_value = matches .value_of(name) .expect("parameter is required; thus it can't be None; qed"); - str::parse::(str_value).expect("Invalid 'nonce' parameter; expecting an integer.") + str::parse::(str_value).unwrap_or_else(|_| + panic!("Invalid `{}' parameter; expecting an integer.", name) + ) } fn read_genesis_hash(matches: &ArgMatches) -> H256 { @@ -388,8 +389,7 @@ fn read_genesis_hash(matches: &ArgMatches) -> H256 { genesis_hash } -fn read_signature(matches: &ArgMatches) -> SignatureOf -where +fn read_signature(matches: &ArgMatches) -> SignatureOf where SignatureOf: SignatureT, PublicOf: PublicT, { @@ -446,8 +446,7 @@ fn read_account_id(matched_uri: Option<&str>) -> AccountId { fn read_pair( matched_suri: Option<&str>, password: Option<&str>, -) -> ::Pair -where +) -> ::Pair where SignatureOf: SignatureT, PublicOf: PublicT, { @@ -484,12 +483,12 @@ fn create_extrinsic( { let extra = |i: Index, f: Balance| { ( - system::CheckVersion::::new(), - system::CheckGenesis::::new(), - system::CheckEra::::from(Era::Immortal), - system::CheckNonce::::from(i), - system::CheckWeight::::new(), - transaction_payment::ChargeTransactionPayment::::from(f), + frame_system::CheckVersion::::new(), + frame_system::CheckGenesis::::new(), + frame_system::CheckEra::::from(Era::Immortal), + frame_system::CheckNonce::::from(i), + frame_system::CheckWeight::::new(), + pallet_transaction_payment::ChargeTransactionPayment::::from(f), Default::default(), ) }; diff --git a/bin/subkey/src/vanity.rs b/bin/utils/subkey/src/vanity.rs similarity index 98% rename from bin/subkey/src/vanity.rs rename to bin/utils/subkey/src/vanity.rs index 835001a0aa9d0d4dd82b7e719a91f907cce4f495..33e8559b1fbc4de2510d16c2cd8062885115ee6d 100644 --- a/bin/subkey/src/vanity.rs +++ b/bin/utils/subkey/src/vanity.rs @@ -15,7 +15,7 @@ // along with Substrate. If not, see . use super::{PublicOf, PublicT, Crypto}; -use primitives::Pair; +use sp_core::Pair; use rand::{rngs::OsRng, RngCore}; fn good_waypoint(done: u64) -> u64 { @@ -110,7 +110,7 @@ pub(super) fn generate_key(desired: &str) -> Result, &str> mod tests { use super::super::Ed25519; use super::*; - use primitives::{crypto::Ss58Codec, Pair}; + use sp_core::{crypto::Ss58Codec, Pair}; #[cfg(feature = "bench")] use test::Bencher; diff --git a/client/Cargo.toml b/client/Cargo.toml index 6f6799a48ce2ca574f4bc956a224a85240ccbaa9..da4f5e3cc2c9b929f43a200f737cfdaa1d4b22cc 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -1,40 +1,40 @@ [package] -name = "substrate-client" +name = "sc-client" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" [dependencies] -block-builder = { package = "substrate-block-builder", path = "block-builder" } -client-api = { package = "substrate-client-api", path = "api" } +sc-block-builder = { version = "2.0.0", path = "block-builder" } +sc-client-api = { version = "2.0.0", path = "api" } codec = { package = "parity-scale-codec", version = "1.0.0", features = ["derive"] } -consensus = { package = "substrate-consensus-common", path = "../primitives/consensus/common" } -derive_more = { version = "0.15.0" } -executor = { package = "substrate-executor", path = "executor" } -externalities = { package = "substrate-externalities", path = "../primitives/externalities" } +sp-consensus = { version = "0.8", path = "../primitives/consensus/common" } +derive_more = { version = "0.99.2" } +sc-executor = { version = "2.0.0", path = "executor" } +sp-externalities = { version = "2.0.0", path = "../primitives/externalities" } fnv = { version = "1.0.6" } futures = { version = "0.3.1", features = ["compat"] } hash-db = { version = "0.15.2" } -header-metadata = { package = "substrate-header-metadata", path = "header-metadata" } hex-literal = { version = "0.2.1" } -inherents = { package = "substrate-inherents", path = "../primitives/inherents" } -keyring = { package = "substrate-keyring", path = "../primitives/keyring" } -kvdb = { git = "https://github.com/paritytech/parity-common", rev="b0317f649ab2c665b7987b8475878fc4d2e1f81d" } +sp-inherents = { version = "2.0.0", path = "../primitives/inherents" } +sp-keyring = { version = "2.0.0", path = "../primitives/keyring" } +kvdb = "0.1.1" log = { version = "0.4.8" } parking_lot = { version = "0.9.0" } -primitives = { package = "substrate-primitives", path = "../primitives/core" } -rstd = { package = "sr-std", path = "../primitives/sr-std" } -runtime-version = { package = "sr-version", path = "../primitives/sr-version" } -sr-api = { path = "../primitives/sr-api" } -sr-primitives = { path = "../primitives/sr-primitives" } -state-machine = { package = "substrate-state-machine", path = "../primitives/state-machine" } -substrate-telemetry = { path = "telemetry" } -trie = { package = "substrate-trie", path = "../primitives/trie" } +sp-core = { version = "2.0.0", path = "../primitives/core" } +sp-std = { version = "2.0.0", path = "../primitives/std" } +sp-version = { version = "2.0.0", path = "../primitives/version" } +sp-api = { version = "2.0.0", path = "../primitives/api" } +sp-runtime = { version = "2.0.0", path = "../primitives/runtime" } +sp-blockchain = { version = "2.0.0", path = "../primitives/blockchain" } +sp-state-machine = { version = "2.0.0", path = "../primitives/state-machine" } +sc-telemetry = { version = "2.0.0", path = "telemetry" } +sp-trie = { version = "2.0.0", path = "../primitives/trie" } +tracing = "0.1.10" [dev-dependencies] env_logger = "0.7.0" tempfile = "3.1.0" -client-db = { package = "substrate-client-db", path = "./db", features = ["kvdb-rocksdb"] } -test-client = { package = "substrate-test-runtime-client", path = "../test/utils/runtime/client" } -kvdb-memorydb = { git = "https://github.com/paritytech/parity-common", rev="b0317f649ab2c665b7987b8475878fc4d2e1f81d" } -panic-handler = { package = "substrate-panic-handler", path = "../primitives/panic-handler" } +substrate-test-runtime-client = { version = "2.0.0", path = "../test-utils/runtime/client" } +kvdb-memorydb = "0.1.2" +sp-panic-handler = { version = "2.0.0", path = "../primitives/panic-handler" } diff --git a/client/api/Cargo.toml b/client/api/Cargo.toml index af4d03f00113c416394a41eae8044e07baebf41f..e445e9bc4c4ceaaef1d7aee9d9a9840586579c55 100644 --- a/client/api/Cargo.toml +++ b/client/api/Cargo.toml @@ -1,41 +1,34 @@ [package] -name = "substrate-client-api" +name = "sc-client-api" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" [dependencies] -block-builder = { package = "substrate-block-builder", path = "../block-builder" } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -consensus = { package = "substrate-consensus-common", path = "../../primitives/consensus/common" } -derive_more = { version = "0.15.0" } -executor = { package = "substrate-executor", path = "../executor" } -externalities = { package = "substrate-externalities", path = "../../primitives/externalities" } +sp-consensus = { version = "0.8", path = "../../primitives/consensus/common" } +derive_more = { version = "0.99.2" } +sc-executor = { version = "2.0.0", path = "../executor" } +sp-externalities = { version = "2.0.0", path = "../../primitives/externalities" } fnv = { version = "1.0.6" } futures = { version = "0.3.1" } hash-db = { version = "0.15.2", default-features = false } -header-metadata = { package = "substrate-header-metadata", path = "../header-metadata" } +sp-blockchain = { version = "2.0.0", path = "../../primitives/blockchain" } hex-literal = { version = "0.2.1" } -inherents = { package = "substrate-inherents", path = "../../primitives/inherents", default-features = false } -keyring = { package = "substrate-keyring", path = "../../primitives/keyring" } -kvdb = { git = "https://github.com/paritytech/parity-common", rev="b0317f649ab2c665b7987b8475878fc4d2e1f81d" } +sp-inherents = { version = "2.0.0", default-features = false, path = "../../primitives/inherents" } +sp-keyring = { version = "2.0.0", path = "../../primitives/keyring" } +kvdb = "0.1.1" log = { version = "0.4.8" } parking_lot = { version = "0.9.0" } -primitives = { package = "substrate-primitives", path = "../../primitives/core", default-features = false } -rstd = { package = "sr-std", path = "../../primitives/sr-std", default-features = false } -runtime-version = { package = "sr-version", path = "../../primitives/sr-version", default-features = false } -sr-api = { path = "../../primitives/sr-api" } -sr-primitives = { path = "../../primitives/sr-primitives", default-features = false } -state-machine = { package = "substrate-state-machine", path = "../../primitives/state-machine" } -substrate-telemetry = { path = "../telemetry" } -trie = { package = "substrate-trie", path = "../../primitives/trie" } +sp-core = { version = "2.0.0", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0", default-features = false, path = "../../primitives/std" } +sp-version = { version = "2.0.0", default-features = false, path = "../../primitives/version" } +sp-api = { version = "2.0.0", path = "../../primitives/api" } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" } +sp-state-machine = { version = "2.0.0", path = "../../primitives/state-machine" } +sc-telemetry = { version = "2.0.0", path = "../telemetry" } +sp-trie = { version = "2.0.0", path = "../../primitives/trie" } +sp-transaction-pool = { version = "2.0.0", path = "../../primitives/transaction-pool" } [dev-dependencies] -env_logger = "0.7.0" -tempfile = "3.1.0" -client-db = { package = "substrate-client-db", path = ".././db", features = ["kvdb-rocksdb"] } -test-primitives = { package = "substrate-test-primitives", path = "../../test/utils/primitives" } -test-client = { package = "substrate-test-runtime-client", path = "../../test/utils/runtime/client" } -kvdb-memorydb = { git = "https://github.com/paritytech/parity-common", rev="b0317f649ab2c665b7987b8475878fc4d2e1f81d" } -panic-handler = { package = "substrate-panic-handler", path = "../../primitives/panic-handler" } - +sp-test-primitives = { version = "2.0.0", path = "../../primitives/test-primitives" } \ No newline at end of file diff --git a/client/api/src/backend.rs b/client/api/src/backend.rs index a00c5a3ac89f5a86385e66a966db2dfb81ec8d1b..963bb6083b4a052393d5bc5995d7bb74e83f633d 100644 --- a/client/api/src/backend.rs +++ b/client/api/src/backend.rs @@ -18,22 +18,22 @@ use std::sync::Arc; use std::collections::HashMap; -use primitives::ChangesTrieConfiguration; -use primitives::offchain::OffchainStorage; -use sr_primitives::{generic::BlockId, Justification, StorageOverlay, ChildrenStorageOverlay}; -use sr_primitives::traits::{Block as BlockT, NumberFor}; -use state_machine::backend::Backend as StateBackend; -use state_machine::{ChangesTrieStorage as StateChangesTrieStorage, ChangesTrieTransaction}; +use sp_core::ChangesTrieConfiguration; +use sp_core::offchain::OffchainStorage; +use sp_runtime::{generic::BlockId, Justification, Storage}; +use sp_runtime::traits::{Block as BlockT, NumberFor}; +use sp_state_machine::backend::Backend as StateBackend; +use sp_state_machine::{ChangesTrieStorage as StateChangesTrieStorage, ChangesTrieTransaction}; use crate::{ blockchain::{ Backend as BlockchainBackend, well_known_cache_keys }, - error, light::RemoteBlockchain, }; -use consensus::BlockOrigin; +use sp_blockchain; +use sp_consensus::BlockOrigin; use hash_db::Hasher; -use parking_lot::Mutex; +use parking_lot::RwLock; /// In memory array of storage values. pub type StorageCollection = Vec<(Vec, Option>)>; @@ -116,7 +116,7 @@ pub trait BlockImportOperation where /// Returns pending state. /// /// Returns None for backends with locally-unavailable state data. - fn state(&self) -> error::Result>; + fn state(&self) -> sp_blockchain::Result>; /// Append block data to the transaction. fn set_block_data( @@ -125,37 +125,37 @@ pub trait BlockImportOperation where body: Option>, justification: Option, state: NewBlockState, - ) -> error::Result<()>; + ) -> sp_blockchain::Result<()>; /// Update cached data. fn update_cache(&mut self, cache: HashMap>); /// Inject storage data into the database. - fn update_db_storage(&mut self, update: >::Transaction) -> error::Result<()>; + fn update_db_storage(&mut self, update: >::Transaction) -> sp_blockchain::Result<()>; /// Inject storage data into the database replacing any existing data. - fn reset_storage(&mut self, top: StorageOverlay, children: ChildrenStorageOverlay) -> error::Result; + fn reset_storage(&mut self, storage: Storage) -> sp_blockchain::Result; /// Set storage changes. fn update_storage( &mut self, update: StorageCollection, child_update: ChildStorageCollection, - ) -> error::Result<()>; + ) -> sp_blockchain::Result<()>; /// Inject changes trie data into the database. - fn update_changes_trie(&mut self, update: ChangesTrieTransaction>) -> error::Result<()>; + fn update_changes_trie(&mut self, update: ChangesTrieTransaction>) -> sp_blockchain::Result<()>; /// Insert auxiliary keys. /// /// Values are `None` if should be deleted. - fn insert_aux(&mut self, ops: I) -> error::Result<()> + fn insert_aux(&mut self, ops: I) -> sp_blockchain::Result<()> where I: IntoIterator, Option>)>; /// Mark a block as finalized. - fn mark_finalized(&mut self, id: BlockId, justification: Option) -> error::Result<()>; + fn mark_finalized(&mut self, id: BlockId, justification: Option) -> sp_blockchain::Result<()>; /// Mark a block as new head. If both block import and set head are specified, set head overrides block import's best block rule. - fn mark_head(&mut self, id: BlockId) -> error::Result<()>; + fn mark_head(&mut self, id: BlockId) -> sp_blockchain::Result<()>; } /// Finalize Facilities @@ -175,7 +175,7 @@ pub trait Finalizer, B: Backend, justification: Option, notify: bool, - ) -> error::Result<()>; + ) -> sp_blockchain::Result<()>; /// Finalize a block. @@ -196,7 +196,7 @@ pub trait Finalizer, B: Backend, justification: Option, notify: bool, - ) -> error::Result<()>; + ) -> sp_blockchain::Result<()>; } @@ -211,10 +211,10 @@ pub trait AuxStore { 'c: 'a, I: IntoIterator, D: IntoIterator, - >(&self, insert: I, delete: D) -> error::Result<()>; + >(&self, insert: I, delete: D) -> sp_blockchain::Result<()>; /// Query auxiliary data from key-value store. - fn get_aux(&self, key: &[u8]) -> error::Result>>; + fn get_aux(&self, key: &[u8]) -> sp_blockchain::Result>>; } /// Client backend. @@ -245,18 +245,18 @@ pub trait Backend: AuxStore + Send + Sync where /// Begin a new block insertion transaction with given parent block id. /// /// When constructing the genesis, this is called with all-zero hash. - fn begin_operation(&self) -> error::Result; + fn begin_operation(&self) -> sp_blockchain::Result; /// Note an operation to contain state transition. - fn begin_state_operation(&self, operation: &mut Self::BlockImportOperation, block: BlockId) -> error::Result<()>; + fn begin_state_operation(&self, operation: &mut Self::BlockImportOperation, block: BlockId) -> sp_blockchain::Result<()>; /// Commit block insertion. - fn commit_operation(&self, transaction: Self::BlockImportOperation) -> error::Result<()>; + fn commit_operation(&self, transaction: Self::BlockImportOperation) -> sp_blockchain::Result<()>; /// Finalize block with given Id. /// /// This should only be called if the parent of the given block has been finalized. - fn finalize_block(&self, block: BlockId, justification: Option) -> error::Result<()>; + fn finalize_block(&self, block: BlockId, justification: Option) -> sp_blockchain::Result<()>; /// Returns reference to blockchain backend. fn blockchain(&self) -> &Self::Blockchain; @@ -276,17 +276,17 @@ pub trait Backend: AuxStore + Send + Sync where } /// Returns state backend with post-state of given block. - fn state_at(&self, block: BlockId) -> error::Result; + fn state_at(&self, block: BlockId) -> sp_blockchain::Result; /// Destroy state and save any useful data, such as cache. - fn destroy_state(&self, _state: Self::State) -> error::Result<()> { + fn destroy_state(&self, _state: Self::State) -> sp_blockchain::Result<()> { Ok(()) } /// Attempts to revert the chain by `n` blocks. /// /// Returns the number of blocks that were successfully reverted. - fn revert(&self, n: NumberFor) -> error::Result>; + fn revert(&self, n: NumberFor) -> sp_blockchain::Result>; /// Insert auxiliary data into key-value store. fn insert_aux< @@ -295,12 +295,12 @@ pub trait Backend: AuxStore + Send + Sync where 'c: 'a, I: IntoIterator, D: IntoIterator, - >(&self, insert: I, delete: D) -> error::Result<()> + >(&self, insert: I, delete: D) -> sp_blockchain::Result<()> { AuxStore::insert_aux(self, insert, delete) } /// Query auxiliary data from key-value store. - fn get_aux(&self, key: &[u8]) -> error::Result>> { + fn get_aux(&self, key: &[u8]) -> sp_blockchain::Result>> { AuxStore::get_aux(self, key) } @@ -310,7 +310,7 @@ pub trait Backend: AuxStore + Send + Sync where /// the using components should acquire and hold the lock whenever they do /// something that the import of a block would interfere with, e.g. importing /// a new block or calculating the best head. - fn get_import_lock(&self) -> &Mutex<()>; + fn get_import_lock(&self) -> &RwLock<()>; } /// Changes trie storage that supports pruning. diff --git a/client/api/src/call_executor.rs b/client/api/src/call_executor.rs index 73273336330ae850457558acc2d2b3f73883f6c7..b54f6f52054fe8998ea2c29a4ba236963426b005 100644 --- a/client/api/src/call_executor.rs +++ b/client/api/src/call_executor.rs @@ -18,20 +18,20 @@ use std::{cmp::Ord, panic::UnwindSafe, result, cell::RefCell}; use codec::{Encode, Decode}; -use sr_primitives::{ +use sp_runtime::{ generic::BlockId, traits::Block as BlockT, traits::NumberFor, }; -use state_machine::{ +use sp_state_machine::{ self, OverlayedChanges, ExecutionManager, ExecutionStrategy, ChangesTrieTransaction, StorageProof, }; -use executor::{RuntimeVersion, NativeVersion}; -use externalities::Extensions; +use sc_executor::{RuntimeVersion, NativeVersion}; +use sp_externalities::Extensions; use hash_db::Hasher; -use primitives::{Blake2Hasher, NativeOrEncoded}; +use sp_core::{Blake2Hasher, NativeOrEncoded}; -use sr_api::{ProofRecorder, InitializeBlock}; -use crate::error; +use sp_api::{ProofRecorder, InitializeBlock}; +use sp_blockchain; /// Method call executor. pub trait CallExecutor @@ -41,7 +41,7 @@ where H::Out: Ord, { /// Externalities error type. - type Error: state_machine::Error; + type Error: sp_state_machine::Error; /// Execute a call to a contract on top of state in a block of given hash. /// @@ -53,7 +53,7 @@ where call_data: &[u8], strategy: ExecutionStrategy, extensions: Option, - ) -> Result, error::Error>; + ) -> Result, sp_blockchain::Error>; /// Execute a contextual call on top of state in a block of a given hash. /// @@ -62,7 +62,7 @@ where /// of the execution context. fn contextual_call< 'a, - IB: Fn() -> error::Result<()>, + IB: Fn() -> sp_blockchain::Result<()>, EM: Fn( Result, Self::Error>, Result, Self::Error> @@ -81,18 +81,18 @@ where native_call: Option, proof_recorder: &Option>, extensions: Option, - ) -> error::Result> where ExecutionManager: Clone; + ) -> sp_blockchain::Result> where ExecutionManager: Clone; /// Extract RuntimeVersion of given block /// /// No changes are made. - fn runtime_version(&self, id: &BlockId) -> Result; + fn runtime_version(&self, id: &BlockId) -> Result; /// Execute a call to a contract on top of given state. /// /// No changes are made. fn call_at_state< - S: state_machine::Backend, + S: sp_state_machine::Backend, F: FnOnce( Result, Self::Error>, Result, Self::Error>, @@ -113,23 +113,23 @@ where (S::Transaction, H::Out), Option>> ), - error::Error, + sp_blockchain::Error, >; /// Execute a call to a contract on top of given state, gathering execution proof. /// /// No changes are made. - fn prove_at_state>( + fn prove_at_state>( &self, mut state: S, overlay: &mut OverlayedChanges, method: &str, call_data: &[u8] - ) -> Result<(Vec, StorageProof), error::Error> { + ) -> Result<(Vec, StorageProof), sp_blockchain::Error> { let trie_state = state.as_trie_backend() .ok_or_else(|| - Box::new(state_machine::ExecutionError::UnableToGenerateProof) - as Box + Box::new(sp_state_machine::ExecutionError::UnableToGenerateProof) + as Box )?; self.prove_at_trie_state(trie_state, overlay, method, call_data) } @@ -137,13 +137,13 @@ where /// Execute a call to a contract on top of given trie state, gathering execution proof. /// /// No changes are made. - fn prove_at_trie_state>( + fn prove_at_trie_state>( &self, - trie_state: &state_machine::TrieBackend, + trie_state: &sp_state_machine::TrieBackend, overlay: &mut OverlayedChanges, method: &str, call_data: &[u8] - ) -> Result<(Vec, StorageProof), error::Error>; + ) -> Result<(Vec, StorageProof), sp_blockchain::Error>; /// Get runtime version if supported. fn native_runtime_version(&self) -> Option<&NativeVersion>; diff --git a/client/api/src/client.rs b/client/api/src/client.rs index 8b4343c327a50884d71d81ae14aaae7dcac510d6..17da85b5de95b04a5ce2aa4e1fdea98674631dfb 100644 --- a/client/api/src/client.rs +++ b/client/api/src/client.rs @@ -18,16 +18,16 @@ use std::collections::HashMap; use futures::channel::mpsc; -use primitives::storage::StorageKey; -use sr_primitives::{ +use sp_core::storage::StorageKey; +use sp_runtime::{ traits::{Block as BlockT, NumberFor}, generic::BlockId }; -use consensus::BlockOrigin; +use sp_consensus::BlockOrigin; use crate::blockchain::Info; use crate::notifications::StorageEventStream; -use crate::error; +use sp_blockchain; /// Type that implements `futures::Stream` of block import events. pub type ImportNotifications = mpsc::UnboundedReceiver>; @@ -63,7 +63,7 @@ pub trait BlockchainEvents { &self, filter_keys: Option<&[StorageKey]>, child_filter_keys: Option<&[(StorageKey, Option>)]>, - ) -> error::Result>; + ) -> sp_blockchain::Result>; } /// Fetch block body by ID. @@ -71,14 +71,14 @@ pub trait BlockBody { /// Get block body by ID. Returns `None` if the body is not stored. fn block_body(&self, id: &BlockId - ) -> error::Result::Extrinsic>>>; + ) -> sp_blockchain::Result::Extrinsic>>>; } /// Provide a list of potential uncle headers for a given block. pub trait ProvideUncles { /// Gets the uncles of the block with `target_hash` going back `max_generation` ancestors. fn uncles(&self, target_hash: Block::Hash, max_generation: NumberFor) - -> error::Result>; + -> sp_blockchain::Result>; } /// Client info diff --git a/client/api/src/execution_extensions.rs b/client/api/src/execution_extensions.rs index 83d70998e16aa6eb549a581b0c8c14d9398074b9..e1be4d8ec0530e30823d4a594a5842454c3df692 100644 --- a/client/api/src/execution_extensions.rs +++ b/client/api/src/execution_extensions.rs @@ -22,18 +22,17 @@ use std::sync::{Weak, Arc}; use codec::Decode; -use primitives::{ +use sp_core::{ ExecutionContext, offchain::{self, OffchainExt, TransactionPoolExt}, traits::{BareCryptoStorePtr, KeystoreExt}, }; -use sr_primitives::{ +use sp_runtime::{ generic::BlockId, traits, - offchain::{TransactionPool}, }; -use state_machine::{ExecutionStrategy, ExecutionManager, DefaultHandler}; -use externalities::Extensions; +use sp_state_machine::{ExecutionStrategy, ExecutionManager, DefaultHandler}; +use sp_externalities::Extensions; use parking_lot::RwLock; /// Execution strategies settings. @@ -71,7 +70,7 @@ impl Default for ExecutionStrategies { pub struct ExecutionExtensions { strategies: ExecutionStrategies, keystore: Option, - transaction_pool: RwLock>>>, + transaction_pool: RwLock>>>, } impl Default for ExecutionExtensions { @@ -105,7 +104,7 @@ impl ExecutionExtensions { /// extension to be a `Weak` reference. /// That's also the reason why it's being registered lazily instead of /// during initialisation. - pub fn register_transaction_pool(&self, pool: Weak>) { + pub fn register_transaction_pool(&self, pool: Weak>) { *self.transaction_pool.write() = Some(pool); } @@ -166,7 +165,7 @@ impl ExecutionExtensions { /// A wrapper type to pass `BlockId` to the actual transaction pool. struct TransactionPoolAdapter { at: BlockId, - pool: Arc>, + pool: Arc>, } impl offchain::TransactionPool for TransactionPoolAdapter { diff --git a/client/api/src/lib.rs b/client/api/src/lib.rs index 04abc863085456c5a67e6fcb21b5358aca1cb73a..d51157d2451522d8921b7be1bc71bb537d3be674 100644 --- a/client/api/src/lib.rs +++ b/client/api/src/lib.rs @@ -18,33 +18,28 @@ #![warn(missing_docs)] pub mod backend; -pub mod blockchain; pub mod call_executor; pub mod client; -pub mod error; pub mod execution_extensions; pub mod light; pub mod notifications; -// TODO: avoid re-exports +pub use sp_blockchain as blockchain; pub use backend::*; -pub use blockchain::*; +pub use notifications::*; pub use call_executor::*; pub use client::*; -pub use error::*; pub use light::*; pub use notifications::*; -pub use state_machine::{StorageProof, ExecutionStrategy}; +pub use sp_state_machine::{StorageProof, ExecutionStrategy}; /// Utility methods for the client. pub mod utils { - use super::HeaderBackend; - use header_metadata::HeaderMetadata; - use crate::error; - use primitives::H256; - use sr_primitives::traits::{Block as BlockT}; + use sp_blockchain::{HeaderBackend, HeaderMetadata, Error}; + use sp_core::H256; + use sp_runtime::traits::{Block as BlockT}; use std::borrow::Borrow; /// Returns a function for checking block ancestry, the returned function will @@ -56,8 +51,8 @@ pub mod utils { pub fn is_descendent_of<'a, Block: BlockT, T, H: Borrow + 'a>( client: &'a T, current: Option<(H, H)>, - ) -> impl Fn(&H256, &H256) -> Result + 'a - where T: HeaderBackend + HeaderMetadata, + ) -> impl Fn(&H256, &H256) -> Result + 'a + where T: HeaderBackend + HeaderMetadata, { move |base, hash| { if base == hash { return Ok(false); } @@ -76,7 +71,7 @@ pub mod utils { } } - let ancestor = header_metadata::lowest_common_ancestor(client, *hash, *base)?; + let ancestor = sp_blockchain::lowest_common_ancestor(client, *hash, *base)?; Ok(ancestor.hash == *base) } diff --git a/client/api/src/light.rs b/client/api/src/light.rs index 433d1dbec10e6adae6d724b586ca0da85d62e0e1..073e62e687cce5fab7e9ef942933058eed7cf764 100644 --- a/client/api/src/light.rs +++ b/client/api/src/light.rs @@ -20,24 +20,19 @@ use std::sync::Arc; use std::collections::{BTreeMap, HashMap}; use std::future::Future; -use sr_primitives::{ +use sp_runtime::{ traits::{ Block as BlockT, Header as HeaderT, NumberFor, }, generic::BlockId }; -use primitives::{ChangesTrieConfiguration}; -use state_machine::StorageProof; -use header_metadata::HeaderMetadata; -use crate::{ - backend::{ - AuxStore, NewBlockState, - }, - blockchain::{ - well_known_cache_keys, HeaderBackend, Cache as BlockchainCache, - }, - error::{ Error as ClientError, Result as ClientResult }, +use sp_core::ChangesTrieConfiguration; +use sp_state_machine::StorageProof; +use sp_blockchain::{ + HeaderMetadata, well_known_cache_keys, HeaderBackend, Cache as BlockchainCache, + Error as ClientError, Result as ClientResult, }; +use crate::backend::{ AuxStore, NewBlockState }; /// Remote call request. #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct RemoteCallRequest { @@ -86,6 +81,11 @@ pub struct RemoteReadChildRequest { pub header: Header, /// Storage key for child. pub storage_key: Vec, + /// Child trie source information. + pub child_info: Vec, + /// Child type, its required to resolve `child_info` + /// content and choose child implementation. + pub child_type: u32, /// Child storage key to read. pub keys: Vec>, /// Number of times to retry request. None means that default RETRY_COUNT is used. @@ -144,15 +144,30 @@ pub struct RemoteBodyRequest { /// is correct (see FetchedDataChecker) and return already checked data. pub trait Fetcher: Send + Sync { /// Remote header future. - type RemoteHeaderResult: Future> + Send + 'static; + type RemoteHeaderResult: Future> + Unpin + Send + 'static; /// Remote storage read future. - type RemoteReadResult: Future, Option>>, ClientError>> + Send + 'static; + type RemoteReadResult: Future, Option>>, + ClientError, + >> + Unpin + Send + 'static; /// Remote call result future. - type RemoteCallResult: Future, ClientError>> + Send + 'static; + type RemoteCallResult: Future, + ClientError, + >> + Unpin + Send + 'static; /// Remote changes result future. - type RemoteChangesResult: Future, u32)>, ClientError>> + Send + 'static; + type RemoteChangesResult: Future, u32)>, + ClientError, + >> + Unpin + Send + 'static; /// Remote block body result future. - type RemoteBodyResult: Future, ClientError>> + Send + 'static; + type RemoteBodyResult: Future, + ClientError, + >> + Unpin + Send + 'static; /// Fetch remote header. fn remote_header(&self, request: RemoteHeaderRequest) -> Self::RemoteHeaderResult; @@ -288,8 +303,8 @@ pub trait RemoteBlockchain: Send + Sync { pub mod tests { use futures::future::Ready; use parking_lot::Mutex; - use crate::error::Error as ClientError; - use test_primitives::{Block, Header, Extrinsic}; + use sp_blockchain::Error as ClientError; + use sp_test_primitives::{Block, Header, Extrinsic}; use super::*; pub type OkCallFetcher = Mutex>; diff --git a/client/api/src/notifications.rs b/client/api/src/notifications.rs index 0ddc4c72cdb5530aba3570a2586a3132a353df24..88b0b2d307528ce2ed5e04189d4afdd7dded3665 100644 --- a/client/api/src/notifications.rs +++ b/client/api/src/notifications.rs @@ -23,8 +23,8 @@ use std::{ use fnv::{FnvHashSet, FnvHashMap}; use futures::channel::mpsc; -use primitives::storage::{StorageKey, StorageData}; -use sr_primitives::traits::Block as BlockT; +use sp_core::storage::{StorageKey, StorageData}; +use sp_runtime::traits::Block as BlockT; /// Storage change set #[derive(Debug)] @@ -307,7 +307,7 @@ impl StorageNotifications { #[cfg(test)] mod tests { - use sr_primitives::testing::{H256 as Hash, Block as RawBlock, ExtrinsicWrapper}; + use sp_runtime::testing::{H256 as Hash, Block as RawBlock, ExtrinsicWrapper}; use super::*; use std::iter::{empty, Empty}; diff --git a/client/authority-discovery/Cargo.toml b/client/authority-discovery/Cargo.toml index c45eb4168468fa16641e0fe30c37fd20e699af92..3564ad477d4f95ea6ce98ae6b6657d9f3200b016 100644 --- a/client/authority-discovery/Cargo.toml +++ b/client/authority-discovery/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "substrate-authority-discovery" +name = "sc-authority-discovery" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" @@ -9,24 +9,26 @@ build = "build.rs" prost-build = "0.5.0" [dependencies] -authority-discovery-primitives = { package = "substrate-authority-discovery-primitives", path = "../../primitives/authority-discovery" } +sp-authority-discovery = { version = "2.0.0", path = "../../primitives/authority-discovery" } bytes = "0.4.12" -client-api = { package = "substrate-client-api", path = "../api" } +sc-client-api = { version = "2.0.0", path = "../api" } codec = { package = "parity-scale-codec", default-features = false, version = "1.0.3" } -derive_more = "0.15.0" +derive_more = "0.99.2" futures = "0.3.1" futures-timer = "2.0" -keystore = { package = "substrate-keystore", path = "../keystore" } +sc-keystore = { version = "2.0.0", path = "../keystore" } libp2p = { version = "0.13.0", default-features = false, features = ["secp256k1", "libp2p-websocket"] } log = "0.4.8" -network = { package = "substrate-network", path = "../network" } -primitives = { package = "substrate-primitives", path = "../../primitives/core" } +sc-network = { version = "0.8", path = "../network" } +sp-core = { version = "2.0.0", path = "../../primitives/core" } +sp-blockchain = { version = "2.0.0", path = "../../primitives/blockchain" } prost = "0.5.0" serde_json = "1.0.41" -sr-primitives = { path = "../../primitives/sr-primitives" } +sp-runtime = { version = "2.0.0", path = "../../primitives/runtime" } [dev-dependencies] +env_logger = "0.7.0" parking_lot = "0.9.0" -peerset = { package = "substrate-peerset", path = "../../primitives/peerset" } -test-client = { package = "substrate-test-runtime-client", path = "../../test/utils/runtime/client" } -sr-api = { path = "../../primitives/sr-api" } +sc-peerset = { version = "2.0.0", path = "../peerset" } +sp-test-primitives = { version = "2.0.0", path = "../../primitives/test-primitives" } +sp-api = { version = "2.0.0", path = "../../primitives/api" } diff --git a/client/authority-discovery/src/error.rs b/client/authority-discovery/src/error.rs index a05bc3b68005dd13cd57efb911e37e9582e28bd7..fdbd5b31fe2c1e6badb715072a08c9600bde42d0 100644 --- a/client/authority-discovery/src/error.rs +++ b/client/authority-discovery/src/error.rs @@ -27,7 +27,7 @@ pub enum Error { /// Failed to hash the authority id to be used as a dht key. HashingAuthorityId(libp2p::core::multiaddr::multihash::EncodeError), /// Failed calling into the Substrate runtime. - CallingRuntime(client_api::error::Error), + CallingRuntime(sp_blockchain::Error), /// From the Dht we only get the hashed authority id. In order to retrieve the actual authority id and to ensure it /// is actually an authority, we match the hash against the hash of the authority id of all other authorities. This /// error is the result of the above failing. diff --git a/client/authority-discovery/src/lib.rs b/client/authority-discovery/src/lib.rs index 0c9d8e59ac38236c2cf7e0203eb1495e77bcba6e..6ab2d899a562e759d0e5bb9c5ce33a3ddbe9de3f 100644 --- a/client/authority-discovery/src/lib.rs +++ b/client/authority-discovery/src/lib.rs @@ -18,8 +18,9 @@ //! Substrate authority discovery. //! -//! This crate enables Substrate authorities to directly connect to other authorities. [`AuthorityDiscovery`] implements -//! the Future trait. By polling [`AuthorityDiscovery`] an authority: +//! This crate enables Substrate authorities to directly connect to other authorities. +//! [`AuthorityDiscovery`] implements the Future trait. By polling [`AuthorityDiscovery`] an +//! authority: //! //! //! 1. **Makes itself discoverable** @@ -54,18 +55,21 @@ use futures::task::{Context, Poll}; use futures::{Future, FutureExt, Stream, StreamExt}; use futures_timer::Delay; -use authority_discovery_primitives::{AuthorityDiscoveryApi, AuthorityId, AuthoritySignature, AuthorityPair}; -use client_api::blockchain::HeaderBackend; +use sp_authority_discovery::{ + AuthorityDiscoveryApi, AuthorityId, AuthoritySignature, AuthorityPair +}; +use sc_client_api::blockchain::HeaderBackend; use codec::{Decode, Encode}; use error::{Error, Result}; use log::{debug, error, log_enabled, warn}; -use network::specialization::NetworkSpecialization; -use network::{DhtEvent, ExHashT}; -use primitives::crypto::{key_types, Pair}; -use primitives::traits::BareCryptoStorePtr; +use libp2p::Multiaddr; +use sc_network::specialization::NetworkSpecialization; +use sc_network::{DhtEvent, ExHashT}; +use sp_core::crypto::{key_types, Pair}; +use sp_core::traits::BareCryptoStorePtr; use prost::Message; -use sr_primitives::generic::BlockId; -use sr_primitives::traits::{Block as BlockT, ProvideRuntimeApi}; +use sp_runtime::generic::BlockId; +use sp_runtime::traits::{Block as BlockT, ProvideRuntimeApi}; type Interval = Box + Unpin + Send + Sync>; @@ -78,9 +82,16 @@ mod schema { /// Upper bound estimation on how long one should wait before accessing the Kademlia DHT. const LIBP2P_KADEMLIA_BOOTSTRAP_TIME: Duration = Duration::from_secs(30); -/// Name of the Substrate peerset priority group for authorities discovered through the authority discovery module. +/// Name of the Substrate peerset priority group for authorities discovered through the authority +/// discovery module. const AUTHORITIES_PRIORITY_GROUP_NAME: &'static str = "authorities"; +/// The maximum number of sentry node public addresses that we accept per authority. +/// +/// Everything above this threshold should be dropped to prevent a single authority from filling up +/// our peer set priority group. +const MAX_NUM_SENTRY_ADDRESSES_PER_AUTHORITY: usize = 5; + /// An `AuthorityDiscovery` makes a given authority discoverable and discovers other authorities. pub struct AuthorityDiscovery where @@ -93,6 +104,14 @@ where client: Arc, network: Arc, + /// List of sentry node public addresses. + // + // There are 3 states: + // - None: No addresses were specified. + // - Some(vec![]): Addresses were specified, but none could be parsed as proper + // Multiaddresses. + // - Some(vec![a, b, c, ...]): Valid addresses were specified. + sentry_nodes: Option>, /// Channel we receive Dht events on. dht_event_rx: Pin + Send>>, @@ -103,11 +122,12 @@ where /// Interval on which to query for addresses of other authorities. query_interval: Interval, - /// The network peerset interface for priority groups lets us only set an entire group, but we retrieve the - /// addresses of other authorities one by one from the network. To use the peerset interface we need to cache the - /// addresses and always overwrite the entire peerset priority group. To ensure this map doesn't grow indefinitely - /// `purge_old_authorities_from_cache` function is called each time we add a new entry. - address_cache: HashMap>, + /// The network peerset interface for priority groups lets us only set an entire group, but we + /// retrieve the addresses of other authorities one by one from the network. To use the peerset + /// interface we need to cache the addresses and always overwrite the entire peerset priority + /// group. To ensure this map doesn't grow indefinitely `purge_old_authorities_from_cache` + /// function is called each time we add a new entry. + address_cache: HashMap>, phantom: PhantomData, } @@ -117,36 +137,70 @@ where Block: BlockT + Unpin + 'static, Network: NetworkProvider, Client: ProvideRuntimeApi + Send + Sync + 'static + HeaderBackend, - ::Api: AuthorityDiscoveryApi, + ::Api: AuthorityDiscoveryApi, Self: Future, { /// Return a new authority discovery. + /// + /// Note: When specifying `sentry_nodes` this module will not advertise the public addresses of + /// the node itself but only the public addresses of its sentry nodes. pub fn new( client: Arc, network: Arc, + sentry_nodes: Vec, key_store: BareCryptoStorePtr, dht_event_rx: Pin + Send>>, ) -> Self { - // Kademlia's default time-to-live for Dht records is 36h, republishing records every 24h. Given that a node - // could restart at any point in time, one can not depend on the republishing process, thus publishing own - // external addresses should happen on an interval < 36h. + // Kademlia's default time-to-live for Dht records is 36h, republishing records every 24h. + // Given that a node could restart at any point in time, one can not depend on the + // republishing process, thus publishing own external addresses should happen on an interval + // < 36h. let publish_interval = interval_at( Instant::now() + LIBP2P_KADEMLIA_BOOTSTRAP_TIME, Duration::from_secs(12 * 60 * 60), ); - // External addresses of other authorities can change at any given point in time. The interval on which to query - // for external addresses of other authorities is a trade off between efficiency and performance. + // External addresses of other authorities can change at any given point in time. The + // interval on which to query for external addresses of other authorities is a trade off + // between efficiency and performance. let query_interval = interval_at( Instant::now() + LIBP2P_KADEMLIA_BOOTSTRAP_TIME, Duration::from_secs(10 * 60), ); + let sentry_nodes = if !sentry_nodes.is_empty() { + let addrs = sentry_nodes.into_iter().filter_map(|a| match a.parse() { + Ok(addr) => Some(addr), + Err(e) => { + error!( + target: "sub-authority-discovery", + "Failed to parse sentry node public address '{:?}', continuing anyways.", e, + ); + None + } + }).collect::>(); + + if addrs.len() > MAX_NUM_SENTRY_ADDRESSES_PER_AUTHORITY { + warn!( + target: "sub-authority-discovery", + "More than MAX_NUM_SENTRY_ADDRESSES_PER_AUTHORITY ({:?}) were specified. Other \ + nodes will likely ignore the remainder.", + MAX_NUM_SENTRY_ADDRESSES_PER_AUTHORITY, + ); + } + + Some(addrs) + } else { + None + }; + + let address_cache = HashMap::new(); AuthorityDiscovery { client, network, + sentry_nodes, dht_event_rx, key_store, publish_interval, @@ -156,18 +210,20 @@ where } } - fn publish_own_ext_addresses(&mut self) -> Result<()> { - let addresses = self - .network - .external_addresses() - .into_iter() - .map(|a| { - a.with(libp2p::core::multiaddr::Protocol::P2p( + /// Publish either our own or if specified the public addresses of our sentry nodes. + fn publish_ext_addresses(&mut self) -> Result<()> { + let addresses = match &self.sentry_nodes { + Some(addrs) => addrs.clone().into_iter() + .map(|a| a.to_vec()) + .collect(), + None => self.network.external_addresses() + .into_iter() + .map(|a| a.with(libp2p::core::multiaddr::Protocol::P2p( self.network.local_peer_id().into(), - )) - }) - .map(|a| a.to_vec()) - .collect(); + ))) + .map(|a| a.to_vec()) + .collect(), + }; let mut serialized_addresses = vec![]; schema::AuthorityAddresses { addresses } @@ -217,7 +273,10 @@ where DhtEvent::ValueFound(v) => { if log_enabled!(log::Level::Debug) { let hashes = v.iter().map(|(hash, _value)| hash.clone()); - debug!(target: "sub-authority-discovery", "Value for hash '{:?}' found on Dht.", hashes); + debug!( + target: "sub-authority-discovery", + "Value for hash '{:?}' found on Dht.", hashes, + ); } self.handle_dht_value_found_event(v)?; @@ -247,8 +306,9 @@ where let block_id = BlockId::hash(self.client.info().best_hash); - // From the Dht we only get the hashed authority id. In order to retrieve the actual authority id and to ensure - // it is actually an authority, we match the hash against the hash of the authority id of all other authorities. + // From the Dht we only get the hashed authority id. In order to retrieve the actual + // authority id and to ensure it is actually an authority, we match the hash against the + // hash of the authority id of all other authorities. let authorities = self.client.runtime_api().authorities(&block_id)?; self.purge_old_authorities_from_cache(&authorities); @@ -267,13 +327,14 @@ where signature, addresses, } = schema::SignedAuthorityAddresses::decode(value).map_err(Error::DecodingProto)?; - let signature = AuthoritySignature::decode(&mut &signature[..]).map_err(Error::EncodingDecodingScale)?; + let signature = AuthoritySignature::decode(&mut &signature[..]) + .map_err(Error::EncodingDecodingScale)?; if !AuthorityPair::verify(&signature, &addresses, authority_id) { return Err(Error::VerifyingDhtPayload); } - let addresses: Vec = schema::AuthorityAddresses::decode(addresses) + let mut addresses: Vec = schema::AuthorityAddresses::decode(addresses) .map(|a| a.addresses) .map_err(Error::DecodingProto)? .into_iter() @@ -281,6 +342,18 @@ where .collect::>() .map_err(Error::ParsingMultiaddress)?; + if addresses.len() > MAX_NUM_SENTRY_ADDRESSES_PER_AUTHORITY { + warn!( + target: "sub-authority-discovery", + "Got more than MAX_NUM_SENTRY_ADDRESSES_PER_AUTHORITY ({:?}) for Authority \ + '{:?}' from DHT, dropping the remainder.", + MAX_NUM_SENTRY_ADDRESSES_PER_AUTHORITY, authority_id, + ); + addresses = addresses.into_iter() + .take(MAX_NUM_SENTRY_ADDRESSES_PER_AUTHORITY) + .collect(); + } + self.address_cache.insert(authority_id.clone(), addresses); } @@ -293,7 +366,10 @@ where .flatten(), ); - debug!(target: "sub-authority-discovery", "Applying priority group {:#?} to peerset.", addresses); + debug!( + target: "sub-authority-discovery", + "Applying priority group {:#?} to peerset.", addresses, + ); self.network .set_priority_group(AUTHORITIES_PRIORITY_GROUP_NAME.to_string(), addresses) .map_err(Error::SettingPeersetPriorityGroup)?; @@ -358,7 +434,7 @@ where Block: BlockT + Unpin + 'static, Network: NetworkProvider, Client: ProvideRuntimeApi + Send + Sync + 'static + HeaderBackend, - ::Api: AuthorityDiscoveryApi, + ::Api: AuthorityDiscoveryApi, { type Output = (); @@ -368,20 +444,20 @@ where self.handle_dht_events(cx)?; if let Poll::Ready(_) = self.publish_interval.poll_next_unpin(cx) { - // Make sure to call interval.poll until it returns Async::NotReady once. Otherwise, in case one of the - // function calls within this block do a `return`, we don't call `interval.poll` again and thereby the - // underlying Tokio task is never registered with Tokio's Reactor to be woken up on the next interval - // tick. + // Make sure to call interval.poll until it returns Async::NotReady once. Otherwise, + // in case one of the function calls within this block do a `return`, we don't call + // `interval.poll` again and thereby the underlying Tokio task is never registered + // with Tokio's Reactor to be woken up on the next interval tick. while let Poll::Ready(_) = self.publish_interval.poll_next_unpin(cx) {} - self.publish_own_ext_addresses()?; + self.publish_ext_addresses()?; } if let Poll::Ready(_) = self.query_interval.poll_next_unpin(cx) { - // Make sure to call interval.poll until it returns Async::NotReady once. Otherwise, in case one of the - // function calls within this block do a `return`, we don't call `interval.poll` again and thereby the - // underlying Tokio task is never registered with Tokio's Reactor to be woken up on the next interval - // tick. + // Make sure to call interval.poll until it returns Async::NotReady once. Otherwise, + // in case one of the function calls within this block do a `return`, we don't call + // `interval.poll` again and thereby the underlying Tokio task is never registered + // with Tokio's Reactor to be woken up on the next interval tick. while let Poll::Ready(_) = self.query_interval.poll_next_unpin(cx) {} self.request_addresses_of_others()?; @@ -395,13 +471,15 @@ where Err(e) => error!(target: "sub-authority-discovery", "Poll failure: {:?}", e), }; - // Make sure to always return NotReady as this is a long running task with the same lifetime as the node itself. + // Make sure to always return NotReady as this is a long running task with the same lifetime + // as the node itself. Poll::Pending } } -/// NetworkProvider provides AuthorityDiscovery with all necessary hooks into the underlying Substrate networking. Using -/// this trait abstraction instead of NetworkService directly is necessary to unit test AuthorityDiscovery. +/// NetworkProvider provides AuthorityDiscovery with all necessary hooks into the underlying +/// Substrate networking. Using this trait abstraction instead of NetworkService directly is +/// necessary to unit test AuthorityDiscovery. pub trait NetworkProvider { /// Returns the local external addresses. fn external_addresses(&self) -> Vec; @@ -423,7 +501,7 @@ pub trait NetworkProvider { fn get_value(&self, key: &libp2p::kad::record::Key); } -impl NetworkProvider for network::NetworkService +impl NetworkProvider for sc_network::NetworkService where B: BlockT + 'static, S: NetworkSpecialization, @@ -457,14 +535,11 @@ fn hash_authority_id(id: &[u8]) -> Result { } fn interval_at(start: Instant, duration: Duration) -> Interval { - let stream = futures::stream::unfold((), move |_| { - let wait_time = start.saturating_duration_since(Instant::now()); + let stream = futures::stream::unfold(start, move |next| { + let time_until_next = next.saturating_duration_since(Instant::now()); - futures::future::join( - Delay::new(wait_time), - Delay::new(duration) - ).map(|_| Some(((), ()))) - }).map(drop); + Delay::new(time_until_next).map(move |_| Some(((), next + duration))) + }); Box::new(stream) } @@ -472,15 +547,78 @@ fn interval_at(start: Instant, duration: Duration) -> Interval { #[cfg(test)] mod tests { use super::*; - use sr_api::{ApiExt, Core, RuntimeVersion, StorageProof}; + use sp_api::{ApiExt, Core, RuntimeVersion, StorageProof}; use futures::channel::mpsc::channel; use futures::executor::block_on; use futures::future::poll_fn; - use primitives::{ExecutionContext, NativeOrEncoded, testing::KeyStore}; - use sr_primitives::traits::Zero; - use sr_primitives::traits::{ApiRef, Block as BlockT, NumberFor, ProvideRuntimeApi}; + use sp_core::{ExecutionContext, NativeOrEncoded, testing::KeyStore}; + use sp_runtime::traits::Zero; + use sp_runtime::traits::{ApiRef, Block as BlockT, NumberFor, ProvideRuntimeApi}; use std::sync::{Arc, Mutex}; - use test_client::runtime::Block; + use sp_test_primitives::Block; + + #[test] + fn interval_at_with_start_now() { + let start = Instant::now(); + + let mut interval = interval_at( + std::time::Instant::now(), + std::time::Duration::from_secs(10), + ); + + futures::executor::block_on(async { + interval.next().await; + }); + + assert!( + Instant::now().saturating_duration_since(start) < Duration::from_secs(1), + "Expected low resolution instant interval to fire within less than a second.", + ); + } + + #[test] + fn interval_at_is_queuing_ticks() { + let start = Instant::now(); + + let interval = interval_at( + start, + std::time::Duration::from_millis(100), + ); + + // Let's wait for 200ms, thus 3 elements should be queued up (1st at 0ms, 2nd at 100ms, 3rd + // at 200ms). + std::thread::sleep(Duration::from_millis(200)); + + futures::executor::block_on(async { + interval.take(3).collect::>().await; + }); + + // Make sure we did not wait for more than 300 ms, which would imply that `at_interval` is + // not queuing ticks. + assert!( + Instant::now().saturating_duration_since(start) < Duration::from_millis(300), + "Expect interval to /queue/ events when not polled for a while.", + ); + } + + #[test] + fn interval_at_with_initial_delay() { + let start = Instant::now(); + + let mut interval = interval_at( + std::time::Instant::now() + Duration::from_millis(100), + std::time::Duration::from_secs(10), + ); + + futures::executor::block_on(async { + interval.next().await; + }); + + assert!( + Instant::now().saturating_duration_since(start) > Duration::from_millis(100), + "Expected interval with initial delay not to fire right away.", + ); + } #[derive(Clone)] struct TestApi { @@ -500,12 +638,12 @@ mod tests { fn header( &self, _id: BlockId, - ) -> std::result::Result, client_api::error::Error> { + ) -> std::result::Result, sp_blockchain::Error> { Ok(None) } - fn info(&self) -> client_api::blockchain::Info { - client_api::blockchain::Info { + fn info(&self) -> sc_client_api::blockchain::Info { + sc_client_api::blockchain::Info { best_hash: Default::default(), best_number: Zero::zero(), finalized_hash: Default::default(), @@ -517,21 +655,21 @@ mod tests { fn status( &self, _id: BlockId, - ) -> std::result::Result { - Ok(client_api::blockchain::BlockStatus::Unknown) + ) -> std::result::Result { + Ok(sc_client_api::blockchain::BlockStatus::Unknown) } fn number( &self, _hash: Block::Hash, - ) -> std::result::Result>, client_api::error::Error> { + ) -> std::result::Result>, sp_blockchain::Error> { Ok(None) } fn hash( &self, _number: NumberFor, - ) -> std::result::Result, client_api::error::Error> { + ) -> std::result::Result, sp_blockchain::Error> { Ok(None) } } @@ -547,7 +685,7 @@ mod tests { _: ExecutionContext, _: Option<()>, _: Vec, - ) -> std::result::Result, client_api::error::Error> { + ) -> std::result::Result, sp_blockchain::Error> { unimplemented!("Not required for testing!") } @@ -557,7 +695,7 @@ mod tests { _: ExecutionContext, _: Option<(Block)>, _: Vec, - ) -> std::result::Result, client_api::error::Error> { + ) -> std::result::Result, sp_blockchain::Error> { unimplemented!("Not required for testing!") } @@ -567,13 +705,13 @@ mod tests { _: ExecutionContext, _: Option<&::Header>, _: Vec, - ) -> std::result::Result, client_api::error::Error> { + ) -> std::result::Result, sp_blockchain::Error> { unimplemented!("Not required for testing!") } } impl ApiExt for RuntimeApi { - type Error = client_api::error::Error; + type Error = sp_blockchain::Error; fn map_api_result std::result::Result, R, E>( &self, @@ -585,7 +723,7 @@ mod tests { fn runtime_version_at( &self, _: &BlockId, - ) -> std::result::Result { + ) -> std::result::Result { unimplemented!("Not required for testing!") } @@ -605,14 +743,15 @@ mod tests { _: ExecutionContext, _: Option<()>, _: Vec, - ) -> std::result::Result>, client_api::error::Error> { + ) -> std::result::Result>, sp_blockchain::Error> { return Ok(NativeOrEncoded::Native(self.authorities.clone())); } } #[derive(Default)] struct TestNetwork { - // Whenever functions on `TestNetwork` are called, the function arguments are added to the vectors below. + // Whenever functions on `TestNetwork` are called, the function arguments are added to the + // vectors below. pub put_value_call: Arc)>>>, pub get_value_call: Arc>>, pub set_priority_group_call: Arc)>>>, @@ -645,17 +784,20 @@ mod tests { } #[test] - fn publish_own_ext_addresses_puts_record_on_dht() { + fn publish_ext_addresses_puts_record_on_dht() { let (_dht_event_tx, dht_event_rx) = channel(1000); let network: Arc = Arc::new(Default::default()); let key_store = KeyStore::new(); - let public = key_store.write().sr25519_generate_new(key_types::AUTHORITY_DISCOVERY, None).unwrap(); + let public = key_store.write() + .sr25519_generate_new(key_types::AUTHORITY_DISCOVERY, None) + .unwrap(); let test_api = Arc::new(TestApi {authorities: vec![public.into()]}); - let mut authority_discovery = - AuthorityDiscovery::new(test_api, network.clone(), key_store, dht_event_rx.boxed()); + let mut authority_discovery = AuthorityDiscovery::new( + test_api, network.clone(), vec![], key_store, dht_event_rx.boxed(), + ); - authority_discovery.publish_own_ext_addresses().unwrap(); + authority_discovery.publish_ext_addresses().unwrap(); // Expect authority discovery to put a new record onto the dht. assert_eq!(network.put_value_call.lock().unwrap().len(), 1); @@ -663,6 +805,7 @@ mod tests { #[test] fn request_addresses_of_others_triggers_dht_get_query() { + let _ = ::env_logger::try_init(); let (_dht_event_tx, dht_event_rx) = channel(1000); // Generate authority keys @@ -676,8 +819,9 @@ mod tests { let network: Arc = Arc::new(Default::default()); let key_store = KeyStore::new(); - let mut authority_discovery = - AuthorityDiscovery::new(test_api, network.clone(), key_store, dht_event_rx.boxed()); + let mut authority_discovery = AuthorityDiscovery::new( + test_api, network.clone(), vec![], key_store, dht_event_rx.boxed(), + ); authority_discovery.request_addresses_of_others().unwrap(); @@ -687,6 +831,7 @@ mod tests { #[test] fn handle_dht_events_with_value_found_should_call_set_priority_group() { + let _ = ::env_logger::try_init(); // Create authority discovery. let (mut dht_event_tx, dht_event_rx) = channel(1000); @@ -695,8 +840,9 @@ mod tests { let network: Arc = Arc::new(Default::default()); let key_store = KeyStore::new(); - let mut authority_discovery = - AuthorityDiscovery::new(test_api, network.clone(), key_store, dht_event_rx.boxed()); + let mut authority_discovery = AuthorityDiscovery::new( + test_api, network.clone(), vec![], key_store, dht_event_rx.boxed(), + ); // Create sample dht event. @@ -719,7 +865,7 @@ mod tests { .encode(&mut signed_addresses) .unwrap(); - let dht_event = network::DhtEvent::ValueFound(vec![(authority_id_1, signed_addresses)]); + let dht_event = sc_network::DhtEvent::ValueFound(vec![(authority_id_1, signed_addresses)]); dht_event_tx.try_send(dht_event).unwrap(); // Make authority discovery handle the event. diff --git a/client/basic-authorship/Cargo.toml b/client/basic-authorship/Cargo.toml index 4d3309fb2d1d7006fd87a07ead0f1d387f69b284..a93ca94282ad79f447eb76d962964cd594589582 100644 --- a/client/basic-authorship/Cargo.toml +++ b/client/basic-authorship/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "substrate-basic-authorship" +name = "sc-basic-authority" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" @@ -8,15 +8,19 @@ edition = "2018" log = "0.4.8" futures = "0.3.1" codec = { package = "parity-scale-codec", version = "1.0.0" } -sr-primitives = { path = "../../primitives/sr-primitives" } -primitives = { package = "substrate-primitives", path = "../../primitives/core" } -client = { package = "substrate-client", path = "../" } -client-api = { package = "substrate-client-api", path = "../api" } -consensus_common = { package = "substrate-consensus-common", path = "../../primitives/consensus/common" } -inherents = { package = "substrate-inherents", path = "../../primitives/inherents" } -substrate-telemetry = { path = "../telemetry" } -transaction_pool = { package = "substrate-transaction-pool", path = "../transaction-pool" } -block-builder = { package = "substrate-block-builder", path = "../block-builder" } +sp-runtime = { version = "2.0.0", path = "../../primitives/runtime" } +sp-core = { version = "2.0.0", path = "../../primitives/core" } +sp-blockchain = { version = "2.0.0", path = "../../primitives/blockchain" } +sc-client = { version = "2.0.0", path = "../" } +sc-client-api = { version = "2.0.0", path = "../api" } +sp-consensus = { version = "0.8", path = "../../primitives/consensus/common" } +sp-inherents = { version = "2.0.0", path = "../../primitives/inherents" } +sc-telemetry = { version = "2.0.0", path = "../telemetry" } +sp-transaction-pool = { version = "2.0.0", path = "../../primitives/transaction-pool" } +sc-block-builder = { version = "2.0.0", path = "../block-builder" } +tokio-executor = { version = "0.2.0-alpha.6", features = ["blocking"] } [dev-dependencies] -test-client = { package = "substrate-test-runtime-client", path = "../../test/utils/runtime/client" } +sc-transaction-pool = { version = "2.0.0", path = "../../client/transaction-pool" } +substrate-test-runtime-client = { version = "2.0.0", path = "../../test-utils/runtime/client" } +parking_lot = "0.9" diff --git a/client/basic-authorship/src/basic_authorship.rs b/client/basic-authorship/src/basic_authorship.rs index 7d8956152c13f1dda52a7c363b92477fda2bd97d..55f358cdd78010765448d6c57d98517bfdf270d7 100644 --- a/client/basic-authorship/src/basic_authorship.rs +++ b/client/basic-authorship/src/basic_authorship.rs @@ -16,54 +16,51 @@ //! A consensus proposer for "basic" chains which use the primitive inherent-data. -// FIXME #1021 move this into substrate-consensus-common -// +// FIXME #1021 move this into sp-consensus use std::{time, sync::Arc}; -use client_api::{error, CallExecutor}; -use client::Client as SubstrateClient; +use sc_client_api::CallExecutor; +use sp_blockchain; +use sc_client::Client as SubstrateClient; use codec::Decode; -use consensus_common::{evaluation}; -use inherents::InherentData; +use sp_consensus::{evaluation}; +use sp_inherents::InherentData; use log::{error, info, debug, trace}; -use primitives::{H256, Blake2Hasher, ExecutionContext}; -use sr_primitives::{ +use sp_core::{H256, Blake2Hasher, ExecutionContext}; +use sp_runtime::{ traits::{ Block as BlockT, Hash as HashT, Header as HeaderT, ProvideRuntimeApi, DigestFor, BlakeTwo256 }, generic::BlockId, }; -use transaction_pool::txpool::{self, Pool as TransactionPool}; -use substrate_telemetry::{telemetry, CONSENSUS_INFO}; -use block_builder::BlockBuilderApi; +use sp_transaction_pool::{TransactionPool, InPoolTransaction}; +use sc_telemetry::{telemetry, CONSENSUS_INFO}; +use sc_block_builder::BlockBuilderApi; /// Proposer factory. -pub struct ProposerFactory where A: txpool::ChainApi { +pub struct ProposerFactory where A: TransactionPool { /// The client instance. pub client: Arc, /// The transaction pool. - pub transaction_pool: Arc>, + pub transaction_pool: Arc, } -impl consensus_common::Environment for -ProposerFactory, A> +impl ProposerFactory, A> where - A: txpool::ChainApi, - B: client_api::backend::Backend + Send + Sync + 'static, + A: TransactionPool + 'static, + B: sc_client_api::backend::Backend + Send + Sync + 'static, E: CallExecutor + Send + Sync + Clone + 'static, Block: BlockT, RA: Send + Sync + 'static, SubstrateClient: ProvideRuntimeApi, as ProvideRuntimeApi>::Api: - BlockBuilderApi, + BlockBuilderApi, { - type Proposer = Proposer, A>; - type Error = error::Error; - - fn init( + pub fn init_with_now( &mut self, parent_header: &::Header, - ) -> Result { + now: Box time::Instant + Send + Sync>, + ) -> Result, A>, sp_blockchain::Error> { let parent_hash = parent_header.hash(); let id = BlockId::hash(parent_hash); @@ -71,42 +68,72 @@ where info!("Starting consensus session on top of parent {:?}", parent_hash); let proposer = Proposer { - client: self.client.clone(), - parent_hash, - parent_id: id, - parent_number: *parent_header.number(), - transaction_pool: self.transaction_pool.clone(), - now: Box::new(time::Instant::now), + inner: Arc::new(ProposerInner { + client: self.client.clone(), + parent_hash, + parent_id: id, + parent_number: *parent_header.number(), + transaction_pool: self.transaction_pool.clone(), + now, + }), }; Ok(proposer) } } +impl sp_consensus::Environment for +ProposerFactory, A> +where + A: TransactionPool + 'static, + B: sc_client_api::backend::Backend + Send + Sync + 'static, + E: CallExecutor + Send + Sync + Clone + 'static, + Block: BlockT, + RA: Send + Sync + 'static, + SubstrateClient: ProvideRuntimeApi, + as ProvideRuntimeApi>::Api: + BlockBuilderApi, +{ + type Proposer = Proposer, A>; + type Error = sp_blockchain::Error; + + fn init( + &mut self, + parent_header: &::Header, + ) -> Result { + self.init_with_now(parent_header, Box::new(time::Instant::now)) + } +} + /// The proposer logic. -pub struct Proposer { +pub struct Proposer { + inner: Arc>, +} + +/// Proposer inner, to wrap parameters under Arc. +struct ProposerInner { client: Arc, parent_hash: ::Hash, parent_id: BlockId, parent_number: <::Header as HeaderT>::Number, - transaction_pool: Arc>, - now: Box time::Instant>, + transaction_pool: Arc, + now: Box time::Instant + Send + Sync>, } -impl consensus_common::Proposer for +impl sp_consensus::Proposer for Proposer, A> where - A: txpool::ChainApi, - B: client_api::backend::Backend + Send + Sync + 'static, + A: TransactionPool + 'static, + B: sc_client_api::backend::Backend + Send + Sync + 'static, E: CallExecutor + Send + Sync + Clone + 'static, Block: BlockT, RA: Send + Sync + 'static, SubstrateClient: ProvideRuntimeApi, as ProvideRuntimeApi>::Api: - BlockBuilderApi, + BlockBuilderApi, { - type Create = futures::future::Ready>; - type Error = error::Error; + type Create = tokio_executor::blocking::Blocking>; + type Error = sp_blockchain::Error; fn propose( &mut self, @@ -114,28 +141,31 @@ where inherent_digests: DigestFor, max_duration: time::Duration, ) -> Self::Create { - // leave some time for evaluation and block finalization (33%) - let deadline = (self.now)() + max_duration - max_duration / 3; - futures::future::ready(self.propose_with(inherent_data, inherent_digests, deadline)) + let inner = self.inner.clone(); + tokio_executor::blocking::run(move || { + // leave some time for evaluation and block finalization (33%) + let deadline = (inner.now)() + max_duration - max_duration / 3; + inner.propose_with(inherent_data, inherent_digests, deadline) + }) } } -impl Proposer, A> where - A: txpool::ChainApi, - B: client_api::backend::Backend + Send + Sync + 'static, +impl ProposerInner, A> where + A: TransactionPool + 'static, + B: sc_client_api::backend::Backend + Send + Sync + 'static, E: CallExecutor + Send + Sync + Clone + 'static, Block: BlockT, RA: Send + Sync + 'static, SubstrateClient: ProvideRuntimeApi, as ProvideRuntimeApi>::Api: - BlockBuilderApi, + BlockBuilderApi, { fn propose_with( &self, inherent_data: InherentData, inherent_digests: DigestFor, deadline: time::Instant, - ) -> Result { + ) -> Result { /// If the block is full we will attempt to push at most /// this number of transactions before quitting for real. /// It allows us to increase block utilization. @@ -162,21 +192,24 @@ impl Proposer, A> wh let pending_iterator = self.transaction_pool.ready(); debug!("Attempting to push transactions from the pool."); - for pending in pending_iterator { + for pending_tx in pending_iterator { if (self.now)() > deadline { debug!("Consensus deadline reached when pushing block transactions, proceeding with proposing."); break; } - trace!("[{:?}] Pushing to the block.", pending.hash); - match block_builder::BlockBuilder::push(&mut block_builder, pending.data.clone()) { + let pending_tx_data = pending_tx.data().clone(); + let pending_tx_hash = pending_tx.hash().clone(); + trace!("[{:?}] Pushing to the block.", pending_tx_hash); + match sc_block_builder::BlockBuilder::push(&mut block_builder, pending_tx_data) { Ok(()) => { - debug!("[{:?}] Pushed to the block.", pending.hash); + debug!("[{:?}] Pushed to the block.", pending_tx_hash); } - Err(error::Error::ApplyExtrinsicFailed(e)) if e.exhausted_resources() => { + Err(sp_blockchain::Error::ApplyExtrinsicFailed(sp_blockchain::ApplyExtrinsicFailed::Validity(e))) + if e.exhausted_resources() => { if is_first { - debug!("[{:?}] Invalid transaction: FullBlock on empty block", pending.hash); - unqueue_invalid.push(pending.hash.clone()); + debug!("[{:?}] Invalid transaction: FullBlock on empty block", pending_tx_hash); + unqueue_invalid.push(pending_tx_hash); } else if skipped < MAX_SKIPPED_TRANSACTIONS { skipped += 1; debug!( @@ -189,8 +222,8 @@ impl Proposer, A> wh } } Err(e) => { - debug!("[{:?}] Invalid transaction: {}", pending.hash, e); - unqueue_invalid.push(pending.hash.clone()); + debug!("[{:?}] Invalid transaction: {}", pending_tx_hash, e); + unqueue_invalid.push(pending_tx_hash); } } @@ -232,9 +265,10 @@ impl Proposer, A> wh mod tests { use super::*; - use std::cell::RefCell; - use consensus_common::{Environment, Proposer}; - use test_client::{self, runtime::{Extrinsic, Transfer}, AccountKeyring}; + use parking_lot::Mutex; + use sp_consensus::Proposer; + use substrate_test_runtime_client::{self, runtime::{Extrinsic, Transfer}, AccountKeyring}; + use sc_transaction_pool::{BasicPool, FullChainApi}; fn extrinsic(nonce: u64) -> Extrinsic { Transfer { @@ -248,12 +282,11 @@ mod tests { #[test] fn should_cease_building_block_when_deadline_is_reached() { // given - let client = Arc::new(test_client::new()); - let chain_api = transaction_pool::FullChainApi::new(client.clone()); - let txpool = Arc::new(TransactionPool::new(Default::default(), chain_api)); + let client = Arc::new(substrate_test_runtime_client::new()); + let txpool = Arc::new(BasicPool::new(Default::default(), FullChainApi::new(client.clone()))); futures::executor::block_on( - txpool.submit_at(&BlockId::number(0), vec![extrinsic(0), extrinsic(1)], false) + txpool.submit_at(&BlockId::number(0), vec![extrinsic(0), extrinsic(1)]) ).unwrap(); let mut proposer_factory = ProposerFactory { @@ -261,16 +294,19 @@ mod tests { transaction_pool: txpool.clone(), }; - let mut proposer = proposer_factory.init( + let cell = Mutex::new(time::Instant::now()); + let mut proposer = proposer_factory.init_with_now( &client.header(&BlockId::number(0)).unwrap().unwrap(), + Box::new(move || { + let mut value = cell.lock(); + let old = *value; + let new = old + time::Duration::from_secs(2); + *value = new; + old + }) ).unwrap(); // when - let cell = RefCell::new(time::Instant::now()); - proposer.now = Box::new(move || { - let new = *cell.borrow() + time::Duration::from_secs(2); - cell.replace(new) - }); let deadline = time::Duration::from_secs(3); let block = futures::executor::block_on(proposer.propose(Default::default(), Default::default(), deadline)) .unwrap(); diff --git a/client/basic-authorship/src/lib.rs b/client/basic-authorship/src/lib.rs index 7961e4fe9e9dfe7b8e4ccf41fb448335fd286173..65ac39f9ff2092155c6ecb2775e1770594b31892 100644 --- a/client/basic-authorship/src/lib.rs +++ b/client/basic-authorship/src/lib.rs @@ -19,15 +19,14 @@ //! # Example //! //! ``` -//! # use substrate_basic_authorship::ProposerFactory; -//! # use consensus_common::{Environment, Proposer}; -//! # use sr_primitives::generic::BlockId; +//! # use sc_basic_authority::ProposerFactory; +//! # use sp_consensus::{Environment, Proposer}; +//! # use sp_runtime::generic::BlockId; //! # use std::{sync::Arc, time::Duration}; -//! # use test_client::{self, runtime::{Extrinsic, Transfer}, AccountKeyring}; -//! # use transaction_pool::txpool::{self, Pool as TransactionPool}; -//! # let client = Arc::new(test_client::new()); -//! # let chain_api = transaction_pool::FullChainApi::new(client.clone()); -//! # let txpool = Arc::new(TransactionPool::new(Default::default(), chain_api)); +//! # use substrate_test_runtime_client::{self, runtime::{Extrinsic, Transfer}, AccountKeyring}; +//! # use sc_transaction_pool::{BasicPool, FullChainApi}; +//! # let client = Arc::new(substrate_test_runtime_client::new()); +//! # let txpool = Arc::new(BasicPool::new(Default::default(), FullChainApi::new(client.clone()))); //! // The first step is to create a `ProposerFactory`. //! let mut proposer_factory = ProposerFactory { //! client: client.clone(), diff --git a/client/block-builder/Cargo.toml b/client/block-builder/Cargo.toml index 34bfac17bf774791d524dc853675f74fb776c8ff..157fa54960edca8a4b55f7a1a3047104f8564b2e 100644 --- a/client/block-builder/Cargo.toml +++ b/client/block-builder/Cargo.toml @@ -1,14 +1,14 @@ [package] -name = "substrate-block-builder" +name = "sc-block-builder" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" [dependencies] -state-machine = { package = "substrate-state-machine", path = "../../primitives/state-machine" } -sr-primitives = { path = "../../primitives/sr-primitives" } -primitives = { package = "substrate-primitives", path = "../../primitives/core" } +sp-state-machine = { version = "2.0.0", path = "../../primitives/state-machine" } +sp-runtime = { version = "2.0.0", path = "../../primitives/runtime" } +sp-blockchain = { version = "2.0.0", path = "../../primitives/blockchain" } +sp-core = { version = "2.0.0", path = "../../primitives/core" } codec = { package = "parity-scale-codec", version = "1.0.6", features = ["derive"] } -runtime_api = { package = "substrate-block-builder-runtime-api", path = "../../primitives/block-builder/runtime-api" } -sr-api = { path = "../../primitives/sr-api" } - +sp-block-builder = { version = "2.0.0", path = "../../primitives/block-builder" } +sp-api = { version = "2.0.0", path = "../../primitives/api" } diff --git a/client/block-builder/src/lib.rs b/client/block-builder/src/lib.rs index f6e793dce77ee5866c9b138a874ceab98dcddf07..ba5c5694c11464f709e160d1596f1ba875854837 100644 --- a/client/block-builder/src/lib.rs +++ b/client/block-builder/src/lib.rs @@ -17,7 +17,7 @@ //! Substrate block builder //! //! This crate provides the [`BlockBuilder`] utility and the corresponding runtime api -//! [`BlockBuilder`](api::BlockBuilder). +//! [`BlockBuilder`](api::BlockBuilder).Error //! //! The block builder utility is used in the node as an abstraction over the runtime api to //! initialize a block, to push extrinsics and to finalize a block. @@ -26,47 +26,20 @@ use codec::Encode; -use sr_primitives::{ +use sp_runtime::{ generic::BlockId, traits::{ Header as HeaderT, Hash, Block as BlockT, HashFor, ProvideRuntimeApi, ApiRef, DigestFor, NumberFor, One, - }, - transaction_validity::TransactionValidityError, + } }; +use sp_blockchain::{ApplyExtrinsicFailed, Error}; +use sp_core::ExecutionContext; +use sp_state_machine::StorageProof; +use sp_api::{Core, ApiExt, ApiErrorFor}; -use primitives::ExecutionContext; -use state_machine::StorageProof; -use sr_api::{Core, ApiExt, ApiErrorFor}; - -#[allow(deprecated)] -use runtime_api::compatability_v3; - -pub use runtime_api::BlockBuilder as BlockBuilderApi; - -/// Error when the runtime failed to apply an extrinsic. -pub enum ApplyExtrinsicFailed { - /// The transaction cannot be included into the current block. - /// - /// This doesn't necessary mean that the transaction itself is invalid, but it might be just - /// unappliable onto the current block. - Validity(TransactionValidityError), - /// This is used for miscelanious errors that can be represented by string and not handleable. - /// - /// This will become obsolete with complete migration to v4 APIs. - Msg(String), -} +pub use sp_block_builder::BlockBuilder as BlockBuilderApi; -#[allow(deprecated)] -impl From for ApplyExtrinsicFailed { - fn from(e: compatability_v3::ApplyError) -> Self { - use self::compatability_v3::ApplyError::*; - match e { - Validity(tx_validity) => Self::Validity(tx_validity), - e => Self::Msg(format!("Apply extrinsic failed: {:?}", e)), - } - } -} /// Utility for building new (valid) blocks from a stream of extrinsics. pub struct BlockBuilder<'a, Block: BlockT, A: ProvideRuntimeApi> { @@ -81,7 +54,7 @@ where Block: BlockT, A: ProvideRuntimeApi + 'a, A::Api: BlockBuilderApi, - ApiErrorFor: From, + ApiErrorFor: From, { /// Create a new instance of builder based on the given `parent_hash` and `parent_number`. /// @@ -149,7 +122,7 @@ where extrinsics.push(xt); Ok(()) } - Err(e) => Err(ApplyExtrinsicFailed::from(e))?, + Err(e) => Err(ApplyExtrinsicFailed::from(e).into())?, } }) } else { @@ -163,7 +136,7 @@ where extrinsics.push(xt); Ok(()) } - Err(tx_validity) => Err(ApplyExtrinsicFailed::Validity(tx_validity))?, + Err(tx_validity) => Err(ApplyExtrinsicFailed::Validity(tx_validity).into())?, } }) } diff --git a/client/chain-spec/Cargo.toml b/client/chain-spec/Cargo.toml index da9543e398774dd0161a83c6bc166abd85da2a8a..fee166df322665f8148e62e1c44f3201fea9af99 100644 --- a/client/chain-spec/Cargo.toml +++ b/client/chain-spec/Cargo.toml @@ -1,15 +1,15 @@ [package] -name = "substrate-chain-spec" +name = "sc-chain-spec" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" [dependencies] -substrate-chain-spec-derive = { path = "./derive" } +sc-chain-spec-derive = { version = "2.0.0", path = "./derive" } impl-trait-for-tuples = "0.1.3" -network = { package = "substrate-network", path = "../network" } -primitives = { package = "substrate-primitives", path = "../../primitives/core" } +sc-network = { version = "0.8", path = "../network" } +sp-core = { version = "2.0.0", path = "../../primitives/core" } serde = { version = "1.0.101", features = ["derive"] } serde_json = "1.0.41" -sr-primitives = { path = "../../primitives/sr-primitives" } -tel = { package = "substrate-telemetry", path = "../telemetry" } +sp-runtime = { version = "2.0.0", path = "../../primitives/runtime" } +sc-telemetry = { version = "2.0.0", path = "../telemetry" } diff --git a/client/chain-spec/derive/Cargo.toml b/client/chain-spec/derive/Cargo.toml index 9fb8eabc608444dbbb4a52684e35d8ee1a28ffa4..108644066496fcc4bcf24a703d85da8bd83bbdc4 100644 --- a/client/chain-spec/derive/Cargo.toml +++ b/client/chain-spec/derive/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "substrate-chain-spec-derive" +name = "sc-chain-spec-derive" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" diff --git a/client/chain-spec/derive/src/impls.rs b/client/chain-spec/derive/src/impls.rs index cdc27aef0b9c698aac9742056814f76a49091d5f..fb16823151bd80613497faeb44a71cf730bb11cc 100644 --- a/client/chain-spec/derive/src/impls.rs +++ b/client/chain-spec/derive/src/impls.rs @@ -19,7 +19,7 @@ use quote::quote; use syn::{DeriveInput, Ident, Error}; use proc_macro_crate::crate_name; -const CRATE_NAME: &str = "substrate-chain-spec"; +const CRATE_NAME: &str = "sc-chain-spec"; const ATTRIBUTE_NAME: &str = "forks"; /// Implements `Extension's` `Group` accessor. diff --git a/client/chain-spec/src/chain_spec.rs b/client/chain-spec/src/chain_spec.rs index 0f69654b9e8f6cf217e1d54c8dbf8d0fb0ef03b3..c5d0fcf402aa2d8062f204d733e03b5a75c795c5 100644 --- a/client/chain-spec/src/chain_spec.rs +++ b/client/chain-spec/src/chain_spec.rs @@ -22,12 +22,12 @@ use std::fs::File; use std::path::PathBuf; use std::rc::Rc; use serde::{Serialize, Deserialize}; -use primitives::storage::{StorageKey, StorageData}; -use sr_primitives::{BuildStorage, StorageOverlay, ChildrenStorageOverlay}; +use sp_core::storage::{StorageKey, StorageData, ChildInfo, Storage, StorageChild}; +use sp_runtime::BuildStorage; use serde_json as json; use crate::RuntimeGenesis; -use network::Multiaddr; -use tel::TelemetryEndpoints; +use sc_network::Multiaddr; +use sc_telemetry::TelemetryEndpoints; enum GenesisSource { File(PathBuf), @@ -71,36 +71,62 @@ impl GenesisSource { } impl<'a, G: RuntimeGenesis, E> BuildStorage for &'a ChainSpec { - fn build_storage(&self) -> Result<(StorageOverlay, ChildrenStorageOverlay), String> { + fn build_storage(&self) -> Result { match self.genesis.resolve()? { Genesis::Runtime(gc) => gc.build_storage(), - Genesis::Raw(map, children_map) => Ok(( - map.into_iter().map(|(k, v)| (k.0, v.0)).collect(), - children_map.into_iter().map(|(sk, map)| ( - sk.0, - map.into_iter().map(|(k, v)| (k.0, v.0)).collect(), - )).collect(), - )), + Genesis::Raw(RawGenesis { top: map, children: children_map }) => Ok(Storage { + top: map.into_iter().map(|(k, v)| (k.0, v.0)).collect(), + children: children_map.into_iter().map(|(sk, child_content)| { + let child_info = ChildInfo::resolve_child_info( + child_content.child_type, + child_content.child_info.as_slice(), + ).expect("chainspec contains correct content").to_owned(); + ( + sk.0, + StorageChild { + data: child_content.data.into_iter().map(|(k, v)| (k.0, v.0)).collect(), + child_info, + }, + ) + }).collect(), + }), } } fn assimilate_storage( &self, - _: &mut (StorageOverlay, ChildrenStorageOverlay) + _: &mut Storage, ) -> Result<(), String> { Err("`assimilate_storage` not implemented for `ChainSpec`.".into()) } } +type GenesisStorage = HashMap; + +#[derive(Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +#[serde(deny_unknown_fields)] +struct ChildRawStorage { + data: GenesisStorage, + child_info: Vec, + child_type: u32, +} + +#[derive(Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +#[serde(deny_unknown_fields)] +/// Storage content for genesis block. +struct RawGenesis { + pub top: GenesisStorage, + pub children: HashMap, +} + #[derive(Serialize, Deserialize)] #[serde(rename_all = "camelCase")] #[serde(deny_unknown_fields)] enum Genesis { Runtime(G), - Raw( - HashMap, - HashMap>, - ), + Raw(RawGenesis), } #[derive(Serialize, Deserialize, Clone, Debug)] @@ -255,19 +281,26 @@ impl ChainSpec { let genesis = match (raw, self.genesis.resolve()?) { (true, Genesis::Runtime(g)) => { let storage = g.build_storage()?; - let top = storage.0.into_iter() + let top = storage.top.into_iter() .map(|(k, v)| (StorageKey(k), StorageData(v))) .collect(); - let children = storage.1.into_iter() - .map(|(sk, child)| ( + let children = storage.children.into_iter() + .map(|(sk, child)| { + let info = child.child_info.as_ref(); + let (info, ci_type) = info.info(); + ( StorageKey(sk), - child.into_iter() - .map(|(k, v)| (StorageKey(k), StorageData(v))) - .collect(), - )) + ChildRawStorage { + data: child.data.into_iter() + .map(|(k, v)| (StorageKey(k), StorageData(v))) + .collect(), + child_info: info.to_vec(), + child_type: ci_type, + }, + )}) .collect(); - Genesis::Raw(top, children) + Genesis::Raw(RawGenesis { top, children }) }, (_, genesis) => genesis, }; @@ -290,9 +323,9 @@ mod tests { impl BuildStorage for Genesis { fn assimilate_storage( &self, - storage: &mut (StorageOverlay, ChildrenStorageOverlay), + storage: &mut Storage, ) -> Result<(), String> { - storage.0.extend( + storage.top.extend( self.0.iter().map(|(a, b)| (a.clone().into_bytes(), b.clone().into_bytes())) ); Ok(()) diff --git a/client/chain-spec/src/extension.rs b/client/chain-spec/src/extension.rs index 6b999281607ecd68d63dd89a7a878241c0db5ac6..8a42408fba96bef292451c086181f82947a36fae 100644 --- a/client/chain-spec/src/extension.rs +++ b/client/chain-spec/src/extension.rs @@ -253,9 +253,9 @@ impl Extension for Forks where #[cfg(test)] mod tests { use super::*; - use substrate_chain_spec_derive::{ChainSpecGroup, ChainSpecExtension}; + use sc_chain_spec_derive::{ChainSpecGroup, ChainSpecExtension}; // Make the proc macro work for tests and doc tests. - use crate as substrate_chain_spec; + use crate as sc_chain_spec; #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ChainSpecGroup)] #[serde(deny_unknown_fields)] diff --git a/client/chain-spec/src/lib.rs b/client/chain-spec/src/lib.rs index 8c35c22d9b2b34959d8dbf05226fffb9e971011f..d8876e8aa88a6efa16cc6f879521860335ed39af 100644 --- a/client/chain-spec/src/lib.rs +++ b/client/chain-spec/src/lib.rs @@ -30,7 +30,7 @@ //! ```rust //! use std::collections::HashMap; //! use serde::{Serialize, Deserialize}; -//! use substrate_chain_spec::{ChainSpec, ChainSpecExtension}; +//! use sc_chain_spec::{ChainSpec, ChainSpecExtension}; //! //! #[derive(Clone, Debug, Serialize, Deserialize, ChainSpecExtension)] //! pub struct MyExtension { @@ -49,7 +49,7 @@ //! //! ```rust //! use serde::{Serialize, Deserialize}; -//! use substrate_chain_spec::{Forks, ChainSpec, ChainSpecGroup, ChainSpecExtension}; +//! use sc_chain_spec::{Forks, ChainSpec, ChainSpecGroup, ChainSpecExtension}; //! //! #[derive(Clone, Debug, Serialize, Deserialize, ChainSpecGroup)] //! pub struct ClientParams { @@ -84,7 +84,7 @@ //! //! ```rust //! use serde::{Serialize, Deserialize}; -//! use substrate_chain_spec::{Forks, ChainSpec, ChainSpecGroup, ChainSpecExtension}; +//! use sc_chain_spec::{Forks, ChainSpec, ChainSpecGroup, ChainSpecExtension}; //! //! #[derive(Clone, Debug, Serialize, Deserialize, ChainSpecGroup)] //! pub struct ClientParams { @@ -113,10 +113,10 @@ mod extension; pub use chain_spec::{ChainSpec, Properties, NoExtension}; pub use extension::{Group, Fork, Forks, Extension}; -pub use substrate_chain_spec_derive::{ChainSpecExtension, ChainSpecGroup}; +pub use sc_chain_spec_derive::{ChainSpecExtension, ChainSpecGroup}; use serde::{Serialize, de::DeserializeOwned}; -use sr_primitives::BuildStorage; +use sp_runtime::BuildStorage; /// A set of traits for the runtime genesis config. pub trait RuntimeGenesis: Serialize + DeserializeOwned + BuildStorage {} diff --git a/client/cli/Cargo.toml b/client/cli/Cargo.toml index af3be8dc941b000d79df4af7173d8cdd56c21ebb..937135a8c30eb4af91d4fb802a0d4e5347c57c02 100644 --- a/client/cli/Cargo.toml +++ b/client/cli/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "substrate-cli" +name = "sc-cli" version = "2.0.0" authors = ["Parity Technologies "] description = "Substrate CLI interface." @@ -7,7 +7,7 @@ edition = "2018" [dependencies] clap = "2.33.0" -derive_more = "0.15.0" +derive_more = "0.99.2" env_logger = "0.7.0" log = "0.4.8" atty = "0.2.13" @@ -16,30 +16,31 @@ time = "0.1.42" ansi_term = "0.12.1" lazy_static = "1.4.0" app_dirs = "1.2.1" -tokio = "0.1.22" +tokio = "0.2.1" futures = { version = "0.3.1", features = ["compat"] } -futures01 = "0.1.29" fdlimit = "0.1.1" serde_json = "1.0.41" -panic-handler = { package = "substrate-panic-handler", path = "../../primitives/panic-handler" } -client-api = { package = "substrate-client-api", path = "../api" } -header-metadata = { package = "substrate-header-metadata", path = "../header-metadata" } -network = { package = "substrate-network", path = "../network" } -sr-primitives = { path = "../../primitives/sr-primitives" } -primitives = { package = "substrate-primitives", path = "../../primitives/core" } -service = { package = "substrate-service", path = "../service", default-features = false } -state-machine = { package = "substrate-state-machine", path = "../../primitives/state-machine" } -substrate-telemetry = { path = "../telemetry" } -keyring = { package = "substrate-keyring", path = "../../primitives/keyring" } +sp-panic-handler = { version = "2.0.0", path = "../../primitives/panic-handler" } +sc-client-api = { version = "2.0.0", path = "../api" } +sp-blockchain = { version = "2.0.0", path = "../../primitives/blockchain" } +sc-network = { version = "0.8", path = "../network" } +sp-runtime = { version = "2.0.0", path = "../../primitives/runtime" } +sp-core = { version = "2.0.0", path = "../../primitives/core" } +sc-service = { version = "2.0.0", default-features = false, path = "../service" } +sp-state-machine = { version = "2.0.0", path = "../../primitives/state-machine" } +sc-telemetry = { version = "2.0.0", path = "../telemetry" } +sp-keyring = { version = "2.0.0", path = "../../primitives/keyring" } names = "0.11.0" structopt = "0.3.3" +sc-tracing = { version = "2.0.0", path = "../tracing" } + +[target.'cfg(not(target_os = "unknown"))'.dependencies] rpassword = "4.0.1" -substrate-tracing = { package = "substrate-tracing", path = "../tracing" } [dev-dependencies] -tempdir = "0.3.7" +tempfile = "3.1.0" [features] wasmtime = [ - "service/wasmtime", + "sc-service/wasmtime", ] diff --git a/client/cli/src/error.rs b/client/cli/src/error.rs index 6b42773bb833ab1fcf63bb3b6f21f87ce6afc98d..80fbdd553baf2169854c9d8aae232ad7d614588e 100644 --- a/client/cli/src/error.rs +++ b/client/cli/src/error.rs @@ -16,8 +16,6 @@ //! Initialization errors. -use client_api; - /// Result type alias for the CLI. pub type Result = std::result::Result; @@ -29,15 +27,17 @@ pub enum Error { /// Cli error Cli(clap::Error), /// Service error - Service(service::Error), + Service(sc_service::Error), /// Client error - Client(client_api::error::Error), + Client(sp_blockchain::Error), /// Input error + #[from(ignore)] Input(String), /// Invalid listen multiaddress #[display(fmt="Invalid listen multiaddress")] InvalidListenMultiaddress, /// Other uncategorized error. + #[from(ignore)] Other(String), } diff --git a/client/cli/src/informant.rs b/client/cli/src/informant.rs index 2f32f95b67f84b956eb789e7ae7911c202b99dce..be896e180dffffa77a4510f45b87b4ab85325b29 100644 --- a/client/cli/src/informant.rs +++ b/client/cli/src/informant.rs @@ -16,11 +16,11 @@ //! Console informant. Prints sync progress and block events. Runs on the calling thread. -use client_api::BlockchainEvents; +use sc_client_api::BlockchainEvents; use futures::{StreamExt, TryStreamExt, FutureExt, future, compat::Stream01CompatExt}; use log::{info, warn}; -use sr_primitives::traits::Header; -use service::AbstractService; +use sp_runtime::traits::Header; +use sc_service::AbstractService; use std::time::Duration; mod display; @@ -50,7 +50,7 @@ pub fn build(service: &impl AbstractService) -> impl futures::Future. use ansi_term::Colour; -use client_api::ClientInfo; +use sc_client_api::ClientInfo; use log::info; -use network::SyncState; -use sr_primitives::traits::{Block as BlockT, CheckedDiv, NumberFor, Zero, Saturating}; -use service::NetworkStatus; +use sc_network::SyncState; +use sp_runtime::traits::{Block as BlockT, CheckedDiv, NumberFor, Zero, Saturating}; +use sc_service::NetworkStatus; use std::{convert::{TryFrom, TryInto}, fmt, time}; /// State of the informant display system. diff --git a/client/cli/src/lib.rs b/client/cli/src/lib.rs index 5d67f42c63016616034510d3179f3c569de810ad..41456fc8c4aee798ba934f5e7271479d26fb257c 100644 --- a/client/cli/src/lib.rs +++ b/client/cli/src/lib.rs @@ -26,24 +26,24 @@ mod execution_strategy; pub mod error; pub mod informant; -use client_api::execution_extensions::ExecutionStrategies; -use service::{ +use sc_client_api::execution_extensions::ExecutionStrategies; +use sc_service::{ config::{Configuration, DatabaseConfig}, - ServiceBuilderExport, ServiceBuilderImport, ServiceBuilderRevert, + ServiceBuilderCommand, RuntimeGenesis, ChainSpecExtension, PruningMode, ChainSpec, }; -use network::{ +use sc_network::{ self, multiaddr::Protocol, config::{ NetworkConfiguration, TransportConfig, NonReservedPeerMode, NodeKeyConfig, build_multiaddr }, }; -use primitives::H256; +use sp_core::H256; use std::{ - io::{Write, Read, Seek, Cursor, stdin, stdout, ErrorKind}, iter, fs::{self, File}, - net::{Ipv4Addr, SocketAddr}, path::{Path, PathBuf}, str::FromStr, + io::{Write, Read, Seek, Cursor, stdin, stdout, ErrorKind}, iter, fmt::Debug, fs::{self, File}, + net::{Ipv4Addr, SocketAddr}, path::{Path, PathBuf}, str::FromStr, pin::Pin, task::Poll }; use names::{Generator, Name}; @@ -54,16 +54,17 @@ pub use structopt::clap::App; use params::{ RunCmd, PurgeChainCmd, RevertCmd, ImportBlocksCmd, ExportBlocksCmd, BuildSpecCmd, NetworkConfigurationParams, MergeParameters, TransactionPoolParams, - NodeKeyParams, NodeKeyType, Cors, + NodeKeyParams, NodeKeyType, Cors, CheckBlockCmd, }; -pub use params::{NoCustom, CoreParams, SharedParams, ExecutionStrategy as ExecutionStrategyParam}; +pub use params::{NoCustom, CoreParams, SharedParams, ImportParams, ExecutionStrategy}; pub use traits::{GetLogFilter, AugmentClap}; use app_dirs::{AppInfo, AppDataType}; use log::info; use lazy_static::lazy_static; -use futures::{Future, FutureExt, TryFutureExt}; -use futures01::{Async, Future as _}; -use substrate_telemetry::TelemetryEndpoints; +use futures::{Future, compat::Future01CompatExt, executor::block_on}; +use sc_telemetry::TelemetryEndpoints; +use sp_runtime::generic::BlockId; +use sp_runtime::traits::{Block as BlockT, Header as HeaderT}; /// default sub directory to store network config const DEFAULT_NETWORK_CONFIG_PATH : &'static str = "network"; @@ -199,12 +200,12 @@ where I: IntoIterator, ::Item: Into + Clone, { - let full_version = service::config::full_version_from_strs( + let full_version = sc_service::config::full_version_from_strs( version.version, version.commit ); - panic_handler::set(version.support_url, &full_version); + sp_panic_handler::set(version.support_url, &full_version); let matches = CoreParams::::clap() .name(version.executable_name) .author(version.author) @@ -231,6 +232,9 @@ where params::CoreParams::ImportBlocks(params) => ParseAndPrepare::ImportBlocks( ParseAndPrepareImport { params, version } ), + params::CoreParams::CheckBlock(params) => ParseAndPrepare::CheckBlock( + CheckBlock { params, version } + ), params::CoreParams::PurgeChain(params) => ParseAndPrepare::PurgeChain( ParseAndPreparePurge { params, version } ), @@ -263,6 +267,8 @@ pub enum ParseAndPrepare<'a, CC, RP> { ExportBlocks(ParseAndPrepareExport<'a>), /// Command ready to import the chain. ImportBlocks(ParseAndPrepareImport<'a>), + /// Command to check a block. + CheckBlock(CheckBlock<'a>), /// Command ready to purge the chain. PurgeChain(ParseAndPreparePurge<'a>), /// Command ready to revert the chain. @@ -327,7 +333,7 @@ impl<'a> ParseAndPrepareBuildSpec<'a> { if spec.boot_nodes().is_empty() && !self.params.disable_default_bootnode { let base_path = base_path(&self.params.shared_params, self.version); - let cfg = service::Configuration::::default_with_spec_and_base_path(spec.clone(), Some(base_path)); + let cfg = sc_service::Configuration::::default_with_spec_and_base_path(spec.clone(), Some(base_path)); let node_key = node_key_config( self.params.node_key_params, &Some(cfg.in_chain_config_dir(DEFAULT_NETWORK_CONFIG_PATH).expect("We provided a base_path")) @@ -342,7 +348,7 @@ impl<'a> ParseAndPrepareBuildSpec<'a> { spec.add_boot_node(addr) } - let json = service::chain_ops::build_spec(spec, raw_output)?; + let json = sc_service::chain_ops::build_spec(spec, raw_output)?; print!("{}", json); @@ -366,7 +372,9 @@ impl<'a> ParseAndPrepareExport<'a> { ) -> error::Result<()> where S: FnOnce(&str) -> Result>, String>, F: FnOnce(Configuration) -> Result, - B: ServiceBuilderExport, + B: ServiceBuilderCommand, + <<<::Block as BlockT>::Header as HeaderT> + ::Number as FromStr>::Err: Debug, C: Default, G: RuntimeGenesis, E: ChainSpecExtension, @@ -377,8 +385,9 @@ impl<'a> ParseAndPrepareExport<'a> { if let DatabaseConfig::Path { ref path, .. } = &config.database { info!("DB path: {}", path.display()); } - let from = self.params.from.unwrap_or(1); - let to = self.params.to; + let from = self.params.from.and_then(|f| f.parse().ok()).unwrap_or(1); + let to = self.params.to.and_then(|t| t.parse().ok()); + let json = self.params.json; let file: Box = match self.params.output { @@ -389,23 +398,23 @@ impl<'a> ParseAndPrepareExport<'a> { // Note: while we would like the user to handle the exit themselves, we handle it here // for backwards compatibility reasons. let (exit_send, exit_recv) = std::sync::mpsc::channel(); - let exit = exit.into_exit() - .map(|_| Ok::<_, ()>(())) - .compat(); + let exit = exit.into_exit(); std::thread::spawn(move || { - let _ = exit.wait(); + block_on(exit); let _ = exit_send.send(()); }); - let mut export_fut = builder(config)?.export_blocks(file, from.into(), to.map(Into::into), json); - let fut = futures01::future::poll_fn(|| { + let mut export_fut = builder(config)? + .export_blocks(file, from.into(), to, json) + .compat(); + let fut = futures::future::poll_fn(|cx| { if exit_recv.try_recv().is_ok() { - return Ok(Async::Ready(())); + return Poll::Ready(Ok(())); } - export_fut.poll() + Pin::new(&mut export_fut).poll(cx) }); - let mut runtime = tokio::runtime::current_thread::Runtime::new().unwrap(); + let mut runtime = tokio::runtime::Runtime::new().unwrap(); runtime.block_on(fut)?; Ok(()) } @@ -427,19 +436,14 @@ impl<'a> ParseAndPrepareImport<'a> { ) -> error::Result<()> where S: FnOnce(&str) -> Result>, String>, F: FnOnce(Configuration) -> Result, - B: ServiceBuilderImport, + B: ServiceBuilderCommand, C: Default, G: RuntimeGenesis, E: ChainSpecExtension, Exit: IntoExit { let mut config = create_config_with_db_path(spec_factory, &self.params.shared_params, self.version)?; - config.wasm_method = self.params.wasm_method.into(); - config.execution_strategies = ExecutionStrategies { - importing: self.params.execution.into(), - other: self.params.execution.into(), - ..Default::default() - }; + fill_import_params(&mut config, &self.params.import_params, sc_service::Roles::FULL)?; let file: Box = match self.params.input { Some(filename) => Box::new(File::open(filename)?), @@ -453,28 +457,74 @@ impl<'a> ParseAndPrepareImport<'a> { // Note: while we would like the user to handle the exit themselves, we handle it here // for backwards compatibility reasons. let (exit_send, exit_recv) = std::sync::mpsc::channel(); - let exit = exit.into_exit() - .map(|_| Ok::<_, ()>(())) - .compat(); + let exit = exit.into_exit(); std::thread::spawn(move || { - let _ = exit.wait(); + block_on(exit); let _ = exit_send.send(()); }); - let mut import_fut = builder(config)?.import_blocks(file); - let fut = futures01::future::poll_fn(|| { + let mut import_fut = builder(config)? + .import_blocks(file, false) + .compat(); + let fut = futures::future::poll_fn(|cx| { if exit_recv.try_recv().is_ok() { - return Ok(Async::Ready(())); + return Poll::Ready(Ok(())); } - import_fut.poll() + Pin::new(&mut import_fut).poll(cx) }); - let mut runtime = tokio::runtime::current_thread::Runtime::new().unwrap(); + let mut runtime = tokio::runtime::Runtime::new().unwrap(); runtime.block_on(fut)?; Ok(()) } } +/// Command to check a block. +pub struct CheckBlock<'a> { + params: CheckBlockCmd, + version: &'a VersionInfo, +} + +impl<'a> CheckBlock<'a> { + /// Runs the command and imports to the chain. + pub fn run_with_builder( + self, + builder: F, + spec_factory: S, + _exit: Exit, + ) -> error::Result<()> + where S: FnOnce(&str) -> Result>, String>, + F: FnOnce(Configuration) -> Result, + B: ServiceBuilderCommand, + <::Block as BlockT>::Hash: FromStr, + C: Default, + G: RuntimeGenesis, + E: ChainSpecExtension, + Exit: IntoExit + { + let mut config = create_config_with_db_path(spec_factory, &self.params.shared_params, self.version)?; + fill_import_params(&mut config, &self.params.import_params, sc_service::Roles::FULL)?; + + let input = if self.params.input.starts_with("0x") { &self.params.input[2..] } else { &self.params.input[..] }; + let block_id = match FromStr::from_str(input) { + Ok(hash) => BlockId::hash(hash), + Err(_) => match self.params.input.parse::() { + Ok(n) => BlockId::number((n as u32).into()), + Err(_) => return Err(error::Error::Input("Invalid hash or number specified".into())), + } + }; + + let start = std::time::Instant::now(); + let check = builder(config)? + .check_block(block_id) + .compat(); + let mut runtime = tokio::runtime::Runtime::new().unwrap(); + runtime.block_on(check)?; + println!("Completed in {} ms.", start.elapsed().as_millis()); + Ok(()) + } +} + /// Command ready to purge the chain. pub struct ParseAndPreparePurge<'a> { params: PurgeChainCmd, @@ -548,7 +598,9 @@ impl<'a> ParseAndPrepareRevert<'a> { ) -> error::Result<()> where S: FnOnce(&str) -> Result>, String>, F: FnOnce(Configuration) -> Result, - B: ServiceBuilderRevert, + B: ServiceBuilderCommand, + <<<::Block as BlockT>::Header as HeaderT> + ::Number as FromStr>::Err: Debug, C: Default, G: RuntimeGenesis, E: ChainSpecExtension, @@ -556,8 +608,8 @@ impl<'a> ParseAndPrepareRevert<'a> { let config = create_config_with_db_path( spec_factory, &self.params.shared_params, self.version )?; - let blocks = self.params.num; - builder(config)?.revert_chain(blocks.into())?; + let blocks = self.params.num.parse()?; + builder(config)?.revert_chain(blocks)?; Ok(()) } } @@ -574,8 +626,8 @@ where params.node_key.as_ref().map(parse_ed25519_secret).unwrap_or_else(|| Ok(params.node_key_file .or_else(|| net_config_file(net_config_dir, NODE_KEY_ED25519_FILE)) - .map(network::config::Secret::File) - .unwrap_or(network::config::Secret::New))) + .map(sc_network::config::Secret::File) + .unwrap_or(sc_network::config::Secret::New))) .map(NodeKeyConfig::Ed25519) } } @@ -592,11 +644,11 @@ fn invalid_node_key(e: impl std::fmt::Display) -> error::Error { error::Error::Input(format!("Invalid node key: {}", e)) } -/// Parse a Ed25519 secret key from a hex string into a `network::Secret`. -fn parse_ed25519_secret(hex: &String) -> error::Result { +/// Parse a Ed25519 secret key from a hex string into a `sc_network::Secret`. +fn parse_ed25519_secret(hex: &String) -> error::Result { H256::from_str(&hex).map_err(invalid_node_key).and_then(|bytes| - network::config::identity::ed25519::SecretKey::from_bytes(bytes) - .map(network::config::Secret::Input) + sc_network::config::identity::ed25519::SecretKey::from_bytes(bytes) + .map(sc_network::config::Secret::Input) .map_err(invalid_node_key)) } @@ -628,12 +680,14 @@ fn fill_network_configuration( config.boot_nodes.extend(cli.bootnodes.into_iter()); config.config_path = Some(config_path.to_string_lossy().into()); config.net_config_path = config.config_path.clone(); - config.reserved_nodes.extend(cli.reserved_nodes.into_iter()); + config.reserved_nodes.extend(cli.reserved_nodes.into_iter()); if cli.reserved_only { config.non_reserved_mode = NonReservedPeerMode::Deny; } + config.sentry_nodes.extend(cli.sentry_nodes.into_iter()); + for addr in cli.listen_addr.iter() { let addr = addr.parse().ok().ok_or(error::Error::InvalidListenMultiaddress)?; config.listen_addresses.push(addr); @@ -671,6 +725,7 @@ fn fill_network_configuration( Ok(()) } +#[cfg(not(target_os = "unknown"))] fn input_keystore_password() -> Result { rpassword::read_password_from_tty(Some("Keystore password: ")) .map_err(|e| format!("{:?}", e)) @@ -678,11 +733,16 @@ fn input_keystore_password() -> Result { /// Fill the password field of the given config instance. fn fill_config_keystore_password( - config: &mut service::Configuration, + config: &mut sc_service::Configuration, cli: &RunCmd, ) -> Result<(), String> { config.keystore_password = if cli.password_interactive { - Some(input_keystore_password()?.into()) + #[cfg(not(target_os = "unknown"))] + { + Some(input_keystore_password()?.into()) + } + #[cfg(target_os = "unknown")] + None } else if let Some(ref file) = cli.password_filename { Some(fs::read_to_string(file).map_err(|e| format!("{}", e))?.into()) } else if let Some(ref password) = cli.password { @@ -694,6 +754,61 @@ fn fill_config_keystore_password( Ok(()) } +/// Put block import CLI params into `config` object. +pub fn fill_import_params( + config: &mut Configuration, + cli: &ImportParams, + role: sc_service::Roles, +) -> error::Result<()> + where + C: Default, + G: RuntimeGenesis, + E: ChainSpecExtension, +{ + match config.database { + DatabaseConfig::Path { ref mut cache_size, .. } => + *cache_size = Some(cli.database_cache_size), + DatabaseConfig::Custom(_) => {}, + } + + config.state_cache_size = cli.state_cache_size; + + // by default we disable pruning if the node is an authority (i.e. + // `ArchiveAll`), otherwise we keep state for the last 256 blocks. if the + // node is an authority and pruning is enabled explicitly, then we error + // unless `unsafe_pruning` is set. + config.pruning = match &cli.pruning { + Some(ref s) if s == "archive" => PruningMode::ArchiveAll, + None if role == sc_service::Roles::AUTHORITY => PruningMode::ArchiveAll, + None => PruningMode::default(), + Some(s) => { + if role == sc_service::Roles::AUTHORITY && !cli.unsafe_pruning { + return Err(error::Error::Input( + "Validators should run with state pruning disabled (i.e. archive). \ + You can ignore this check with `--unsafe-pruning`.".to_string() + )); + } + + PruningMode::keep_blocks(s.parse() + .map_err(|_| error::Error::Input("Invalid pruning mode specified".to_string()))? + ) + }, + }; + + config.wasm_method = cli.wasm_method.into(); + + let exec = &cli.execution_strategies; + let exec_all_or = |strat: ExecutionStrategy| exec.execution.unwrap_or(strat).into(); + config.execution_strategies = ExecutionStrategies { + syncing: exec_all_or(exec.execution_syncing), + importing: exec_all_or(exec.execution_import_block), + block_construction: exec_all_or(exec.execution_block_construction), + offchain_worker: exec_all_or(exec.execution_offchain_worker), + other: exec_all_or(exec.execution_other), + }; + Ok(()) +} + fn create_run_node_config( cli: RunCmd, spec_factory: S, impl_name: &'static str, version: &VersionInfo, ) -> error::Result> @@ -703,12 +818,23 @@ where E: ChainSpecExtension, S: FnOnce(&str) -> Result>, String>, { - let spec = load_spec(&cli.shared_params, spec_factory)?; - let base_path = base_path(&cli.shared_params, &version); - let mut config = service::Configuration::default_with_spec_and_base_path(spec.clone(), Some(base_path)); + let mut config = create_config_with_db_path(spec_factory, &cli.shared_params, &version)?; fill_config_keystore_password(&mut config, &cli)?; + let is_dev = cli.shared_params.dev; + let is_authority = cli.validator || cli.sentry || is_dev || cli.keyring.account.is_some(); + let role = + if cli.light { + sc_service::Roles::LIGHT + } else if is_authority { + sc_service::Roles::AUTHORITY + } else { + sc_service::Roles::FULL + }; + + fill_import_params(&mut config, &cli.import_params, role)?; + config.impl_name = impl_name; config.impl_commit = version.commit; config.impl_version = version.version; @@ -731,63 +857,11 @@ where config.keystore_path = cli.keystore_path.or_else(|| config.in_chain_config_dir(DEFAULT_KEYSTORE_CONFIG_PATH)); - config.database = DatabaseConfig::Path { - path: config.in_chain_config_dir(DEFAULT_DB_CONFIG_PATH).expect("We provided a base_path."), - cache_size: cli.database_cache_size, - }; - config.state_cache_size = cli.state_cache_size; - - let is_dev = cli.shared_params.dev; - let is_authority = cli.validator || cli.sentry || is_dev || cli.keyring.account.is_some(); - - let role = - if cli.light { - service::Roles::LIGHT - } else if is_authority { - service::Roles::AUTHORITY - } else { - service::Roles::FULL - }; - // set sentry mode (i.e. act as an authority but **never** actively participate) config.sentry_mode = cli.sentry; - // by default we disable pruning if the node is an authority (i.e. - // `ArchiveAll`), otherwise we keep state for the last 256 blocks. if the - // node is an authority and pruning is enabled explicitly, then we error - // unless `unsafe_pruning` is set. - config.pruning = match cli.pruning { - Some(ref s) if s == "archive" => PruningMode::ArchiveAll, - None if role == service::Roles::AUTHORITY => PruningMode::ArchiveAll, - None => PruningMode::default(), - Some(s) => { - if role == service::Roles::AUTHORITY && !cli.unsafe_pruning { - return Err(error::Error::Input( - "Validators should run with state pruning disabled (i.e. archive). \ - You can ignore this check with `--unsafe-pruning`.".to_string() - )); - } - - PruningMode::keep_blocks(s.parse() - .map_err(|_| error::Error::Input("Invalid pruning mode specified".to_string()))? - ) - }, - }; - - config.wasm_method = cli.wasm_method.into(); - - let exec = cli.execution_strategies; - let exec_all_or = |strat: params::ExecutionStrategy| exec.execution.unwrap_or(strat).into(); - config.execution_strategies = ExecutionStrategies { - syncing: exec_all_or(exec.execution_syncing), - importing: exec_all_or(exec.execution_import_block), - block_construction: exec_all_or(exec.execution_block_construction), - offchain_worker: exec_all_or(exec.execution_offchain_worker), - other: exec_all_or(exec.execution_other), - }; - config.offchain_worker = match (cli.offchain_worker, role) { - (params::OffchainWorkerEnabled::WhenValidating, service::Roles::AUTHORITY) => true, + (params::OffchainWorkerEnabled::WhenValidating, sc_service::Roles::AUTHORITY) => true, (params::OffchainWorkerEnabled::Always, _) => true, (params::OffchainWorkerEnabled::Never, _) => false, (params::OffchainWorkerEnabled::WhenValidating, _) => false, @@ -816,8 +890,8 @@ where } }); - let rpc_interface: &str = if cli.rpc_external { "0.0.0.0" } else { "127.0.0.1" }; - let ws_interface: &str = if cli.ws_external { "0.0.0.0" } else { "127.0.0.1" }; + let rpc_interface: &str = interface_str(cli.rpc_external, cli.unsafe_rpc_external, cli.validator)?; + let ws_interface: &str = interface_str(cli.ws_external, cli.unsafe_ws_external, cli.validator)?; let grafana_interface: &str = if cli.grafana_external { "0.0.0.0" } else { "127.0.0.1" }; config.rpc_http = Some(parse_address(&format!("{}:{}", rpc_interface, 9933), cli.rpc_port)?); @@ -857,6 +931,27 @@ where Ok(config) } +fn interface_str( + is_external: bool, + is_unsafe_external: bool, + is_validator: bool, +) -> Result<&'static str, error::Error> { + if is_external && is_validator { + return Err(error::Error::Input("--rpc-external and --ws-external options shouldn't be \ + used if the node is running as a validator. Use `--unsafe-rpc-external` if you understand \ + the risks. See the options description for more information.".to_owned())); + } + + if is_external || is_unsafe_external { + log::warn!("It isn't safe to expose RPC publicly without a proxy server that filters \ + available set of RPC methods."); + + Ok("0.0.0.0") + } else { + Ok("127.0.0.1") + } +} + /// Creates a configuration including the database path. pub fn create_config_with_db_path( spec_factory: S, cli: &SharedParams, version: &VersionInfo, @@ -870,7 +965,11 @@ where let spec = load_spec(cli, spec_factory)?; let base_path = base_path(cli, version); - let mut config = service::Configuration::default_with_spec_and_base_path(spec.clone(), Some(base_path)); + let mut config = sc_service::Configuration::default_with_spec_and_base_path( + spec.clone(), + Some(base_path), + ); + config.database = DatabaseConfig::Path { path: config.in_chain_config_dir(DEFAULT_DB_CONFIG_PATH).expect("We provided a base_path."), cache_size: None, @@ -906,8 +1005,8 @@ fn init_logger(pattern: &str) { builder.filter(Some("ws"), log::LevelFilter::Off); builder.filter(Some("hyper"), log::LevelFilter::Warn); builder.filter(Some("cranelift_wasm"), log::LevelFilter::Warn); - // Always log the special target `substrate_tracing`, overrides global level - builder.filter(Some("substrate_tracing"), log::LevelFilter::Info); + // Always log the special target `sc_tracing`, overrides global level + builder.filter(Some("sc_tracing"), log::LevelFilter::Info); // Enable info for others. builder.filter(None, log::LevelFilter::Info); @@ -943,14 +1042,15 @@ fn init_logger(pattern: &str) { ) }; - if !enable_color { - output = kill_color(output.as_ref()); - } - if !isatty && record.level() <= log::Level::Info && atty::is(atty::Stream::Stdout) { // duplicate INFO/WARN output to console println!("{}", output); } + + if !enable_color { + output = kill_color(output.as_ref()); + } + writeln!(buf, "{}", output) }); @@ -969,8 +1069,7 @@ fn kill_color(s: &str) -> String { #[cfg(test)] mod tests { use super::*; - use tempdir::TempDir; - use network::config::identity::ed25519; + use sc_network::config::identity::ed25519; #[test] fn tests_node_name_good() { @@ -1001,7 +1100,7 @@ mod tests { node_key_file: None }; node_key_config(params, &net_config_dir).and_then(|c| match c { - NodeKeyConfig::Ed25519(network::config::Secret::Input(ref ski)) + NodeKeyConfig::Ed25519(sc_network::config::Secret::Input(ref ski)) if node_key_type == NodeKeyType::Ed25519 && &sk[..] == ski.as_ref() => Ok(()), _ => Err(error::Error::Input("Unexpected node key config".into())) @@ -1018,7 +1117,7 @@ mod tests { fn secret_file(net_config_dir: Option) -> error::Result<()> { NodeKeyType::variants().into_iter().try_for_each(|t| { let node_key_type = NodeKeyType::from_str(t).unwrap(); - let tmp = TempDir::new("alice")?; + let tmp = tempfile::Builder::new().prefix("alice").tempdir()?; let file = tmp.path().join(format!("{}_mysecret", t)).to_path_buf(); let params = NodeKeyParams { node_key_type, @@ -1026,7 +1125,7 @@ mod tests { node_key_file: Some(file.clone()) }; node_key_config(params, &net_config_dir).and_then(|c| match c { - NodeKeyConfig::Ed25519(network::config::Secret::File(ref f)) + NodeKeyConfig::Ed25519(sc_network::config::Secret::File(ref f)) if node_key_type == NodeKeyType::Ed25519 && f == &file => Ok(()), _ => Err(error::Error::Input("Unexpected node key config".into())) }) @@ -1058,7 +1157,7 @@ mod tests { let typ = params.node_key_type; node_key_config::(params, &None) .and_then(|c| match c { - NodeKeyConfig::Ed25519(network::config::Secret::New) + NodeKeyConfig::Ed25519(sc_network::config::Secret::New) if typ == NodeKeyType::Ed25519 => Ok(()), _ => Err(error::Error::Input("Unexpected node key config".into())) }) @@ -1071,7 +1170,7 @@ mod tests { let typ = params.node_key_type; node_key_config(params, &Some(net_config_dir.clone())) .and_then(move |c| match c { - NodeKeyConfig::Ed25519(network::config::Secret::File(ref f)) + NodeKeyConfig::Ed25519(sc_network::config::Secret::File(ref f)) if typ == NodeKeyType::Ed25519 && f == &dir.join(NODE_KEY_ED25519_FILE) => Ok(()), _ => Err(error::Error::Input("Unexpected node key config".into())) diff --git a/client/cli/src/params.rs b/client/cli/src/params.rs index 15ec2fa113c054282258135bc1db537d73187090..6cb425bd74232ff8f2443dc1bbcb11f1f96f41bd 100644 --- a/client/cli/src/params.rs +++ b/client/cli/src/params.rs @@ -16,7 +16,7 @@ use crate::traits::{AugmentClap, GetLogFilter}; -use std::path::PathBuf; +use std::{str::FromStr, path::PathBuf}; use structopt::{StructOpt, clap::{arg_enum, App, AppSettings, SubCommand, Arg}}; pub use crate::execution_strategy::ExecutionStrategy; @@ -32,13 +32,13 @@ macro_rules! impl_get_log_filter { } } -impl Into for ExecutionStrategy { - fn into(self) -> client_api::ExecutionStrategy { +impl Into for ExecutionStrategy { + fn into(self) -> sc_client_api::ExecutionStrategy { match self { - ExecutionStrategy::Native => client_api::ExecutionStrategy::NativeWhenPossible, - ExecutionStrategy::Wasm => client_api::ExecutionStrategy::AlwaysWasm, - ExecutionStrategy::Both => client_api::ExecutionStrategy::Both, - ExecutionStrategy::NativeElseWasm => client_api::ExecutionStrategy::NativeElseWasm, + ExecutionStrategy::Native => sc_client_api::ExecutionStrategy::NativeWhenPossible, + ExecutionStrategy::Wasm => sc_client_api::ExecutionStrategy::AlwaysWasm, + ExecutionStrategy::Both => sc_client_api::ExecutionStrategy::Both, + ExecutionStrategy::NativeElseWasm => sc_client_api::ExecutionStrategy::NativeElseWasm, } } } @@ -46,7 +46,7 @@ impl Into for ExecutionStrategy { arg_enum! { /// How to execute Wasm runtime code #[allow(missing_docs)] - #[derive(Debug, Clone)] + #[derive(Debug, Clone, Copy)] pub enum WasmExecutionMethod { // Uses an interpreter. Interpreted, @@ -66,12 +66,12 @@ impl WasmExecutionMethod { } } -impl Into for WasmExecutionMethod { - fn into(self) -> service::config::WasmExecutionMethod { +impl Into for WasmExecutionMethod { + fn into(self) -> sc_service::config::WasmExecutionMethod { match self { - WasmExecutionMethod::Interpreted => service::config::WasmExecutionMethod::Interpreted, + WasmExecutionMethod::Interpreted => sc_service::config::WasmExecutionMethod::Interpreted, #[cfg(feature = "wasmtime")] - WasmExecutionMethod::Compiled => service::config::WasmExecutionMethod::Compiled, + WasmExecutionMethod::Compiled => sc_service::config::WasmExecutionMethod::Compiled, #[cfg(not(feature = "wasmtime"))] WasmExecutionMethod::Compiled => panic!( "Substrate must be compiled with \"wasmtime\" feature for compiled Wasm execution" @@ -111,6 +111,48 @@ pub struct SharedParams { pub log: Option, } +/// Parameters for block import. +#[derive(Debug, StructOpt, Clone)] +pub struct ImportParams { + /// Specify the state pruning mode, a number of blocks to keep or 'archive'. + /// + /// Default is to keep all block states if the node is running as a + /// validator (i.e. 'archive'), otherwise state is only kept for the last + /// 256 blocks. + #[structopt(long = "pruning", value_name = "PRUNING_MODE")] + pub pruning: Option, + + /// Force start with unsafe pruning settings. + /// + /// When running as a validator it is highly recommended to disable state + /// pruning (i.e. 'archive') which is the default. The node will refuse to + /// start as a validator if pruning is enabled unless this option is set. + #[structopt(long = "unsafe-pruning")] + pub unsafe_pruning: bool, + + /// Method for executing Wasm runtime code. + #[structopt( + long = "wasm-execution", + value_name = "METHOD", + possible_values = &WasmExecutionMethod::enabled_variants(), + case_insensitive = true, + default_value = "Interpreted" + )] + pub wasm_method: WasmExecutionMethod, + + #[allow(missing_docs)] + #[structopt(flatten)] + pub execution_strategies: ExecutionStrategies, + + /// Limit the memory the database cache can use. + #[structopt(long = "db-cache", value_name = "MiB", default_value = "1024")] + pub database_cache_size: u32, + + /// Specify the state cache size. + #[structopt(long = "state-cache-size", value_name = "Bytes", default_value = "67108864")] + pub state_cache_size: usize, +} + impl GetLogFilter for SharedParams { fn get_log_filter(&self) -> Option { self.log.clone() @@ -135,6 +177,14 @@ pub struct NetworkConfigurationParams { #[structopt(long = "reserved-only")] pub reserved_only: bool, + /// Specify a list of sentry node public addresses. + #[structopt( + long = "sentry-nodes", + value_name = "URL", + conflicts_with_all = &[ "sentry" ] + )] + pub sentry_nodes: Vec, + /// Listen on this multiaddress. #[structopt(long = "listen-addr", value_name = "LISTEN_ADDR")] pub listen_addr: Vec, @@ -265,14 +315,16 @@ arg_enum! { pub enum TracingReceiver { Log, Telemetry, + Grafana, } } -impl Into for TracingReceiver { - fn into(self) -> substrate_tracing::TracingReceiver { +impl Into for TracingReceiver { + fn into(self) -> sc_tracing::TracingReceiver { match self { - TracingReceiver::Log => substrate_tracing::TracingReceiver::Log, - TracingReceiver::Telemetry => substrate_tracing::TracingReceiver::Telemetry, + TracingReceiver::Log => sc_tracing::TracingReceiver::Log, + TracingReceiver::Telemetry => sc_tracing::TracingReceiver::Telemetry, + TracingReceiver::Grafana => sc_tracing::TracingReceiver::Grafana, } } } @@ -384,26 +436,34 @@ pub struct RunCmd { #[structopt(long = "light")] pub light: bool, - /// Limit the memory the database cache can use. - #[structopt(long = "db-cache", value_name = "MiB")] - pub database_cache_size: Option, - - /// Specify the state cache size. - #[structopt(long = "state-cache-size", value_name = "Bytes", default_value = "67108864")] - pub state_cache_size: usize, - /// Listen to all RPC interfaces. /// - /// Default is local. + /// Default is local. Note: not all RPC methods are safe to be exposed publicly. Use a RPC proxy + /// server to filter out dangerous methods. More details: https://github.com/paritytech/substrate/wiki/Public-RPC. + /// Use `--unsafe-rpc-external` to suppress the warning if you understand the risks. #[structopt(long = "rpc-external")] pub rpc_external: bool, + /// Listen to all RPC interfaces. + /// + /// Same as `--rpc-external`. + #[structopt(long = "unsafe-rpc-external")] + pub unsafe_rpc_external: bool, + /// Listen to all Websocket interfaces. /// - /// Default is local. + /// Default is local. Note: not all RPC methods are safe to be exposed publicly. Use a RPC proxy + /// server to filter out dangerous methods. More details: https://github.com/paritytech/substrate/wiki/Public-RPC. + /// Use `--unsafe-ws-external` to suppress the warning if you understand the risks. #[structopt(long = "ws-external")] pub ws_external: bool, + /// Listen to all Websocket interfaces. + /// + /// Same as `--ws-external`. + #[structopt(long = "unsafe-ws-external")] + pub unsafe_ws_external: bool, + /// Listen to all Grafana data source interfaces. /// /// Default is local. @@ -436,22 +496,6 @@ pub struct RunCmd { #[structopt(long = "grafana-port", value_name = "PORT")] pub grafana_port: Option, - /// Specify the state pruning mode, a number of blocks to keep or 'archive'. - /// - /// Default is to keep all block states if the node is running as a - /// validator (i.e. 'archive'), otherwise state is only kept for the last - /// 256 blocks. - #[structopt(long = "pruning", value_name = "PRUNING_MODE")] - pub pruning: Option, - - /// Force start with unsafe pruning settings. - /// - /// When running as a validator it is highly recommended to disable state - /// pruning (i.e. 'archive') which is the default. The node will refuse to - /// start as a validator if pruning is enabled unless this option is set. - #[structopt(long = "unsafe-pruning")] - pub unsafe_pruning: bool, - /// The human-readable name for this node. /// /// The node name will be reported to the telemetry server, if enabled. @@ -485,23 +529,13 @@ pub struct RunCmd { )] pub offchain_worker: OffchainWorkerEnabled, - /// Method for executing Wasm runtime code. - #[structopt( - long = "wasm-execution", - value_name = "METHOD", - possible_values = &WasmExecutionMethod::enabled_variants(), - case_insensitive = true, - default_value = "Interpreted" - )] - pub wasm_method: WasmExecutionMethod, - #[allow(missing_docs)] #[structopt(flatten)] - pub execution_strategies: ExecutionStrategies, + pub shared_params: SharedParams, #[allow(missing_docs)] #[structopt(flatten)] - pub shared_params: SharedParams, + pub import_params: ImportParams, #[allow(missing_docs)] #[structopt(flatten)] @@ -566,19 +600,19 @@ struct KeyringTestAccountCliValues { help: String, conflicts_with: Vec, name: String, - variant: keyring::Sr25519Keyring, + variant: sp_keyring::Sr25519Keyring, } lazy_static::lazy_static! { /// The Cli values for all test accounts. static ref TEST_ACCOUNTS_CLI_VALUES: Vec = { - keyring::Sr25519Keyring::iter().map(|a| { + sp_keyring::Sr25519Keyring::iter().map(|a| { let help = format!( "Shortcut for `--name {} --validator` with session keys for `{}` added to keystore.", a, a, ); - let conflicts_with = keyring::Sr25519Keyring::iter() + let conflicts_with = sp_keyring::Sr25519Keyring::iter() .filter(|b| a != *b) .map(|b| b.to_string().to_lowercase()) .chain(std::iter::once("name".to_string())) @@ -598,7 +632,7 @@ lazy_static::lazy_static! { /// Wrapper for exposing the keyring test accounts into the Cli. #[derive(Debug, Clone)] pub struct Keyring { - pub account: Option, + pub account: Option, } impl StructOpt for Keyring { @@ -716,6 +750,41 @@ pub struct BuildSpecCmd { impl_get_log_filter!(BuildSpecCmd); +/// Wrapper type of `String` which holds an arbitary sized unsigned integer formatted as decimal. +#[derive(Debug, Clone)] +pub struct BlockNumber(String); + +impl FromStr for BlockNumber { + type Err = String; + + fn from_str(block_number: &str) -> Result { + if block_number.chars().any(|d| !d.is_digit(10)) { + Err(format!( + "Invalid block number: {}, expected decimal formatted unsigned integer", + block_number + )) + } else { + Ok(Self(block_number.to_owned())) + } + } +} + +impl BlockNumber { + /// Wrapper on top of `std::str::parse` but with `Error` as a `String` + /// + /// See `https://doc.rust-lang.org/std/primitive.str.html#method.parse` for more elaborate + /// documentation. + pub fn parse(&self) -> Result + where + N: FromStr, + N::Err: std::fmt::Debug, + { + self.0 + .parse() + .map_err(|e| format!("BlockNumber: {} parsing failed because of {:?}", self.0, e)) + } +} + /// The `export-blocks` command used to export blocks. #[derive(Debug, StructOpt, Clone)] pub struct ExportBlocksCmd { @@ -727,13 +796,13 @@ pub struct ExportBlocksCmd { /// /// Default is 1. #[structopt(long = "from", value_name = "BLOCK")] - pub from: Option, + pub from: Option, /// Specify last block number. /// /// Default is best block. #[structopt(long = "to", value_name = "BLOCK")] - pub to: Option, + pub to: Option, /// Use JSON output rather than binary. #[structopt(long = "json")] @@ -763,35 +832,43 @@ pub struct ImportBlocksCmd { #[structopt(flatten)] pub shared_params: SharedParams, - /// Method for executing Wasm runtime code. - #[structopt( - long = "wasm-execution", - value_name = "METHOD", - possible_values = &WasmExecutionMethod::variants(), - case_insensitive = true, - default_value = "Interpreted" - )] - pub wasm_method: WasmExecutionMethod, - - /// The means of execution used when calling into the runtime while importing blocks. - #[structopt( - long = "execution", - value_name = "STRATEGY", - possible_values = &ExecutionStrategy::variants(), - case_insensitive = true, - default_value = "NativeElseWasm" - )] - pub execution: ExecutionStrategy, + #[allow(missing_docs)] + #[structopt(flatten)] + pub import_params: ImportParams, } impl_get_log_filter!(ImportBlocksCmd); +/// The `check-block` command used to validate blocks. +#[derive(Debug, StructOpt, Clone)] +pub struct CheckBlockCmd { + /// Block hash or number + #[structopt(value_name = "HASH or NUMBER")] + pub input: String, + + /// The default number of 64KB pages to ever allocate for Wasm execution. + /// + /// Don't alter this unless you know what you're doing. + #[structopt(long = "default-heap-pages", value_name = "COUNT")] + pub default_heap_pages: Option, + + #[allow(missing_docs)] + #[structopt(flatten)] + pub shared_params: SharedParams, + + #[allow(missing_docs)] + #[structopt(flatten)] + pub import_params: ImportParams, +} + +impl_get_log_filter!(CheckBlockCmd); + /// The `revert` command used revert the chain to a previous state. #[derive(Debug, StructOpt, Clone)] pub struct RevertCmd { /// Number of blocks to revert. #[structopt(default_value = "256")] - pub num: u32, + pub num: BlockNumber, #[allow(missing_docs)] #[structopt(flatten)] @@ -833,6 +910,9 @@ pub enum CoreParams { /// Import blocks from file. ImportBlocks(ImportBlocksCmd), + /// Validte a single block. + CheckBlock(CheckBlockCmd), + /// Revert chain to the previous state. Revert(RevertCmd), @@ -866,6 +946,10 @@ impl StructOpt for CoreParams where ImportBlocksCmd::augment_clap(SubCommand::with_name("import-blocks")) .about("Import blocks from file.") ) + .subcommand( + CheckBlockCmd::augment_clap(SubCommand::with_name("check-block")) + .about("Re-validate a known block.") + ) .subcommand( RevertCmd::augment_clap(SubCommand::with_name("revert")) .about("Revert chain to the previous state.") @@ -884,6 +968,8 @@ impl StructOpt for CoreParams where CoreParams::ExportBlocks(ExportBlocksCmd::from_clap(matches)), ("import-blocks", Some(matches)) => CoreParams::ImportBlocks(ImportBlocksCmd::from_clap(matches)), + ("check-block", Some(matches)) => + CoreParams::CheckBlock(CheckBlockCmd::from_clap(matches)), ("revert", Some(matches)) => CoreParams::Revert(RevertCmd::from_clap(matches)), ("purge-chain", Some(matches)) => CoreParams::PurgeChain(PurgeChainCmd::from_clap(matches)), @@ -900,6 +986,7 @@ impl GetLogFilter for CoreParams where CC: GetLogFilter { CoreParams::BuildSpec(c) => c.get_log_filter(), CoreParams::ExportBlocks(c) => c.get_log_filter(), CoreParams::ImportBlocks(c) => c.get_log_filter(), + CoreParams::CheckBlock(c) => c.get_log_filter(), CoreParams::PurgeChain(c) => c.get_log_filter(), CoreParams::Revert(c) => c.get_log_filter(), CoreParams::Custom(c) => c.get_log_filter(), diff --git a/client/consensus/aura/Cargo.toml b/client/consensus/aura/Cargo.toml index 7ef9b514f0cb0af0f2c4360dc85fd62a5bfd750a..ddae989b4170f817fb509602f8c0170235c42bac 100644 --- a/client/consensus/aura/Cargo.toml +++ b/client/consensus/aura/Cargo.toml @@ -1,41 +1,43 @@ [package] -name = "substrate-consensus-aura" -version = "2.0.0" +name = "sc-consensus-aura" +version = "0.8.0" authors = ["Parity Technologies "] description = "Aura consensus algorithm for substrate" edition = "2018" [dependencies] -app-crypto = { package = "substrate-application-crypto", path = "../../../primitives/application-crypto" } -aura_primitives = { package = "substrate-consensus-aura-primitives", path = "../../../primitives/consensus/aura" } -block-builder-api = { package = "substrate-block-builder-runtime-api", path = "../../../primitives/block-builder/runtime-api" } -client = { package = "substrate-client", path = "../../" } -client-api = { package = "substrate-client-api", path = "../../api" } +sp-application-crypto = { version = "2.0.0", path = "../../../primitives/application-crypto" } +sp-consensus-aura = { version = "0.8", path = "../../../primitives/consensus/aura" } +sp-block-builder = { version = "2.0.0", path = "../../../primitives/block-builder" } +sc-client = { version = "2.0.0", path = "../../" } +sc-client-api = { version = "2.0.0", path = "../../api" } codec = { package = "parity-scale-codec", version = "1.0.0" } -consensus_common = { package = "substrate-consensus-common", path = "../../../primitives/consensus/common" } -derive_more = "0.15.0" +sp-consensus = { version = "0.8", path = "../../../primitives/consensus/common" } +derive_more = "0.99.2" futures = { version = "0.3.1", features = ["compat"] } futures01 = { package = "futures", version = "0.1" } futures-timer = "0.4.0" -inherents = { package = "substrate-inherents", path = "../../../primitives/inherents" } -keystore = { package = "substrate-keystore", path = "../../keystore" } +sp-inherents = { version = "2.0.0", path = "../../../primitives/inherents" } +sc-keystore = { version = "2.0.0", path = "../../keystore" } log = "0.4.8" parking_lot = "0.9.0" -primitives = { package = "substrate-primitives", path = "../../../primitives/core" } -runtime_io = { package = "sr-io", path = "../../../primitives/sr-io" } -runtime_version = { package = "sr-version", path = "../../../primitives/sr-version" } -slots = { package = "substrate-consensus-slots", path = "../slots" } -sr-api = { path = "../../../primitives/sr-api" } -sr-primitives = { path = "../../../primitives/sr-primitives" } -sp-timestamp = { path = "../../../primitives/timestamp" } -substrate-telemetry = { path = "../../telemetry" } +sp-core = { version = "2.0.0", path = "../../../primitives/core" } +sp-blockchain = { version = "2.0.0", path = "../../../primitives/blockchain" } +sp-io = { version = "2.0.0", path = "../../../primitives/io" } +sp-version = { version = "2.0.0", path = "../../../primitives/version" } +sc-consensus-slots = { version = "0.8", path = "../slots" } +sp-api = { version = "2.0.0", path = "../../../primitives/api" } +sp-runtime = { version = "2.0.0", path = "../../../primitives/runtime" } +sp-timestamp = { version = "2.0.0", path = "../../../primitives/timestamp" } +sc-telemetry = { version = "2.0.0", path = "../../telemetry" } [dev-dependencies] -keyring = { package = "substrate-keyring", path = "../../../primitives/keyring" } -substrate-executor = { path = "../../executor" } -network = { package = "substrate-network", path = "../../network", features = ["test-helpers"]} -service = { package = "substrate-service", path = "../../service" } -test-client = { package = "substrate-test-runtime-client", path = "../../../test/utils/runtime/client" } +sp-keyring = { version = "2.0.0", path = "../../../primitives/keyring" } +sc-executor = { version = "2.0.0", path = "../../executor" } +sc-network = { version = "0.8", path = "../../network" } +sc-network-test = { version = "2.0.0", path = "../../network/test" } +sc-service = { version = "2.0.0", path = "../../service" } +substrate-test-runtime-client = { version = "2.0.0", path = "../../../test-utils/runtime/client" } tokio = "0.1.22" env_logger = "0.7.0" tempfile = "3.1.0" diff --git a/client/consensus/aura/src/digest.rs b/client/consensus/aura/src/digest.rs index 3baa18587bc7cc9c5a7df3728bed7176c3d4a952..b1633fbfc8ac83114551d4522bbc200a5ea22aa4 100644 --- a/client/consensus/aura/src/digest.rs +++ b/client/consensus/aura/src/digest.rs @@ -19,9 +19,9 @@ //! This implements the digests for AuRa, to allow the private //! `CompatibleDigestItem` trait to appear in public interfaces. -use primitives::Pair; -use aura_primitives::AURA_ENGINE_ID; -use sr_primitives::generic::{DigestItem, OpaqueDigestItemId}; +use sp_core::Pair; +use sp_consensus_aura::AURA_ENGINE_ID; +use sp_runtime::generic::{DigestItem, OpaqueDigestItemId}; use codec::{Encode, Codec}; use std::fmt::Debug; diff --git a/client/consensus/aura/src/lib.rs b/client/consensus/aura/src/lib.rs index 7b396a95c3645417e6fcb2338dbb30df5c9c7aa6..82ea2e764c03cd5cb06170bc165bcd98ce9a8ef8 100644 --- a/client/consensus/aura/src/lib.rs +++ b/client/consensus/aura/src/lib.rs @@ -31,52 +31,55 @@ use std::{sync::Arc, time::Duration, thread, marker::PhantomData, hash::Hash, fmt::Debug, pin::Pin}; use codec::{Encode, Decode, Codec}; -use consensus_common::{self, BlockImport, Environment, Proposer, - ForkChoiceStrategy, BlockImportParams, BlockOrigin, Error as ConsensusError, - SelectChain, +use sp_consensus::{ + self, BlockImport, Environment, Proposer, CanAuthorWith, ForkChoiceStrategy, BlockImportParams, + BlockOrigin, Error as ConsensusError, SelectChain, SlotData, }; -use consensus_common::import_queue::{ +use sp_consensus::import_queue::{ Verifier, BasicQueue, BoxBlockImport, BoxJustificationImport, BoxFinalityProofImport, }; -use client_api::{ error::Result as CResult, backend::AuxStore }; -use client::{ - blockchain::ProvideCache, BlockOf, - well_known_cache_keys::{self, Id as CacheKeyId}, +use sc_client_api::backend::AuxStore; +use sc_client::{ + blockchain::ProvideCache, BlockOf +}; +use sp_blockchain::{ + Result as CResult, well_known_cache_keys::{self, Id as CacheKeyId}, }; -use block_builder_api::BlockBuilder as BlockBuilderApi; +use sp_block_builder::BlockBuilder as BlockBuilderApi; -use sr_primitives::{generic::{BlockId, OpaqueDigestItemId}, Justification}; -use sr_primitives::traits::{Block as BlockT, Header, DigestItemFor, ProvideRuntimeApi, Zero, Member}; +use sp_runtime::{generic::{BlockId, OpaqueDigestItemId}, Justification}; +use sp_runtime::traits::{Block as BlockT, Header, DigestItemFor, ProvideRuntimeApi, Zero, Member}; -use primitives::crypto::Pair; -use inherents::{InherentDataProviders, InherentData}; +use sp_core::crypto::Pair; +use sp_inherents::{InherentDataProviders, InherentData}; use futures::prelude::*; use parking_lot::Mutex; use log::{debug, info, trace}; +use sp_blockchain; use sp_timestamp::{ TimestampInherentData, InherentType as TimestampInherent, InherentError as TIError }; -use substrate_telemetry::{telemetry, CONSENSUS_TRACE, CONSENSUS_DEBUG, CONSENSUS_INFO}; +use sc_telemetry::{telemetry, CONSENSUS_TRACE, CONSENSUS_DEBUG, CONSENSUS_INFO}; -use slots::{CheckedHeader, SlotData, SlotWorker, SlotInfo, SlotCompatible}; -use slots::check_equivocation; +use sc_consensus_slots::{CheckedHeader, SlotWorker, SlotInfo, SlotCompatible}; +use sc_consensus_slots::check_equivocation; -use keystore::KeyStorePtr; +use sc_keystore::KeyStorePtr; -use sr_api::ApiExt; +use sp_api::ApiExt; -pub use aura_primitives::{ +pub use sp_consensus_aura::{ ConsensusLog, AuraApi, AURA_ENGINE_ID, inherents::{ InherentType as AuraInherent, AuraInherentData, INHERENT_IDENTIFIER, InherentDataProvider, }, }; -pub use consensus_common::SyncOracle; +pub use sp_consensus::SyncOracle; pub use digest::CompatibleDigestItem; mod digest; @@ -85,7 +88,7 @@ type AuthorityId

=

::Public; /// A slot duration. Create with `get_or_compute`. #[derive(Clone, Copy, Debug, Encode, Decode, Hash, PartialOrd, Ord, PartialEq, Eq)] -pub struct SlotDuration(slots::SlotDuration); +pub struct SlotDuration(sc_consensus_slots::SlotDuration); impl SlotDuration { /// Either fetch the slot duration from disk or compute it from the genesis @@ -95,9 +98,9 @@ impl SlotDuration { A: Codec, B: BlockT, C: AuxStore + ProvideRuntimeApi, - C::Api: AuraApi, + C::Api: AuraApi, { - slots::SlotDuration::get_or_compute(client, |a, b| a.slot_duration(b)).map(Self) + sc_consensus_slots::SlotDuration::get_or_compute(client, |a, b| a.slot_duration(b)).map(Self) } /// Get the slot duration in milliseconds. @@ -130,17 +133,17 @@ impl SlotCompatible for AuraSlotCompatible { fn extract_timestamp_and_slot( &self, data: &InherentData - ) -> Result<(TimestampInherent, AuraInherent, std::time::Duration), consensus_common::Error> { + ) -> Result<(TimestampInherent, AuraInherent, std::time::Duration), sp_consensus::Error> { data.timestamp_inherent_data() .and_then(|t| data.aura_inherent_data().map(|a| (t, a))) .map_err(Into::into) - .map_err(consensus_common::Error::InherentData) + .map_err(sp_consensus::Error::InherentData) .map(|(x, y)| (x, y, Default::default())) } } /// Start the aura worker. The returned future should be run in a futures executor. -pub fn start_aura( +pub fn start_aura( slot_duration: SlotDuration, client: Arc, select_chain: SC, @@ -150,7 +153,8 @@ pub fn start_aura( inherent_data_providers: InherentDataProviders, force_authoring: bool, keystore: KeyStorePtr, -) -> Result, consensus_common::Error> where + can_author_with: CAW, +) -> Result, sp_consensus::Error> where B: BlockT, C: ProvideRuntimeApi + BlockOf + ProvideCache + AuxStore + Send + Sync, C::Api: AuraApi>, @@ -163,8 +167,9 @@ pub fn start_aura( P::Signature: Hash + Member + Encode + Decode, H: Header, I: BlockImport + Send + Sync + 'static, - Error: ::std::error::Error + Send + From<::consensus_common::Error> + From + 'static, + Error: ::std::error::Error + Send + From<::sp_consensus::Error> + From + 'static, SO: SyncOracle + Send + Sync + Clone, + CAW: CanAuthorWith + Send, { let worker = AuraWorker { client: client.clone(), @@ -179,13 +184,14 @@ pub fn start_aura( &inherent_data_providers, slot_duration.0.slot_duration() )?; - Ok(slots::start_slot_worker::<_, _, _, _, _, AuraSlotCompatible>( + Ok(sc_consensus_slots::start_slot_worker::<_, _, _, _, _, AuraSlotCompatible, _>( slot_duration.0, select_chain, worker, sync_oracle, inherent_data_providers, AuraSlotCompatible, + can_author_with, ).map(|()| Ok::<(), ()>(())).compat()) } @@ -199,7 +205,7 @@ struct AuraWorker { _key_type: PhantomData

, } -impl slots::SimpleSlotWorker for AuraWorker where +impl sc_consensus_slots::SimpleSlotWorker for AuraWorker where B: BlockT, C: ProvideRuntimeApi + BlockOf + ProvideCache + Sync, C::Api: AuraApi>, @@ -212,7 +218,7 @@ impl slots::SimpleSlotWorker for AuraWorker + From + 'static, + Error: ::std::error::Error + Send + From<::sp_consensus::Error> + From + 'static, { type EpochData = Vec>; type Claim = P; @@ -228,7 +234,7 @@ impl slots::SimpleSlotWorker for AuraWorker Result { + fn epoch_data(&self, header: &B::Header, _slot_number: u64) -> Result { authorities(self.client.as_ref(), &BlockId::Hash(header.hash())) } @@ -246,11 +252,11 @@ impl slots::SimpleSlotWorker for AuraWorker(&p, app_crypto::key_types::AURA).ok() + .key_pair_by_type::

(&p, sp_application_crypto::key_types::AURA).ok() }) } - fn pre_digest_data(&self, slot_number: u64, _claim: &Self::Claim) -> Vec> { + fn pre_digest_data(&self, slot_number: u64, _claim: &Self::Claim) -> Vec> { vec![ as CompatibleDigestItem

>::aura_pre_digest(slot_number), ] @@ -261,7 +267,7 @@ impl slots::SimpleSlotWorker for AuraWorker, Self::Claim, - ) -> consensus_common::BlockImportParams + Send> { + ) -> sp_consensus::BlockImportParams + Send> { Box::new(|header, header_hash, body, pair| { // sign the pre-sealed hash of the block and then // add it to a digest item. @@ -278,6 +284,7 @@ impl slots::SimpleSlotWorker for AuraWorker slots::SimpleSlotWorker for AuraWorker Result { + fn proposer(&mut self, block: &B::Header) -> Result { self.env.init(block).map_err(|e| { - consensus_common::Error::ClientImport(format!("{:?}", e)).into() + sp_consensus::Error::ClientImport(format!("{:?}", e)).into() }) } + + fn proposing_remaining_duration( + &self, + head: &B::Header, + slot_info: &SlotInfo + ) -> Option { + // never give more than 20 times more lenience. + const BACKOFF_CAP: u64 = 20; + + let slot_remaining = self.slot_remaining_duration(slot_info); + let parent_slot = match find_pre_digest::(head) { + Err(_) => return Some(slot_remaining), + Ok(d) => d, + }; + + // we allow a lenience of the number of slots since the head of the + // chain was produced, minus 1 (since there is always a difference of at least 1) + // + // linear back-off. + // in normal cases we only attempt to issue blocks up to the end of the slot. + // when the chain has been stalled for a few slots, we give more lenience. + let slot_lenience = slot_info.number.saturating_sub(parent_slot + 1); + let slot_lenience = std::cmp::min(slot_lenience, BACKOFF_CAP); + let slot_lenience = Duration::from_secs(slot_lenience * slot_info.duration); + Some(slot_lenience + slot_remaining) + } } impl SlotWorker for AuraWorker where @@ -310,12 +343,12 @@ impl SlotWorker for AuraWorker + From + 'static, + Error: ::std::error::Error + Send + From<::sp_consensus::Error> + From + 'static, { - type OnSlot = Pin> + Send>>; + type OnSlot = Pin> + Send>>; fn on_slot(&mut self, chain_head: B::Header, slot_info: SlotInfo) -> Self::OnSlot { - >::on_slot(self, chain_head, slot_info) + >::on_slot(self, chain_head, slot_info) } } @@ -340,7 +373,7 @@ enum Error { BadSignature(B::Hash), #[display(fmt = "Rejecting block too far in future")] TooFarInFuture, - Client(client::error::Error), + Client(sp_blockchain::Error), DataProvider(String), Runtime(String), } @@ -350,6 +383,10 @@ fn find_pre_digest(header: &B::Header) -> Result = None; for log in header.digest().logs() { trace!(target: "aura", "Checking log {:?}", log); @@ -379,7 +416,7 @@ fn check_header( ) -> Result)>, Error> where DigestItemFor: CompatibleDigestItem

, P::Signature: Decode, - C: client_api::backend::AuxStore, + C: sc_client_api::backend::AuxStore, P::Public: Encode + Decode + PartialEq + Clone, T: Send + Sync + 'static, { @@ -434,7 +471,7 @@ fn check_header( pub struct AuraVerifier { client: Arc, phantom: PhantomData

, - inherent_data_providers: inherents::InherentDataProviders, + inherent_data_providers: sp_inherents::InherentDataProviders, transaction_pool: Option>, } @@ -448,7 +485,7 @@ impl AuraVerifier inherent_data: InherentData, timestamp_now: u64, ) -> Result<(), Error> - where C: ProvideRuntimeApi, C::Api: BlockBuilderApi + where C: ProvideRuntimeApi, C::Api: BlockBuilderApi { const MAX_TIMESTAMP_DRIFT_SECS: u64 = 60; @@ -494,8 +531,8 @@ impl AuraVerifier #[forbid(deprecated)] impl Verifier for AuraVerifier where - C: ProvideRuntimeApi + Send + Sync + client_api::backend::AuxStore + ProvideCache + BlockOf, - C::Api: BlockBuilderApi + AuraApi> + ApiExt, + C: ProvideRuntimeApi + Send + Sync + sc_client_api::backend::AuxStore + ProvideCache + BlockOf, + C::Api: BlockBuilderApi + AuraApi> + ApiExt, DigestItemFor: CompatibleDigestItem

, P: Pair + Send + Sync + 'static, P::Public: Send + Sync + Hash + Eq + Clone + Decode + Encode + Debug + 'static, @@ -587,6 +624,7 @@ impl Verifier for AuraVerifier where auxiliary: Vec::new(), fork_choice: ForkChoiceStrategy::LongestChain, allow_missing_state: false, + import_existing: false, }; Ok((block_import_params, maybe_keys)) @@ -623,7 +661,7 @@ fn initialize_authorities_cache(client: &C) -> Result<(), ConsensusErro return Ok(()); } - let map_err = |error| consensus_common::Error::from(consensus_common::Error::ClientImport( + let map_err = |error| sp_consensus::Error::from(sp_consensus::Error::ClientImport( format!( "Error initializing authorities cache: {}", error, @@ -649,7 +687,7 @@ fn authorities(client: &C, at: &BlockId) -> Result, Consensus .and_then(|(_, _, v)| Decode::decode(&mut &v[..]).ok()) ) .or_else(|| AuraApi::authorities(&*client.runtime_api(), at).ok()) - .ok_or_else(|| consensus_common::Error::InvalidAuthoritiesSet.into()) + .ok_or_else(|| sp_consensus::Error::InvalidAuthoritiesSet.into()) } /// The Aura import queue type. @@ -659,12 +697,12 @@ pub type AuraImportQueue = BasicQueue; fn register_aura_inherent_data_provider( inherent_data_providers: &InherentDataProviders, slot_duration: u64, -) -> Result<(), consensus_common::Error> { +) -> Result<(), sp_consensus::Error> { if !inherent_data_providers.has_provider(&INHERENT_IDENTIFIER) { inherent_data_providers .register_provider(InherentDataProvider::new(slot_duration)) .map_err(Into::into) - .map_err(consensus_common::Error::InherentData) + .map_err(sp_consensus::Error::InherentData) } else { Ok(()) } @@ -679,10 +717,10 @@ pub fn import_queue( client: Arc, inherent_data_providers: InherentDataProviders, transaction_pool: Option>, -) -> Result, consensus_common::Error> where +) -> Result, sp_consensus::Error> where B: BlockT, C: 'static + ProvideRuntimeApi + BlockOf + ProvideCache + Send + Sync + AuxStore, - C::Api: BlockBuilderApi + AuraApi> + ApiExt, + C::Api: BlockBuilderApi + AuraApi> + ApiExt, DigestItemFor: CompatibleDigestItem

, P: Pair + Send + Sync + 'static, P::Public: Clone + Eq + Send + Sync + Hash + Debug + Encode + Decode, @@ -709,25 +747,23 @@ pub fn import_queue( #[cfg(test)] mod tests { use super::*; - use consensus_common::NoNetwork as DummyOracle; - use network::test::*; - use network::test::{Block as TestBlock, PeersClient, PeersFullClient}; - use sr_primitives::traits::{Block as BlockT, DigestFor}; - use network::config::ProtocolConfig; + use sp_consensus::NoNetwork as DummyOracle; + use sc_network_test::{Block as TestBlock, *}; + use sp_runtime::traits::{Block as BlockT, DigestFor}; + use sc_network::config::ProtocolConfig; use parking_lot::Mutex; use tokio::runtime::current_thread; - use keyring::sr25519::Keyring; - use client::BlockchainEvents; - use test_client; - use aura_primitives::sr25519::AuthorityPair; + use sp_keyring::sr25519::Keyring; + use sc_client::BlockchainEvents; + use sp_consensus_aura::sr25519::AuthorityPair; - type Error = client::error::Error; + type Error = sp_blockchain::Error; - type TestClient = client::Client< - test_client::Backend, - test_client::Executor, + type TestClient = sc_client::Client< + substrate_test_runtime_client::Backend, + substrate_test_runtime_client::Executor, TestBlock, - test_client::runtime::RuntimeApi + substrate_test_runtime_client::runtime::RuntimeApi >; struct DummyFactory(Arc); @@ -838,7 +874,7 @@ mod tests { let client = peer.client().as_full().expect("full clients are created").clone(); let select_chain = peer.select_chain().expect("full client has a select chain"); let keystore_path = tempfile::tempdir().expect("Creates keystore path"); - let keystore = keystore::Store::open(keystore_path.path(), None).expect("Creates keystore."); + let keystore = sc_keystore::Store::open(keystore_path.path(), None).expect("Creates keystore."); keystore.write().insert_ephemeral_from_seed::(&key.to_seed()) .expect("Creates authority key"); @@ -859,7 +895,7 @@ mod tests { &inherent_data_providers, slot_duration.get() ).expect("Registers aura inherent data provider"); - let aura = start_aura::<_, _, _, _, _, AuthorityPair, _, _, _>( + let aura = start_aura::<_, _, _, _, _, AuthorityPair, _, _, _, _>( slot_duration, client.clone(), select_chain, @@ -869,6 +905,7 @@ mod tests { inherent_data_providers, false, keystore, + sp_consensus::AlwaysCanAuthor, ).expect("Starts aura"); runtime.spawn(aura); @@ -885,7 +922,7 @@ mod tests { #[test] fn authorities_call_works() { - let client = test_client::new(); + let client = substrate_test_runtime_client::new(); assert_eq!(client.info().chain.best_number, 0); assert_eq!(authorities(&client, &BlockId::Number(0)).unwrap(), vec![ diff --git a/client/consensus/babe/Cargo.toml b/client/consensus/babe/Cargo.toml index c23bd1b84c613f9afa84068732bf10f0b6e13e74..eb2875b3d37ff341ff19545a72db6ceef5ade0a2 100644 --- a/client/consensus/babe/Cargo.toml +++ b/client/consensus/babe/Cargo.toml @@ -1,34 +1,34 @@ [package] -name = "substrate-consensus-babe" -version = "2.0.0" +name = "sc-consensus-babe" +version = "0.8.0" authors = ["Parity Technologies "] description = "BABE consensus algorithm for substrate" edition = "2018" [dependencies] codec = { package = "parity-scale-codec", version = "1.0.0", features = ["derive"] } -babe_primitives = { package = "substrate-consensus-babe-primitives", path = "../../../primitives/consensus/babe" } -primitives = { package = "substrate-primitives", path = "../../../primitives/core" } -app-crypto = { package = "substrate-application-crypto", path = "../../../primitives/application-crypto" } +sp-consensus-babe = { version = "0.8", path = "../../../primitives/consensus/babe" } +sp-core = { version = "2.0.0", path = "../../../primitives/core" } +sp-application-crypto = { version = "2.0.0", path = "../../../primitives/application-crypto" } num-bigint = "0.2.3" num-rational = "0.2.2" num-traits = "0.2.8" -runtime-version = { package = "sr-version", path = "../../../primitives/sr-version" } -runtime-io = { package = "sr-io", path = "../../../primitives/sr-io" } -inherents = { package = "substrate-inherents", path = "../../../primitives/inherents" } -sp-timestamp = { path = "../../../primitives/timestamp" } -substrate-telemetry = { path = "../../telemetry" } -keystore = { package = "substrate-keystore", path = "../../keystore" } -client-api = { package = "substrate-client-api", path = "../../api" } -client = { package = "substrate-client", path = "../../" } -sr-api = { path = "../../../primitives/sr-api" } -block-builder-api = { package = "substrate-block-builder-runtime-api", path = "../../../primitives/block-builder/runtime-api" } -header-metadata = { package = "substrate-header-metadata", path = "../../header-metadata" } -consensus-common = { package = "substrate-consensus-common", path = "../../../primitives/consensus/common" } -uncles = { package = "substrate-consensus-uncles", path = "../uncles" } -slots = { package = "substrate-consensus-slots", path = "../slots" } -sr-primitives = { path = "../../../primitives/sr-primitives" } -fork-tree = { path = "../../../utils/fork-tree" } +sp-version = { version = "2.0.0", path = "../../../primitives/version" } +sp-io = { version = "2.0.0", path = "../../../primitives/io" } +sp-inherents = { version = "2.0.0", path = "../../../primitives/inherents" } +sp-timestamp = { version = "2.0.0", path = "../../../primitives/timestamp" } +sc-telemetry = { version = "2.0.0", path = "../../telemetry" } +sc-keystore = { version = "2.0.0", path = "../../keystore" } +sc-client-api = { version = "2.0.0", path = "../../api" } +sc-client = { version = "2.0.0", path = "../../" } +sp-api = { version = "2.0.0", path = "../../../primitives/api" } +sp-block-builder = { version = "2.0.0", path = "../../../primitives/block-builder" } +sp-blockchain = { version = "2.0.0", path = "../../../primitives/blockchain" } +sp-consensus = { version = "0.8", path = "../../../primitives/consensus/common" } +sc-consensus-uncles = { version = "0.8", path = "../uncles" } +sc-consensus-slots = { version = "0.8", path = "../slots" } +sp-runtime = { version = "2.0.0", path = "../../../primitives/runtime" } +fork-tree = { version = "2.0.0", path = "../../../utils/fork-tree" } futures = { version = "0.3.1", features = ["compat"] } futures01 = { package = "futures", version = "0.1" } futures-timer = "0.4.0" @@ -38,15 +38,16 @@ schnorrkel = { version = "0.8.5", features = ["preaudit_deprecated"] } rand = "0.7.2" merlin = "1.2.1" pdqselect = "0.1.0" -derive_more = "0.15.0" +derive_more = "0.99.2" [dev-dependencies] -keyring = { package = "substrate-keyring", path = "../../../primitives/keyring" } -substrate-executor = { path = "../../executor" } -network = { package = "substrate-network", path = "../../network", features = ["test-helpers"]} -service = { package = "substrate-service", path = "../../service" } -test-client = { package = "substrate-test-runtime-client", path = "../../../test/utils/runtime/client" } -block-builder = { package = "substrate-block-builder", path = "../../block-builder" } +sp-keyring = { version = "2.0.0", path = "../../../primitives/keyring" } +sc-executor = { version = "2.0.0", path = "../../executor" } +sc-network = { version = "0.8", path = "../../network" } +sc-network-test = { version = "2.0.0", path = "../../network/test" } +sc-service = { version = "2.0.0", path = "../../service" } +substrate-test-runtime-client = { version = "2.0.0", path = "../../../test-utils/runtime/client" } +sc-block-builder = { version = "2.0.0", path = "../../block-builder" } tokio = "0.1.22" env_logger = "0.7.0" tempfile = "3.1.0" diff --git a/client/consensus/babe/src/authorship.rs b/client/consensus/babe/src/authorship.rs index 93405ff7776e62c739a07212594ffac540fa1eea..52d593c7639a735f32161bf65731e1c7ca0f54da 100644 --- a/client/consensus/babe/src/authorship.rs +++ b/client/consensus/babe/src/authorship.rs @@ -17,13 +17,13 @@ //! BABE authority selection and slot claiming. use merlin::Transcript; -use babe_primitives::{AuthorityId, BabeAuthorityWeight, BABE_ENGINE_ID, BABE_VRF_PREFIX}; -use babe_primitives::{Epoch, SlotNumber, AuthorityPair, BabePreDigest, BabeConfiguration}; -use primitives::{U256, blake2_256}; +use sp_consensus_babe::{AuthorityId, BabeAuthorityWeight, BABE_ENGINE_ID, BABE_VRF_PREFIX}; +use sp_consensus_babe::{Epoch, SlotNumber, AuthorityPair, BabePreDigest, BabeConfiguration}; +use sp_core::{U256, blake2_256}; use codec::Encode; use schnorrkel::vrf::VRFInOut; -use primitives::Pair; -use keystore::KeyStorePtr; +use sp_core::Pair; +use sc_keystore::KeyStorePtr; /// Calculates the primary selection threshold for a given authority, taking /// into account `c` (`1 - c` represents the probability of a slot being empty). @@ -162,8 +162,8 @@ pub(super) fn claim_slot( } fn get_keypair(q: &AuthorityPair) -> &schnorrkel::Keypair { - use primitives::crypto::IsWrappedBy; - primitives::sr25519::Pair::from_ref(q).as_ref() + use sp_core::crypto::IsWrappedBy; + sp_core::sr25519::Pair::from_ref(q).as_ref() } /// Claim a primary slot if it is our turn. Returns `None` if it is not our turn. diff --git a/client/consensus/babe/src/aux_schema.rs b/client/consensus/babe/src/aux_schema.rs index 04e9f81e5cffef9735f6c3b3b5ee598542659bab..0e37a8b3a5983e9ef31b3b83e3518f8d41ffafa4 100644 --- a/client/consensus/babe/src/aux_schema.rs +++ b/client/consensus/babe/src/aux_schema.rs @@ -19,12 +19,10 @@ use log::info; use codec::{Decode, Encode}; -use client_api::{ - backend::AuxStore, - error::{Result as ClientResult, Error as ClientError}, -}; -use sr_primitives::traits::Block as BlockT; -use babe_primitives::BabeBlockWeight; +use sc_client_api::backend::AuxStore; +use sp_blockchain::{Result as ClientResult, Error as ClientError}; +use sp_runtime::traits::Block as BlockT; +use sp_consensus_babe::BabeBlockWeight; use super::{epoch_changes::EpochChangesFor, SharedEpochChanges}; diff --git a/client/consensus/babe/src/epoch_changes.rs b/client/consensus/babe/src/epoch_changes.rs index a5621efcd15a39ea7c9220e5e048948f2501fbc9..06b459c0f7932c7f88cd96669d845e639bcc49d0 100644 --- a/client/consensus/babe/src/epoch_changes.rs +++ b/client/consensus/babe/src/epoch_changes.rs @@ -20,18 +20,14 @@ //! persistent DAG superimposed over the forks of the blockchain. use std::sync::Arc; -use babe_primitives::{Epoch, SlotNumber, NextEpochDescriptor}; +use sp_consensus_babe::{Epoch, SlotNumber, NextEpochDescriptor}; use fork_tree::ForkTree; use parking_lot::{Mutex, MutexGuard}; -use sr_primitives::traits::{Block as BlockT, NumberFor, One, Zero}; +use sp_runtime::traits::{Block as BlockT, NumberFor, One, Zero}; use codec::{Encode, Decode}; -use client_api::{ - error::Error as ClientError, - utils::is_descendent_of, - blockchain::HeaderBackend -}; -use header_metadata::HeaderMetadata; -use primitives::H256; +use sc_client_api::utils::is_descendent_of; +use sp_blockchain::{HeaderMetadata, HeaderBackend, Error as ClientError}; +use sp_core::H256; use std::ops::Add; /// A builder for `is_descendent_of` functions. diff --git a/client/consensus/babe/src/lib.rs b/client/consensus/babe/src/lib.rs index 5d327bcedf7f6c0c41cdfa37505c8cc8237e81db..20f06332e2dab5f6b6bc1fdc68102bb4683c60b6 100644 --- a/client/consensus/babe/src/lib.rs +++ b/client/consensus/babe/src/lib.rs @@ -54,59 +54,60 @@ //! blocks) and will go with the longest one in case of a tie. //! //! An in-depth description and analysis of the protocol can be found here: -//! +//! #![forbid(unsafe_code)] #![warn(missing_docs)] -pub use babe_primitives::{ +pub use sp_consensus_babe::{ BabeApi, ConsensusLog, BABE_ENGINE_ID, BabePreDigest, SlotNumber, BabeConfiguration, CompatibleDigestItem, }; -pub use consensus_common::SyncOracle; +pub use sp_consensus::SyncOracle; use std::{collections::HashMap, sync::Arc, u64, pin::Pin, time::{Instant, Duration}}; -use babe_primitives; -use consensus_common::ImportResult; -use consensus_common::import_queue::{ +use sp_consensus_babe; +use sp_consensus::{ImportResult, CanAuthorWith}; +use sp_consensus::import_queue::{ BoxJustificationImport, BoxFinalityProofImport, }; -use sr_primitives::{generic::{BlockId, OpaqueDigestItemId}, Justification}; -use sr_primitives::traits::{ +use sp_runtime::{generic::{BlockId, OpaqueDigestItemId}, Justification}; +use sp_runtime::traits::{ Block as BlockT, Header, DigestItemFor, ProvideRuntimeApi, Zero, }; -use keystore::KeyStorePtr; +use sc_keystore::KeyStorePtr; use parking_lot::Mutex; -use primitives::{Blake2Hasher, H256, Pair}; -use inherents::{InherentDataProviders, InherentData}; -use substrate_telemetry::{telemetry, CONSENSUS_TRACE, CONSENSUS_DEBUG}; -use consensus_common::{ +use sp_core::{Blake2Hasher, H256, Pair}; +use sp_inherents::{InherentDataProviders, InherentData}; +use sc_telemetry::{telemetry, CONSENSUS_TRACE, CONSENSUS_DEBUG}; +use sp_consensus::{ self, BlockImport, Environment, Proposer, BlockCheckParams, ForkChoiceStrategy, BlockImportParams, BlockOrigin, Error as ConsensusError, + SelectChain, SlotData, }; -use babe_primitives::inherents::BabeInherentData; +use sp_consensus_babe::inherents::BabeInherentData; use sp_timestamp::{TimestampInherentData, InherentType as TimestampInherent}; -use consensus_common::SelectChain; -use consensus_common::import_queue::{Verifier, BasicQueue, CacheKeyId}; -use client_api::{ +use sp_consensus::import_queue::{Verifier, BasicQueue, CacheKeyId}; +use sc_client_api::{ backend::{AuxStore, Backend}, call_executor::CallExecutor, - error::{Result as ClientResult, Error as ClientError}, - blockchain::{self, HeaderBackend, ProvideCache}, BlockchainEvents, ProvideUncles, }; -use client::Client; +use sc_client::Client; -use block_builder_api::BlockBuilder as BlockBuilderApi; +use sp_block_builder::BlockBuilder as BlockBuilderApi; -use slots::{CheckedHeader, check_equivocation}; +use sc_consensus_slots::{CheckedHeader, check_equivocation}; use futures::prelude::*; use log::{warn, debug, info, trace}; -use slots::{SlotWorker, SlotData, SlotInfo, SlotCompatible}; +use sc_consensus_slots::{SlotWorker, SlotInfo, SlotCompatible}; use epoch_changes::descendent_query; -use header_metadata::HeaderMetadata; +use sp_blockchain::{ + Result as ClientResult, Error as ClientError, + HeaderBackend, ProvideCache, HeaderMetadata +}; use schnorrkel::SignatureError; -use sr_api::ApiExt; +use sp_api::ApiExt; mod aux_schema; mod verification; @@ -114,7 +115,7 @@ mod epoch_changes; mod authorship; #[cfg(test)] mod tests; -pub use babe_primitives::{ +pub use sp_consensus_babe::{ AuthorityId, AuthorityPair, AuthoritySignature, Epoch, NextEpochDescriptor, }; pub use epoch_changes::{EpochChanges, EpochChangesFor, SharedEpochChanges}; @@ -129,7 +130,7 @@ enum Error { #[display(fmt = "Multiple BABE epoch change digests, rejecting!")] MultipleEpochChangeDigests, #[display(fmt = "Could not extract timestamp and slot: {:?}", _0)] - Extraction(consensus_common::Error), + Extraction(sp_consensus::Error), #[display(fmt = "Could not fetch epoch at {:?}", _0)] FetchEpoch(B::Hash), #[display(fmt = "Header {:?} rejected: too far in the future", _0)] @@ -157,11 +158,11 @@ enum Error { #[display(fmt = "VRF verification failed: {:?}", _0)] VRFVerificationFailed(SignatureError), #[display(fmt = "Could not fetch parent header: {:?}", _0)] - FetchParentHeader(client_api::error::Error), + FetchParentHeader(sp_blockchain::Error), #[display(fmt = "Expected epoch change to happen at {:?}, s{}", _0, _1)] ExpectedEpochChange(B::Hash, u64), #[display(fmt = "Could not look up epoch: {:?}", _0)] - CouldNotLookUpEpoch(Box>), + CouldNotLookUpEpoch(Box>), #[display(fmt = "Block {} is not valid under any epoch.", _0)] BlockNotValid(B::Hash), #[display(fmt = "Unexpected epoch change")] @@ -170,9 +171,9 @@ enum Error { ParentBlockNoAssociatedWeight(B::Hash), #[display(fmt = "Checking inherents failed: {}", _0)] CheckInherents(String), - Client(client_api::error::Error), - Runtime(inherents::Error), - ForkTree(Box>), + Client(sp_blockchain::Error), + Runtime(sp_inherents::Error), + ForkTree(Box>), } impl std::convert::From> for String { @@ -200,16 +201,16 @@ macro_rules! babe_info { // and `super::babe::Config` can be eliminated. // https://github.com/paritytech/substrate/issues/2434 #[derive(Clone)] -pub struct Config(slots::SlotDuration); +pub struct Config(sc_consensus_slots::SlotDuration); impl Config { /// Either fetch the slot duration from disk or compute it from the genesis /// state. pub fn get_or_compute(client: &C) -> ClientResult where - C: AuxStore + ProvideRuntimeApi, C::Api: BabeApi, + C: AuxStore + ProvideRuntimeApi, C::Api: BabeApi, { trace!(target: "babe", "Getting slot duration"); - match slots::SlotDuration::get_or_compute(client, |a, b| a.configuration(b)).map(Self) { + match sc_consensus_slots::SlotDuration::get_or_compute(client, |a, b| a.configuration(b)).map(Self) { Ok(s) => Ok(s), Err(s) => { warn!(target: "babe", "Failed to get slot duration"); @@ -240,7 +241,7 @@ impl std::ops::Deref for Config { } /// Parameters for BABE. -pub struct BabeParams { +pub struct BabeParams { /// The keystore that manages the keys of the node. pub keystore: KeyStorePtr, @@ -269,10 +270,13 @@ pub struct BabeParams { /// The source of timestamps for relative slots pub babe_link: BabeLink, + + /// Checks if the current native implementation can author with a runtime at a given block. + pub can_author_with: CAW, } /// Start the babe worker. The returned future should be run in a tokio runtime. -pub fn start_babe(BabeParams { +pub fn start_babe(BabeParams { keystore, client, select_chain, @@ -282,9 +286,10 @@ pub fn start_babe(BabeParams { inherent_data_providers, force_authoring, babe_link, -}: BabeParams) -> Result< + can_author_with, +}: BabeParams) -> Result< impl futures01::Future, - consensus_common::Error, + sp_consensus::Error, > where B: BlockT, C: ProvideRuntimeApi + ProvideCache + ProvideUncles + BlockchainEvents @@ -295,8 +300,9 @@ pub fn start_babe(BabeParams { E::Proposer: Proposer, >::Create: Unpin + Send + 'static, I: BlockImport + Send + Sync + 'static, - Error: std::error::Error + Send + From<::consensus_common::Error> + From + 'static, + Error: std::error::Error + Send + From<::sp_consensus::Error> + From + 'static, SO: SyncOracle + Send + Sync + Clone, + CAW: CanAuthorWith + Send, { let config = babe_link.config; let worker = BabeWorker { @@ -311,20 +317,21 @@ pub fn start_babe(BabeParams { }; register_babe_inherent_data_provider(&inherent_data_providers, config.slot_duration())?; - uncles::register_uncles_inherent_data_provider( + sc_consensus_uncles::register_uncles_inherent_data_provider( client.clone(), select_chain.clone(), &inherent_data_providers, )?; babe_info!("Starting BABE Authorship worker"); - let slot_worker = slots::start_slot_worker( + let slot_worker = sc_consensus_slots::start_slot_worker( config.0, select_chain, worker, sync_oracle, inherent_data_providers, babe_link.time_source, + can_author_with, ); Ok(slot_worker.map(|_| Ok::<(), ()>(())).compat()) @@ -341,7 +348,7 @@ struct BabeWorker { config: Config, } -impl slots::SimpleSlotWorker for BabeWorker where +impl sc_consensus_slots::SimpleSlotWorker for BabeWorker where B: BlockT, C: ProvideRuntimeApi + ProvideCache + HeaderBackend + HeaderMetadata, C::Api: BabeApi, @@ -350,7 +357,7 @@ impl slots::SimpleSlotWorker for BabeWorker>::Create: Unpin + Send + 'static, I: BlockImport + Send + Sync + 'static, SO: SyncOracle + Send + Clone, - Error: std::error::Error + Send + From<::consensus_common::Error> + From + 'static, + Error: std::error::Error + Send + From<::sp_consensus::Error> + From + 'static, { type EpochData = Epoch; type Claim = (BabePreDigest, AuthorityPair); @@ -366,7 +373,7 @@ impl slots::SimpleSlotWorker for BabeWorker Result { + fn epoch_data(&self, parent: &B::Header, slot_number: u64) -> Result { self.epoch_changes.lock().epoch_for_child_of( descendent_query(&*self.client), &parent.hash(), @@ -376,7 +383,7 @@ impl slots::SimpleSlotWorker for BabeWorker usize { @@ -404,7 +411,7 @@ impl slots::SimpleSlotWorker for BabeWorker Vec> { + fn pre_digest_data(&self, _slot_number: u64, claim: &Self::Claim) -> Vec> { vec![ as CompatibleDigestItem>::babe_pre_digest(claim.0.clone()), ] @@ -415,7 +422,7 @@ impl slots::SimpleSlotWorker for BabeWorker, Self::Claim, - ) -> consensus_common::BlockImportParams + Send> { + ) -> sp_consensus::BlockImportParams + Send> { Box::new(|header, header_hash, body, (_, pair)| { // sign the pre-sealed hash of the block and then // add it to a digest item. @@ -435,6 +442,7 @@ impl slots::SimpleSlotWorker for BabeWorker slots::SimpleSlotWorker for BabeWorker Result { + fn proposer(&mut self, block: &B::Header) -> Result { self.env.init(block).map_err(|e| { - consensus_common::Error::ClientImport(format!("{:?}", e)) + sp_consensus::Error::ClientImport(format!("{:?}", e)) }) } + + fn proposing_remaining_duration( + &self, + head: &B::Header, + slot_info: &SlotInfo + ) -> Option { + // never give more than 2^this times the lenience. + const BACKOFF_CAP: u64 = 8; + + // how many slots it takes before we double the lenience. + const BACKOFF_STEP: u64 = 2; + + let slot_remaining = self.slot_remaining_duration(slot_info); + let parent_slot = match find_pre_digest::(head) { + Err(_) => return Some(slot_remaining), + Ok(d) => d.slot_number(), + }; + + // we allow a lenience of the number of slots since the head of the + // chain was produced, minus 1 (since there is always a difference of at least 1) + // + // exponential back-off. + // in normal cases we only attempt to issue blocks up to the end of the slot. + // when the chain has been stalled for a few slots, we give more lenience. + let slot_lenience = slot_info.number.saturating_sub(parent_slot + 1); + + let slot_lenience = std::cmp::min(slot_lenience, BACKOFF_CAP); + let slot_duration = slot_info.duration << (slot_lenience / BACKOFF_STEP); + + if slot_lenience >= 1 { + debug!(target: "babe", "No block for {} slots. Applying 2^({}/{}) lenience", + slot_lenience, slot_lenience, BACKOFF_STEP); + } + + let slot_lenience = Duration::from_secs(slot_duration); + Some(slot_lenience + slot_remaining) + } } impl SlotWorker for BabeWorker where @@ -463,12 +508,12 @@ impl SlotWorker for BabeWorker where >::Create: Unpin + Send + 'static, I: BlockImport + Send + Sync + 'static, SO: SyncOracle + Send + Sync + Clone, - Error: std::error::Error + Send + From<::consensus_common::Error> + From + 'static, + Error: std::error::Error + Send + From<::sp_consensus::Error> + From + 'static, { - type OnSlot = Pin> + Send>>; + type OnSlot = Pin> + Send>>; fn on_slot(&mut self, chain_head: B::Header, slot_info: SlotInfo) -> Self::OnSlot { - >::on_slot(self, chain_head, slot_info) + >::on_slot(self, chain_head, slot_info) } } @@ -524,12 +569,12 @@ impl SlotCompatible for TimeSource { fn extract_timestamp_and_slot( &self, data: &InherentData, - ) -> Result<(TimestampInherent, u64, std::time::Duration), consensus_common::Error> { + ) -> Result<(TimestampInherent, u64, std::time::Duration), sp_consensus::Error> { trace!(target: "babe", "extract timestamp"); data.timestamp_inherent_data() .and_then(|t| data.babe_inherent_data().map(|a| (t, a))) .map_err(Into::into) - .map_err(consensus_common::Error::InherentData) + .map_err(sp_consensus::Error::InherentData) .map(|(x, y)| (x, y, self.0.lock().0.take().unwrap_or_default())) } } @@ -545,7 +590,7 @@ pub struct BabeLink { pub struct BabeVerifier { client: Arc>, api: Arc, - inherent_data_providers: inherents::InherentDataProviders, + inherent_data_providers: sp_inherents::InherentDataProviders, config: Config, epoch_changes: SharedEpochChanges, time_source: TimeSource, @@ -558,7 +603,7 @@ impl BabeVerifier { block_id: BlockId, inherent_data: InherentData, ) -> Result<(), Error> - where PRA: ProvideRuntimeApi, PRA::Api: BlockBuilderApi + where PRA: ProvideRuntimeApi, PRA::Api: BlockBuilderApi { let inherent_res = self.api.runtime_api().check_inherents( &block_id, @@ -627,8 +672,8 @@ impl Verifier for BabeVerifier + 'static + Clone + Send + Sync, RA: Send + Sync, PRA: ProvideRuntimeApi + Send + Sync + AuxStore + ProvideCache, - PRA::Api: BlockBuilderApi - + BabeApi, + PRA::Api: BlockBuilderApi + + BabeApi, { fn verify( &mut self, @@ -748,6 +793,7 @@ impl Verifier for BabeVerifier = BasicQueue; fn register_babe_inherent_data_provider( inherent_data_providers: &InherentDataProviders, slot_duration: u64, -) -> Result<(), consensus_common::Error> { +) -> Result<(), sp_consensus::Error> { debug!(target: "babe", "Registering"); - if !inherent_data_providers.has_provider(&babe_primitives::inherents::INHERENT_IDENTIFIER) { + if !inherent_data_providers.has_provider(&sp_consensus_babe::inherents::INHERENT_IDENTIFIER) { inherent_data_providers - .register_provider(babe_primitives::inherents::InherentDataProvider::new(slot_duration)) + .register_provider(sp_consensus_babe::inherents::InherentDataProvider::new(slot_duration)) .map_err(Into::into) - .map_err(consensus_common::Error::InherentData) + .map_err(sp_consensus::Error::InherentData) } else { Ok(()) } @@ -851,8 +897,8 @@ impl BlockImport for BabeBlockImport return Ok(ImportResult::AlreadyInChain), - Ok(blockchain::BlockStatus::Unknown) => {}, + Ok(sp_blockchain::BlockStatus::InChain) => return Ok(ImportResult::AlreadyInChain), + Ok(sp_blockchain::BlockStatus::Unknown) => {}, Err(e) => return Err(ConsensusError::ClientImport(e.to_string())), } @@ -907,7 +953,7 @@ impl BlockImport for BabeBlockImport| ConsensusError::ChainLookup( + .map_err(|e: fork_tree::Error| ConsensusError::ChainLookup( babe_err(Error::::CouldNotLookUpEpoch(Box::new(e))).into() ))? .ok_or_else(|| ConsensusError::ClientImport( @@ -1146,7 +1192,7 @@ pub fn import_queue, I, RA, PRA>( E: CallExecutor + Clone + Send + Sync + 'static, RA: Send + Sync + 'static, PRA: ProvideRuntimeApi + ProvideCache + Send + Sync + AuxStore + 'static, - PRA::Api: BlockBuilderApi + BabeApi + ApiExt, + PRA::Api: BlockBuilderApi + BabeApi + ApiExt, { register_babe_inherent_data_provider(&inherent_data_providers, babe_link.config.slot_duration)?; diff --git a/client/consensus/babe/src/tests.rs b/client/consensus/babe/src/tests.rs index 19c5844511288a5f7f0d69824c2e741d83558f51..8ee4ae22e248b048bd4b3fbab2f10622b19722b8 100644 --- a/client/consensus/babe/src/tests.rs +++ b/client/consensus/babe/src/tests.rs @@ -22,32 +22,30 @@ use super::*; use authorship::claim_slot; -use babe_primitives::{AuthorityPair, SlotNumber}; -use block_builder::BlockBuilder; -use consensus_common::NoNetwork as DummyOracle; -use consensus_common::import_queue::{ +use sp_consensus_babe::{AuthorityPair, SlotNumber}; +use sc_block_builder::BlockBuilder; +use sp_consensus::NoNetwork as DummyOracle; +use sp_consensus::import_queue::{ BoxBlockImport, BoxJustificationImport, BoxFinalityProofImport, }; -use network::test::*; -use network::test::{Block as TestBlock, PeersClient}; -use network::config::BoxFinalityProofRequestBuilder; -use sr_primitives::{generic::DigestItem, traits::{Block as BlockT, DigestFor}}; -use network::config::ProtocolConfig; +use sc_network_test::*; +use sc_network_test::{Block as TestBlock, PeersClient}; +use sc_network::config::{BoxFinalityProofRequestBuilder, ProtocolConfig}; +use sp_runtime::{generic::DigestItem, traits::{Block as BlockT, DigestFor}}; use tokio::runtime::current_thread; -use client_api::BlockchainEvents; -use test_client; +use sc_client_api::BlockchainEvents; use log::debug; use std::{time::Duration, cell::RefCell}; type Item = DigestItem; -type Error = client::error::Error; +type Error = sp_blockchain::Error; -type TestClient = client::Client< - test_client::Backend, - test_client::Executor, +type TestClient = sc_client::Client< + substrate_test_runtime_client::Backend, + substrate_test_runtime_client::Executor, TestBlock, - test_client::runtime::RuntimeApi, + substrate_test_runtime_client::runtime::RuntimeApi, >; #[derive(Copy, Clone, PartialEq)] @@ -197,10 +195,10 @@ type TestExtrinsic = ::Extrinsic; pub struct TestVerifier { inner: BabeVerifier< - test_client::Backend, - test_client::Executor, + substrate_test_runtime_client::Backend, + substrate_test_runtime_client::Executor, TestBlock, - test_client::runtime::RuntimeApi, + substrate_test_runtime_client::runtime::RuntimeApi, PeersFullClient, >, mutator: Mutator, @@ -359,7 +357,7 @@ fn run_one_test( let select_chain = peer.select_chain().expect("Full client has select_chain"); let keystore_path = tempfile::tempdir().expect("Creates keystore path"); - let keystore = keystore::Store::open(keystore_path.path(), None).expect("Creates keystore"); + let keystore = sc_keystore::Store::open(keystore_path.path(), None).expect("Creates keystore"); keystore.write().insert_ephemeral_from_seed::(seed).expect("Generates authority key"); keystore_paths.push(keystore_path); @@ -404,6 +402,7 @@ fn run_one_test( force_authoring: false, babe_link: data.link.clone(), keystore, + can_author_with: sp_consensus::AlwaysCanAuthor, }).expect("Starts babe")); } @@ -483,7 +482,7 @@ fn sig_is_not_pre_digest() { fn can_author_block() { let _ = env_logger::try_init(); let keystore_path = tempfile::tempdir().expect("Creates keystore path"); - let keystore = keystore::Store::open(keystore_path.path(), None).expect("Creates keystore"); + let keystore = sc_keystore::Store::open(keystore_path.path(), None).expect("Creates keystore"); let pair = keystore.write().insert_ephemeral_from_seed::("//Alice") .expect("Generates authority pair"); @@ -539,7 +538,7 @@ fn propose_and_import_block( parent_pre_digest.slot_number() + 1 }); - let pre_digest = sr_primitives::generic::Digest { + let pre_digest = sp_runtime::generic::Digest { logs: vec![ Item::babe_pre_digest( BabePreDigest::Secondary { @@ -579,6 +578,7 @@ fn propose_and_import_block( auxiliary: Vec::new(), fork_choice: ForkChoiceStrategy::LongestChain, allow_missing_state: false, + import_existing: false, }, Default::default(), ).unwrap(); @@ -633,7 +633,7 @@ fn importing_block_one_sets_genesis_epoch() { #[test] fn importing_epoch_change_block_prunes_tree() { - use client_api::Finalizer; + use sc_client_api::Finalizer; let mut net = BabeTestNet::new(1); diff --git a/client/consensus/babe/src/verification.rs b/client/consensus/babe/src/verification.rs index 36e34dfb9578b8ace59b25ee0eff192b284a4a1e..0717e81a49149fcb8c08252d4fa8a67ab5a1e5f6 100644 --- a/client/consensus/babe/src/verification.rs +++ b/client/consensus/babe/src/verification.rs @@ -16,11 +16,11 @@ //! Verification for BABE headers. use schnorrkel::vrf::{VRFOutput, VRFProof}; -use sr_primitives::{traits::Header, traits::DigestItemFor}; -use primitives::{Pair, Public}; -use babe_primitives::{Epoch, BabePreDigest, CompatibleDigestItem, AuthorityId}; -use babe_primitives::{AuthoritySignature, SlotNumber, AuthorityIndex, AuthorityPair}; -use slots::CheckedHeader; +use sp_runtime::{traits::Header, traits::DigestItemFor}; +use sp_core::{Pair, Public}; +use sp_consensus_babe::{Epoch, BabePreDigest, CompatibleDigestItem, AuthorityId}; +use sp_consensus_babe::{AuthoritySignature, SlotNumber, AuthorityIndex, AuthorityPair}; +use sc_consensus_slots::CheckedHeader; use log::{debug, trace}; use super::{find_pre_digest, babe_err, BlockT, Error}; use super::authorship::{make_transcript, calculate_primary_threshold, check_primary_threshold, secondary_slot_author}; diff --git a/client/consensus/pow/Cargo.toml b/client/consensus/pow/Cargo.toml index 455986e2f6e176454bfc346ac0ed25805fd0c7ba..c7c4eeb6fffe3e4d8ef9edef63578938ccfcbfc8 100644 --- a/client/consensus/pow/Cargo.toml +++ b/client/consensus/pow/Cargo.toml @@ -1,20 +1,21 @@ [package] -name = "substrate-consensus-pow" -version = "2.0.0" +name = "sc-consensus-pow" +version = "0.8.0" authors = ["Parity Technologies "] description = "PoW consensus algorithm for substrate" edition = "2018" [dependencies] codec = { package = "parity-scale-codec", version = "1.0.0", features = ["derive"] } -primitives = { package = "substrate-primitives", path = "../../../primitives/core" } -sr-primitives = { path = "../../../primitives/sr-primitives" } -client-api = { package = "substrate-client-api", path = "../../api" } -block-builder-api = { package = "substrate-block-builder-runtime-api", path = "../../../primitives/block-builder/runtime-api" } -inherents = { package = "substrate-inherents", path = "../../../primitives/inherents" } -pow-primitives = { package = "substrate-consensus-pow-primitives", path = "../../../primitives/consensus/pow" } -consensus-common = { package = "substrate-consensus-common", path = "../../../primitives/consensus/common" } +sp-core = { version = "2.0.0", path = "../../../primitives/core" } +sp-blockchain = { version = "2.0.0", path = "../../../primitives/blockchain" } +sp-runtime = { version = "2.0.0", path = "../../../primitives/runtime" } +sc-client-api = { version = "2.0.0", path = "../../api" } +sp-block-builder = { version = "2.0.0", path = "../../../primitives/block-builder" } +sp-inherents = { version = "2.0.0", path = "../../../primitives/inherents" } +sp-consensus-pow = { version = "0.8", path = "../../../primitives/consensus/pow" } +sp-consensus = { version = "0.8", path = "../../../primitives/consensus/common" } log = "0.4.8" futures = { version = "0.3.1", features = ["compat"] } -sp-timestamp = { path = "../../../primitives/timestamp" } -derive_more = "0.15.0" +sp-timestamp = { version = "2.0.0", path = "../../../primitives/timestamp" } +derive_more = "0.99.2" diff --git a/client/consensus/pow/src/lib.rs b/client/consensus/pow/src/lib.rs index cb3f23fbf57dc670f3d17f4e85a63ff3313a58ac..b620a785259a80e7f83c0a86104c13dfc2897d5c 100644 --- a/client/consensus/pow/src/lib.rs +++ b/client/consensus/pow/src/lib.rs @@ -32,25 +32,23 @@ use std::sync::Arc; use std::thread; use std::collections::HashMap; -use client_api::{ - BlockOf, blockchain::{HeaderBackend, ProvideCache}, backend::AuxStore, - well_known_cache_keys::Id as CacheKeyId, -}; -use block_builder_api::BlockBuilder as BlockBuilderApi; -use sr_primitives::{Justification, RuntimeString}; -use sr_primitives::generic::{BlockId, Digest, DigestItem}; -use sr_primitives::traits::{Block as BlockT, Header as HeaderT, ProvideRuntimeApi}; +use sc_client_api::{BlockOf, backend::AuxStore}; +use sp_blockchain::{HeaderBackend, ProvideCache, well_known_cache_keys::Id as CacheKeyId}; +use sp_block_builder::BlockBuilder as BlockBuilderApi; +use sp_runtime::{Justification, RuntimeString}; +use sp_runtime::generic::{BlockId, Digest, DigestItem}; +use sp_runtime::traits::{Block as BlockT, Header as HeaderT, ProvideRuntimeApi}; use sp_timestamp::{TimestampInherentData, InherentError as TIError}; -use pow_primitives::{Seal, TotalDifficulty, POW_ENGINE_ID}; -use primitives::H256; -use inherents::{InherentDataProviders, InherentData}; -use consensus_common::{ +use sp_consensus_pow::{Seal, TotalDifficulty, POW_ENGINE_ID}; +use sp_core::H256; +use sp_inherents::{InherentDataProviders, InherentData}; +use sp_consensus::{ BlockImportParams, BlockOrigin, ForkChoiceStrategy, SyncOracle, Environment, Proposer, - SelectChain, Error as ConsensusError + SelectChain, Error as ConsensusError, CanAuthorWith, }; -use consensus_common::import_queue::{BoxBlockImport, BasicQueue, Verifier}; +use sp_consensus::import_queue::{BoxBlockImport, BasicQueue, Verifier}; use codec::{Encode, Decode}; -use client_api; +use sc_client_api; use log::*; #[derive(derive_more::Display, Debug)] @@ -66,7 +64,7 @@ pub enum Error { #[display(fmt = "Fetching best header failed using select chain: {:?}", _0)] BestHeaderSelectChain(ConsensusError), #[display(fmt = "Fetching best header failed: {:?}", _0)] - BestHeader(client_api::error::Error), + BestHeader(sp_blockchain::Error), #[display(fmt = "Best header does not exist")] NoBestHeader, #[display(fmt = "Block proposing error: {:?}", _0)] @@ -76,10 +74,10 @@ pub enum Error { #[display(fmt = "Error with block built on {:?}: {:?}", _0, _1)] BlockBuiltError(B::Hash, ConsensusError), #[display(fmt = "Creating inherents failed: {}", _0)] - CreateInherents(inherents::Error), + CreateInherents(sp_inherents::Error), #[display(fmt = "Checking inherents failed: {}", _0)] CheckInherents(String), - Client(client_api::error::Error), + Client(sp_blockchain::Error), Codec(codec::Error), Environment(String), Runtime(RuntimeString) @@ -153,7 +151,7 @@ pub trait PowAlgorithm { pub struct PowVerifier, C, S, Algorithm> { client: Arc, algorithm: Algorithm, - inherent_data_providers: inherents::InherentDataProviders, + inherent_data_providers: sp_inherents::InherentDataProviders, select_chain: Option, check_inherents_after: <::Header as HeaderT>::Number, } @@ -164,7 +162,7 @@ impl, C, S, Algorithm> PowVerifier { algorithm: Algorithm, check_inherents_after: <::Header as HeaderT>::Number, select_chain: Option, - inherent_data_providers: inherents::InherentDataProviders, + inherent_data_providers: sp_inherents::InherentDataProviders, ) -> Self { Self { client, algorithm, inherent_data_providers, select_chain, check_inherents_after } } @@ -211,7 +209,7 @@ impl, C, S, Algorithm> PowVerifier { inherent_data: InherentData, timestamp_now: u64, ) -> Result<(), Error> where - C: ProvideRuntimeApi, C::Api: BlockBuilderApi + C: ProvideRuntimeApi, C::Api: BlockBuilderApi { const MAX_TIMESTAMP_DRIFT_SECS: u64 = 60; @@ -249,7 +247,7 @@ impl, C, S, Algorithm> PowVerifier { impl, C, S, Algorithm> Verifier for PowVerifier where C: ProvideRuntimeApi + Send + Sync + HeaderBackend + AuxStore + ProvideCache + BlockOf, - C::Api: BlockBuilderApi, + C::Api: BlockBuilderApi, S: SelectChain, Algorithm: PowAlgorithm + Send + Sync, { @@ -306,6 +304,7 @@ impl, C, S, Algorithm> Verifier for PowVerifier best_aux.total_difficulty), allow_missing_state: false, + import_existing: false, }; Ok((import_block, None)) @@ -315,12 +314,12 @@ impl, C, S, Algorithm> Verifier for PowVerifier Result<(), consensus_common::Error> { +) -> Result<(), sp_consensus::Error> { if !inherent_data_providers.has_provider(&sp_timestamp::INHERENT_IDENTIFIER) { inherent_data_providers .register_provider(sp_timestamp::InherentDataProvider) .map_err(Into::into) - .map_err(consensus_common::Error::InherentData) + .map_err(sp_consensus::Error::InherentData) } else { Ok(()) } @@ -337,11 +336,11 @@ pub fn import_queue( check_inherents_after: <::Header as HeaderT>::Number, select_chain: Option, inherent_data_providers: InherentDataProviders, -) -> Result, consensus_common::Error> where +) -> Result, sp_consensus::Error> where B: BlockT, C: ProvideRuntimeApi + HeaderBackend + BlockOf + ProvideCache + AuxStore, C: Send + Sync + AuxStore + 'static, - C::Api: BlockBuilderApi, + C::Api: BlockBuilderApi, Algorithm: PowAlgorithm + Send + Sync + 'static, S: SelectChain + 'static, { @@ -373,7 +372,7 @@ pub fn import_queue( /// information, or just be a graffiti. `round` is for number of rounds the /// CPU miner runs each time. This parameter should be tweaked so that each /// mining round is within sub-second time. -pub fn start_mine, C, Algorithm, E, SO, S>( +pub fn start_mine, C, Algorithm, E, SO, S, CAW>( mut block_import: BoxBlockImport, client: Arc, algorithm: Algorithm, @@ -383,7 +382,8 @@ pub fn start_mine, C, Algorithm, E, SO, S>( mut sync_oracle: SO, build_time: std::time::Duration, select_chain: Option, - inherent_data_providers: inherents::InherentDataProviders, + inherent_data_providers: sp_inherents::InherentDataProviders, + can_author_with: CAW, ) where C: HeaderBackend + AuxStore + 'static, Algorithm: PowAlgorithm + Send + Sync + 'static, @@ -391,6 +391,7 @@ pub fn start_mine, C, Algorithm, E, SO, S>( E::Error: std::fmt::Debug, SO: SyncOracle + Send + Sync + 'static, S: SelectChain + 'static, + CAW: CanAuthorWith + Send + 'static, { if let Err(_) = register_pow_inherent_data_provider(&inherent_data_providers) { warn!("Registering inherent data provider for timestamp failed"); @@ -408,7 +409,8 @@ pub fn start_mine, C, Algorithm, E, SO, S>( &mut sync_oracle, build_time.clone(), select_chain.as_ref(), - &inherent_data_providers + &inherent_data_providers, + &can_author_with, ) { Ok(()) => (), Err(e) => error!( @@ -421,7 +423,7 @@ pub fn start_mine, C, Algorithm, E, SO, S>( }); } -fn mine_loop, C, Algorithm, E, SO, S>( +fn mine_loop, C, Algorithm, E, SO, S, CAW>( block_import: &mut BoxBlockImport, client: &C, algorithm: &Algorithm, @@ -431,7 +433,8 @@ fn mine_loop, C, Algorithm, E, SO, S>( sync_oracle: &mut SO, build_time: std::time::Duration, select_chain: Option<&S>, - inherent_data_providers: &inherents::InherentDataProviders, + inherent_data_providers: &sp_inherents::InherentDataProviders, + can_author_with: &CAW, ) -> Result<(), Error> where C: HeaderBackend + AuxStore, Algorithm: PowAlgorithm, @@ -439,6 +442,7 @@ fn mine_loop, C, Algorithm, E, SO, S>( E::Error: std::fmt::Debug, SO: SyncOracle, S: SelectChain, + CAW: CanAuthorWith, { 'outer: loop { if sync_oracle.is_major_syncing() { @@ -462,6 +466,18 @@ fn mine_loop, C, Algorithm, E, SO, S>( (hash, header) }, }; + + if let Err(err) = can_author_with.can_author_with(&BlockId::Hash(best_hash)) { + warn!( + target: "pow", + "Skipping proposal `can_author_with` returned: {} \ + Probably a node update is required!", + err, + ); + std::thread::sleep(std::time::Duration::from_secs(1)); + continue 'outer + } + let mut aux = PowAux::read(client, &best_hash)?; let mut proposer = env.init(&best_header) .map_err(|e| Error::Environment(format!("{:?}", e)))?; @@ -534,6 +550,7 @@ fn mine_loop, C, Algorithm, E, SO, S>( auxiliary: vec![(key, Some(aux.encode()))], fork_choice: ForkChoiceStrategy::Custom(true), allow_missing_state: false, + import_existing: false, }; block_import.import_block(import_block, HashMap::default()) diff --git a/client/consensus/slots/Cargo.toml b/client/consensus/slots/Cargo.toml index 6218d965c72a28fa91084e79c3d80031409cf16b..510ea72abc1c0b57c9a6492a419f6f56238fc839 100644 --- a/client/consensus/slots/Cargo.toml +++ b/client/consensus/slots/Cargo.toml @@ -1,6 +1,6 @@ [package] -name = "substrate-consensus-slots" -version = "2.0.0" +name = "sc-consensus-slots" +version = "0.8.0" authors = ["Parity Technologies "] description = "Generic slots-based utilities for consensus" edition = "2018" @@ -8,16 +8,17 @@ build = "build.rs" [dependencies] codec = { package = "parity-scale-codec", version = "1.0.0" } -client-api = { package = "substrate-client-api", path = "../../api" } -primitives = { package = "substrate-primitives", path = "../../../primitives/core" } -sr-primitives = { path = "../../../primitives/sr-primitives" } -substrate-telemetry = { path = "../../telemetry" } -consensus_common = { package = "substrate-consensus-common", path = "../../../primitives/consensus/common" } -inherents = { package = "substrate-inherents", path = "../../../primitives/inherents" } +sc-client-api = { version = "2.0.0", path = "../../api" } +sp-core = { version = "2.0.0", path = "../../../primitives/core" } +sp-blockchain = { version = "2.0.0", path = "../../../primitives/blockchain" } +sp-runtime = { version = "2.0.0", path = "../../../primitives/runtime" } +sc-telemetry = { version = "2.0.0", path = "../../telemetry" } +sp-consensus = { version = "0.8", path = "../../../primitives/consensus/common" } +sp-inherents = { version = "2.0.0", path = "../../../primitives/inherents" } futures = "0.3.1" futures-timer = "2.0" parking_lot = "0.9.0" log = "0.4.8" [dev-dependencies] -test-client = { package = "substrate-test-runtime-client", path = "../../../test/utils/runtime/client" } +substrate-test-runtime-client = { version = "2.0.0", path = "../../../test-utils/runtime/client" } diff --git a/client/consensus/slots/src/aux_schema.rs b/client/consensus/slots/src/aux_schema.rs index 1e777f35a17edafbdcda9fa36ab286a66f1c7c64..ada9661550340a555191f3068935147913f88bcd 100644 --- a/client/consensus/slots/src/aux_schema.rs +++ b/client/consensus/slots/src/aux_schema.rs @@ -17,9 +17,9 @@ //! Schema for slots in the aux-db. use codec::{Encode, Decode}; -use client_api::backend::AuxStore; -use client_api::error::{Result as ClientResult, Error as ClientError}; -use sr_primitives::traits::Header; +use sc_client_api::backend::AuxStore; +use sp_blockchain::{Result as ClientResult, Error as ClientError}; +use sp_runtime::traits::Header; const SLOT_HEADER_MAP_KEY: &[u8] = b"slot_header_map"; const SLOT_HEADER_START: &[u8] = b"slot_header_start"; @@ -151,10 +151,10 @@ pub fn check_equivocation( #[cfg(test)] mod test { - use primitives::{sr25519, Pair}; - use primitives::hash::H256; - use sr_primitives::testing::{Header as HeaderTest, Digest as DigestTest}; - use test_client; + use sp_core::{sr25519, Pair}; + use sp_core::hash::H256; + use sp_runtime::testing::{Header as HeaderTest, Digest as DigestTest}; + use substrate_test_runtime_client; use super::{MAX_SLOT_CAPACITY, PRUNING_BOUND, check_equivocation}; @@ -175,7 +175,7 @@ mod test { #[test] fn check_equivocation_works() { - let client = test_client::new(); + let client = substrate_test_runtime_client::new(); let (pair, _seed) = sr25519::Pair::generate(); let public = pair.public(); diff --git a/client/consensus/slots/src/lib.rs b/client/consensus/slots/src/lib.rs index 02f6c15b79492edf4eced4ef1ea4daeba3176ad4..9010771145384f58f039d76c3d647f670b34b75a 100644 --- a/client/consensus/slots/src/lib.rs +++ b/client/consensus/slots/src/lib.rs @@ -31,23 +31,23 @@ use slots::Slots; pub use aux_schema::{check_equivocation, MAX_SLOT_CAPACITY, PRUNING_BOUND}; use codec::{Decode, Encode}; -use consensus_common::{BlockImport, Proposer, SyncOracle, SelectChain}; +use sp_consensus::{BlockImport, Proposer, SyncOracle, SelectChain, CanAuthorWith, SlotData}; use futures::{prelude::*, future::{self, Either}}; use futures_timer::Delay; -use inherents::{InherentData, InherentDataProviders}; +use sp_inherents::{InherentData, InherentDataProviders}; use log::{debug, error, info, warn}; -use sr_primitives::generic::BlockId; -use sr_primitives::traits::{ApiRef, Block as BlockT, Header, ProvideRuntimeApi}; -use std::{fmt::Debug, ops::Deref, pin::Pin, sync::Arc}; -use substrate_telemetry::{telemetry, CONSENSUS_DEBUG, CONSENSUS_WARN, CONSENSUS_INFO}; +use sp_runtime::generic::BlockId; +use sp_runtime::traits::{ApiRef, Block as BlockT, Header, ProvideRuntimeApi}; +use std::{fmt::Debug, ops::Deref, pin::Pin, sync::Arc, time::{Instant, Duration}}; +use sc_telemetry::{telemetry, CONSENSUS_DEBUG, CONSENSUS_WARN, CONSENSUS_INFO}; use parking_lot::Mutex; -use client_api; +use sc_client_api; /// A worker that should be invoked at every new slot. pub trait SlotWorker { /// The type of the future that will be returned when a new slot is /// triggered. - type OnSlot: Future>; + type OnSlot: Future>; /// Called when a new slot is triggered. fn on_slot(&mut self, chain_head: B::Header, slot_info: SlotInfo) -> Self::OnSlot; @@ -80,7 +80,7 @@ pub trait SimpleSlotWorker { /// Returns the epoch data necessary for authoring. For time-dependent epochs, /// use the provided slot number as a canonical source of time. - fn epoch_data(&self, header: &B::Header, slot_number: u64) -> Result; + fn epoch_data(&self, header: &B::Header, slot_number: u64) -> Result; /// Returns the number of authorities given the epoch data. fn authorities_len(&self, epoch_data: &Self::EpochData) -> usize; @@ -94,7 +94,7 @@ pub trait SimpleSlotWorker { ) -> Option; /// Return the pre digest data to include in a block authored with the given claim. - fn pre_digest_data(&self, slot_number: u64, claim: &Self::Claim) -> Vec>; + fn pre_digest_data(&self, slot_number: u64, claim: &Self::Claim) -> Vec>; /// Returns a function which produces a `BlockImportParams`. fn block_import_params(&self) -> Box { &B::Hash, Vec, Self::Claim, - ) -> consensus_common::BlockImportParams + Send>; + ) -> sp_consensus::BlockImportParams + Send>; /// Whether to force authoring if offline. fn force_authoring(&self) -> bool; @@ -111,17 +111,49 @@ pub trait SimpleSlotWorker { fn sync_oracle(&mut self) -> &mut Self::SyncOracle; /// Returns a `Proposer` to author on top of the given block. - fn proposer(&mut self, block: &B::Header) -> Result; + fn proposer(&mut self, block: &B::Header) -> Result; + + /// Remaining duration of the slot. + fn slot_remaining_duration(&self, slot_info: &SlotInfo) -> Duration { + let now = Instant::now(); + if now < slot_info.ends_at { + slot_info.ends_at.duration_since(now) + } else { + Duration::from_millis(0) + } + } + + /// Remaining duration for proposing. None means unlimited. + fn proposing_remaining_duration( + &self, + _head: &B::Header, + slot_info: &SlotInfo + ) -> Option { + Some(self.slot_remaining_duration(slot_info)) + } /// Implements the `on_slot` functionality from `SlotWorker`. fn on_slot(&mut self, chain_head: B::Header, slot_info: SlotInfo) - -> Pin> + Send>> where + -> Pin> + Send>> where Self: Send + Sync, >::Create: Unpin + Send + 'static, { let (timestamp, slot_number, slot_duration) = (slot_info.timestamp, slot_info.number, slot_info.duration); + { + let slot_now = SignedDuration::default().slot_now(slot_duration); + if slot_now > slot_number { + // if this is behind, return. + debug!(target: self.logging_target(), + "Skipping proposal slot {} since our current view is {}", + slot_number, slot_now, + ); + + return Box::pin(future::ready(Ok(()))); + } + } + let epoch_data = match self.epoch_data(&chain_head, slot_number) { Ok(epoch_data) => epoch_data, Err(err) => { @@ -179,45 +211,43 @@ pub trait SimpleSlotWorker { }, }; - let remaining_duration = slot_info.remaining_duration(); + let slot_remaining_duration = self.slot_remaining_duration(&slot_info); + let proposing_remaining_duration = self.proposing_remaining_duration(&chain_head, &slot_info); let logs = self.pre_digest_data(slot_number, &claim); // deadline our production to approx. the end of the slot - let proposal_work = futures::future::select( - proposer.propose( - slot_info.inherent_data, - sr_primitives::generic::Digest { - logs, + let proposing = proposer.propose( + slot_info.inherent_data, + sp_runtime::generic::Digest { + logs, + }, + slot_remaining_duration, + ).map_err(|e| sp_consensus::Error::ClientImport(format!("{:?}", e))); + let delay: Box + Unpin + Send> = match proposing_remaining_duration { + Some(r) => Box::new(Delay::new(r)), + None => Box::new(future::pending()), + }; + + let proposal_work = + Box::new(futures::future::select(proposing, delay).map(move |v| match v { + futures::future::Either::Left((b, _)) => b.map(|b| (b, claim)), + futures::future::Either::Right(_) => { + info!("Discarding proposal for slot {}; block production took too long", slot_number); + // If the node was compiled with debug, tell the user to use release optimizations. + #[cfg(build_type="debug")] + info!("Recompile your node in `--release` mode to mitigate this problem."); + telemetry!(CONSENSUS_INFO; "slots.discarding_proposal_took_too_long"; + "slot" => slot_number, + ); + Err(sp_consensus::Error::ClientImport("Timeout in the Slots proposer".into())) }, - remaining_duration, - ).map_err(|e| consensus_common::Error::ClientImport(format!("{:?}", e))), - Delay::new(remaining_duration) - ).map(|v| match v { - futures::future::Either::Left((b, _)) => b.map(|b| (b, claim)), - futures::future::Either::Right(_) => - Err(consensus_common::Error::ClientImport("Timeout in the Slots proposer".into())), - }); + })); let block_import_params_maker = self.block_import_params(); let block_import = self.block_import(); let logging_target = self.logging_target(); Box::pin(proposal_work.map_ok(move |(block, claim)| { - // minor hack since we don't have access to the timestamp - // that is actually set by the proposer. - let slot_after_building = SignedDuration::default().slot_now(slot_duration); - if slot_after_building != slot_number { - info!("Discarding proposal for slot {}; block production took too long", slot_number); - // If the node was compiled with debug, tell the user to use release optimizations. - #[cfg(build_type="debug")] - info!("Recompile your node in `--release` mode to mitigate this problem."); - telemetry!(CONSENSUS_INFO; "slots.discarding_proposal_took_too_long"; - "slot" => slot_number, - ); - - return; - } - let (header, body) = block.deconstruct(); let header_num = *header.number(); let header_hash = header.hash(); @@ -263,7 +293,7 @@ pub trait SlotCompatible { fn extract_timestamp_and_slot( &self, inherent: &InherentData, - ) -> Result<(u64, u64, std::time::Duration), consensus_common::Error>; + ) -> Result<(u64, u64, std::time::Duration), sp_consensus::Error>; /// Get the difference between chain time and local time. Defaults to /// always returning zero. @@ -274,22 +304,24 @@ pub trait SlotCompatible { /// /// Every time a new slot is triggered, `worker.on_slot` is called and the future it returns is /// polled until completion, unless we are major syncing. -pub fn start_slot_worker( +pub fn start_slot_worker( slot_duration: SlotDuration, client: C, mut worker: W, mut sync_oracle: SO, inherent_data_providers: InherentDataProviders, timestamp_extractor: SC, + can_author_with: CAW, ) -> impl Future where B: BlockT, - C: SelectChain + Clone, + C: SelectChain, W: SlotWorker, W::OnSlot: Unpin, - SO: SyncOracle + Send + Clone, + SO: SyncOracle + Send, SC: SlotCompatible + Unpin, T: SlotData + Clone, + CAW: CanAuthorWith + Send, { let SlotDuration(slot_duration) = slot_duration; @@ -316,11 +348,24 @@ where } }; - Either::Left(worker.on_slot(chain_head, slot_info).map_err( - |e| { - warn!(target: "slots", "Encountered consensus error: {:?}", e); - }).or_else(|_| future::ready(Ok(()))) - ) + if let Err(err) = can_author_with.can_author_with(&BlockId::Hash(chain_head.hash())) { + warn!( + target: "slots", + "Unable to author block in slot {},. `can_author_with` returned: {} \ + Probably a node update is required!", + slot_num, + err, + ); + Either::Right(future::ready(Ok(()))) + } else { + Either::Left( + worker.on_slot(chain_head, slot_info) + .map_err(|e| { + warn!(target: "slots", "Encountered consensus error: {:?}", e); + }) + .or_else(|_| future::ready(Ok(()))) + ) + } }).then(|res| { if let Err(err) = res { warn!(target: "slots", "Slots stream terminated with an error: {:?}", err); @@ -341,23 +386,6 @@ pub enum CheckedHeader { Checked(H, S), } -/// A type from which a slot duration can be obtained. -pub trait SlotData { - /// Gets the slot duration. - fn slot_duration(&self) -> u64; - - /// The static slot key - const SLOT_KEY: &'static [u8]; -} - -impl SlotData for u64 { - fn slot_duration(&self) -> u64 { - *self - } - - const SLOT_KEY: &'static [u8] = b"aura_slot_duration"; -} - /// A slot duration. Create with `get_or_compute`. // The internal member should stay private here to maintain invariants of // `get_or_compute`. @@ -388,23 +416,23 @@ impl SlotDuration { /// /// `slot_key` is marked as `'static`, as it should really be a /// compile-time constant. - pub fn get_or_compute(client: &C, cb: CB) -> client_api::error::Result where - C: client_api::backend::AuxStore, + pub fn get_or_compute(client: &C, cb: CB) -> sp_blockchain::Result where + C: sc_client_api::backend::AuxStore, C: ProvideRuntimeApi, - CB: FnOnce(ApiRef, &BlockId) -> client_api::error::Result, + CB: FnOnce(ApiRef, &BlockId) -> sp_blockchain::Result, T: SlotData + Encode + Decode + Debug, { match client.get_aux(T::SLOT_KEY)? { Some(v) => ::decode(&mut &v[..]) .map(SlotDuration) .map_err(|_| { - client_api::error::Error::Backend({ + sp_blockchain::Error::Backend({ error!(target: "slots", "slot duration kept in invalid format"); "slot duration kept in invalid format".to_string() }) }), None => { - use sr_primitives::traits::Zero; + use sp_runtime::traits::Zero; let genesis_slot_duration = cb(client.runtime_api(), &BlockId::number(Zero::zero()))?; diff --git a/client/consensus/slots/src/slots.rs b/client/consensus/slots/src/slots.rs index 0166d09bb74d2ef20dc4bde0802f37e7044c221c..16d53fc54a295865361ae1066327fa437c7df91e 100644 --- a/client/consensus/slots/src/slots.rs +++ b/client/consensus/slots/src/slots.rs @@ -19,9 +19,9 @@ //! This is used instead of `futures_timer::Interval` because it was unreliable. use super::SlotCompatible; -use consensus_common::Error; +use sp_consensus::Error; use futures::{prelude::*, task::Context, task::Poll}; -use inherents::{InherentData, InherentDataProviders}; +use sp_inherents::{InherentData, InherentDataProviders}; use std::{pin::Pin, time::{Duration, Instant}}; use futures_timer::Delay; @@ -71,6 +71,8 @@ pub fn time_until_next(now: Duration, slot_duration: u64) -> Duration { pub struct SlotInfo { /// The slot number. pub number: u64, + /// The last slot number produced. + pub last_number: u64, /// Current timestamp. pub timestamp: u64, /// The instant at which the slot ends. @@ -81,18 +83,6 @@ pub struct SlotInfo { pub duration: u64, } -impl SlotInfo { - /// Yields the remaining duration in the slot. - pub fn remaining_duration(&self) -> Duration { - let now = Instant::now(); - if now < self.ends_at { - self.ends_at.duration_since(now) - } else { - Duration::from_millis(0) - } - } -} - /// A stream that returns every time there is a new slot. pub(crate) struct Slots { last_slot: u64, @@ -145,7 +135,7 @@ impl Stream for Slots { let inherent_data = match self.inherent_data_providers.create_inherent_data() { Ok(id) => id, - Err(err) => return Poll::Ready(Some(Err(consensus_common::Error::InherentData(err)))), + Err(err) => return Poll::Ready(Some(Err(sp_consensus::Error::InherentData(err)))), }; let result = self.timestamp_extractor.extract_timestamp_and_slot(&inherent_data); let (timestamp, slot_num, offset) = match result { @@ -160,11 +150,13 @@ impl Stream for Slots { // never yield the same slot twice. if slot_num > self.last_slot { + let last_slot = self.last_slot; self.last_slot = slot_num; break Poll::Ready(Some(Ok(SlotInfo { number: slot_num, duration: self.slot_duration, + last_number: last_slot, timestamp, ends_at, inherent_data, diff --git a/client/consensus/uncles/Cargo.toml b/client/consensus/uncles/Cargo.toml index 01e81ef198a3d8b6a56b6da49a0cda0001d162d7..54789c57944a1075caeff2e5a00283ba5bb6b826 100644 --- a/client/consensus/uncles/Cargo.toml +++ b/client/consensus/uncles/Cargo.toml @@ -1,15 +1,15 @@ [package] -name = "substrate-consensus-uncles" -version = "2.0.0" +name = "sc-consensus-uncles" +version = "0.8.0" authors = ["Parity Technologies "] description = "Generic uncle inclusion utilities for consensus" edition = "2018" [dependencies] -client-api = { package = "substrate-client-api", path = "../../api" } -primitives = { package = "substrate-primitives", path = "../../../primitives/core" } -sr-primitives = { path = "../../../primitives/sr-primitives" } -sp-authorship = { path = "../../../primitives/authorship" } -consensus_common = { package = "substrate-consensus-common", path = "../../../primitives/consensus/common" } -inherents = { package = "substrate-inherents", path = "../../../primitives/inherents" } +sc-client-api = { version = "2.0.0", path = "../../api" } +sp-core = { version = "2.0.0", path = "../../../primitives/core" } +sp-runtime = { version = "2.0.0", path = "../../../primitives/runtime" } +sp-authorship = { version = "2.0.0", path = "../../../primitives/authorship" } +sp-consensus = { version = "0.8", path = "../../../primitives/consensus/common" } +sp-inherents = { version = "2.0.0", path = "../../../primitives/inherents" } log = "0.4.8" diff --git a/client/consensus/uncles/src/lib.rs b/client/consensus/uncles/src/lib.rs index abbd6d2b65d9967573b62c72de7956fd5ea89f7f..4a7e8dc0d63bb58b7994b4048552ccdd0818a19d 100644 --- a/client/consensus/uncles/src/lib.rs +++ b/client/consensus/uncles/src/lib.rs @@ -15,15 +15,13 @@ // along with Substrate. If not, see . //! Uncles functionality for Substrate. -//! -#![deny(warnings)] #![forbid(unsafe_code, missing_docs)] -use consensus_common::SelectChain; -use inherents::{InherentDataProviders}; +use sp_consensus::SelectChain; +use sp_inherents::{InherentDataProviders}; use log::warn; -use client_api::ProvideUncles; -use sr_primitives::traits::{Block as BlockT, Header}; +use sc_client_api::ProvideUncles; +use sp_runtime::traits::{Block as BlockT, Header}; use std::sync::Arc; use sp_authorship; @@ -35,7 +33,7 @@ pub fn register_uncles_inherent_data_provider( client: Arc, select_chain: SC, inherent_data_providers: &InherentDataProviders, -) -> Result<(), consensus_common::Error> where +) -> Result<(), sp_consensus::Error> where B: BlockT, C: ProvideUncles + Send + Sync + 'static, SC: SelectChain + 'static, @@ -60,7 +58,7 @@ pub fn register_uncles_inherent_data_provider( } } })) - .map_err(|err| consensus_common::Error::InherentData(err.into()))?; + .map_err(|err| sp_consensus::Error::InherentData(err.into()))?; } Ok(()) } diff --git a/client/db/Cargo.toml b/client/db/Cargo.toml index f03fde576e21b0ec86bdb8e2f0e939dcc84fd12b..955f6f8e0d18da5e93c49ab509ad7401f2693fcc 100644 --- a/client/db/Cargo.toml +++ b/client/db/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "substrate-client-db" +name = "sc-client-db" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" @@ -7,29 +7,28 @@ edition = "2018" [dependencies] parking_lot = "0.9.0" log = "0.4.8" -kvdb = { git = "https://github.com/paritytech/parity-common", rev="b0317f649ab2c665b7987b8475878fc4d2e1f81d" } -# FIXME replace with release as soon as our rocksdb changes are released upstream https://github.com/paritytech/parity-common/issues/88 -kvdb-rocksdb = { git = "https://github.com/paritytech/parity-common", rev="b0317f649ab2c665b7987b8475878fc4d2e1f81d", optional = true } -kvdb-memorydb = { git = "https://github.com/paritytech/parity-common", rev="b0317f649ab2c665b7987b8475878fc4d2e1f81d" } +kvdb = "0.1.1" +kvdb-rocksdb = { version = "0.2", optional = true } +kvdb-memorydb = "0.1.2" linked-hash-map = "0.5.2" hash-db = "0.15.2" -client-api = { package = "substrate-client-api", path = "../api" } -primitives = { package = "substrate-primitives", path = "../../primitives/core" } -sr-primitives = { path = "../../primitives/sr-primitives" } -client = { package = "substrate-client", path = "../" } -state-machine = { package = "substrate-state-machine", path = "../../primitives/state-machine" } +sc-client-api = { version = "2.0.0", path = "../api" } +sp-core = { version = "2.0.0", path = "../../primitives/core" } +sp-runtime = { version = "2.0.0", path = "../../primitives/runtime" } +sc-client = { version = "2.0.0", path = "../" } +sp-state-machine = { version = "2.0.0", path = "../../primitives/state-machine" } codec = { package = "parity-scale-codec", version = "1.0.0", features = ["derive"] } -executor = { package = "substrate-executor", path = "../executor" } -state_db = { package = "substrate-state-db", path = "../state-db" } -trie = { package = "substrate-trie", path = "../../primitives/trie" } -consensus_common = { package = "substrate-consensus-common", path = "../../primitives/consensus/common" } -header_metadata = { package = "substrate-header-metadata", path = "../header-metadata" } +sc-executor = { version = "2.0.0", path = "../executor" } +sc-state-db = { version = "2.0.0", path = "../state-db" } +sp-trie = { version = "2.0.0", path = "../../primitives/trie" } +sp-consensus = { version = "0.8", path = "../../primitives/consensus/common" } +sp-blockchain = { version = "2.0.0", path = "../../primitives/blockchain" } [dev-dependencies] -substrate-keyring = { path = "../../primitives/keyring" } -test-client = { package = "substrate-test-runtime-client", path = "../../test/utils/runtime/client" } +sp-keyring = { version = "2.0.0", path = "../../primitives/keyring" } +substrate-test-runtime-client = { version = "2.0.0", path = "../../test-utils/runtime/client" } env_logger = "0.7.0" -quickcheck = "0.8" +quickcheck = "0.9" [features] default = [] diff --git a/client/db/src/cache/list_cache.rs b/client/db/src/cache/list_cache.rs index a51e6045c02fb98b00a157fac0f0b0077f404261..3760838bdf524acf5923c95276f740a195fe3c41 100644 --- a/client/db/src/cache/list_cache.rs +++ b/client/db/src/cache/list_cache.rs @@ -43,8 +43,8 @@ use std::collections::{BTreeSet, BTreeMap}; use log::warn; -use client_api::error::{Error as ClientError, Result as ClientResult}; -use sr_primitives::traits::{ +use sp_blockchain::{Error as ClientError, Result as ClientResult}; +use sp_runtime::traits::{ Block as BlockT, NumberFor, Zero, Bounded, CheckedSub }; @@ -651,7 +651,7 @@ pub fn destroy_fork, Tx: Stor /// Blockchain related functions. mod chain { - use sr_primitives::traits::Header as HeaderT; + use sp_runtime::traits::Header as HeaderT; use super::*; /// Is the block1 connected both ends of the range. @@ -724,9 +724,9 @@ fn read_forks>( #[cfg(test)] pub mod tests { - use test_client::runtime::H256; - use sr_primitives::testing::{Header, Block as RawBlock, ExtrinsicWrapper}; - use sr_primitives::traits::Header as HeaderT; + use substrate_test_runtime_client::runtime::H256; + use sp_runtime::testing::{Header, Block as RawBlock, ExtrinsicWrapper}; + use sp_runtime::traits::Header as HeaderT; use crate::cache::list_storage::tests::{DummyStorage, FaultyStorage, DummyTransaction}; use super::*; diff --git a/client/db/src/cache/list_entry.rs b/client/db/src/cache/list_entry.rs index afb2899362f91138569e559f701ae9e32c171305..e00da3b57c11ee6a4d96bee6029c66de67cbd9df 100644 --- a/client/db/src/cache/list_entry.rs +++ b/client/db/src/cache/list_entry.rs @@ -16,8 +16,8 @@ //! List-cache storage entries. -use client_api::error::Result as ClientResult; -use sr_primitives::traits::{Block as BlockT, NumberFor}; +use sp_blockchain::Result as ClientResult; +use sp_runtime::traits::{Block as BlockT, NumberFor}; use codec::{Encode, Decode}; use crate::cache::{CacheItemT, ComplexBlockId}; diff --git a/client/db/src/cache/list_storage.rs b/client/db/src/cache/list_storage.rs index d689619053d4667f0d2a35d77773b7b9a9a8efd7..236feac88aed251401ac0712e6472e691e6dc506 100644 --- a/client/db/src/cache/list_storage.rs +++ b/client/db/src/cache/list_storage.rs @@ -20,10 +20,10 @@ use std::sync::Arc; use kvdb::{KeyValueDB, DBTransaction}; -use client_api::error::{Error as ClientError, Result as ClientResult}; +use sp_blockchain::{Error as ClientError, Result as ClientResult}; use codec::{Encode, Decode}; -use sr_primitives::generic::BlockId; -use sr_primitives::traits::{Block as BlockT, Header as HeaderT, NumberFor}; +use sp_runtime::generic::BlockId; +use sp_runtime::traits::{Block as BlockT, Header as HeaderT, NumberFor}; use crate::utils::{self, db_err, meta_keys}; use crate::cache::{CacheItemT, ComplexBlockId}; diff --git a/client/db/src/cache/mod.rs b/client/db/src/cache/mod.rs index b3ff1a4ea6dbc270c77dc3c1e5bd49bc330207eb..a25b4e4fd730ca2179b0c36185f0e10917607b81 100644 --- a/client/db/src/cache/mod.rs +++ b/client/db/src/cache/mod.rs @@ -21,11 +21,11 @@ use parking_lot::RwLock; use kvdb::{KeyValueDB, DBTransaction}; -use client_api::blockchain::{well_known_cache_keys::{self, Id as CacheKeyId}, Cache as BlockchainCache}; -use client_api::error::Result as ClientResult; +use sc_client_api::blockchain::{well_known_cache_keys::{self, Id as CacheKeyId}, Cache as BlockchainCache}; +use sp_blockchain::Result as ClientResult; use codec::{Encode, Decode}; -use sr_primitives::generic::BlockId; -use sr_primitives::traits::{Block as BlockT, Header as HeaderT, NumberFor, Zero}; +use sp_runtime::generic::BlockId; +use sp_runtime::traits::{Block as BlockT, Header as HeaderT, NumberFor, Zero}; use crate::utils::{self, COLUMN_META, db_err}; use self::list_cache::{ListCache, PruningStrategy}; @@ -211,7 +211,7 @@ impl<'a, Block: BlockT> DbCacheTransaction<'a, Block> { .cloned() .collect::>(); - let mut insert_op = |name: CacheKeyId, value: Option>| -> Result<(), client_api::error::Error> { + let mut insert_op = |name: CacheKeyId, value: Option>| -> Result<(), sp_blockchain::Error> { let cache = self.cache.get_cache(name); let op = cache.on_block_insert( &mut self::list_storage::DbStorageTransaction::new( diff --git a/client/db/src/children.rs b/client/db/src/children.rs index f6dd7299e43f5616e3643f06fa8470871c14a19e..db0469098b7d94c54e1c92a38ecae1eddcd1fed4 100644 --- a/client/db/src/children.rs +++ b/client/db/src/children.rs @@ -18,7 +18,7 @@ use kvdb::{KeyValueDB, DBTransaction}; use codec::{Encode, Decode}; -use client_api::error; +use sp_blockchain; use std::hash::Hash; @@ -26,13 +26,13 @@ use std::hash::Hash; pub fn read_children< K: Eq + Hash + Clone + Encode + Decode, V: Eq + Hash + Clone + Encode + Decode, ->(db: &dyn KeyValueDB, column: Option, prefix: &[u8], parent_hash: K) -> error::Result> { +>(db: &dyn KeyValueDB, column: Option, prefix: &[u8], parent_hash: K) -> sp_blockchain::Result> { let mut buf = prefix.to_vec(); parent_hash.using_encoded(|s| buf.extend(s)); let raw_val_opt = match db.get(column, &buf[..]) { Ok(raw_val_opt) => raw_val_opt, - Err(_) => return Err(error::Error::Backend("Error reading value from database".into())), + Err(_) => return Err(sp_blockchain::Error::Backend("Error reading value from database".into())), }; let raw_val = match raw_val_opt { @@ -42,7 +42,7 @@ pub fn read_children< let children: Vec = match Decode::decode(&mut &raw_val[..]) { Ok(children) => children, - Err(_) => return Err(error::Error::Backend("Error decoding children".into())), + Err(_) => return Err(sp_blockchain::Error::Backend("Error decoding children".into())), }; Ok(children) diff --git a/client/db/src/lib.rs b/client/db/src/lib.rs index 155d2aaeab7b5453971088b8f943c01cd79847ec..8523ff30a395d21be53b0328b0a886bf9fa0ea49 100644 --- a/client/db/src/lib.rs +++ b/client/db/src/lib.rs @@ -39,41 +39,42 @@ use std::path::PathBuf; use std::io; use std::collections::{HashMap, HashSet}; -use client_api::ForkBlocks; -use client_api::backend::NewBlockState; -use client_api::backend::{StorageCollection, ChildStorageCollection}; -use client_api::blockchain::{well_known_cache_keys, HeaderBackend}; -use client_api::error::{Result as ClientResult, Error as ClientError}; -use client_api::execution_extensions::ExecutionExtensions; +use sc_client_api::{execution_extensions::ExecutionExtensions, ForkBlocks}; +use sc_client_api::backend::NewBlockState; +use sc_client_api::backend::{StorageCollection, ChildStorageCollection}; +use sp_blockchain::{ + Result as ClientResult, Error as ClientError, + well_known_cache_keys, HeaderBackend, +}; use codec::{Decode, Encode}; use hash_db::{Hasher, Prefix}; use kvdb::{KeyValueDB, DBTransaction}; -use trie::{MemoryDB, PrefixedMemoryDB, prefixed_key}; +use sp_trie::{MemoryDB, PrefixedMemoryDB, prefixed_key}; use parking_lot::{Mutex, RwLock}; -use primitives::{H256, Blake2Hasher, ChangesTrieConfiguration, convert_hash, traits::CodeExecutor}; -use primitives::storage::well_known_keys; -use sr_primitives::{ - generic::{BlockId, DigestItem}, Justification, StorageOverlay, ChildrenStorageOverlay, +use sp_core::{H256, Blake2Hasher, ChangesTrieConfiguration, convert_hash, traits::CodeExecutor}; +use sp_core::storage::{well_known_keys, ChildInfo}; +use sp_runtime::{ + generic::{BlockId, DigestItem}, Justification, Storage, BuildStorage, }; -use sr_primitives::traits::{ +use sp_runtime::traits::{ Block as BlockT, Header as HeaderT, NumberFor, Zero, One, SaturatedConversion }; -use executor::RuntimeInfo; -use state_machine::{ +use sc_executor::RuntimeInfo; +use sp_state_machine::{ DBValue, ChangesTrieTransaction, ChangesTrieCacheAction, ChangesTrieBuildCache, backend::Backend as StateBackend, }; use crate::utils::{Meta, db_err, meta_keys, read_db, read_meta}; -use client::leaves::{LeafSet, FinalizationDisplaced}; -use state_db::StateDb; -use header_metadata::{CachedHeaderMetadata, HeaderMetadata, HeaderMetadataCache}; +use sc_client::leaves::{LeafSet, FinalizationDisplaced}; +use sc_state_db::StateDb; +use sp_blockchain::{CachedHeaderMetadata, HeaderMetadata, HeaderMetadataCache}; use crate::storage_cache::{CachingState, SharedCache, new_shared_cache}; use log::{trace, debug, warn}; -pub use state_db::PruningMode; +pub use sc_state_db::PruningMode; #[cfg(feature = "test-helpers")] -use client::in_mem::Backend as InMemoryBackend; +use sc_client::in_mem::Backend as InMemoryBackend; const CANONICALIZATION_DELAY: u64 = 4096; const MIN_BLOCKS_TO_KEEP_CHANGES_TRIES_FOR: u32 = 32768; @@ -82,7 +83,7 @@ const MIN_BLOCKS_TO_KEEP_CHANGES_TRIES_FOR: u32 = 32768; const DEFAULT_CHILD_RATIO: (usize, usize) = (1, 10); /// DB-backed patricia trie state, transaction type is an overlay of changes to commit. -pub type DbState = state_machine::TrieBackend>, Blake2Hasher>; +pub type DbState = sp_state_machine::TrieBackend>, Blake2Hasher>; /// Re-export the KVDB trait so that one can pass an implementation of it. pub use kvdb; @@ -98,7 +99,11 @@ pub struct RefTrackingState { } impl RefTrackingState { - fn new(state: DbState, storage: Arc>, parent_hash: Option) -> RefTrackingState { + fn new( + state: DbState, + storage: Arc>, + parent_hash: Option, + ) -> RefTrackingState { RefTrackingState { state, parent_hash, @@ -134,16 +139,39 @@ impl StateBackend for RefTrackingState { self.state.storage_hash(key) } - fn child_storage(&self, storage_key: &[u8], key: &[u8]) -> Result>, Self::Error> { - self.state.child_storage(storage_key, key) + fn child_storage( + &self, + storage_key: &[u8], + child_info: ChildInfo, + key: &[u8], + ) -> Result>, Self::Error> { + self.state.child_storage(storage_key, child_info, key) } fn exists_storage(&self, key: &[u8]) -> Result { self.state.exists_storage(key) } - fn exists_child_storage(&self, storage_key: &[u8], key: &[u8]) -> Result { - self.state.exists_child_storage(storage_key, key) + fn exists_child_storage( + &self, + storage_key: &[u8], + child_info: ChildInfo, + key: &[u8], + ) -> Result { + self.state.exists_child_storage(storage_key, child_info, key) + } + + fn next_storage_key(&self, key: &[u8]) -> Result>, Self::Error> { + self.state.next_storage_key(key) + } + + fn next_child_storage_key( + &self, + storage_key: &[u8], + child_info: ChildInfo, + key: &[u8], + ) -> Result>, Self::Error> { + self.state.next_child_storage_key(storage_key, child_info, key) } fn for_keys_with_prefix(&self, prefix: &[u8], f: F) { @@ -154,12 +182,23 @@ impl StateBackend for RefTrackingState { self.state.for_key_values_with_prefix(prefix, f) } - fn for_keys_in_child_storage(&self, storage_key: &[u8], f: F) { - self.state.for_keys_in_child_storage(storage_key, f) + fn for_keys_in_child_storage( + &self, + storage_key: &[u8], + child_info: ChildInfo, + f: F, + ) { + self.state.for_keys_in_child_storage(storage_key, child_info, f) } - fn for_child_keys_with_prefix(&self, storage_key: &[u8], prefix: &[u8], f: F) { - self.state.for_child_keys_with_prefix(storage_key, prefix, f) + fn for_child_keys_with_prefix( + &self, + storage_key: &[u8], + child_info: ChildInfo, + prefix: &[u8], + f: F, + ) { + self.state.for_child_keys_with_prefix(storage_key, child_info, prefix, f) } fn storage_root(&self, delta: I) -> (H256, Self::Transaction) @@ -169,11 +208,16 @@ impl StateBackend for RefTrackingState { self.state.storage_root(delta) } - fn child_storage_root(&self, storage_key: &[u8], delta: I) -> (Vec, bool, Self::Transaction) + fn child_storage_root( + &self, + storage_key: &[u8], + child_info: ChildInfo, + delta: I, + ) -> (H256, bool, Self::Transaction) where I: IntoIterator, Option>)>, { - self.state.child_storage_root(storage_key, delta) + self.state.child_storage_root(storage_key, child_info, delta) } fn pairs(&self) -> Vec<(Vec, Vec)> { @@ -184,11 +228,18 @@ impl StateBackend for RefTrackingState { self.state.keys(prefix) } - fn child_keys(&self, child_key: &[u8], prefix: &[u8]) -> Vec> { - self.state.child_keys(child_key, prefix) + fn child_keys( + &self, + storage_key: &[u8], + child_info: ChildInfo, + prefix: &[u8], + ) -> Vec> { + self.state.child_keys(storage_key, child_info, prefix) } - fn as_trie_backend(&mut self) -> Option<&state_machine::TrieBackend> { + fn as_trie_backend( + &mut self, + ) -> Option<&sp_state_machine::TrieBackend> { self.state.as_trie_backend() } } @@ -227,15 +278,15 @@ pub fn new_client( fork_blocks: ForkBlocks, execution_extensions: ExecutionExtensions, ) -> Result<( - client::Client< + sc_client::Client< Backend, - client::LocalCallExecutor, E>, + sc_client::LocalCallExecutor, E>, Block, RA, >, Arc>, ), - client::error::Error, + sp_blockchain::Error, > where Block: BlockT, @@ -243,9 +294,9 @@ pub fn new_client( S: BuildStorage, { let backend = Arc::new(Backend::new(settings, CANONICALIZATION_DELAY)?); - let executor = client::LocalCallExecutor::new(backend.clone(), executor); + let executor = sc_client::LocalCallExecutor::new(backend.clone(), executor); Ok(( - client::Client::new(backend.clone(), executor, genesis_storage, fork_blocks, execution_extensions)?, + sc_client::Client::new(backend.clone(), executor, genesis_storage, fork_blocks, execution_extensions)?, backend, )) } @@ -275,7 +326,7 @@ struct PendingBlock { // wrapper that implements trait required for state_db struct StateMetaDb<'a>(&'a dyn KeyValueDB); -impl<'a> state_db::MetaDb for StateMetaDb<'a> { +impl<'a> sc_state_db::MetaDb for StateMetaDb<'a> { type Error = io::Error; fn get_meta(&self, key: &[u8]) -> Result>, Self::Error> { @@ -328,14 +379,14 @@ impl BlockchainDb { } } -impl client::blockchain::HeaderBackend for BlockchainDb { +impl sc_client::blockchain::HeaderBackend for BlockchainDb { fn header(&self, id: BlockId) -> ClientResult> { utils::read_header(&*self.db, columns::KEY_LOOKUP, columns::HEADER, id) } - fn info(&self) -> client::blockchain::Info { + fn info(&self) -> sc_client::blockchain::Info { let meta = self.meta.read(); - client::blockchain::Info { + sc_client::blockchain::Info { best_hash: meta.best_hash, best_number: meta.best_number, genesis_hash: meta.genesis_hash, @@ -344,7 +395,7 @@ impl client::blockchain::HeaderBackend for BlockchainDb) -> ClientResult { + fn status(&self, id: BlockId) -> ClientResult { let exists = match id { BlockId::Hash(_) => read_db( &*self.db, @@ -355,8 +406,8 @@ impl client::blockchain::HeaderBackend for BlockchainDb n <= self.meta.read().best_number, }; match exists { - true => Ok(client::blockchain::BlockStatus::InChain), - false => Ok(client::blockchain::BlockStatus::Unknown), + true => Ok(sc_client::blockchain::BlockStatus::InChain), + false => Ok(sc_client::blockchain::BlockStatus::Unknown), } } @@ -372,12 +423,12 @@ impl client::blockchain::HeaderBackend for BlockchainDb client::blockchain::Backend for BlockchainDb { +impl sc_client::blockchain::Backend for BlockchainDb { fn body(&self, id: BlockId) -> ClientResult>> { match read_db(&*self.db, columns::KEY_LOOKUP, columns::BODY, id)? { Some(body) => match Decode::decode(&mut &body[..]) { Ok(body) => Ok(Some(body)), - Err(err) => return Err(client::error::Error::Backend( + Err(err) => return Err(sp_blockchain::Error::Backend( format!("Error decoding body: {}", err) )), } @@ -389,7 +440,7 @@ impl client::blockchain::Backend for BlockchainDb { match read_db(&*self.db, columns::KEY_LOOKUP, columns::JUSTIFICATION, id)? { Some(justification) => match Decode::decode(&mut &justification[..]) { Ok(justification) => Ok(Some(justification)), - Err(err) => return Err(client::error::Error::Backend( + Err(err) => return Err(sp_blockchain::Error::Backend( format!("Error decoding justification: {}", err) )), } @@ -401,7 +452,7 @@ impl client::blockchain::Backend for BlockchainDb { Ok(self.meta.read().finalized_hash.clone()) } - fn cache(&self) -> Option>> { + fn cache(&self) -> Option>> { None } @@ -414,14 +465,14 @@ impl client::blockchain::Backend for BlockchainDb { } } -impl client::blockchain::ProvideCache for BlockchainDb { - fn cache(&self) -> Option>> { +impl sc_client::blockchain::ProvideCache for BlockchainDb { + fn cache(&self) -> Option>> { None } } impl HeaderMetadata for BlockchainDb { - type Error = client::error::Error; + type Error = sp_blockchain::Error; fn header_metadata(&self, hash: Block::Hash) -> Result, Self::Error> { self.header_metadata_cache.header_metadata(hash).or_else(|_| { @@ -471,7 +522,7 @@ impl BlockImportOperation { } } -impl client_api::backend::BlockImportOperation +impl sc_client_api::backend::BlockImportOperation for BlockImportOperation where Block: BlockT, { type State = CachingState, Block>; @@ -508,26 +559,26 @@ impl client_api::backend::BlockImportOperation fn reset_storage( &mut self, - top: StorageOverlay, - children: ChildrenStorageOverlay + storage: Storage, ) -> ClientResult { - if top.iter().any(|(k, _)| well_known_keys::is_child_storage_key(k)) { - return Err(client::error::Error::GenesisInvalid.into()); + if storage.top.iter().any(|(k, _)| well_known_keys::is_child_storage_key(k)) { + return Err(sp_blockchain::Error::GenesisInvalid.into()); } - for child_key in children.keys() { + for child_key in storage.children.keys() { if !well_known_keys::is_child_storage_key(&child_key) { - return Err(client::error::Error::GenesisInvalid.into()); + return Err(sp_blockchain::Error::GenesisInvalid.into()); } } - let child_delta = children.into_iter() - .map(|(storage_key, child_overlay)| - (storage_key, child_overlay.into_iter().map(|(k, v)| (k, Some(v))))); + let child_delta = storage.children.into_iter().map(|(storage_key, child_content)| ( + storage_key, + child_content.data.into_iter().map(|(k, v)| (k, Some(v))), child_content.child_info), + ); let (root, transaction) = self.old_state.full_storage_root( - top.into_iter().map(|(k, v)| (k, Some(v))), + storage.top.into_iter().map(|(k, v)| (k, Some(v))), child_delta ); @@ -579,7 +630,7 @@ struct StorageDb { pub state_db: StateDb>, } -impl state_machine::Storage for StorageDb { +impl sp_state_machine::Storage for StorageDb { fn get(&self, key: &H256, prefix: Prefix) -> Result, String> { let key = prefixed_key::(key, prefix); self.state_db.get(&key, self).map(|r| r.map(|v| DBValue::from_slice(&v))) @@ -587,7 +638,7 @@ impl state_machine::Storage for StorageDb { } } -impl state_db::NodeDb for StorageDb { +impl sc_state_db::NodeDb for StorageDb { type Error = io::Error; type Key = [u8]; @@ -602,12 +653,12 @@ impl DbGenesisStorage { pub fn new() -> Self { let mut root = H256::default(); let mut mdb = MemoryDB::::default(); - state_machine::TrieDBMut::::new(&mut mdb, &mut root); + sp_state_machine::TrieDBMut::::new(&mut mdb, &mut root); DbGenesisStorage(root) } } -impl state_machine::Storage for DbGenesisStorage { +impl sp_state_machine::Storage for DbGenesisStorage { fn get(&self, _key: &H256, _prefix: Prefix) -> Result, String> { Ok(None) } @@ -649,11 +700,11 @@ impl> DbChangesTrieStorage { None => return, }; - state_machine::prune_changes_tries( + sp_state_machine::prune_changes_tries( config, &*self, min_blocks_to_keep.into(), - &state_machine::ChangesTrieAnchorBlockId { + &sp_state_machine::ChangesTrieAnchorBlockId { hash: convert_hash(&block_hash), number: block_num, }, @@ -661,7 +712,7 @@ impl> DbChangesTrieStorage { } } -impl client_api::backend::PrunableStateChangesTrieStorage +impl sc_client_api::backend::PrunableStateChangesTrieStorage for DbChangesTrieStorage where Block: BlockT, @@ -672,7 +723,7 @@ where best_finalized_block: NumberFor, ) -> NumberFor { match self.min_blocks_to_keep { - Some(min_blocks_to_keep) => state_machine::oldest_non_pruned_changes_trie( + Some(min_blocks_to_keep) => sp_state_machine::oldest_non_pruned_changes_trie( config, min_blocks_to_keep.into(), best_finalized_block, @@ -682,7 +733,7 @@ where } } -impl state_machine::ChangesTrieRootsStorage> +impl sp_state_machine::ChangesTrieRootsStorage> for DbChangesTrieStorage where Block: BlockT, @@ -690,11 +741,11 @@ where fn build_anchor( &self, hash: H256, - ) -> Result>, String> { + ) -> Result>, String> { utils::read_header::(&*self.db, columns::KEY_LOOKUP, columns::HEADER, BlockId::Hash(hash)) .map_err(|e| e.to_string()) .and_then(|maybe_header| maybe_header.map(|header| - state_machine::ChangesTrieAnchorBlockId { + sp_state_machine::ChangesTrieAnchorBlockId { hash, number: *header.number(), } @@ -703,7 +754,7 @@ where fn root( &self, - anchor: &state_machine::ChangesTrieAnchorBlockId>, + anchor: &sp_state_machine::ChangesTrieAnchorBlockId>, block: NumberFor, ) -> Result, String> { // check API requirement: we can't get NEXT block(s) based on anchor @@ -749,12 +800,12 @@ where } } -impl state_machine::ChangesTrieStorage> +impl sp_state_machine::ChangesTrieStorage> for DbChangesTrieStorage where Block: BlockT, { - fn as_roots_storage(&self) -> &dyn state_machine::ChangesTrieRootsStorage> { + fn as_roots_storage(&self) -> &dyn sp_state_machine::ChangesTrieRootsStorage> { self } @@ -784,7 +835,7 @@ pub struct Backend { blockchain: BlockchainDb, canonicalization_delay: u64, shared_cache: SharedCache, - import_lock: Mutex<()>, + import_lock: RwLock<()>, is_archive: bool, } @@ -819,7 +870,7 @@ impl> Backend { let is_archive_pruning = config.pruning.is_archive(); let blockchain = BlockchainDb::new(db.clone())?; let meta = blockchain.meta.clone(); - let map_e = |e: state_db::Error| ::client::error::Error::from(format!("State database error: {:?}", e)); + let map_e = |e: sc_state_db::Error| ::sp_blockchain::Error::from(format!("State database error: {:?}", e)); let state_db: StateDb<_, _> = StateDb::new(config.pruning.clone(), &StateMetaDb(&*db)).map_err(map_e)?; let storage_db = StorageDb { db: db.clone(), @@ -853,8 +904,8 @@ impl> Backend { /// Returns in-memory blockchain that contains the same set of blocks that the self. #[cfg(feature = "test-helpers")] pub fn as_in_memory(&self) -> InMemoryBackend { - use client_api::backend::{Backend as ClientBackend, BlockImportOperation}; - use client::blockchain::Backend as BlockchainBackend; + use sc_client_api::backend::{Backend as ClientBackend, BlockImportOperation}; + use sc_client::blockchain::Backend as BlockchainBackend; let inmem = InMemoryBackend::::new(); @@ -888,7 +939,8 @@ impl> Backend { }; let mut op = inmem.begin_operation().unwrap(); op.set_block_data(header, body, justification, new_block_state).unwrap(); - op.update_db_storage(state.into_iter().map(|(k, v)| (None, k, Some(v))).collect()).unwrap(); + op.update_db_storage(vec![(None, state.into_iter().map(|(k, v)| (k, Some(v))).collect())]) + .unwrap(); inmem.commit_operation(op).unwrap(); } @@ -913,7 +965,7 @@ impl> Backend { match cached_changes_trie_config.clone() { Some(cached_changes_trie_config) => Ok(cached_changes_trie_config), None => { - use client_api::backend::Backend; + use sc_client_api::backend::Backend; let changes_trie_config = self .state_at(BlockId::Hash(block))? .storage(well_known_keys::CHANGES_TRIE_CONFIG)? @@ -944,7 +996,7 @@ impl> Backend { // cannot find tree route with empty DB. if meta.best_hash != Default::default() { - let tree_route = header_metadata::tree_route( + let tree_route = sp_blockchain::tree_route( &self.blockchain, meta.best_hash, route_to, @@ -959,7 +1011,7 @@ impl> Backend { (&r.number, &r.hash) ); - return Err(::client::error::Error::NotInFinalizedChain.into()); + return Err(::sp_blockchain::Error::NotInFinalizedChain.into()); } retracted.push(r.hash.clone()); @@ -1001,7 +1053,7 @@ impl> Backend { ) -> ClientResult<()> { let last_finalized = last_finalized.unwrap_or_else(|| self.blockchain.meta.read().finalized_hash); if *header.parent_hash() != last_finalized { - return Err(::client::error::Error::NonSequentialFinalization( + return Err(::sp_blockchain::Error::NonSequentialFinalization( format!("Last finalized {:?} not parent of {:?}", last_finalized, header.hash()), ).into()); } @@ -1057,14 +1109,14 @@ impl> Backend { let hash = if new_canonical == number_u64 { hash } else { - ::client::blockchain::HeaderBackend::hash(&self.blockchain, new_canonical.saturated_into())? + ::sc_client::blockchain::HeaderBackend::hash(&self.blockchain, new_canonical.saturated_into())? .expect("existence of block with number `new_canonical` \ implies existence of blocks with all numbers before it; qed") }; trace!(target: "db", "Canonicalize block #{} ({:?})", new_canonical, hash); let commit = self.storage.state_db.canonicalize_block(&hash) - .map_err(|e: state_db::Error| client::error::Error::from(format!("State database error: {:?}", e)))?; + .map_err(|e: sc_state_db::Error| sp_blockchain::Error::from(format!("State database error: {:?}", e)))?; apply_state_commit(transaction, commit); }; @@ -1138,7 +1190,7 @@ impl> Backend { } let finalized = if operation.commit_state { - let mut changeset: state_db::ChangeSet> = state_db::ChangeSet::default(); + let mut changeset: sc_state_db::ChangeSet> = sc_state_db::ChangeSet::default(); for (key, (val, rc)) in operation.db_updates.drain() { if rc > 0 { changeset.inserted.push((key, val.to_vec())); @@ -1148,7 +1200,7 @@ impl> Backend { } let number_u64 = number.saturated_into::(); let commit = self.storage.state_db.insert_block(&hash, number_u64, &pending_block.header.parent_hash(), changeset) - .map_err(|e: state_db::Error| client::error::Error::from(format!("State database error: {:?}", e)))?; + .map_err(|e: sc_state_db::Error| sp_blockchain::Error::from(format!("State database error: {:?}", e)))?; apply_state_commit(&mut transaction, commit); // Check if need to finalize. Genesis is always finalized instantly. @@ -1201,7 +1253,7 @@ impl> Backend { }; let cache_update = if let Some(set_head) = operation.set_head { - if let Some(header) = ::client::blockchain::HeaderBackend::header(&self.blockchain, set_head)? { + if let Some(header) = ::sc_client::blockchain::HeaderBackend::header(&self.blockchain, set_head)? { let number = header.number(); let hash = header.hash(); @@ -1213,7 +1265,7 @@ impl> Backend { meta_updates.push((hash, *number, true, false)); Some((enacted, retracted)) } else { - return Err(client::error::Error::UnknownBlock(format!("Cannot set head {:?}", set_head))) + return Err(sp_blockchain::Error::UnknownBlock(format!("Cannot set head {:?}", set_head))) } } else { None @@ -1247,7 +1299,7 @@ impl> Backend { operation.child_storage_updates, Some(hash), Some(number), - || is_best, + is_best, ); } @@ -1284,7 +1336,7 @@ impl> Backend { transaction.put(columns::META, meta_keys::FINALIZED_BLOCK, &lookup_key); let commit = self.storage.state_db.canonicalize_block(&f_hash) - .map_err(|e: state_db::Error| client::error::Error::from(format!("State database error: {:?}", e)))?; + .map_err(|e: sc_state_db::Error| sp_blockchain::Error::from(format!("State database error: {:?}", e)))?; apply_state_commit(transaction, commit); let changes_trie_config = self.changes_trie_config(parent_hash)?; @@ -1303,7 +1355,7 @@ impl> Backend { } } -fn apply_state_commit(transaction: &mut DBTransaction, commit: state_db::CommitSet>) { +fn apply_state_commit(transaction: &mut DBTransaction, commit: sc_state_db::CommitSet>) { for (key, val) in commit.data.inserted.into_iter() { transaction.put(columns::STATE, &key[..], &val); } @@ -1318,7 +1370,7 @@ fn apply_state_commit(transaction: &mut DBTransaction, commit: state_db::CommitS } } -impl client_api::backend::AuxStore for Backend where Block: BlockT { +impl sc_client_api::backend::AuxStore for Backend where Block: BlockT { fn insert_aux< 'a, 'b: 'a, @@ -1342,7 +1394,7 @@ impl client_api::backend::AuxStore for Backend where Block: BlockT } } -impl client_api::backend::Backend for Backend where Block: BlockT { +impl sc_client_api::backend::Backend for Backend where Block: BlockT { type BlockImportOperation = BlockImportOperation; type Blockchain = BlockchainDb; type State = CachingState, Block>; @@ -1447,12 +1499,12 @@ impl client_api::backend::Backend for Backend Some(commit) => { apply_state_commit(&mut transaction, commit); let removed = self.blockchain.header(BlockId::Number(best))?.ok_or_else( - || client::error::Error::UnknownBlock( + || sp_blockchain::Error::UnknownBlock( format!("Error reverting to {}. Block hash not found.", best)))?; best -= One::one(); // prev block let hash = self.blockchain.hash(best)?.ok_or_else( - || client::error::Error::UnknownBlock( + || sp_blockchain::Error::UnknownBlock( format!("Error reverting to {}. Block hash not found.", best)))?; let key = utils::number_and_hash_to_lookup_key(best.clone(), &hash)?; transaction.put(columns::META, meta_keys::BEST_BLOCK, &key); @@ -1478,7 +1530,7 @@ impl client_api::backend::Backend for Backend } fn state_at(&self, block: BlockId) -> ClientResult { - use client::blockchain::HeaderBackend as BcHeaderBackend; + use sc_client::blockchain::HeaderBackend as BcHeaderBackend; // special case for genesis initialization match block { @@ -1496,7 +1548,7 @@ impl client_api::backend::Backend for Backend Ok(Some(ref hdr)) => { let hash = hdr.hash(); if !self.have_state_at(&hash, *hdr.number()) { - return Err(client::error::Error::UnknownBlock(format!("State already discarded for {:?}", block))) + return Err(sp_blockchain::Error::UnknownBlock(format!("State already discarded for {:?}", block))) } if let Ok(()) = self.storage.state_db.pin(&hash) { let root = H256::from_slice(hdr.state_root().as_ref()); @@ -1504,10 +1556,10 @@ impl client_api::backend::Backend for Backend let state = RefTrackingState::new(db_state, self.storage.clone(), Some(hash.clone())); Ok(CachingState::new(state, self.shared_cache.clone(), Some(hash))) } else { - Err(client::error::Error::UnknownBlock(format!("State already discarded for {:?}", block))) + Err(sp_blockchain::Error::UnknownBlock(format!("State already discarded for {:?}", block))) } }, - Ok(None) => Err(client::error::Error::UnknownBlock(format!("Unknown state for block {:?}", block))), + Ok(None) => Err(sp_blockchain::Error::UnknownBlock(format!("Unknown state for block {:?}", block))), Err(e) => Err(e), } } @@ -1516,7 +1568,7 @@ impl client_api::backend::Backend for Backend if self.is_archive { match self.blockchain.header(BlockId::Hash(hash.clone())) { Ok(Some(header)) => { - state_machine::Storage::get(self.storage.as_ref(), &header.state_root(), (&[], None)).unwrap_or(None).is_some() + sp_state_machine::Storage::get(self.storage.as_ref(), &header.state_root(), (&[], None)).unwrap_or(None).is_some() }, _ => false, } @@ -1527,18 +1579,18 @@ impl client_api::backend::Backend for Backend fn destroy_state(&self, state: Self::State) -> ClientResult<()> { if let Some(hash) = state.cache.parent_hash.clone() { - let is_best = || self.blockchain.meta.read().best_hash == hash; + let is_best = self.blockchain.meta.read().best_hash == hash; state.release().sync_cache(&[], &[], vec![], vec![], None, None, is_best); } Ok(()) } - fn get_import_lock(&self) -> &Mutex<()> { + fn get_import_lock(&self) -> &RwLock<()> { &self.import_lock } } -impl client_api::backend::LocalBackend for Backend +impl sc_client_api::backend::LocalBackend for Backend where Block: BlockT {} /// TODO: remove me in #3201 @@ -1552,14 +1604,12 @@ mod tests { use hash_db::{HashDB, EMPTY_PREFIX}; use super::*; use crate::columns; - use client_api::backend::{Backend as BTrait, BlockImportOperation as Op}; - use client::blockchain::Backend as BLBTrait; - use sr_primitives::testing::{Header, Block as RawBlock, ExtrinsicWrapper}; - use sr_primitives::traits::{Hash, BlakeTwo256}; - use state_machine::{TrieMut, TrieDBMut, ChangesTrieRootsStorage, ChangesTrieStorage}; - use header_metadata::{lowest_common_ancestor, tree_route}; - - use test_client; + use sc_client_api::backend::{Backend as BTrait, BlockImportOperation as Op}; + use sc_client::blockchain::Backend as BLBTrait; + use sp_runtime::testing::{Header, Block as RawBlock, ExtrinsicWrapper}; + use sp_runtime::traits::{Hash, BlakeTwo256}; + use sp_state_machine::{TrieMut, TrieDBMut, ChangesTrieRootsStorage, ChangesTrieStorage}; + use sp_blockchain::{lowest_common_ancestor, tree_route}; type Block = RawBlock>; @@ -1586,7 +1636,7 @@ mod tests { changes: Vec<(Vec, Vec)>, extrinsics_root: H256, ) -> H256 { - use sr_primitives::testing::Digest; + use sp_runtime::testing::Digest; let (changes_root, changes_trie_update) = prepare_changes(changes); let digest = Digest { logs: vec![ @@ -1696,7 +1746,10 @@ mod tests { ).0.into(); let hash = header.hash(); - op.reset_storage(storage.iter().cloned().collect(), Default::default()).unwrap(); + op.reset_storage(Storage { + top: storage.iter().cloned().collect(), + children: Default::default(), + }).unwrap(); op.set_block_data( header.clone(), Some(vec![]), @@ -1778,7 +1831,10 @@ mod tests { ).0.into(); let hash = header.hash(); - op.reset_storage(storage.iter().cloned().collect(), Default::default()).unwrap(); + op.reset_storage(Storage { + top: storage.iter().cloned().collect(), + children: Default::default(), + }).unwrap(); key = op.db_updates.insert(EMPTY_PREFIX, b"hello"); op.set_block_data( @@ -1791,7 +1847,7 @@ mod tests { backend.commit_operation(op).unwrap(); assert_eq!(backend.storage.db.get( columns::STATE, - &trie::prefixed_key::(&key, EMPTY_PREFIX) + &sp_trie::prefixed_key::(&key, EMPTY_PREFIX) ).unwrap().unwrap(), &b"hello"[..]); hash }; @@ -1828,7 +1884,7 @@ mod tests { backend.commit_operation(op).unwrap(); assert_eq!(backend.storage.db.get( columns::STATE, - &trie::prefixed_key::(&key, EMPTY_PREFIX) + &sp_trie::prefixed_key::(&key, EMPTY_PREFIX) ).unwrap().unwrap(), &b"hello"[..]); hash }; @@ -1866,7 +1922,7 @@ mod tests { assert!(backend.storage.db.get( columns::STATE, - &trie::prefixed_key::(&key, EMPTY_PREFIX) + &sp_trie::prefixed_key::(&key, EMPTY_PREFIX) ).unwrap().is_some()); hash }; @@ -1900,7 +1956,7 @@ mod tests { backend.commit_operation(op).unwrap(); assert!(backend.storage.db.get( columns::STATE, - &trie::prefixed_key::(&key, EMPTY_PREFIX) + &sp_trie::prefixed_key::(&key, EMPTY_PREFIX) ).unwrap().is_none()); } @@ -1909,7 +1965,7 @@ mod tests { backend.finalize_block(BlockId::Number(3), None).unwrap(); assert!(backend.storage.db.get( columns::STATE, - &trie::prefixed_key::(&key, EMPTY_PREFIX) + &sp_trie::prefixed_key::(&key, EMPTY_PREFIX) ).unwrap().is_none()); } @@ -1921,7 +1977,7 @@ mod tests { let check_changes = |backend: &Backend, block: u64, changes: Vec<(Vec, Vec)>| { let (changes_root, mut changes_trie_update) = prepare_changes(changes); - let anchor = state_machine::ChangesTrieAnchorBlockId { + let anchor = sp_state_machine::ChangesTrieAnchorBlockId { hash: backend.blockchain().header(BlockId::Number(block)).unwrap().unwrap().hash(), number: block }; @@ -1975,21 +2031,21 @@ mod tests { // branch1: when asking for finalized block hash let (changes1_root, _) = prepare_changes(changes1); - let anchor = state_machine::ChangesTrieAnchorBlockId { hash: block2_1_1, number: 4 }; + let anchor = sp_state_machine::ChangesTrieAnchorBlockId { hash: block2_1_1, number: 4 }; assert_eq!(backend.changes_tries_storage.root(&anchor, 1), Ok(Some(changes1_root))); // branch2: when asking for finalized block hash - let anchor = state_machine::ChangesTrieAnchorBlockId { hash: block2_2_1, number: 4 }; + let anchor = sp_state_machine::ChangesTrieAnchorBlockId { hash: block2_2_1, number: 4 }; assert_eq!(backend.changes_tries_storage.root(&anchor, 1), Ok(Some(changes1_root))); // branch1: when asking for non-finalized block hash (search by traversal) let (changes2_1_0_root, _) = prepare_changes(changes2_1_0); - let anchor = state_machine::ChangesTrieAnchorBlockId { hash: block2_1_1, number: 4 }; + let anchor = sp_state_machine::ChangesTrieAnchorBlockId { hash: block2_1_1, number: 4 }; assert_eq!(backend.changes_tries_storage.root(&anchor, 3), Ok(Some(changes2_1_0_root))); // branch2: when asking for non-finalized block hash (search using canonicalized hint) let (changes2_2_0_root, _) = prepare_changes(changes2_2_0); - let anchor = state_machine::ChangesTrieAnchorBlockId { hash: block2_2_1, number: 4 }; + let anchor = sp_state_machine::ChangesTrieAnchorBlockId { hash: block2_2_1, number: 4 }; assert_eq!(backend.changes_tries_storage.root(&anchor, 3), Ok(Some(changes2_2_0_root))); // finalize first block of branch2 (block2_2_0) @@ -2001,7 +2057,7 @@ mod tests { // branch1: when asking for finalized block of other branch // => result is incorrect (returned for the block of branch1), but this is expected, // because the other fork is abandoned (forked before finalized header) - let anchor = state_machine::ChangesTrieAnchorBlockId { hash: block2_1_1, number: 4 }; + let anchor = sp_state_machine::ChangesTrieAnchorBlockId { hash: block2_1_1, number: 4 }; assert_eq!(backend.changes_tries_storage.root(&anchor, 3), Ok(Some(changes2_2_0_root))); } @@ -2032,7 +2088,7 @@ mod tests { backend.changes_tries_storage.meta.write().finalized_number = 13; // check that roots of all tries are in the columns::CHANGES_TRIE - let anchor = state_machine::ChangesTrieAnchorBlockId { hash: block13, number: 13 }; + let anchor = sp_state_machine::ChangesTrieAnchorBlockId { hash: block13, number: 13 }; fn read_changes_trie_root(backend: &Backend, num: u64) -> H256 { backend.blockchain().header(BlockId::Number(num)).unwrap().unwrap().digest().logs().iter() .find(|i| i.as_changes_trie_root().is_some()).unwrap().as_changes_trie_root().unwrap().clone() @@ -2103,7 +2159,7 @@ mod tests { let block6 = insert_header(&backend, 6, block5, vec![(b"key_at_6".to_vec(), b"val_at_6".to_vec())], Default::default()); // check that roots of all tries are in the columns::CHANGES_TRIE - let anchor = state_machine::ChangesTrieAnchorBlockId { hash: block6, number: 6 }; + let anchor = sp_state_machine::ChangesTrieAnchorBlockId { hash: block6, number: 6 }; fn read_changes_trie_root(backend: &Backend, num: u64) -> H256 { backend.blockchain().header(BlockId::Number(num)).unwrap().unwrap().digest().logs().iter() .find(|i| i.as_changes_trie_root().is_some()).unwrap().as_changes_trie_root().unwrap().clone() @@ -2290,20 +2346,20 @@ mod tests { #[test] fn test_leaves_with_complex_block_tree() { - let backend: Arc> = Arc::new(Backend::new_test(20, 20)); - test_client::trait_tests::test_leaves_for_backend(backend); + let backend: Arc> = Arc::new(Backend::new_test(20, 20)); + substrate_test_runtime_client::trait_tests::test_leaves_for_backend(backend); } #[test] fn test_children_with_complex_block_tree() { - let backend: Arc> = Arc::new(Backend::new_test(20, 20)); - test_client::trait_tests::test_children_for_backend(backend); + let backend: Arc> = Arc::new(Backend::new_test(20, 20)); + substrate_test_runtime_client::trait_tests::test_children_for_backend(backend); } #[test] fn test_blockchain_query_by_number_gets_canonical() { - let backend: Arc> = Arc::new(Backend::new_test(20, 20)); - test_client::trait_tests::test_blockchain_query_by_number_gets_canonical(backend); + let backend: Arc> = Arc::new(Backend::new_test(20, 20)); + substrate_test_runtime_client::trait_tests::test_blockchain_query_by_number_gets_canonical(backend); } #[test] @@ -2332,7 +2388,7 @@ mod tests { #[test] fn test_aux() { - let backend: Backend = Backend::new_test(0, 0); + let backend: Backend = Backend::new_test(0, 0); assert!(backend.get_aux(b"test").unwrap().is_none()); backend.insert_aux(&[(&b"test"[..], &b"hello"[..])], &[]).unwrap(); assert_eq!(b"hello", &backend.get_aux(b"test").unwrap().unwrap()[..]); @@ -2342,7 +2398,7 @@ mod tests { #[test] fn test_finalize_block_with_justification() { - use client::blockchain::{Backend as BlockChainBackend}; + use sc_client::blockchain::{Backend as BlockChainBackend}; let backend = Backend::::new_test(10, 10); diff --git a/client/db/src/light.rs b/client/db/src/light.rs index bdce0e638428e16f561330d62ffab0e721efb7db..31ed012622c8acfed142d18776a2759f842b4fac 100644 --- a/client/db/src/light.rs +++ b/client/db/src/light.rs @@ -22,20 +22,22 @@ use parking_lot::RwLock; use kvdb::{KeyValueDB, DBTransaction}; -use client_api::backend::{AuxStore, NewBlockState}; -use client::blockchain::{ - BlockStatus, Cache as BlockchainCache, - HeaderBackend as BlockchainHeaderBackend, Info as BlockchainInfo, +use sc_client_api::backend::{AuxStore, NewBlockState}; +use sc_client::blockchain::{ + BlockStatus, Cache as BlockchainCache,Info as BlockchainInfo, +}; +use sc_client::cht; +use sp_blockchain::{ + CachedHeaderMetadata, HeaderMetadata, HeaderMetadataCache, + Error as ClientError, Result as ClientResult, + HeaderBackend as BlockchainHeaderBackend, well_known_cache_keys, }; -use client::cht; -use client::error::{Error as ClientError, Result as ClientResult}; -use client::light::blockchain::Storage as LightBlockchainStorage; +use sc_client::light::blockchain::Storage as LightBlockchainStorage; use codec::{Decode, Encode}; -use primitives::Blake2Hasher; -use sr_primitives::generic::{DigestItem, BlockId}; -use sr_primitives::traits::{Block as BlockT, Header as HeaderT, Zero, One, NumberFor}; -use header_metadata::{CachedHeaderMetadata, HeaderMetadata, HeaderMetadataCache}; +use sp_core::Blake2Hasher; +use sp_runtime::generic::{DigestItem, BlockId}; +use sp_runtime::traits::{Block as BlockT, Header as HeaderT, Zero, One, NumberFor}; use crate::cache::{DbCacheSync, DbCache, ComplexBlockId, EntryType as CacheEntryType}; use crate::utils::{self, meta_keys, Meta, db_err, read_db, block_id_to_lookup_key, read_meta}; use crate::DatabaseSettings; @@ -235,7 +237,7 @@ impl LightStorage { // handle reorg. let meta = self.meta.read(); if meta.best_hash != Default::default() { - let tree_route = header_metadata::tree_route(self, meta.best_hash, route_to)?; + let tree_route = sp_blockchain::tree_route(self, meta.best_hash, route_to)?; // update block number to hash lookup entries. for retracted in tree_route.retracted() { @@ -282,7 +284,7 @@ impl LightStorage { ) -> ClientResult<()> { let meta = self.meta.read(); if &meta.finalized_hash != header.parent_hash() { - return Err(::client::error::Error::NonSequentialFinalization( + return Err(::sp_blockchain::Error::NonSequentialFinalization( format!("Last finalized {:?} not parent of {:?}", meta.finalized_hash, hash), ).into()) @@ -557,14 +559,14 @@ fn cht_key>(cht_type: u8, block: N) -> ClientResult<[u8; 5]> { #[cfg(test)] pub(crate) mod tests { - use client::cht; - use sr_primitives::generic::DigestItem; - use sr_primitives::testing::{H256 as Hash, Header, Block as RawBlock, ExtrinsicWrapper}; - use header_metadata::{lowest_common_ancestor, tree_route}; + use sc_client::cht; + use sp_runtime::generic::DigestItem; + use sp_runtime::testing::{H256 as Hash, Header, Block as RawBlock, ExtrinsicWrapper}; + use sp_blockchain::{lowest_common_ancestor, tree_route}; use super::*; type Block = RawBlock>; - type AuthorityId = primitives::ed25519::Public; + type AuthorityId = sp_core::ed25519::Public; pub fn default_header(parent: &Hash, number: u64) -> Header { Header { diff --git a/client/db/src/offchain.rs b/client/db/src/offchain.rs index 0435a1c865bda9c712467a3450c70c07fb164a19..44be8b0768b5a8e2e19058f75c4acdfc71c028da 100644 --- a/client/db/src/offchain.rs +++ b/client/db/src/offchain.rs @@ -43,7 +43,7 @@ impl LocalStorage { /// Create new offchain storage for tests (backed by memorydb) #[cfg(any(test, feature = "test-helpers"))] pub fn new_test() -> Self { - let db = Arc::new(::kvdb_memorydb::create(crate::utils::NUM_COLUMNS)); + let db = Arc::new(kvdb_memorydb::create(crate::utils::NUM_COLUMNS)); Self::new(db as _) } @@ -56,7 +56,7 @@ impl LocalStorage { } } -impl primitives::offchain::OffchainStorage for LocalStorage { +impl sp_core::offchain::OffchainStorage for LocalStorage { fn set(&mut self, prefix: &[u8], key: &[u8], value: &[u8]) { let key: Vec = prefix.iter().chain(key).cloned().collect(); let mut tx = self.db.transaction(); @@ -117,7 +117,7 @@ impl primitives::offchain::OffchainStorage for LocalStorage { #[cfg(test)] mod tests { use super::*; - use primitives::offchain::OffchainStorage; + use sp_core::offchain::OffchainStorage; #[test] fn should_compare_and_set_and_clear_the_locks_map() { diff --git a/client/db/src/storage_cache.rs b/client/db/src/storage_cache.rs index 9888dfbe647a5fcc1ac523958a0f69c82833e7d3..9f28539e3e20496da105707235686670727cbb79 100644 --- a/client/db/src/storage_cache.rs +++ b/client/db/src/storage_cache.rs @@ -21,11 +21,12 @@ use std::sync::Arc; use parking_lot::{Mutex, RwLock, RwLockUpgradableReadGuard}; use linked_hash_map::{LinkedHashMap, Entry}; use hash_db::Hasher; -use sr_primitives::traits::{Block as BlockT, Header}; -use primitives::hexdisplay::HexDisplay; -use state_machine::{backend::Backend as StateBackend, TrieBackend}; +use sp_runtime::traits::{Block as BlockT, Header}; +use sp_core::hexdisplay::HexDisplay; +use sp_core::storage::ChildInfo; +use sp_state_machine::{backend::Backend as StateBackend, TrieBackend}; use log::trace; -use client_api::backend::{StorageCollection, ChildStorageCollection}; +use sc_client_api::backend::{StorageCollection, ChildStorageCollection}; use std::hash::Hash as StdHash; const STATE_CACHE_BLOCKS: usize = 12; @@ -309,7 +310,7 @@ impl CacheChanges { /// that are invalidated by chain reorganization. `sync_cache` /// should be called after the block has been committed and the /// blockchain route has been calculated. - pub fn sync_cache bool> ( + pub fn sync_cache( &mut self, enacted: &[B::Hash], retracted: &[B::Hash], @@ -317,10 +318,9 @@ impl CacheChanges { child_changes: ChildStorageCollection, commit_hash: Option, commit_number: Option<::Number>, - is_best: F, + is_best: bool, ) { let mut cache = self.shared_cache.lock(); - let is_best = is_best(); trace!("Syncing cache, id = (#{:?}, {:?}), parent={:?}, best={}", commit_number, commit_hash, self.parent_hash, is_best); let cache = &mut *cache; // Filter out commiting block if any. @@ -517,7 +517,12 @@ impl, B: BlockT> StateBackend for CachingState< Ok(hash) } - fn child_storage(&self, storage_key: &[u8], key: &[u8]) -> Result>, Self::Error> { + fn child_storage( + &self, + storage_key: &[u8], + child_info: ChildInfo, + key: &[u8], + ) -> Result>, Self::Error> { let key = (storage_key.to_vec(), key.to_vec()); let local_cache = self.cache.local_cache.upgradable_read(); if let Some(entry) = local_cache.child_storage.get(&key).cloned() { @@ -532,7 +537,7 @@ impl, B: BlockT> StateBackend for CachingState< } } trace!("Cache miss: {:?}", key); - let value = self.state.child_storage(storage_key, &key.1[..])?; + let value = self.state.child_storage(storage_key, child_info, &key.1[..])?; RwLockUpgradableReadGuard::upgrade(local_cache).child_storage.insert(key, value.clone()); Ok(value) } @@ -541,12 +546,35 @@ impl, B: BlockT> StateBackend for CachingState< Ok(self.storage(key)?.is_some()) } - fn exists_child_storage(&self, storage_key: &[u8], key: &[u8]) -> Result { - self.state.exists_child_storage(storage_key, key) + fn exists_child_storage( + &self, + storage_key: &[u8], + child_info: ChildInfo, + key: &[u8], + ) -> Result { + self.state.exists_child_storage(storage_key, child_info, key) } - fn for_keys_in_child_storage(&self, storage_key: &[u8], f: F) { - self.state.for_keys_in_child_storage(storage_key, f) + fn for_keys_in_child_storage( + &self, + storage_key: &[u8], + child_info: ChildInfo, + f: F, + ) { + self.state.for_keys_in_child_storage(storage_key, child_info, f) + } + + fn next_storage_key(&self, key: &[u8]) -> Result>, Self::Error> { + self.state.next_storage_key(key) + } + + fn next_child_storage_key( + &self, + storage_key: &[u8], + child_info: ChildInfo, + key: &[u8], + ) -> Result>, Self::Error> { + self.state.next_child_storage_key(storage_key, child_info, key) } fn for_keys_with_prefix(&self, prefix: &[u8], f: F) { @@ -557,8 +585,14 @@ impl, B: BlockT> StateBackend for CachingState< self.state.for_key_values_with_prefix(prefix, f) } - fn for_child_keys_with_prefix(&self, storage_key: &[u8], prefix: &[u8], f: F) { - self.state.for_child_keys_with_prefix(storage_key, prefix, f) + fn for_child_keys_with_prefix( + &self, + storage_key: &[u8], + child_info: ChildInfo, + prefix: &[u8], + f: F, + ) { + self.state.for_child_keys_with_prefix(storage_key, child_info, prefix, f) } fn storage_root(&self, delta: I) -> (H::Out, Self::Transaction) @@ -569,12 +603,17 @@ impl, B: BlockT> StateBackend for CachingState< self.state.storage_root(delta) } - fn child_storage_root(&self, storage_key: &[u8], delta: I) -> (Vec, bool, Self::Transaction) + fn child_storage_root( + &self, + storage_key: &[u8], + child_info: ChildInfo, + delta: I, + ) -> (H::Out, bool, Self::Transaction) where I: IntoIterator, Option>)>, H::Out: Ord { - self.state.child_storage_root(storage_key, delta) + self.state.child_storage_root(storage_key, child_info, delta) } fn pairs(&self) -> Vec<(Vec, Vec)> { @@ -585,8 +624,13 @@ impl, B: BlockT> StateBackend for CachingState< self.state.keys(prefix) } - fn child_keys(&self, child_key: &[u8], prefix: &[u8]) -> Vec> { - self.state.child_keys(child_key, prefix) + fn child_keys( + &self, + storage_key: &[u8], + child_info: ChildInfo, + prefix: &[u8], + ) -> Vec> { + self.state.child_keys(storage_key, child_info, prefix) } fn as_trie_backend(&mut self) -> Option<&TrieBackend> { @@ -597,9 +641,9 @@ impl, B: BlockT> StateBackend for CachingState< #[cfg(test)] mod tests { use super::*; - use sr_primitives::testing::{H256, Block as RawBlock, ExtrinsicWrapper}; - use state_machine::backend::InMemory; - use primitives::Blake2Hasher; + use sp_runtime::testing::{H256, Block as RawBlock, ExtrinsicWrapper}; + use sp_state_machine::backend::InMemory; + use sp_core::Blake2Hasher; type Block = RawBlock>; @@ -621,22 +665,22 @@ mod tests { // blocks [ 3a(c) 2a(c) 2b 1b 1a(c) 0 ] // state [ 5 5 4 3 2 2 ] let mut s = CachingState::new(InMemory::::default(), shared.clone(), Some(root_parent)); - s.cache.sync_cache(&[], &[], vec![(key.clone(), Some(vec![2]))], vec![], Some(h0), Some(0), || true); + s.cache.sync_cache(&[], &[], vec![(key.clone(), Some(vec![2]))], vec![], Some(h0), Some(0), true); let mut s = CachingState::new(InMemory::::default(), shared.clone(), Some(h0)); - s.cache.sync_cache(&[], &[], vec![], vec![], Some(h1a), Some(1), || true); + s.cache.sync_cache(&[], &[], vec![], vec![], Some(h1a), Some(1), true); let mut s = CachingState::new(InMemory::::default(), shared.clone(), Some(h0)); - s.cache.sync_cache(&[], &[], vec![(key.clone(), Some(vec![3]))], vec![], Some(h1b), Some(1), || false); + s.cache.sync_cache(&[], &[], vec![(key.clone(), Some(vec![3]))], vec![], Some(h1b), Some(1), false); let mut s = CachingState::new(InMemory::::default(), shared.clone(), Some(h1b.clone())); - s.cache.sync_cache(&[], &[], vec![(key.clone(), Some(vec![4]))], vec![], Some(h2b), Some(2), || false); + s.cache.sync_cache(&[], &[], vec![(key.clone(), Some(vec![4]))], vec![], Some(h2b), Some(2), false); let mut s = CachingState::new(InMemory::::default(), shared.clone(), Some(h1a.clone())); - s.cache.sync_cache(&[], &[], vec![(key.clone(), Some(vec![5]))], vec![], Some(h2a), Some(2), || true); + s.cache.sync_cache(&[], &[], vec![(key.clone(), Some(vec![5]))], vec![], Some(h2a), Some(2), true); let mut s = CachingState::new(InMemory::::default(), shared.clone(), Some(h2a)); - s.cache.sync_cache(&[], &[], vec![], vec![], Some(h3a), Some(3), || true); + s.cache.sync_cache(&[], &[], vec![], vec![], Some(h3a), Some(3), true); let s = CachingState::new(InMemory::::default(), shared.clone(), Some(h3a)); assert_eq!(s.storage(&key).unwrap().unwrap(), vec![5]); @@ -660,7 +704,7 @@ mod tests { vec![], Some(h3b), Some(3), - || true, + true, ); let s = CachingState::new(InMemory::::default(), shared.clone(), Some(h3a)); assert!(s.storage(&key).unwrap().is_none()); @@ -680,16 +724,16 @@ mod tests { let shared = new_shared_cache::(256*1024, (0,1)); let mut s = CachingState::new(InMemory::::default(), shared.clone(), Some(root_parent)); - s.cache.sync_cache(&[], &[], vec![(key.clone(), Some(vec![2]))], vec![], Some(h1), Some(1), || true); + s.cache.sync_cache(&[], &[], vec![(key.clone(), Some(vec![2]))], vec![], Some(h1), Some(1), true); let mut s = CachingState::new(InMemory::::default(), shared.clone(), Some(h1)); - s.cache.sync_cache(&[], &[], vec![], vec![], Some(h2a), Some(2), || true); + s.cache.sync_cache(&[], &[], vec![], vec![], Some(h2a), Some(2), true); let mut s = CachingState::new(InMemory::::default(), shared.clone(), Some(h1)); - s.cache.sync_cache(&[], &[], vec![(key.clone(), Some(vec![3]))], vec![], Some(h2b), Some(2), || false); + s.cache.sync_cache(&[], &[], vec![(key.clone(), Some(vec![3]))], vec![], Some(h2b), Some(2), false); let mut s = CachingState::new(InMemory::::default(), shared.clone(), Some(h2b)); - s.cache.sync_cache(&[], &[], vec![(key.clone(), Some(vec![3]))], vec![], Some(h3b), Some(2), || false); + s.cache.sync_cache(&[], &[], vec![(key.clone(), Some(vec![3]))], vec![], Some(h3b), Some(2), false); let s = CachingState::new(InMemory::::default(), shared.clone(), Some(h2a)); assert_eq!(s.storage(&key).unwrap().unwrap(), vec![2]); @@ -708,19 +752,19 @@ mod tests { let shared = new_shared_cache::(256*1024, (0,1)); let mut s = CachingState::new(InMemory::::default(), shared.clone(), Some(root_parent)); - s.cache.sync_cache(&[], &[], vec![], vec![], Some(h1), Some(1), || true); + s.cache.sync_cache(&[], &[], vec![], vec![], Some(h1), Some(1), true); let mut s = CachingState::new(InMemory::::default(), shared.clone(), Some(h1)); - s.cache.sync_cache(&[], &[], vec![], vec![], Some(h2a), Some(2), || true); + s.cache.sync_cache(&[], &[], vec![], vec![], Some(h2a), Some(2), true); let mut s = CachingState::new(InMemory::::default(), shared.clone(), Some(h2a)); - s.cache.sync_cache(&[], &[], vec![(key.clone(), Some(vec![2]))], vec![], Some(h3a), Some(3), || true); + s.cache.sync_cache(&[], &[], vec![(key.clone(), Some(vec![2]))], vec![], Some(h3a), Some(3), true); let mut s = CachingState::new(InMemory::::default(), shared.clone(), Some(h1)); - s.cache.sync_cache(&[], &[], vec![], vec![], Some(h2b), Some(2), || false); + s.cache.sync_cache(&[], &[], vec![], vec![], Some(h2b), Some(2), false); let mut s = CachingState::new(InMemory::::default(), shared.clone(), Some(h2b)); - s.cache.sync_cache(&[], &[], vec![(key.clone(), Some(vec![3]))], vec![], Some(h3b), Some(3), || false); + s.cache.sync_cache(&[], &[], vec![(key.clone(), Some(vec![3]))], vec![], Some(h3b), Some(3), false); let s = CachingState::new(InMemory::::default(), shared.clone(), Some(h3a)); assert_eq!(s.storage(&key).unwrap().unwrap(), vec![2]); @@ -743,7 +787,7 @@ mod tests { vec![], Some(h0), Some(0), - || true, + true, ); // 32 key, 3 byte size assert_eq!(shared.lock().used_storage_cache_size(), 35 /* bytes */); @@ -756,7 +800,7 @@ mod tests { vec![(s_key.clone(), vec![(key.clone(), Some(vec![1, 2]))])], Some(h0), Some(0), - || true, + true, ); // 35 + (2 * 32) key, 2 byte size assert_eq!(shared.lock().used_storage_cache_size(), 101 /* bytes */); @@ -778,7 +822,7 @@ mod tests { vec![], Some(h0), Some(0), - || true, + true, ); // 32 key, 4 byte size assert_eq!(shared.lock().used_storage_cache_size(), 36 /* bytes */); @@ -791,7 +835,7 @@ mod tests { vec![], Some(h0), Some(0), - || true, + true, ); // 32 key, 2 byte size assert_eq!(shared.lock().used_storage_cache_size(), 34 /* bytes */); @@ -809,10 +853,10 @@ mod tests { let shared = new_shared_cache::(256*1024, (0, 1)); let mut s = CachingState::new(InMemory::::default(), shared.clone(), Some(root_parent)); - s.cache.sync_cache(&[], &[], vec![(key.clone(), Some(vec![2]))], vec![], Some(h0), Some(0), || true); + s.cache.sync_cache(&[], &[], vec![(key.clone(), Some(vec![2]))], vec![], Some(h0), Some(0), true); let mut s = CachingState::new(InMemory::::default(), shared.clone(), Some(h0)); - s.cache.sync_cache(&[], &[], vec![(key.clone(), Some(vec![3]))], vec![], Some(h1), Some(1), || true); + s.cache.sync_cache(&[], &[], vec![(key.clone(), Some(vec![3]))], vec![], Some(h1), Some(1), true); let mut s = CachingState::new(InMemory::::default(), shared.clone(), Some(h1)); assert_eq!(s.storage(&key).unwrap(), Some(vec![3])); @@ -831,7 +875,7 @@ mod tests { s.cache.local_cache.write().storage.insert(key.clone(), Some(vec![42])); // New value is propagated. - s.cache.sync_cache(&[], &[], vec![], vec![], None, None, || true); + s.cache.sync_cache(&[], &[], vec![], vec![], None, None, true); let s = CachingState::new(InMemory::::default(), shared.clone(), Some(h1)); assert_eq!(s.storage(&key).unwrap(), None); @@ -845,9 +889,9 @@ mod qc { use quickcheck::{quickcheck, TestResult, Arbitrary}; use super::*; - use sr_primitives::testing::{H256, Block as RawBlock, ExtrinsicWrapper}; - use state_machine::backend::InMemory; - use primitives::Blake2Hasher; + use sp_runtime::testing::{H256, Block as RawBlock, ExtrinsicWrapper}; + use sp_state_machine::backend::InMemory; + use sp_core::Blake2Hasher; type Block = RawBlock>; @@ -1051,7 +1095,7 @@ mod qc { vec![], Some(hash), Some(total_h as u64), - || false, + false, ); state @@ -1090,7 +1134,7 @@ mod qc { vec![], Some(hash), Some(self.canon.len() as u64 + 1), - || true, + true, ); self.canon.push(next); @@ -1138,7 +1182,7 @@ mod qc { vec![], Some(hash), Some(height), - || true, + true, ); state diff --git a/client/db/src/utils.rs b/client/db/src/utils.rs index 0a6112abe7a6edca2b990612d1a08aced74783fb..c45fe1c064448d8676d13aa88859ed3842774b3a 100644 --- a/client/db/src/utils.rs +++ b/client/db/src/utils.rs @@ -25,11 +25,10 @@ use kvdb::{KeyValueDB, DBTransaction}; use kvdb_rocksdb::{Database, DatabaseConfig}; use log::debug; -use client; use codec::Decode; -use trie::DBValue; -use sr_primitives::generic::BlockId; -use sr_primitives::traits::{ +use sp_trie::DBValue; +use sp_runtime::generic::BlockId; +use sp_runtime::traits::{ Block as BlockT, Header as HeaderT, Zero, UniqueSaturatedFrom, UniqueSaturatedInto, }; @@ -82,9 +81,9 @@ pub type NumberIndexKey = [u8; 4]; /// /// In the current database schema, this kind of key is only used for /// lookups into an index, NOT for storing header data or others. -pub fn number_index_key>(n: N) -> client::error::Result { +pub fn number_index_key>(n: N) -> sp_blockchain::Result { let n = n.try_into().map_err(|_| - client::error::Error::Backend("Block number cannot be converted to u32".into()) + sp_blockchain::Error::Backend("Block number cannot be converted to u32".into()) )?; Ok([ @@ -100,7 +99,7 @@ pub fn number_index_key>(n: N) -> client::error::Result( number: N, hash: H, -) -> client::error::Result> where +) -> sp_blockchain::Result> where N: TryInto, H: AsRef<[u8]>, { @@ -111,11 +110,11 @@ pub fn number_and_hash_to_lookup_key( /// Convert block lookup key into block number. /// all block lookup keys start with the block number. -pub fn lookup_key_to_number(key: &[u8]) -> client::error::Result where +pub fn lookup_key_to_number(key: &[u8]) -> sp_blockchain::Result where N: From { if key.len() < 4 { - return Err(client::error::Error::Backend("Invalid block key".into())); + return Err(sp_blockchain::Error::Backend("Invalid block key".into())); } Ok((key[0] as u32) << 24 | (key[1] as u32) << 16 @@ -128,7 +127,7 @@ pub fn remove_number_to_key_mapping>( transaction: &mut DBTransaction, key_lookup_col: Option, number: N, -) -> client::error::Result<()> { +) -> sp_blockchain::Result<()> { transaction.delete(key_lookup_col, number_index_key(number)?.as_ref()); Ok(()) } @@ -139,7 +138,7 @@ pub fn remove_key_mappings, H: AsRef<[u8]>>( key_lookup_col: Option, number: N, hash: H, -) -> client::error::Result<()> { +) -> sp_blockchain::Result<()> { remove_number_to_key_mapping(transaction, key_lookup_col, number)?; transaction.delete(key_lookup_col, hash.as_ref()); Ok(()) @@ -152,7 +151,7 @@ pub fn insert_number_to_key_mapping + Clone, H: AsRef<[u8]>>( key_lookup_col: Option, number: N, hash: H, -) -> client::error::Result<()> { +) -> sp_blockchain::Result<()> { transaction.put_vec( key_lookup_col, number_index_key(number.clone())?.as_ref(), @@ -167,7 +166,7 @@ pub fn insert_hash_to_key_mapping, H: AsRef<[u8]> + Clone>( key_lookup_col: Option, number: N, hash: H, -) -> client::error::Result<()> { +) -> sp_blockchain::Result<()> { transaction.put_vec( key_lookup_col, hash.clone().as_ref(), @@ -183,9 +182,9 @@ pub fn block_id_to_lookup_key( db: &dyn KeyValueDB, key_lookup_col: Option, id: BlockId -) -> Result>, client::error::Error> where +) -> Result>, sp_blockchain::Error> where Block: BlockT, - ::sr_primitives::traits::NumberFor: UniqueSaturatedFrom + UniqueSaturatedInto, + ::sp_runtime::traits::NumberFor: UniqueSaturatedFrom + UniqueSaturatedInto, { let res = match id { BlockId::Number(n) => db.get( @@ -199,8 +198,8 @@ pub fn block_id_to_lookup_key( } /// Maps database error to client error -pub fn db_err(err: io::Error) -> client::error::Error { - client::error::Error::Backend(format!("{}", err)) +pub fn db_err(err: io::Error) -> sp_blockchain::Error { + sp_blockchain::Error::Backend(format!("{}", err)) } /// Open RocksDB database. @@ -208,19 +207,35 @@ pub fn open_database( config: &DatabaseSettings, col_meta: Option, db_type: &str -) -> client::error::Result> { +) -> sp_blockchain::Result> { let db: Arc = match &config.source { #[cfg(feature = "kvdb-rocksdb")] DatabaseSettingsSrc::Path { path, cache_size } => { let mut db_config = DatabaseConfig::with_columns(Some(NUM_COLUMNS)); - db_config.memory_budget = *cache_size; - let path = path.to_str().ok_or_else(|| client::error::Error::Backend("Invalid database path".into()))?; + + if let Some(cache_size) = cache_size { + let state_col_budget = (*cache_size as f64 * 0.9) as usize; + let other_col_budget = (cache_size - state_col_budget) / (NUM_COLUMNS as usize - 1); + + let mut memory_budget = std::collections::HashMap::new(); + for i in 0..NUM_COLUMNS { + if Some(i) == crate::columns::STATE { + memory_budget.insert(Some(i), state_col_budget); + } else { + memory_budget.insert(Some(i), other_col_budget); + } + } + + db_config.memory_budget = memory_budget; + } + let path = path.to_str() + .ok_or_else(|| sp_blockchain::Error::Backend("Invalid database path".into()))?; Arc::new(Database::open(&db_config, &path).map_err(db_err)?) }, #[cfg(not(feature = "kvdb-rocksdb"))] DatabaseSettingsSrc::Path { .. } => { let msg = "Try to open RocksDB database with RocksDB disabled".into(); - return Err(client::error::Error::Backend(msg)); + return Err(sp_blockchain::Error::Backend(msg)); }, DatabaseSettingsSrc::Custom(db) => db.clone(), }; @@ -229,7 +244,7 @@ pub fn open_database( match db.get(col_meta, meta_keys::TYPE).map_err(db_err)? { Some(stored_type) => { if db_type.as_bytes() != &*stored_type { - return Err(client::error::Error::Backend( + return Err(sp_blockchain::Error::Backend( format!("Unexpected database type. Expected: {}", db_type)).into()); } }, @@ -249,7 +264,7 @@ pub fn read_db( col_index: Option, col: Option, id: BlockId -) -> client::error::Result> +) -> sp_blockchain::Result> where Block: BlockT, { @@ -265,12 +280,12 @@ pub fn read_header( col_index: Option, col: Option, id: BlockId, -) -> client::error::Result> { +) -> sp_blockchain::Result> { match read_db(db, col_index, col, id)? { Some(header) => match Block::Header::decode(&mut &header[..]) { Ok(header) => Ok(Some(header)), Err(_) => return Err( - client::error::Error::Backend("Error decoding header".into()) + sp_blockchain::Error::Backend("Error decoding header".into()) ), } None => Ok(None), @@ -283,15 +298,15 @@ pub fn require_header( col_index: Option, col: Option, id: BlockId, -) -> client::error::Result { +) -> sp_blockchain::Result { read_header(db, col_index, col, id) - .and_then(|header| header.ok_or_else(|| client::error::Error::UnknownBlock(format!("{}", id)))) + .and_then(|header| header.ok_or_else(|| sp_blockchain::Error::UnknownBlock(format!("{}", id)))) } /// Read meta from the database. pub fn read_meta(db: &dyn KeyValueDB, col_meta: Option, col_header: Option) -> Result< Meta<<::Header as HeaderT>::Number, Block::Hash>, - client::error::Error, + sp_blockchain::Error, > where Block: BlockT, @@ -299,7 +314,7 @@ pub fn read_meta(db: &dyn KeyValueDB, col_meta: Option, col_header: let genesis_hash: Block::Hash = match db.get(col_meta, meta_keys::GENESIS_HASH).map_err(db_err)? { Some(h) => match Decode::decode(&mut &h[..]) { Ok(h) => h, - Err(err) => return Err(client::error::Error::Backend( + Err(err) => return Err(sp_blockchain::Error::Backend( format!("Error decoding genesis hash: {}", err) )), }, @@ -312,7 +327,7 @@ pub fn read_meta(db: &dyn KeyValueDB, col_meta: Option, col_header: }), }; - let load_meta_block = |desc, key| -> Result<_, client::error::Error> { + let load_meta_block = |desc, key| -> Result<_, sp_blockchain::Error> { if let Some(Some(header)) = db.get(col_meta, key).and_then(|id| match id { Some(id) => db.get(col_header, &id).map(|h| h.map(|b| Block::Header::decode(&mut &b[..]).ok())), @@ -342,7 +357,7 @@ pub fn read_meta(db: &dyn KeyValueDB, col_meta: Option, col_header: #[cfg(test)] mod tests { use super::*; - use sr_primitives::testing::{Block as RawBlock, ExtrinsicWrapper}; + use sp_runtime::testing::{Block as RawBlock, ExtrinsicWrapper}; type Block = RawBlock>; #[test] diff --git a/client/executor/Cargo.toml b/client/executor/Cargo.toml index 619b974cb6aa017c1370ac14088727a67d52d4a3..b21a8165c5d67c627441f3747feeec9bb465812b 100644 --- a/client/executor/Cargo.toml +++ b/client/executor/Cargo.toml @@ -1,24 +1,24 @@ [package] -name = "substrate-executor" +name = "sc-executor" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" [dependencies] -derive_more = "0.15.0" +derive_more = "0.99.2" codec = { package = "parity-scale-codec", version = "1.0.0" } -runtime_io = { package = "sr-io", path = "../../primitives/sr-io" } -primitives = { package = "substrate-primitives", path = "../../primitives/core" } -trie = { package = "substrate-trie", path = "../../primitives/trie" } -serializer = { package = "substrate-serializer", path = "../../primitives/serializer" } -runtime_version = { package = "sr-version", path = "../../primitives/sr-version" } -panic-handler = { package = "substrate-panic-handler", path = "../../primitives/panic-handler" } +sp-io = { version = "2.0.0", path = "../../primitives/io" } +sp-core = { version = "2.0.0", path = "../../primitives/core" } +sp-trie = { version = "2.0.0", path = "../../primitives/trie" } +sp-serializer = { version = "2.0.0", path = "../../primitives/serializer" } +sp-version = { version = "2.0.0", path = "../../primitives/version" } +sp-panic-handler = { version = "2.0.0", path = "../../primitives/panic-handler" } wasmi = "0.6.2" -parity-wasm = "0.40.3" +parity-wasm = "0.41.0" lazy_static = "1.4.0" -wasm-interface = { package = "substrate-wasm-interface", path = "../../primitives/wasm-interface" } -runtime-interface = { package = "substrate-runtime-interface", path = "../../primitives/runtime-interface" } -externalities = { package = "substrate-externalities", path = "../../primitives/externalities" } +sp-wasm-interface = { version = "2.0.0", path = "../../primitives/wasm-interface" } +sp-runtime-interface = { version = "2.0.0", path = "../../primitives/runtime-interface" } +sp-externalities = { version = "2.0.0", path = "../../primitives/externalities" } parking_lot = "0.9.0" log = "0.4.8" libsecp256k1 = "0.3.2" @@ -36,12 +36,9 @@ wasmtime-runtime = { version = "0.8", optional = true } assert_matches = "1.3.0" wabt = "0.9.2" hex-literal = "0.2.1" -runtime-test = { package = "substrate-runtime-test", path = "runtime-test" } -test-runtime = { package = "substrate-test-runtime", path = "../../test/utils/runtime" } -runtime-interface = { package = "substrate-runtime-interface", path = "../../primitives/runtime-interface" } -client-api = { package = "substrate-client-api", path = "../api" } -substrate-offchain = { path = "../offchain/" } -state_machine = { package = "substrate-state-machine", path = "../../primitives/state-machine" } +sc-runtime-test = { version = "2.0.0", path = "runtime-test" } +substrate-test-runtime = { version = "2.0.0", path = "../../test-utils/runtime" } +sp-state-machine = { version = "2.0.0", path = "../../primitives/state-machine" } test-case = "0.3.3" [features] diff --git a/client/executor/runtime-test/Cargo.toml b/client/executor/runtime-test/Cargo.toml index 610db4545800e65fba1ae6d7dd83eb6bd9e59c8b..ba88550a92ef7dfd1f502229a7ae84778296ca1c 100644 --- a/client/executor/runtime-test/Cargo.toml +++ b/client/executor/runtime-test/Cargo.toml @@ -1,20 +1,20 @@ [package] -name = "substrate-runtime-test" +name = "sc-runtime-test" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" build = "build.rs" [dependencies] -rstd = { package = "sr-std", path = "../../../primitives/sr-std", default-features = false } -runtime_io = { package = "sr-io", path = "../../../primitives/sr-io", default-features = false } -sandbox = { package = "sr-sandbox", path = "../../../primitives/sr-sandbox", default-features = false } -primitives = { package = "substrate-primitives", path = "../../../primitives/core", default-features = false } -sr-primitives = { package = "sr-primitives", path = "../../../primitives/sr-primitives", default-features = false } +sp-std = { version = "2.0.0", default-features = false, path = "../../../primitives/std" } +sp-io = { version = "2.0.0", default-features = false, path = "../../../primitives/io" } +sp-sandbox = { version = "2.0.0", default-features = false, path = "../../../primitives/sandbox" } +sp-core = { version = "2.0.0", default-features = false, path = "../../../primitives/core" } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../../primitives/runtime" } [build-dependencies] -wasm-builder-runner = { package = "substrate-wasm-builder-runner", path = "../../../client/utils/wasm-builder-runner", version = "1.0.4" } +wasm-builder-runner = { version = "1.0.4", package = "substrate-wasm-builder-runner", path = "../../../utils/wasm-builder-runner" } [features] default = [ "std" ] -std = ["runtime_io/std", "sandbox/std", "rstd/std"] +std = ["sp-io/std", "sp-sandbox/std", "sp-std/std"] diff --git a/client/executor/runtime-test/src/lib.rs b/client/executor/runtime-test/src/lib.rs index 16c6c353d9e372211f4aa2e4eb9de5772dfa31d6..c49b9e70b4f85711830f3e6ecec839e67949efb7 100644 --- a/client/executor/runtime-test/src/lib.rs +++ b/client/executor/runtime-test/src/lib.rs @@ -6,19 +6,19 @@ include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); #[cfg(not(feature = "std"))] -use rstd::{vec::Vec, vec}; +use sp_std::{vec::Vec, vec}; #[cfg(not(feature = "std"))] -use runtime_io::{ - storage, hashing::{blake2_128, blake2_256, twox_128, twox_256}, +use sp_io::{ + storage, hashing::{blake2_128, blake2_256, sha2_256, twox_128, twox_256}, crypto::{ed25519_verify, sr25519_verify}, }; #[cfg(not(feature = "std"))] -use sr_primitives::{print, traits::{BlakeTwo256, Hash}}; +use sp_runtime::{print, traits::{BlakeTwo256, Hash}}; #[cfg(not(feature = "std"))] -use primitives::{ed25519, sr25519}; +use sp_core::{ed25519, sr25519}; -primitives::wasm_export_functions! { +sp_core::wasm_export_functions! { fn test_data_in(input: Vec) -> Vec { print("set_storage"); storage::set(b"input", &input); @@ -60,6 +60,10 @@ primitives::wasm_export_functions! { blake2_128(&input).to_vec() } + fn test_sha2_256(input: Vec) -> Vec { + sha2_256(&input).to_vec() + } + fn test_twox_256(input: Vec) -> Vec { twox_256(&input).to_vec() } @@ -108,8 +112,8 @@ primitives::wasm_export_functions! { execute_sandboxed( &code, &[ - sandbox::TypedValue::I32(0x12345678), - sandbox::TypedValue::I64(0x1234567887654321), + sp_sandbox::TypedValue::I32(0x12345678), + sp_sandbox::TypedValue::I64(0x1234567887654321), ], ).is_ok() } @@ -118,10 +122,10 @@ primitives::wasm_export_functions! { let ok = match execute_sandboxed( &code, &[ - sandbox::TypedValue::I32(0x1336), + sp_sandbox::TypedValue::I32(0x1336), ] ) { - Ok(sandbox::ReturnValue::Value(sandbox::TypedValue::I32(0x1337))) => true, + Ok(sp_sandbox::ReturnValue::Value(sp_sandbox::TypedValue::I32(0x1337))) => true, _ => false, }; @@ -129,62 +133,62 @@ primitives::wasm_export_functions! { } fn test_sandbox_instantiate(code: Vec) -> u8 { - let env_builder = sandbox::EnvironmentDefinitionBuilder::new(); - let code = match sandbox::Instance::new(&code, &env_builder, &mut ()) { + let env_builder = sp_sandbox::EnvironmentDefinitionBuilder::new(); + let code = match sp_sandbox::Instance::new(&code, &env_builder, &mut ()) { Ok(_) => 0, - Err(sandbox::Error::Module) => 1, - Err(sandbox::Error::Execution) => 2, - Err(sandbox::Error::OutOfBounds) => 3, + Err(sp_sandbox::Error::Module) => 1, + Err(sp_sandbox::Error::Execution) => 2, + Err(sp_sandbox::Error::OutOfBounds) => 3, }; code } fn test_offchain_local_storage() -> bool { - let kind = primitives::offchain::StorageKind::PERSISTENT; - assert_eq!(runtime_io::offchain::local_storage_get(kind, b"test"), None); - runtime_io::offchain::local_storage_set(kind, b"test", b"asd"); - assert_eq!(runtime_io::offchain::local_storage_get(kind, b"test"), Some(b"asd".to_vec())); + let kind = sp_core::offchain::StorageKind::PERSISTENT; + assert_eq!(sp_io::offchain::local_storage_get(kind, b"test"), None); + sp_io::offchain::local_storage_set(kind, b"test", b"asd"); + assert_eq!(sp_io::offchain::local_storage_get(kind, b"test"), Some(b"asd".to_vec())); - let res = runtime_io::offchain::local_storage_compare_and_set( + let res = sp_io::offchain::local_storage_compare_and_set( kind, b"test", Some(b"asd".to_vec()), b"", ); - assert_eq!(runtime_io::offchain::local_storage_get(kind, b"test"), Some(b"".to_vec())); + assert_eq!(sp_io::offchain::local_storage_get(kind, b"test"), Some(b"".to_vec())); res } fn test_offchain_local_storage_with_none() { - let kind = primitives::offchain::StorageKind::PERSISTENT; - assert_eq!(runtime_io::offchain::local_storage_get(kind, b"test"), None); + let kind = sp_core::offchain::StorageKind::PERSISTENT; + assert_eq!(sp_io::offchain::local_storage_get(kind, b"test"), None); - let res = runtime_io::offchain::local_storage_compare_and_set(kind, b"test", None, b"value"); + let res = sp_io::offchain::local_storage_compare_and_set(kind, b"test", None, b"value"); assert_eq!(res, true); - assert_eq!(runtime_io::offchain::local_storage_get(kind, b"test"), Some(b"value".to_vec())); + assert_eq!(sp_io::offchain::local_storage_get(kind, b"test"), Some(b"value".to_vec())); } fn test_offchain_http() -> bool { - use primitives::offchain::HttpRequestStatus; + use sp_core::offchain::HttpRequestStatus; let run = || -> Option<()> { - let id = runtime_io::offchain::http_request_start( + let id = sp_io::offchain::http_request_start( "POST", "http://localhost:12345", &[], ).ok()?; - runtime_io::offchain::http_request_add_header(id, "X-Auth", "test").ok()?; - runtime_io::offchain::http_request_write_body(id, &[1, 2, 3, 4], None).ok()?; - runtime_io::offchain::http_request_write_body(id, &[], None).ok()?; - let status = runtime_io::offchain::http_response_wait(&[id], None); + sp_io::offchain::http_request_add_header(id, "X-Auth", "test").ok()?; + sp_io::offchain::http_request_write_body(id, &[1, 2, 3, 4], None).ok()?; + sp_io::offchain::http_request_write_body(id, &[], None).ok()?; + let status = sp_io::offchain::http_response_wait(&[id], None); assert!(status == vec![HttpRequestStatus::Finished(200)], "Expected Finished(200) status."); - let headers = runtime_io::offchain::http_response_headers(id); + let headers = sp_io::offchain::http_response_headers(id); assert_eq!(headers, vec![(b"X-Auth".to_vec(), b"hello".to_vec())]); let mut buffer = vec![0; 64]; - let read = runtime_io::offchain::http_response_read_body(id, &mut buffer, None).ok()?; + let read = sp_io::offchain::http_response_read_body(id, &mut buffer, None).ok()?; assert_eq!(read, 3); assert_eq!(&buffer[0..read as usize], &[1, 2, 3]); - let read = runtime_io::offchain::http_response_read_body(id, &mut buffer, None).ok()?; + let read = sp_io::offchain::http_response_read_body(id, &mut buffer, None).ok()?; assert_eq!(read, 0); Some(()) @@ -197,45 +201,45 @@ primitives::wasm_export_functions! { #[cfg(not(feature = "std"))] fn execute_sandboxed( code: &[u8], - args: &[sandbox::TypedValue], -) -> Result { + args: &[sp_sandbox::TypedValue], +) -> Result { struct State { counter: u32, } fn env_assert( _e: &mut State, - args: &[sandbox::TypedValue], - ) -> Result { + args: &[sp_sandbox::TypedValue], + ) -> Result { if args.len() != 1 { - return Err(sandbox::HostError); + return Err(sp_sandbox::HostError); } - let condition = args[0].as_i32().ok_or_else(|| sandbox::HostError)?; + let condition = args[0].as_i32().ok_or_else(|| sp_sandbox::HostError)?; if condition != 0 { - Ok(sandbox::ReturnValue::Unit) + Ok(sp_sandbox::ReturnValue::Unit) } else { - Err(sandbox::HostError) + Err(sp_sandbox::HostError) } } fn env_inc_counter( e: &mut State, - args: &[sandbox::TypedValue], - ) -> Result { + args: &[sp_sandbox::TypedValue], + ) -> Result { if args.len() != 1 { - return Err(sandbox::HostError); + return Err(sp_sandbox::HostError); } - let inc_by = args[0].as_i32().ok_or_else(|| sandbox::HostError)?; + let inc_by = args[0].as_i32().ok_or_else(|| sp_sandbox::HostError)?; e.counter += inc_by as u32; - Ok(sandbox::ReturnValue::Value(sandbox::TypedValue::I32(e.counter as i32))) + Ok(sp_sandbox::ReturnValue::Value(sp_sandbox::TypedValue::I32(e.counter as i32))) } let mut state = State { counter: 0 }; let env_builder = { - let mut env_builder = sandbox::EnvironmentDefinitionBuilder::new(); + let mut env_builder = sp_sandbox::EnvironmentDefinitionBuilder::new(); env_builder.add_host_func("env", "assert", env_assert); env_builder.add_host_func("env", "inc_counter", env_inc_counter); - let memory = match sandbox::Memory::new(1, Some(16)) { + let memory = match sp_sandbox::Memory::new(1, Some(16)) { Ok(m) => m, Err(_) => unreachable!(" Memory::new() can return Err only if parameters are borked; \ @@ -247,8 +251,8 @@ fn execute_sandboxed( env_builder }; - let mut instance = sandbox::Instance::new(code, &env_builder, &mut state)?; + let mut instance = sp_sandbox::Instance::new(code, &env_builder, &mut state)?; let result = instance.invoke("call", args, &mut state); - result.map_err(|_| sandbox::HostError) + result.map_err(|_| sp_sandbox::HostError) } diff --git a/client/executor/src/allocator.rs b/client/executor/src/allocator.rs index 523499db71c6bdb13979b40d1ee198659fd995ab..88624a0ec2289c132f41274bd7295a638e949904 100644 --- a/client/executor/src/allocator.rs +++ b/client/executor/src/allocator.rs @@ -50,7 +50,7 @@ use crate::error::{Error, Result}; use log::trace; use std::convert::{TryFrom, TryInto}; use std::ops::Range; -use wasm_interface::{Pointer, WordSize}; +use sp_wasm_interface::{Pointer, WordSize}; // The pointers need to be aligned to 8 bytes. This is because the // maximum value type handled by wasm32 is u64. diff --git a/client/executor/src/deprecated_host_interface.rs b/client/executor/src/deprecated_host_interface.rs index 223b13367aa87d1b12f5268702e4088e81e4a082..2339dcdf70f280b11bc4ef2dd59bffba9f839282 100644 --- a/client/executor/src/deprecated_host_interface.rs +++ b/client/executor/src/deprecated_host_interface.rs @@ -18,12 +18,12 @@ use codec::Encode; use std::{convert::TryFrom, str}; -use primitives::{ +use sp_core::{ blake2_128, blake2_256, twox_64, twox_128, twox_256, ed25519, sr25519, keccak_256, Blake2Hasher, Pair, crypto::KeyTypeId, offchain, }; -use trie::{TrieConfiguration, trie_types::Layout}; -use wasm_interface::{ +use sp_trie::{TrieConfiguration, trie_types::Layout}; +use sp_wasm_interface::{ Pointer, WordSize, WritePrimitive, ReadPrimitive, FunctionContext, Result as WResult, }; @@ -79,13 +79,13 @@ impl_wasm_host_interface! { impl SubstrateExternals where context { ext_malloc(size: WordSize) -> Pointer { let r = context.allocate_memory(size)?; - debug_trace!(target: "sr-io", "malloc {} bytes at {:?}", size, r); + debug_trace!(target: "sp-io", "malloc {} bytes at {:?}", size, r); Ok(r) } ext_free(addr: Pointer) { context.deallocate_memory(addr)?; - debug_trace!(target: "sr-io", "free {:?}", addr); + debug_trace!(target: "sp-io", "free {:?}", addr); Ok(()) } @@ -168,20 +168,20 @@ impl_wasm_host_interface! { ext_print_utf8(utf8_data: Pointer, utf8_len: WordSize) { if let Ok(utf8) = context.read_memory(utf8_data, utf8_len) { - runtime_io::misc::print_utf8(&utf8); + sp_io::misc::print_utf8(&utf8); } Ok(()) } ext_print_hex(data: Pointer, len: WordSize) { if let Ok(hex) = context.read_memory(data, len) { - runtime_io::misc::print_hex(&hex); + sp_io::misc::print_hex(&hex); } Ok(()) } ext_print_num(number: u64) { - runtime_io::misc::print_num(number); + sp_io::misc::print_num(number); Ok(()) } @@ -200,7 +200,7 @@ impl_wasm_host_interface! { let target_str = std::str::from_utf8(&target) .map_err(|_| "Target invalid utf8 in ext_log")?; - runtime_io::logging::log(level.into(), &target_str, &message); + sp_io::logging::log(level.into(), &target_str, &message); Ok(()) } @@ -214,90 +214,25 @@ impl_wasm_host_interface! { .map_err(|_| "Invalid attempt to determine key in ext_set_storage")?; let value = context.read_memory(value_data, value_len) .map_err(|_| "Invalid attempt to determine value in ext_set_storage")?; - Ok(runtime_io::storage::set(&key, &value)) - } - - ext_set_child_storage( - storage_key_data: Pointer, - storage_key_len: WordSize, - key_data: Pointer, - key_len: WordSize, - value_data: Pointer, - value_len: WordSize, - ) { - let storage_key = context.read_memory(storage_key_data, storage_key_len) - .map_err(|_| "Invalid attempt to determine storage_key in ext_set_child_storage")?; - let key = context.read_memory(key_data, key_len) - .map_err(|_| "Invalid attempt to determine key in ext_set_child_storage")?; - let value = context.read_memory(value_data, value_len) - .map_err(|_| "Invalid attempt to determine value in ext_set_child_storage")?; - - Ok(runtime_io::storage::child_set(&storage_key, &key, &value)) - } - - ext_clear_child_storage( - storage_key_data: Pointer, - storage_key_len: WordSize, - key_data: Pointer, - key_len: WordSize, - ) { - let storage_key = context.read_memory(storage_key_data, storage_key_len) - .map_err(|_| "Invalid attempt to determine storage_key in ext_clear_child_storage")?; - let key = context.read_memory(key_data, key_len) - .map_err(|_| "Invalid attempt to determine key in ext_clear_child_storage")?; - - Ok(runtime_io::storage::child_clear(&storage_key, &key)) + Ok(sp_io::storage::set(&key, &value)) } ext_clear_storage(key_data: Pointer, key_len: WordSize) { let key = context.read_memory(key_data, key_len) .map_err(|_| "Invalid attempt to determine key in ext_clear_storage")?; - Ok(runtime_io::storage::clear(&key)) + Ok(sp_io::storage::clear(&key)) } ext_exists_storage(key_data: Pointer, key_len: WordSize) -> u32 { let key = context.read_memory(key_data, key_len) .map_err(|_| "Invalid attempt to determine key in ext_exists_storage")?; - Ok(if runtime_io::storage::exists(&key) { 1 } else { 0 }) - } - - ext_exists_child_storage( - storage_key_data: Pointer, - storage_key_len: WordSize, - key_data: Pointer, - key_len: WordSize, - ) -> u32 { - let storage_key = context.read_memory(storage_key_data, storage_key_len) - .map_err(|_| "Invalid attempt to determine storage_key in ext_exists_child_storage")?; - let key = context.read_memory(key_data, key_len) - .map_err(|_| "Invalid attempt to determine key in ext_exists_child_storage")?; - - Ok(if runtime_io::storage::child_exists(&storage_key, &key) { 1 } else { 0 }) + Ok(if sp_io::storage::exists(&key) { 1 } else { 0 }) } ext_clear_prefix(prefix_data: Pointer, prefix_len: WordSize) { let prefix = context.read_memory(prefix_data, prefix_len) .map_err(|_| "Invalid attempt to determine prefix in ext_clear_prefix")?; - Ok(runtime_io::storage::clear_prefix(&prefix)) - } - - ext_clear_child_prefix( - storage_key_data: Pointer, - storage_key_len: WordSize, - prefix_data: Pointer, - prefix_len: WordSize, - ) { - let storage_key = context.read_memory(storage_key_data, storage_key_len) - .map_err(|_| "Invalid attempt to determine storage_key in ext_clear_child_prefix")?; - let prefix = context.read_memory(prefix_data, prefix_len) - .map_err(|_| "Invalid attempt to determine prefix in ext_clear_child_prefix")?; - Ok(runtime_io::storage::child_clear_prefix(&storage_key, &prefix)) - } - - ext_kill_child_storage(storage_key_data: Pointer, storage_key_len: WordSize) { - let storage_key = context.read_memory(storage_key_data, storage_key_len) - .map_err(|_| "Invalid attempt to determine storage_key in ext_kill_child_storage")?; - Ok(runtime_io::storage::child_storage_kill(&storage_key)) + Ok(sp_io::storage::clear_prefix(&prefix)) } ext_get_allocated_storage( @@ -308,7 +243,7 @@ impl_wasm_host_interface! { let key = context.read_memory(key_data, key_len) .map_err(|_| "Invalid attempt to determine key in ext_get_allocated_storage")?; - if let Some(value) = runtime_io::storage::get(&key) { + if let Some(value) = sp_io::storage::get(&key) { let offset = context.allocate_memory(value.len() as u32)?; context.write_memory(offset, &value) .map_err(|_| "Invalid attempt to set memory in ext_get_allocated_storage")?; @@ -322,32 +257,6 @@ impl_wasm_host_interface! { } } - ext_get_allocated_child_storage( - storage_key_data: Pointer, - storage_key_len: WordSize, - key_data: Pointer, - key_len: WordSize, - written_out: Pointer, - ) -> Pointer { - let storage_key = context.read_memory(storage_key_data, storage_key_len) - .map_err(|_| "Invalid attempt to determine storage_key in ext_get_allocated_child_storage")?; - let key = context.read_memory(key_data, key_len) - .map_err(|_| "Invalid attempt to determine key in ext_get_allocated_child_storage")?; - - if let Some(value) = runtime_io::storage::child_get(&storage_key, &key) { - let offset = context.allocate_memory(value.len() as u32)?; - context.write_memory(offset, &value) - .map_err(|_| "Invalid attempt to set memory in ext_get_allocated_child_storage")?; - context.write_primitive(written_out, value.len() as u32) - .map_err(|_| "Invalid attempt to write written_out in ext_get_allocated_child_storage")?; - Ok(offset) - } else { - context.write_primitive(written_out, u32::max_value()) - .map_err(|_| "Invalid attempt to write failed written_out in ext_get_allocated_child_storage")?; - Ok(Pointer::null()) - } - } - ext_get_storage_into( key_data: Pointer, key_len: WordSize, @@ -358,7 +267,7 @@ impl_wasm_host_interface! { let key = context.read_memory(key_data, key_len) .map_err(|_| "Invalid attempt to get key in ext_get_storage_into")?; - if let Some(value) = runtime_io::storage::get(&key) { + if let Some(value) = sp_io::storage::get(&key) { let data = &value[value.len().min(value_offset as usize)..]; let written = std::cmp::min(value_len as usize, data.len()); context.write_memory(value_data, &data[..written]) @@ -369,53 +278,11 @@ impl_wasm_host_interface! { } } - ext_get_child_storage_into( - storage_key_data: Pointer, - storage_key_len: WordSize, - key_data: Pointer, - key_len: WordSize, - value_data: Pointer, - value_len: WordSize, - value_offset: WordSize, - ) -> WordSize { - let storage_key = context.read_memory(storage_key_data, storage_key_len) - .map_err(|_| "Invalid attempt to determine storage_key in ext_get_child_storage_into")?; - let key = context.read_memory(key_data, key_len) - .map_err(|_| "Invalid attempt to get key in ext_get_child_storage_into")?; - - if let Some(value) = runtime_io::storage::child_get(&storage_key, &key) { - let data = &value[value.len().min(value_offset as usize)..]; - let written = std::cmp::min(value_len as usize, data.len()); - context.write_memory(value_data, &data[..written]) - .map_err(|_| "Invalid attempt to get value in ext_get_child_storage_into")?; - Ok(value.len() as u32) - } else { - Ok(u32::max_value()) - } - } - ext_storage_root(result: Pointer) { - context.write_memory(result, runtime_io::storage::root().as_ref()) + context.write_memory(result, sp_io::storage::root().as_ref()) .map_err(|_| "Invalid attempt to set memory in ext_storage_root".into()) } - ext_child_storage_root( - storage_key_data: Pointer, - storage_key_len: WordSize, - written_out: Pointer, - ) -> Pointer { - let storage_key = context.read_memory(storage_key_data, storage_key_len) - .map_err(|_| "Invalid attempt to determine storage_key in ext_child_storage_root")?; - let value = runtime_io::storage::child_root(&storage_key); - - let offset = context.allocate_memory(value.len() as u32)?; - context.write_memory(offset, &value) - .map_err(|_| "Invalid attempt to set memory in ext_child_storage_root")?; - context.write_primitive(written_out, value.len() as u32) - .map_err(|_| "Invalid attempt to write written_out in ext_child_storage_root")?; - Ok(offset) - } - ext_storage_changes_root( parent_hash_data: Pointer, _len: WordSize, @@ -425,7 +292,7 @@ impl_wasm_host_interface! { context.read_memory_into(parent_hash_data, &mut parent_hash[..]) .map_err(|_| "Invalid attempt to get parent_hash in ext_storage_changes_root")?; - if let Some(r) = runtime_io::storage::changes_root(parent_hash) { + if let Some(r) = sp_io::storage::changes_root(&parent_hash) { context.write_memory(result, &r[..]) .map_err(|_| "Invalid attempt to set memory in ext_storage_changes_root")?; Ok(1) @@ -459,7 +326,7 @@ impl_wasm_host_interface! { } ext_chain_id() -> u64 { - Ok(runtime_io::misc::chain_id()) + Ok(sp_io::misc::chain_id()) } ext_twox_64(data: Pointer, len: WordSize, out: Pointer) { @@ -555,7 +422,7 @@ impl_wasm_host_interface! { .map_err(|_| "Invalid attempt to get id in ext_ed25519_public_keys")?; let key_type = KeyTypeId(id); - let keys = runtime_io::crypto::ed25519_public_keys(key_type).encode(); + let keys = sp_io::crypto::ed25519_public_keys(key_type).encode(); let len = keys.len() as u32; let offset = context.allocate_memory(len)?; @@ -610,7 +477,7 @@ impl_wasm_host_interface! { ) }; - let pubkey = runtime_io::crypto::ed25519_generate(key_type, seed); + let pubkey = sp_io::crypto::ed25519_generate(key_type, seed); context.write_memory(out, pubkey.as_ref()) .map_err(|_| "Invalid attempt to set out in ext_ed25519_generate".into()) @@ -638,7 +505,7 @@ impl_wasm_host_interface! { let pub_key = ed25519::Public::try_from(pubkey.as_ref()) .map_err(|_| "Invalid `ed25519` public key")?; - let signature = runtime_io::crypto::ed25519_sign(key_type, &pub_key, &msg); + let signature = sp_io::crypto::ed25519_sign(key_type, &pub_key, &msg); match signature { Some(signature) => { @@ -656,7 +523,7 @@ impl_wasm_host_interface! { .map_err(|_| "Invalid attempt to get id in ext_sr25519_public_keys")?; let key_type = KeyTypeId(id); - let keys = runtime_io::crypto::sr25519_public_keys(key_type).encode(); + let keys = sp_io::crypto::sr25519_public_keys(key_type).encode(); let len = keys.len() as u32; let offset = context.allocate_memory(len)?; @@ -710,7 +577,7 @@ impl_wasm_host_interface! { ) }; - let pubkey = runtime_io::crypto::sr25519_generate(key_type, seed); + let pubkey = sp_io::crypto::sr25519_generate(key_type, seed); context.write_memory(out, pubkey.as_ref()) .map_err(|_| "Invalid attempt to set out in ext_sr25519_generate".into()) @@ -738,7 +605,7 @@ impl_wasm_host_interface! { let pub_key = sr25519::Public::try_from(pubkey.as_ref()) .map_err(|_| "Invalid `sr25519` public key")?; - let signature = runtime_io::crypto::sr25519_sign(key_type, &pub_key, &msg); + let signature = sp_io::crypto::sr25519_sign(key_type, &pub_key, &msg); match signature { Some(signature) => { @@ -781,20 +648,20 @@ impl_wasm_host_interface! { } ext_is_validator() -> u32 { - if runtime_io::offchain::is_validator() { Ok(1) } else { Ok(0) } + if sp_io::offchain::is_validator() { Ok(1) } else { Ok(0) } } ext_submit_transaction(msg_data: Pointer, len: WordSize) -> u32 { let extrinsic = context.read_memory(msg_data, len) .map_err(|_| "OOB while ext_submit_transaction: wasm")?; - let res = runtime_io::offchain::submit_transaction(extrinsic); + let res = sp_io::offchain::submit_transaction(extrinsic); Ok(if res.is_ok() { 0 } else { 1 }) } ext_network_state(written_out: Pointer) -> Pointer { - let res = runtime_io::offchain::network_state(); + let res = sp_io::offchain::network_state(); let encoded = res.encode(); let len = encoded.len() as u32; @@ -809,17 +676,17 @@ impl_wasm_host_interface! { } ext_timestamp() -> u64 { - Ok(runtime_io::offchain::timestamp().unix_millis()) + Ok(sp_io::offchain::timestamp().unix_millis()) } ext_sleep_until(deadline: u64) { - runtime_io::offchain::sleep_until(offchain::Timestamp::from_unix_millis(deadline)); + sp_io::offchain::sleep_until(offchain::Timestamp::from_unix_millis(deadline)); Ok(()) } ext_random_seed(seed_data: Pointer) { // NOTE the runtime as assumptions about seed size. - let seed = runtime_io::offchain::random_seed(); + let seed = sp_io::offchain::random_seed(); context.write_memory(seed_data, &seed) .map_err(|_| "Invalid attempt to set value in ext_random_seed")?; @@ -840,7 +707,7 @@ impl_wasm_host_interface! { let value = context.read_memory(value, value_len) .map_err(|_| "OOB while ext_local_storage_set: wasm")?; - runtime_io::offchain::local_storage_set(kind, &key, &value); + sp_io::offchain::local_storage_set(kind, &key, &value); Ok(()) } @@ -856,7 +723,7 @@ impl_wasm_host_interface! { let key = context.read_memory(key, key_len) .map_err(|_| "OOB while ext_local_storage_get: wasm")?; - let maybe_value = runtime_io::offchain::local_storage_get(kind, &key); + let maybe_value = sp_io::offchain::local_storage_get(kind, &key); let (offset, len) = if let Some(value) = maybe_value { let offset = context.allocate_memory(value.len() as u32)?; @@ -898,7 +765,7 @@ impl_wasm_host_interface! { ) }; - let res = runtime_io::offchain::local_storage_compare_and_set( + let res = sp_io::offchain::local_storage_compare_and_set( kind, &key, old_value, @@ -928,7 +795,7 @@ impl_wasm_host_interface! { let url_str = str::from_utf8(&url) .map_err(|_| "invalid str while ext_http_request_start: wasm")?; - let id = runtime_io::offchain::http_request_start(method_str, url_str, &meta); + let id = sp_io::offchain::http_request_start(method_str, url_str, &meta); if let Ok(id) = id { Ok(id.into()) @@ -954,7 +821,7 @@ impl_wasm_host_interface! { let value_str = str::from_utf8(&value) .map_err(|_| "Invalid str while ext_http_request_add_header: wasm")?; - let res = runtime_io::offchain::http_request_add_header( + let res = sp_io::offchain::http_request_add_header( offchain::HttpRequestId(request_id as u16), name_str, value_str, @@ -972,7 +839,7 @@ impl_wasm_host_interface! { let chunk = context.read_memory(chunk, chunk_len) .map_err(|_| "OOB while ext_http_request_write_body: wasm")?; - let res = runtime_io::offchain::http_request_write_body( + let res = sp_io::offchain::http_request_write_body( offchain::HttpRequestId(request_id as u16), &chunk, deadline_to_timestamp(deadline), @@ -998,7 +865,7 @@ impl_wasm_host_interface! { ) .collect::, _>>()?; - let res = runtime_io::offchain::http_response_wait(&ids, deadline_to_timestamp(deadline)) + let res = sp_io::offchain::http_response_wait(&ids, deadline_to_timestamp(deadline)) .into_iter() .map(|status| u32::from(status)) .enumerate() @@ -1019,7 +886,7 @@ impl_wasm_host_interface! { ) -> Pointer { use codec::Encode; - let headers = runtime_io::offchain::http_response_headers( + let headers = sp_io::offchain::http_response_headers( offchain::HttpRequestId(request_id as u16), ); @@ -1044,7 +911,7 @@ impl_wasm_host_interface! { let mut internal_buffer = Vec::with_capacity(buffer_len as usize); internal_buffer.resize(buffer_len as usize, 0); - let res = runtime_io::offchain::http_response_read_body( + let res = sp_io::offchain::http_response_read_body( offchain::HttpRequestId(request_id as u16), &mut internal_buffer, deadline_to_timestamp(deadline), @@ -1072,4 +939,3 @@ fn deadline_to_timestamp(deadline: u64) -> Option { Some(offchain::Timestamp::from_unix_millis(deadline)) } } - diff --git a/client/executor/src/error.rs b/client/executor/src/error.rs index 58a84e09902e9f3b83b5fedc311e426777143d83..a15452c48b4781ec6ab34e1da51fbdb0591273be 100644 --- a/client/executor/src/error.rs +++ b/client/executor/src/error.rs @@ -16,7 +16,7 @@ //! Rust executor possible errors. -use serializer; +use sp_serializer; use wasmi; #[cfg(feature = "wasmtime")] use wasmtime_jit::{ActionError, SetupError}; @@ -28,7 +28,7 @@ pub type Result = std::result::Result; #[derive(Debug, derive_more::Display, derive_more::From)] pub enum Error { /// Unserializable Data - InvalidData(serializer::Error), + InvalidData(sp_serializer::Error), /// Trap occured during execution Trap(wasmi::Trap), /// Wasmi loading/instantiating error @@ -37,12 +37,15 @@ pub enum Error { #[cfg(feature = "wasmtime")] Wasmtime(ActionError), /// Error in the API. Parameter is an error message. + #[from(ignore)] ApiError(String), /// Method is not found #[display(fmt="Method not found: '{}'", _0)] + #[from(ignore)] MethodNotFound(String), /// Code is invalid (expected single byte) #[display(fmt="Invalid Code: {}", _0)] + #[from(ignore)] InvalidCode(String), /// Could not get runtime version. #[display(fmt="On-chain runtime does not specify version")] @@ -70,6 +73,7 @@ pub enum Error { #[display(fmt="The runtime has the `start` function")] RuntimeHasStartFn, /// Some other error occurred + #[from(ignore)] Other(String), /// Some error occurred in the allocator #[display(fmt="Error in allocator: {}", _0)] diff --git a/client/executor/src/host_interface.rs b/client/executor/src/host_interface.rs deleted file mode 100644 index 0499cad5663ce98cf2db15d53f3d8ffdc355302f..0000000000000000000000000000000000000000 --- a/client/executor/src/host_interface.rs +++ /dev/null @@ -1,1075 +0,0 @@ -// Copyright 2017-2019 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate 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. - -// Substrate 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 Substrate. If not, see . - -//! Definition and implementation of the old and deprecated Substrate runtime interface for the host. - -use codec::Encode; -use std::{convert::TryFrom, str}; -use primitives::{ - blake2_128, blake2_256, twox_64, twox_128, twox_256, ed25519, sr25519, Blake2Hasher, Pair, - crypto::KeyTypeId, offchain, -}; -use trie::{TrieConfiguration, trie_types::Layout}; -use wasm_interface::{ - Pointer, WordSize, WritePrimitive, ReadPrimitive, FunctionContext, Result as WResult, -}; - -#[cfg(feature="wasm-extern-trace")] -macro_rules! debug_trace { - ( $( $x:tt )* ) => ( trace!( $( $x )* ) ) -} - -#[cfg(not(feature="wasm-extern-trace"))] -macro_rules! debug_trace { - ( $( $x:tt )* ) => () -} - -/// The old and deprecated Substrate externals. These are still required for backwards compatibility -/// reasons. -pub struct SubstrateExternals; - -enum RecoverResult { - Invalid(u32), - Valid(secp256k1::PublicKey), -} - -fn secp256k1_recover( - context: &mut dyn FunctionContext, - msg_data: Pointer, - sig_data: Pointer, -) -> WResult { - let mut sig = [0u8; 65]; - context.read_memory_into(sig_data, &mut sig[..]) - .map_err(|_| "Invalid attempt to get signature in ext_secp256k1_ecdsa_recover")?; - let rs = match secp256k1::Signature::parse_slice(&sig[0..64]) { - Ok(rs) => rs, - _ => return Ok(RecoverResult::Invalid(1)), - }; - - let recovery_id = if sig[64] > 26 { sig[64] - 27 } else { sig[64] } as u8; - let v = match secp256k1::RecoveryId::parse(recovery_id) { - Ok(v) => v, - _ => return Ok(RecoverResult::Invalid(2)), - }; - - let mut msg = [0u8; 32]; - context.read_memory_into(msg_data, &mut msg[..]) - .map_err(|_| "Invalid attempt to get message in ext_secp256k1_ecdsa_recover")?; - - Ok(match secp256k1::recover(&secp256k1::Message::parse(&msg), &rs, &v) { - Ok(pubkey) => RecoverResult::Valid(pubkey), - Err(_) => RecoverResult::Invalid(3), - }) -} - -impl_wasm_host_interface! { - impl SubstrateExternals where context { - ext_malloc(size: WordSize) -> Pointer { - let r = context.allocate_memory(size)?; - debug_trace!(target: "sr-io", "malloc {} bytes at {:?}", size, r); - Ok(r) - } - - ext_free(addr: Pointer) { - context.deallocate_memory(addr)?; - debug_trace!(target: "sr-io", "free {:?}", addr); - Ok(()) - } - - ext_sandbox_instantiate( - dispatch_thunk_idx: u32, - wasm_ptr: Pointer, - wasm_len: WordSize, - imports_ptr: Pointer, - imports_len: WordSize, - state: u32, - ) -> u32 { - let wasm = context.read_memory(wasm_ptr, wasm_len) - .map_err(|_| "OOB while ext_sandbox_instantiate: wasm")?; - let raw_env_def = context.read_memory(imports_ptr, imports_len) - .map_err(|_| "OOB while ext_sandbox_instantiate: imports")?; - - context.sandbox().instance_new(dispatch_thunk_idx, &wasm, &raw_env_def, state) - } - - ext_sandbox_instance_teardown(instance_idx: u32) { - context.sandbox().instance_teardown(instance_idx) - } - - ext_sandbox_invoke( - instance_idx: u32, - export_ptr: Pointer, - export_len: WordSize, - args_ptr: Pointer, - args_len: WordSize, - return_val_ptr: Pointer, - return_val_len: WordSize, - state: u32, - ) -> u32 { - let export = context.read_memory(export_ptr, export_len) - .map_err(|_| "OOB while ext_sandbox_invoke: export") - .and_then(|b| - String::from_utf8(b) - .map_err(|_| "Export name should be a valid utf-8 sequence") - )?; - - // Deserialize arguments and convert them into wasmi types. - let serialized_args = context.read_memory(args_ptr, args_len) - .map_err(|_| "OOB while ext_sandbox_invoke: args")?; - - context.sandbox().invoke( - instance_idx, - &export, - &serialized_args, - return_val_ptr, - return_val_len, - state, - ) - } - - ext_sandbox_memory_new(initial: WordSize, maximum: WordSize) -> u32 { - context.sandbox().memory_new(initial, maximum) - } - - ext_sandbox_memory_get( - memory_idx: u32, - offset: WordSize, - buf_ptr: Pointer, - buf_len: WordSize, - ) -> u32 { - context.sandbox().memory_get(memory_idx, offset, buf_ptr, buf_len) - } - - ext_sandbox_memory_set( - memory_idx: u32, - offset: WordSize, - val_ptr: Pointer, - val_len: WordSize, - ) -> u32 { - context.sandbox().memory_set(memory_idx, offset, val_ptr, val_len) - } - - ext_sandbox_memory_teardown(memory_idx: u32) { - context.sandbox().memory_teardown(memory_idx) - } - - ext_print_utf8(utf8_data: Pointer, utf8_len: WordSize) { - if let Ok(utf8) = context.read_memory(utf8_data, utf8_len) { - runtime_io::misc::print_utf8(&utf8); - } - Ok(()) - } - - ext_print_hex(data: Pointer, len: WordSize) { - if let Ok(hex) = context.read_memory(data, len) { - runtime_io::misc::print_hex(&hex); - } - Ok(()) - } - - ext_print_num(number: u64) { - runtime_io::misc::print_num(number); - Ok(()) - } - - ext_log( - level: u32, - target_data: Pointer, - target_len: WordSize, - message_data: Pointer, - message_len: WordSize, - ) { - let target = context.read_memory(target_data, target_len) - .map_err(|_| "Invalid attempt to determine target in ext_log")?; - let message = context.read_memory(message_data, message_len) - .map_err(|_| "Invalid attempt to determine message in ext_log")?; - - let target_str = std::str::from_utf8(&target) - .map_err(|_| "Target invalid utf8 in ext_log")?; - - runtime_io::logging::log(level.into(), &target_str, &message); - Ok(()) - } - - ext_set_storage( - key_data: Pointer, - key_len: WordSize, - value_data: Pointer, - value_len: WordSize, - ) { - let key = context.read_memory(key_data, key_len) - .map_err(|_| "Invalid attempt to determine key in ext_set_storage")?; - let value = context.read_memory(value_data, value_len) - .map_err(|_| "Invalid attempt to determine value in ext_set_storage")?; - Ok(runtime_io::storage::set(&key, &value)) - } - - ext_set_child_storage( - storage_key_data: Pointer, - storage_key_len: WordSize, - key_data: Pointer, - key_len: WordSize, - value_data: Pointer, - value_len: WordSize, - ) { - let storage_key = context.read_memory(storage_key_data, storage_key_len) - .map_err(|_| "Invalid attempt to determine storage_key in ext_set_child_storage")?; - let key = context.read_memory(key_data, key_len) - .map_err(|_| "Invalid attempt to determine key in ext_set_child_storage")?; - let value = context.read_memory(value_data, value_len) - .map_err(|_| "Invalid attempt to determine value in ext_set_child_storage")?; - - Ok(runtime_io::storage::child_set(&storage_key, &key, &value)) - } - - ext_clear_child_storage( - storage_key_data: Pointer, - storage_key_len: WordSize, - key_data: Pointer, - key_len: WordSize, - ) { - let storage_key = context.read_memory(storage_key_data, storage_key_len) - .map_err(|_| "Invalid attempt to determine storage_key in ext_clear_child_storage")?; - let key = context.read_memory(key_data, key_len) - .map_err(|_| "Invalid attempt to determine key in ext_clear_child_storage")?; - - Ok(runtime_io::storage::child_clear(&storage_key, &key)) - } - - ext_clear_storage(key_data: Pointer, key_len: WordSize) { - let key = context.read_memory(key_data, key_len) - .map_err(|_| "Invalid attempt to determine key in ext_clear_storage")?; - Ok(runtime_io::storage::clear(&key)) - } - - ext_exists_storage(key_data: Pointer, key_len: WordSize) -> u32 { - let key = context.read_memory(key_data, key_len) - .map_err(|_| "Invalid attempt to determine key in ext_exists_storage")?; - Ok(if runtime_io::storage::exists(&key) { 1 } else { 0 }) - } - - ext_exists_child_storage( - storage_key_data: Pointer, - storage_key_len: WordSize, - key_data: Pointer, - key_len: WordSize, - ) -> u32 { - let storage_key = context.read_memory(storage_key_data, storage_key_len) - .map_err(|_| "Invalid attempt to determine storage_key in ext_exists_child_storage")?; - let key = context.read_memory(key_data, key_len) - .map_err(|_| "Invalid attempt to determine key in ext_exists_child_storage")?; - - Ok(if runtime_io::storage::child_exists(&storage_key, &key) { 1 } else { 0 }) - } - - ext_clear_prefix(prefix_data: Pointer, prefix_len: WordSize) { - let prefix = context.read_memory(prefix_data, prefix_len) - .map_err(|_| "Invalid attempt to determine prefix in ext_clear_prefix")?; - Ok(runtime_io::storage::clear_prefix(&prefix)) - } - - ext_clear_child_prefix( - storage_key_data: Pointer, - storage_key_len: WordSize, - prefix_data: Pointer, - prefix_len: WordSize, - ) { - let storage_key = context.read_memory(storage_key_data, storage_key_len) - .map_err(|_| "Invalid attempt to determine storage_key in ext_clear_child_prefix")?; - let prefix = context.read_memory(prefix_data, prefix_len) - .map_err(|_| "Invalid attempt to determine prefix in ext_clear_child_prefix")?; - Ok(runtime_io::storage::child_clear_prefix(&storage_key, &prefix)) - } - - ext_kill_child_storage(storage_key_data: Pointer, storage_key_len: WordSize) { - let storage_key = context.read_memory(storage_key_data, storage_key_len) - .map_err(|_| "Invalid attempt to determine storage_key in ext_kill_child_storage")?; - Ok(runtime_io::storage::child_storage_kill(&storage_key)) - } - - ext_get_allocated_storage( - key_data: Pointer, - key_len: WordSize, - written_out: Pointer, - ) -> Pointer { - let key = context.read_memory(key_data, key_len) - .map_err(|_| "Invalid attempt to determine key in ext_get_allocated_storage")?; - - if let Some(value) = runtime_io::storage::get(&key) { - let offset = context.allocate_memory(value.len() as u32)?; - context.write_memory(offset, &value) - .map_err(|_| "Invalid attempt to set memory in ext_get_allocated_storage")?; - context.write_primitive(written_out, value.len() as u32) - .map_err(|_| "Invalid attempt to write written_out in ext_get_allocated_storage")?; - Ok(offset) - } else { - context.write_primitive(written_out, u32::max_value()) - .map_err(|_| "Invalid attempt to write failed written_out in ext_get_allocated_storage")?; - Ok(Pointer::null()) - } - } - - ext_get_allocated_child_storage( - storage_key_data: Pointer, - storage_key_len: WordSize, - key_data: Pointer, - key_len: WordSize, - written_out: Pointer, - ) -> Pointer { - let storage_key = context.read_memory(storage_key_data, storage_key_len) - .map_err(|_| "Invalid attempt to determine storage_key in ext_get_allocated_child_storage")?; - let key = context.read_memory(key_data, key_len) - .map_err(|_| "Invalid attempt to determine key in ext_get_allocated_child_storage")?; - - if let Some(value) = runtime_io::storage::child_get(&storage_key, &key) { - let offset = context.allocate_memory(value.len() as u32)?; - context.write_memory(offset, &value) - .map_err(|_| "Invalid attempt to set memory in ext_get_allocated_child_storage")?; - context.write_primitive(written_out, value.len() as u32) - .map_err(|_| "Invalid attempt to write written_out in ext_get_allocated_child_storage")?; - Ok(offset) - } else { - context.write_primitive(written_out, u32::max_value()) - .map_err(|_| "Invalid attempt to write failed written_out in ext_get_allocated_child_storage")?; - Ok(Pointer::null()) - } - } - - ext_get_storage_into( - key_data: Pointer, - key_len: WordSize, - value_data: Pointer, - value_len: WordSize, - value_offset: WordSize, - ) -> WordSize { - let key = context.read_memory(key_data, key_len) - .map_err(|_| "Invalid attempt to get key in ext_get_storage_into")?; - - if let Some(value) = runtime_io::storage::get(&key) { - let data = &value[value.len().min(value_offset as usize)..]; - let written = std::cmp::min(value_len as usize, data.len()); - context.write_memory(value_data, &data[..written]) - .map_err(|_| "Invalid attempt to set value in ext_get_storage_into")?; - Ok(value.len() as u32) - } else { - Ok(u32::max_value()) - } - } - - ext_get_child_storage_into( - storage_key_data: Pointer, - storage_key_len: WordSize, - key_data: Pointer, - key_len: WordSize, - value_data: Pointer, - value_len: WordSize, - value_offset: WordSize, - ) -> WordSize { - let storage_key = context.read_memory(storage_key_data, storage_key_len) - .map_err(|_| "Invalid attempt to determine storage_key in ext_get_child_storage_into")?; - let key = context.read_memory(key_data, key_len) - .map_err(|_| "Invalid attempt to get key in ext_get_child_storage_into")?; - - if let Some(value) = runtime_io::storage::child_get(&storage_key, &key) { - let data = &value[value.len().min(value_offset as usize)..]; - let written = std::cmp::min(value_len as usize, data.len()); - context.write_memory(value_data, &data[..written]) - .map_err(|_| "Invalid attempt to get value in ext_get_child_storage_into")?; - Ok(value.len() as u32) - } else { - Ok(u32::max_value()) - } - } - - ext_storage_root(result: Pointer) { - context.write_memory(result, runtime_io::storage::root().as_ref()) - .map_err(|_| "Invalid attempt to set memory in ext_storage_root".into()) - } - - ext_child_storage_root( - storage_key_data: Pointer, - storage_key_len: WordSize, - written_out: Pointer, - ) -> Pointer { - let storage_key = context.read_memory(storage_key_data, storage_key_len) - .map_err(|_| "Invalid attempt to determine storage_key in ext_child_storage_root")?; - let value = runtime_io::storage::child_root(&storage_key); - - let offset = context.allocate_memory(value.len() as u32)?; - context.write_memory(offset, &value) - .map_err(|_| "Invalid attempt to set memory in ext_child_storage_root")?; - context.write_primitive(written_out, value.len() as u32) - .map_err(|_| "Invalid attempt to write written_out in ext_child_storage_root")?; - Ok(offset) - } - - ext_storage_changes_root( - parent_hash_data: Pointer, - _len: WordSize, - result: Pointer, - ) -> u32 { - let mut parent_hash = [0u8; 32]; - context.read_memory_into(parent_hash_data, &mut parent_hash[..]) - .map_err(|_| "Invalid attempt to get parent_hash in ext_storage_changes_root")?; - - if let Some(r) = runtime_io::storage::changes_root(parent_hash) { - context.write_memory(result, &r[..]) - .map_err(|_| "Invalid attempt to set memory in ext_storage_changes_root")?; - Ok(1) - } else { - Ok(0) - } - } - - ext_blake2_256_enumerated_trie_root( - values_data: Pointer, - lens_data: Pointer, - lens_len: WordSize, - result: Pointer, - ) { - let values = (0..lens_len) - .map(|i| context.read_primitive(lens_data.offset(i).ok_or("Pointer overflow")?)) - .collect::, _>>()? - .into_iter() - .scan(0u32, |acc, v| { let o = *acc; *acc += v; Some((o, v)) }) - .map(|(offset, len)| - context.read_memory(values_data.offset(offset).ok_or("Pointer overflow")?, len) - .map_err(|_| - "Invalid attempt to get memory in ext_blake2_256_enumerated_trie_root" - ) - ) - .collect::, _>>()?; - let r = Layout::::ordered_trie_root(values.into_iter()); - context.write_memory(result, &r[..]) - .map_err(|_| "Invalid attempt to set memory in ext_blake2_256_enumerated_trie_root")?; - Ok(()) - } - - ext_chain_id() -> u64 { - Ok(runtime_io::misc::chain_id()) - } - - ext_twox_64(data: Pointer, len: WordSize, out: Pointer) { - let result: [u8; 8] = if len == 0 { - let hashed = twox_64(&[0u8; 0]); - hashed - } else { - let key = context.read_memory(data, len) - .map_err(|_| "Invalid attempt to get key in ext_twox_64")?; - let hashed_key = twox_64(&key); - hashed_key - }; - - context.write_memory(out, &result) - .map_err(|_| "Invalid attempt to set result in ext_twox_64")?; - Ok(()) - } - - ext_twox_128(data: Pointer, len: WordSize, out: Pointer) { - let result: [u8; 16] = if len == 0 { - let hashed = twox_128(&[0u8; 0]); - hashed - } else { - let key = context.read_memory(data, len) - .map_err(|_| "Invalid attempt to get key in ext_twox_128")?; - let hashed_key = twox_128(&key); - hashed_key - }; - - context.write_memory(out, &result) - .map_err(|_| "Invalid attempt to set result in ext_twox_128")?; - Ok(()) - } - - ext_twox_256(data: Pointer, len: WordSize, out: Pointer) { - let result: [u8; 32] = if len == 0 { - twox_256(&[0u8; 0]) - } else { - let mem = context.read_memory(data, len) - .map_err(|_| "Invalid attempt to get data in ext_twox_256")?; - twox_256(&mem) - }; - context.write_memory(out, &result) - .map_err(|_| "Invalid attempt to set result in ext_twox_256")?; - Ok(()) - } - - ext_blake2_128(data: Pointer, len: WordSize, out: Pointer) { - let result: [u8; 16] = if len == 0 { - let hashed = blake2_128(&[0u8; 0]); - hashed - } else { - let key = context.read_memory(data, len) - .map_err(|_| "Invalid attempt to get key in ext_blake2_128")?; - let hashed_key = blake2_128(&key); - hashed_key - }; - - context.write_memory(out, &result) - .map_err(|_| "Invalid attempt to set result in ext_blake2_128")?; - Ok(()) - } - - ext_blake2_256(data: Pointer, len: WordSize, out: Pointer) { - let result: [u8; 32] = if len == 0 { - blake2_256(&[0u8; 0]) - } else { - let mem = context.read_memory(data, len) - .map_err(|_| "Invalid attempt to get data in ext_blake2_256")?; - blake2_256(&mem) - }; - context.write_memory(out, &result) - .map_err(|_| "Invalid attempt to set result in ext_blake2_256")?; - Ok(()) - } - - ext_keccak_256(data: Pointer, len: WordSize, out: Pointer) { - let result: [u8; 32] = if len == 0 { - tiny_keccak::keccak256(&[0u8; 0]) - } else { - let mem = context.read_memory(data, len) - .map_err(|_| "Invalid attempt to get data in ext_keccak_256")?; - tiny_keccak::keccak256(&mem) - }; - context.write_memory(out, &result) - .map_err(|_| "Invalid attempt to set result in ext_keccak_256")?; - Ok(()) - } - - ext_ed25519_public_keys(id_data: Pointer, result_len: Pointer) -> Pointer { - let mut id = [0u8; 4]; - context.read_memory_into(id_data, &mut id[..]) - .map_err(|_| "Invalid attempt to get id in ext_ed25519_public_keys")?; - let key_type = KeyTypeId(id); - - let keys = runtime_io::crypto::ed25519_public_keys(key_type).encode(); - - let len = keys.len() as u32; - let offset = context.allocate_memory(len)?; - - context.write_memory(offset, keys.as_ref()) - .map_err(|_| "Invalid attempt to set memory in ext_ed25519_public_keys")?; - context.write_primitive(result_len, len) - .map_err(|_| "Invalid attempt to write result_len in ext_ed25519_public_keys")?; - - Ok(offset) - } - - ext_ed25519_verify( - msg_data: Pointer, - msg_len: WordSize, - sig_data: Pointer, - pubkey_data: Pointer, - ) -> u32 { - let mut sig = [0u8; 64]; - context.read_memory_into(sig_data, &mut sig[..]) - .map_err(|_| "Invalid attempt to get signature in ext_ed25519_verify")?; - let mut pubkey = [0u8; 32]; - context.read_memory_into(pubkey_data, &mut pubkey[..]) - .map_err(|_| "Invalid attempt to get pubkey in ext_ed25519_verify")?; - let msg = context.read_memory(msg_data, msg_len) - .map_err(|_| "Invalid attempt to get message in ext_ed25519_verify")?; - - Ok(if ed25519::Pair::verify_weak(&sig, &msg, &pubkey) { - 0 - } else { - 1 - }) - } - - ext_ed25519_generate( - id_data: Pointer, - seed: Pointer, - seed_len: WordSize, - out: Pointer, - ) { - let mut id = [0u8; 4]; - context.read_memory_into(id_data, &mut id[..]) - .map_err(|_| "Invalid attempt to get id in ext_ed25519_generate")?; - let key_type = KeyTypeId(id); - - let seed = if seed_len == 0 { - None - } else { - Some( - context.read_memory(seed, seed_len) - .map_err(|_| "Invalid attempt to get seed in ext_ed25519_generate")? - ) - }; - - let pubkey = runtime_io::crypto::ed25519_generate(key_type, seed); - - context.write_memory(out, pubkey.as_ref()) - .map_err(|_| "Invalid attempt to set out in ext_ed25519_generate".into()) - } - - ext_ed25519_sign( - id_data: Pointer, - pubkey_data: Pointer, - msg_data: Pointer, - msg_len: WordSize, - out: Pointer, - ) -> u32 { - let mut id = [0u8; 4]; - context.read_memory_into(id_data, &mut id[..]) - .map_err(|_| "Invalid attempt to get id in ext_ed25519_sign")?; - let key_type = KeyTypeId(id); - - let mut pubkey = [0u8; 32]; - context.read_memory_into(pubkey_data, &mut pubkey[..]) - .map_err(|_| "Invalid attempt to get pubkey in ext_ed25519_sign")?; - - let msg = context.read_memory(msg_data, msg_len) - .map_err(|_| "Invalid attempt to get message in ext_ed25519_sign")?; - - let pub_key = ed25519::Public::try_from(pubkey.as_ref()) - .map_err(|_| "Invalid `ed25519` public key")?; - - let signature = runtime_io::crypto::ed25519_sign(key_type, &pub_key, &msg); - - match signature { - Some(signature) => { - context.write_memory(out, signature.as_ref()) - .map_err(|_| "Invalid attempt to set out in ext_ed25519_sign")?; - Ok(0) - }, - None => Ok(1), - } - } - - ext_sr25519_public_keys(id_data: Pointer, result_len: Pointer) -> Pointer { - let mut id = [0u8; 4]; - context.read_memory_into(id_data, &mut id[..]) - .map_err(|_| "Invalid attempt to get id in ext_sr25519_public_keys")?; - let key_type = KeyTypeId(id); - - let keys = runtime_io::crypto::sr25519_public_keys(key_type).encode(); - - let len = keys.len() as u32; - let offset = context.allocate_memory(len)?; - - context.write_memory(offset, keys.as_ref()) - .map_err(|_| "Invalid attempt to set memory in ext_sr25519_public_keys")?; - context.write_primitive(result_len, len) - .map_err(|_| "Invalid attempt to write result_len in ext_sr25519_public_keys")?; - - Ok(offset) - } - - ext_sr25519_verify( - msg_data: Pointer, - msg_len: WordSize, - sig_data: Pointer, - pubkey_data: Pointer, - ) -> u32 { - let mut sig = [0u8; 64]; - context.read_memory_into(sig_data, &mut sig[..]) - .map_err(|_| "Invalid attempt to get signature in ext_sr25519_verify")?; - let mut pubkey = [0u8; 32]; - context.read_memory_into(pubkey_data, &mut pubkey[..]) - .map_err(|_| "Invalid attempt to get pubkey in ext_sr25519_verify")?; - let msg = context.read_memory(msg_data, msg_len) - .map_err(|_| "Invalid attempt to get message in ext_sr25519_verify")?; - - Ok(if sr25519::Pair::verify_weak(&sig, &msg, &pubkey) { - 0 - } else { - 1 - }) - } - - ext_sr25519_generate( - id_data: Pointer, - seed: Pointer, - seed_len: WordSize, - out: Pointer, - ) { - let mut id = [0u8; 4]; - context.read_memory_into(id_data, &mut id[..]) - .map_err(|_| "Invalid attempt to get id in ext_sr25519_generate")?; - let key_type = KeyTypeId(id); - let seed = if seed_len == 0 { - None - } else { - Some( - context.read_memory(seed, seed_len) - .map_err(|_| "Invalid attempt to get seed in ext_sr25519_generate")? - ) - }; - - let pubkey = runtime_io::crypto::sr25519_generate(key_type, seed); - - context.write_memory(out, pubkey.as_ref()) - .map_err(|_| "Invalid attempt to set out in ext_sr25519_generate".into()) - } - - ext_sr25519_sign( - id_data: Pointer, - pubkey_data: Pointer, - msg_data: Pointer, - msg_len: WordSize, - out: Pointer, - ) -> u32 { - let mut id = [0u8; 4]; - context.read_memory_into(id_data, &mut id[..]) - .map_err(|_| "Invalid attempt to get id in ext_sr25519_sign")?; - let key_type = KeyTypeId(id); - - let mut pubkey = [0u8; 32]; - context.read_memory_into(pubkey_data, &mut pubkey[..]) - .map_err(|_| "Invalid attempt to get pubkey in ext_sr25519_sign")?; - - let msg = context.read_memory(msg_data, msg_len) - .map_err(|_| "Invalid attempt to get message in ext_sr25519_sign")?; - - let pub_key = sr25519::Public::try_from(pubkey.as_ref()) - .map_err(|_| "Invalid `sr25519` public key")?; - - let signature = runtime_io::crypto::sr25519_sign(key_type, &pub_key, &msg); - - match signature { - Some(signature) => { - context.write_memory(out, signature.as_ref()) - .map_err(|_| "Invalid attempt to set out in ext_sr25519_sign")?; - Ok(0) - }, - None => Ok(1), - } - } - - ext_secp256k1_ecdsa_recover( - msg_data: Pointer, - sig_data: Pointer, - pubkey_data: Pointer, - ) -> u32 { - match secp256k1_recover(context, msg_data, sig_data)? { - RecoverResult::Invalid(c) => Ok(c), - RecoverResult::Valid(pubkey) => { - context.write_memory(pubkey_data, &pubkey.serialize()[1..65]) - .map_err(|_| "Invalid attempt to set pubkey in ext_secp256k1_ecdsa_recover")?; - Ok(0) - } - } - } - - ext_secp256k1_ecdsa_recover_compressed( - msg_data: Pointer, - sig_data: Pointer, - pubkey_data: Pointer, - ) -> u32 { - match secp256k1_recover(context, msg_data, sig_data)? { - RecoverResult::Invalid(c) => Ok(c), - RecoverResult::Valid(pubkey) => { - context.write_memory(pubkey_data, &pubkey.serialize_compressed()[..]) - .map_err(|_| "Invalid attempt to set pubkey in ext_secp256k1_ecdsa_recover")?; - Ok(0) - } - } - } - - ext_is_validator() -> u32 { - if runtime_io::offchain::is_validator() { Ok(1) } else { Ok(0) } - } - - ext_submit_transaction(msg_data: Pointer, len: WordSize) -> u32 { - let extrinsic = context.read_memory(msg_data, len) - .map_err(|_| "OOB while ext_submit_transaction: wasm")?; - - let res = runtime_io::offchain::submit_transaction(extrinsic); - - Ok(if res.is_ok() { 0 } else { 1 }) - } - - ext_network_state(written_out: Pointer) -> Pointer { - let res = runtime_io::offchain::network_state(); - - let encoded = res.encode(); - let len = encoded.len() as u32; - let offset = context.allocate_memory(len)?; - context.write_memory(offset, &encoded) - .map_err(|_| "Invalid attempt to set memory in ext_network_state")?; - - context.write_primitive(written_out, len) - .map_err(|_| "Invalid attempt to write written_out in ext_network_state")?; - - Ok(offset) - } - - ext_timestamp() -> u64 { - Ok(runtime_io::offchain::timestamp().unix_millis()) - } - - ext_sleep_until(deadline: u64) { - runtime_io::offchain::sleep_until(offchain::Timestamp::from_unix_millis(deadline)); - Ok(()) - } - - ext_random_seed(seed_data: Pointer) { - // NOTE the runtime as assumptions about seed size. - let seed = runtime_io::offchain::random_seed(); - - context.write_memory(seed_data, &seed) - .map_err(|_| "Invalid attempt to set value in ext_random_seed")?; - Ok(()) - } - - ext_local_storage_set( - kind: u32, - key: Pointer, - key_len: WordSize, - value: Pointer, - value_len: WordSize, - ) { - let kind = offchain::StorageKind::try_from(kind) - .map_err(|_| "storage kind OOB while ext_local_storage_set: wasm")?; - let key = context.read_memory(key, key_len) - .map_err(|_| "OOB while ext_local_storage_set: wasm")?; - let value = context.read_memory(value, value_len) - .map_err(|_| "OOB while ext_local_storage_set: wasm")?; - - runtime_io::offchain::local_storage_set(kind, &key, &value); - - Ok(()) - } - - ext_local_storage_get( - kind: u32, - key: Pointer, - key_len: WordSize, - value_len: Pointer, - ) -> Pointer { - let kind = offchain::StorageKind::try_from(kind) - .map_err(|_| "storage kind OOB while ext_local_storage_get: wasm")?; - let key = context.read_memory(key, key_len) - .map_err(|_| "OOB while ext_local_storage_get: wasm")?; - - let maybe_value = runtime_io::offchain::local_storage_get(kind, &key); - - let (offset, len) = if let Some(value) = maybe_value { - let offset = context.allocate_memory(value.len() as u32)?; - context.write_memory(offset, &value) - .map_err(|_| "Invalid attempt to set memory in ext_local_storage_get")?; - (offset, value.len() as u32) - } else { - (Pointer::null(), u32::max_value()) - }; - - context.write_primitive(value_len, len) - .map_err(|_| "Invalid attempt to write value_len in ext_local_storage_get")?; - - Ok(offset) - } - - ext_local_storage_compare_and_set( - kind: u32, - key: Pointer, - key_len: WordSize, - old_value: Pointer, - old_value_len: WordSize, - new_value: Pointer, - new_value_len: WordSize, - ) -> u32 { - let kind = offchain::StorageKind::try_from(kind) - .map_err(|_| "storage kind OOB while ext_local_storage_compare_and_set: wasm")?; - let key = context.read_memory(key, key_len) - .map_err(|_| "OOB while ext_local_storage_compare_and_set: wasm")?; - let new_value = context.read_memory(new_value, new_value_len) - .map_err(|_| "OOB while ext_local_storage_compare_and_set: wasm")?; - - let old_value = if old_value_len == u32::max_value() { - None - } else { - Some( - context.read_memory(old_value, old_value_len) - .map_err(|_| "OOB while ext_local_storage_compare_and_set: wasm")? - ) - }; - - let res = runtime_io::offchain::local_storage_compare_and_set( - kind, - &key, - old_value, - &new_value, - ); - - Ok(if res { 0 } else { 1 }) - } - - ext_http_request_start( - method: Pointer, - method_len: WordSize, - url: Pointer, - url_len: WordSize, - meta: Pointer, - meta_len: WordSize, - ) -> u32 { - let method = context.read_memory(method, method_len) - .map_err(|_| "OOB while ext_http_request_start: wasm")?; - let url = context.read_memory(url, url_len) - .map_err(|_| "OOB while ext_http_request_start: wasm")?; - let meta = context.read_memory(meta, meta_len) - .map_err(|_| "OOB while ext_http_request_start: wasm")?; - - let method_str = str::from_utf8(&method) - .map_err(|_| "invalid str while ext_http_request_start: wasm")?; - let url_str = str::from_utf8(&url) - .map_err(|_| "invalid str while ext_http_request_start: wasm")?; - - let id = runtime_io::offchain::http_request_start(method_str, url_str, &meta); - - if let Ok(id) = id { - Ok(id.into()) - } else { - Ok(u32::max_value()) - } - } - - ext_http_request_add_header( - request_id: u32, - name: Pointer, - name_len: WordSize, - value: Pointer, - value_len: WordSize, - ) -> u32 { - let name = context.read_memory(name, name_len) - .map_err(|_| "OOB while ext_http_request_add_header: wasm")?; - let value = context.read_memory(value, value_len) - .map_err(|_| "OOB while ext_http_request_add_header: wasm")?; - - let name_str = str::from_utf8(&name) - .map_err(|_| "Invalid str while ext_http_request_add_header: wasm")?; - let value_str = str::from_utf8(&value) - .map_err(|_| "Invalid str while ext_http_request_add_header: wasm")?; - - let res = runtime_io::offchain::http_request_add_header( - offchain::HttpRequestId(request_id as u16), - name_str, - value_str, - ); - - Ok(if res.is_ok() { 0 } else { 1 }) - } - - ext_http_request_write_body( - request_id: u32, - chunk: Pointer, - chunk_len: WordSize, - deadline: u64, - ) -> u32 { - let chunk = context.read_memory(chunk, chunk_len) - .map_err(|_| "OOB while ext_http_request_write_body: wasm")?; - - let res = runtime_io::offchain::http_request_write_body( - offchain::HttpRequestId(request_id as u16), - &chunk, - deadline_to_timestamp(deadline), - ); - - Ok(match res { - Ok(()) => 0, - Err(e) => e.into(), - }) - } - - ext_http_response_wait( - ids: Pointer, - ids_len: WordSize, - statuses: Pointer, - deadline: u64, - ) { - let ids = (0..ids_len) - .map(|i| - context.read_primitive(ids.offset(i).ok_or("Point overflow")?) - .map(|id: u32| offchain::HttpRequestId(id as u16)) - .map_err(|_| "OOB while ext_http_response_wait: wasm") - ) - .collect::, _>>()?; - - let res = runtime_io::offchain::http_response_wait(&ids, deadline_to_timestamp(deadline)) - .into_iter() - .map(|status| u32::from(status)) - .enumerate() - // make sure to take up to `ids_len` to avoid exceeding the mem. - .take(ids_len as usize); - - for (i, status) in res { - context.write_primitive(statuses.offset(i as u32).ok_or("Point overflow")?, status) - .map_err(|_| "Invalid attempt to set memory in ext_http_response_wait")?; - } - - Ok(()) - } - - ext_http_response_headers( - request_id: u32, - written_out: Pointer, - ) -> Pointer { - use codec::Encode; - - let headers = runtime_io::offchain::http_response_headers( - offchain::HttpRequestId(request_id as u16), - ); - - let encoded = headers.encode(); - let len = encoded.len() as u32; - let offset = context.allocate_memory(len)?; - - context.write_memory(offset, &encoded) - .map_err(|_| "Invalid attempt to set memory in ext_http_response_headers")?; - context.write_primitive(written_out, len) - .map_err(|_| "Invalid attempt to write written_out in ext_http_response_headers")?; - - Ok(offset) - } - - ext_http_response_read_body( - request_id: u32, - buffer: Pointer, - buffer_len: WordSize, - deadline: u64, - ) -> WordSize { - let mut internal_buffer = Vec::with_capacity(buffer_len as usize); - internal_buffer.resize(buffer_len as usize, 0); - - let res = runtime_io::offchain::http_response_read_body( - offchain::HttpRequestId(request_id as u16), - &mut internal_buffer, - deadline_to_timestamp(deadline), - ); - - Ok(match res { - Ok(read) => { - context.write_memory(buffer, &internal_buffer[..read as usize]) - .map_err(|_| "Invalid attempt to set memory in ext_http_response_read_body")?; - - read as u32 - }, - Err(err) => { - u32::max_value() - u32::from(err) + 1 - } - }) - } - } -} - -fn deadline_to_timestamp(deadline: u64) -> Option { - if deadline == 0 { - None - } else { - Some(offchain::Timestamp::from_unix_millis(deadline)) - } -} - diff --git a/client/executor/src/integration_tests/mod.rs b/client/executor/src/integration_tests/mod.rs index 32424c6065ef75dd2a55535045c245ca8f939f57..24e9e022f706359a9ced948410d94933fe426cad 100644 --- a/client/executor/src/integration_tests/mod.rs +++ b/client/executor/src/integration_tests/mod.rs @@ -18,15 +18,15 @@ mod sandbox; use codec::{Encode, Decode}; use hex_literal::hex; -use primitives::{ +use sp_core::{ Blake2Hasher, blake2_128, blake2_256, ed25519, sr25519, map, Pair, offchain::{OffchainExt, testing}, traits::Externalities, }; -use runtime_test::WASM_BINARY; -use state_machine::TestExternalities as CoreTestExternalities; +use sc_runtime_test::WASM_BINARY; +use sp_state_machine::TestExternalities as CoreTestExternalities; use test_case::test_case; -use trie::{TrieConfiguration, trie_types::Layout}; +use sp_trie::{TrieConfiguration, trie_types::Layout}; use crate::WasmExecutionMethod; @@ -40,7 +40,7 @@ fn call_in_wasm( code: &[u8], heap_pages: u64, ) -> crate::error::Result> { - crate::call_in_wasm::( + crate::call_in_wasm::( function, call_data, execution_method, @@ -128,11 +128,14 @@ fn storage_should_work(wasm_method: WasmExecutionMethod) { assert_eq!(output, b"all ok!".to_vec().encode()); } - let expected = TestExternalities::new((map![ + let expected = TestExternalities::new(sp_core::storage::Storage { + top: map![ b"input".to_vec() => b"Hello world".to_vec(), b"foo".to_vec() => b"bar".to_vec(), b"baz".to_vec() => b"bar".to_vec() - ], map![])); + ], + children: map![], + }); assert_eq!(ext, expected); } @@ -162,11 +165,14 @@ fn clear_prefix_should_work(wasm_method: WasmExecutionMethod) { assert_eq!(output, b"all ok!".to_vec().encode()); } - let expected = TestExternalities::new((map![ + let expected = TestExternalities::new(sp_core::storage::Storage { + top: map![ b"aaa".to_vec() => b"1".to_vec(), b"aab".to_vec() => b"2".to_vec(), b"bbb".to_vec() => b"5".to_vec() - ], map![])); + ], + children: map![], + }); assert_eq!(expected, ext); } @@ -230,6 +236,42 @@ fn blake2_128_should_work(wasm_method: WasmExecutionMethod) { ); } +#[test_case(WasmExecutionMethod::Interpreted)] +#[cfg_attr(feature = "wasmtime", test_case(WasmExecutionMethod::Compiled))] +fn sha2_256_should_work(wasm_method: WasmExecutionMethod) { + let mut ext = TestExternalities::default(); + let mut ext = ext.ext(); + let test_code = WASM_BINARY; + assert_eq!( + call_in_wasm( + "test_sha2_256", + &[0], + wasm_method, + &mut ext, + &test_code[..], + 8, + ) + .unwrap(), + hex!("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855") + .to_vec() + .encode(), + ); + assert_eq!( + call_in_wasm( + "test_sha2_256", + &b"Hello world!".to_vec().encode(), + wasm_method, + &mut ext, + &test_code[..], + 8, + ) + .unwrap(), + hex!("c0535e4be2b79ffd93291305436bf889314e4a3faec05ecffcbb7df31ad9e51a") + .to_vec() + .encode(), + ); +} + #[test_case(WasmExecutionMethod::Interpreted)] #[cfg_attr(feature = "wasmtime", test_case(WasmExecutionMethod::Compiled))] fn twox_256_should_work(wasm_method: WasmExecutionMethod) { @@ -401,7 +443,7 @@ fn ordered_trie_root_should_work(wasm_method: WasmExecutionMethod) { #[test_case(WasmExecutionMethod::Interpreted)] #[cfg_attr(feature = "wasmtime", test_case(WasmExecutionMethod::Compiled))] fn offchain_local_storage_should_work(wasm_method: WasmExecutionMethod) { - use primitives::offchain::OffchainStorage; + use sp_core::offchain::OffchainStorage; let mut ext = TestExternalities::default(); let (offchain, state) = testing::TestOffchainExt::new(); @@ -456,4 +498,3 @@ fn offchain_http_should_work(wasm_method: WasmExecutionMethod) { true.encode(), ); } - diff --git a/client/executor/src/integration_tests/sandbox.rs b/client/executor/src/integration_tests/sandbox.rs index c18b848acce7e37440803cfc91987ec7ac205b9b..f18291da67de53a1ee05b7c27b2a945c2e657930 100644 --- a/client/executor/src/integration_tests/sandbox.rs +++ b/client/executor/src/integration_tests/sandbox.rs @@ -18,7 +18,7 @@ use super::{TestExternalities, call_in_wasm}; use crate::WasmExecutionMethod; use codec::Encode; -use runtime_test::WASM_BINARY; +use sc_runtime_test::WASM_BINARY; use test_case::test_case; use wabt; diff --git a/client/executor/src/lib.rs b/client/executor/src/lib.rs index 0638a71d1c873667706c4b72a1590fb12ae9799d..5045874859b8ff5ceef81ca7caac3a4c826eaa34 100644 --- a/client/executor/src/lib.rs +++ b/client/executor/src/lib.rs @@ -46,12 +46,12 @@ mod integration_tests; pub mod error; pub use wasmi; pub use native_executor::{with_native_environment, NativeExecutor, NativeExecutionDispatch}; -pub use runtime_version::{RuntimeVersion, NativeVersion}; +pub use sp_version::{RuntimeVersion, NativeVersion}; pub use codec::Codec; #[doc(hidden)] -pub use primitives::traits::Externalities; +pub use sp_core::traits::Externalities; #[doc(hidden)] -pub use wasm_interface; +pub use sp_wasm_interface; pub use wasm_runtime::WasmExecutionMethod; /// Call the given `function` in the given wasm `code`. @@ -64,7 +64,7 @@ pub use wasm_runtime::WasmExecutionMethod; /// - `heap_pages`: The number of heap pages to allocate. /// /// Returns the `Vec` that contains the return value of the function. -pub fn call_in_wasm( +pub fn call_in_wasm( function: &str, call_data: &[u8], execution_method: WasmExecutionMethod, @@ -87,23 +87,20 @@ pub trait RuntimeInfo { fn native_version(&self) -> &NativeVersion; /// Extract RuntimeVersion of given :code block - fn runtime_version ( - &self, - ext: &mut E, - ) -> Option; + fn runtime_version (&self, ext: &mut E) -> error::Result; } #[cfg(test)] mod tests { use super::*; - use runtime_test::WASM_BINARY; - use runtime_io::TestExternalities; + use sc_runtime_test::WASM_BINARY; + use sp_io::TestExternalities; #[test] fn call_in_interpreted_wasm_works() { let mut ext = TestExternalities::default(); let mut ext = ext.ext(); - let res = call_in_wasm::<_, runtime_io::SubstrateHostFunctions>( + let res = call_in_wasm::<_, sp_io::SubstrateHostFunctions>( "test_empty_return", &[], WasmExecutionMethod::Interpreted, diff --git a/client/executor/src/native_executor.rs b/client/executor/src/native_executor.rs index 23ea17a0c4eaa478738496b7d393d30987d03a9c..09e514f603870867b035e99112d37ac243ef3788 100644 --- a/client/executor/src/native_executor.rs +++ b/client/executor/src/native_executor.rs @@ -19,17 +19,17 @@ use crate::{ wasm_runtime::{RuntimesCache, WasmExecutionMethod, WasmRuntime}, }; -use runtime_version::{NativeVersion, RuntimeVersion}; +use sp_version::{NativeVersion, RuntimeVersion}; use codec::{Decode, Encode}; -use primitives::{NativeOrEncoded, traits::{CodeExecutor, Externalities}}; +use sp_core::{NativeOrEncoded, traits::{CodeExecutor, Externalities}}; -use log::{trace, warn}; +use log::trace; use std::{result, cell::RefCell, panic::{UnwindSafe, AssertUnwindSafe}}; -use wasm_interface::{HostFunctions, Function}; +use sp_wasm_interface::{HostFunctions, Function}; thread_local! { static RUNTIMES_CACHE: RefCell = RefCell::new(RuntimesCache::new()); @@ -43,7 +43,7 @@ pub(crate) fn safe_call(f: F) -> Result { // Substrate uses custom panic hook that terminates process on panic. Disable // termination for the native call. - let _guard = panic_handler::AbortGuard::force_unwind(); + let _guard = sp_panic_handler::AbortGuard::force_unwind(); std::panic::catch_unwind(f).map_err(|_| Error::Runtime) } @@ -53,7 +53,7 @@ pub(crate) fn safe_call(f: F) -> Result pub fn with_native_environment(ext: &mut dyn Externalities, f: F) -> Result where F: UnwindSafe + FnOnce() -> U { - externalities::set_and_run_with_externalities(ext, move || safe_call(f)) + sp_externalities::set_and_run_with_externalities(ext, move || safe_call(f)) } /// Delegate for dispatching a CodeExecutor call. @@ -98,7 +98,7 @@ impl NativeExecutor { /// `default_heap_pages` - Number of 64KB pages to allocate for Wasm execution. /// Defaults to `DEFAULT_HEAP_PAGES` if `None` is provided. pub fn new(fallback_method: WasmExecutionMethod, default_heap_pages: Option) -> Self { - let mut host_functions = runtime_io::SubstrateHostFunctions::host_functions(); + let mut host_functions = sp_io::SubstrateHostFunctions::host_functions(); // Add the old and deprecated host functions as well, so that we support old wasm runtimes. host_functions.extend( crate::deprecated_host_interface::SubstrateExternals::host_functions(), @@ -181,14 +181,8 @@ impl RuntimeInfo for NativeExecutor { fn runtime_version( &self, ext: &mut E, - ) -> Option { - match self.with_runtime(ext, |_runtime, version, _ext| Ok(Ok(version.clone()))) { - Ok(version) => Some(version), - Err(e) => { - warn!(target: "executor", "Failed to fetch runtime: {:?}", e); - None - } - } + ) -> Result { + self.with_runtime(ext, |_runtime, version, _ext| Ok(Ok(version.clone()))) } } @@ -271,10 +265,10 @@ impl CodeExecutor for NativeExecutor { /// # Example /// /// ``` -/// substrate_executor::native_executor_instance!( +/// sc_executor::native_executor_instance!( /// pub MyExecutor, -/// test_runtime::api::dispatch, -/// test_runtime::native_version, +/// substrate_test_runtime::api::dispatch, +/// substrate_test_runtime::native_version, /// ); /// ``` /// @@ -284,7 +278,7 @@ impl CodeExecutor for NativeExecutor { /// executor aware of the host functions for these interfaces. /// /// ``` -/// # use runtime_interface::runtime_interface; +/// # use sp_runtime_interface::runtime_interface; /// /// #[runtime_interface] /// trait MyInterface { @@ -293,10 +287,10 @@ impl CodeExecutor for NativeExecutor { /// } /// } /// -/// substrate_executor::native_executor_instance!( +/// sc_executor::native_executor_instance!( /// pub MyExecutor, -/// test_runtime::api::dispatch, -/// test_runtime::native_version, +/// substrate_test_runtime::api::dispatch, +/// substrate_test_runtime::native_version, /// my_interface::HostFunctions, /// ); /// ``` @@ -343,7 +337,7 @@ macro_rules! native_executor_instance { #[cfg(test)] mod tests { use super::*; - use runtime_interface::runtime_interface; + use sp_runtime_interface::runtime_interface; #[runtime_interface] trait MyInterface { @@ -354,8 +348,8 @@ mod tests { native_executor_instance!( pub MyExecutor, - test_runtime::api::dispatch, - test_runtime::native_version, + substrate_test_runtime::api::dispatch, + substrate_test_runtime::native_version, (my_interface::HostFunctions, my_interface::HostFunctions), ); diff --git a/client/executor/src/sandbox.rs b/client/executor/src/sandbox.rs index da71b06672465f17f8eaad6759aace8f98e77ba6..e0e1780a14c200afba6562e467744345459ee3db 100644 --- a/client/executor/src/sandbox.rs +++ b/client/executor/src/sandbox.rs @@ -21,12 +21,12 @@ use crate::error::{Result, Error}; use std::{collections::HashMap, rc::Rc}; use codec::{Decode, Encode}; -use primitives::sandbox as sandbox_primitives; +use sp_core::sandbox as sandbox_primitives; use wasmi::{ Externals, ImportResolver, MemoryInstance, MemoryRef, Module, ModuleInstance, ModuleRef, RuntimeArgs, RuntimeValue, Trap, TrapKind, memory_units::Pages, }; -use wasm_interface::{Pointer, WordSize}; +use sp_wasm_interface::{Pointer, WordSize}; /// Index of a function inside the supervisor. /// diff --git a/client/executor/src/wasm_runtime.rs b/client/executor/src/wasm_runtime.rs index c58f63a1e03de7e013037d44fa75044bcf5a1562..6181a1aab23c0960b023a84db4b322a6931822e5 100644 --- a/client/executor/src/wasm_runtime.rs +++ b/client/executor/src/wasm_runtime.rs @@ -26,12 +26,12 @@ use log::{trace, warn}; use codec::Decode; -use primitives::{storage::well_known_keys, traits::Externalities, H256}; +use sp_core::{storage::well_known_keys, traits::Externalities}; -use runtime_version::RuntimeVersion; +use sp_version::RuntimeVersion; use std::{collections::hash_map::{Entry, HashMap}, panic::AssertUnwindSafe}; -use wasm_interface::Function; +use sp_wasm_interface::Function; /// The Substrate Wasm runtime. pub trait WasmRuntime { @@ -82,7 +82,7 @@ pub struct RuntimesCache { /// A cache of runtime instances along with metadata, ready to be reused. /// /// Instances are keyed by the Wasm execution method and the hash of their code. - instances: HashMap<(WasmExecutionMethod, [u8; 32]), Result>, + instances: HashMap<(WasmExecutionMethod, Vec), Result>, } impl RuntimesCache { @@ -128,7 +128,7 @@ impl RuntimesCache { wasm_method: WasmExecutionMethod, default_heap_pages: u64, host_functions: &[&'static dyn Function], - ) -> Result<(&mut (dyn WasmRuntime + 'static), &RuntimeVersion, H256), Error> { + ) -> Result<(&mut (dyn WasmRuntime + 'static), &RuntimeVersion, Vec), Error> { let code_hash = ext .original_storage_hash(well_known_keys::CODE) .ok_or(Error::InvalidCode("`CODE` not found in storage.".into()))?; @@ -138,7 +138,7 @@ impl RuntimesCache { .and_then(|pages| u64::decode(&mut &pages[..]).ok()) .unwrap_or(default_heap_pages); - let result = match self.instances.entry((wasm_method, code_hash.into())) { + let result = match self.instances.entry((wasm_method, code_hash.clone())) { Entry::Occupied(o) => { let result = o.into_mut(); if let Ok(ref mut cached_runtime) = result { @@ -198,10 +198,10 @@ impl RuntimesCache { pub fn invalidate_runtime( &mut self, wasm_method: WasmExecutionMethod, - code_hash: H256, + code_hash: Vec, ) { // Just remove the instance, it will be re-created the next time it is requested. - self.instances.remove(&(wasm_method, code_hash.into())); + self.instances.remove(&(wasm_method, code_hash)); } } @@ -259,11 +259,11 @@ fn create_versioned_wasm_runtime( #[cfg(test)] mod tests { - use wasm_interface::HostFunctions; + use sp_wasm_interface::HostFunctions; #[test] fn host_functions_are_equal() { - let host_functions = runtime_io::SubstrateHostFunctions::host_functions(); + let host_functions = sp_io::SubstrateHostFunctions::host_functions(); let equal = &host_functions[..] == &host_functions[..]; assert!(equal, "Host functions are not equal"); diff --git a/client/executor/src/wasm_utils.rs b/client/executor/src/wasm_utils.rs index caa63ddbf298544690ba3ee11c6f77055ce4571d..95b1db65ce3b5621dc151222842b385092eeee60 100644 --- a/client/executor/src/wasm_utils.rs +++ b/client/executor/src/wasm_utils.rs @@ -16,28 +16,28 @@ //! Utilities for defining the wasm host environment. -use wasm_interface::{Pointer, WordSize}; +use sp_wasm_interface::{Pointer, WordSize}; /// Converts arguments into respective WASM types. #[macro_export] macro_rules! convert_args { () => ([]); - ( $( $t:ty ),* ) => ( [ $( <$t as $crate::wasm_interface::IntoValue>::VALUE_TYPE, )* ] ); + ( $( $t:ty ),* ) => ( [ $( <$t as $crate::sp_wasm_interface::IntoValue>::VALUE_TYPE, )* ] ); } /// Generates a WASM signature for given list of parameters. #[macro_export] macro_rules! gen_signature { ( ( $( $params: ty ),* ) ) => ( - $crate::wasm_interface::Signature { + $crate::sp_wasm_interface::Signature { args: std::borrow::Cow::Borrowed(&convert_args!( $( $params ),* )[..]), return_value: None, } ); ( ( $( $params: ty ),* ) -> $returns:ty ) => ( - $crate::wasm_interface::Signature { + $crate::sp_wasm_interface::Signature { args: std::borrow::Cow::Borrowed(&convert_args!( $( $params ),* )[..]), - return_value: Some(<$returns as $crate::wasm_interface::IntoValue>::VALUE_TYPE), + return_value: Some(<$returns as $crate::sp_wasm_interface::IntoValue>::VALUE_TYPE), } ); } @@ -63,18 +63,18 @@ macro_rules! gen_functions { struct $name; #[allow(unused)] - impl $crate::wasm_interface::Function for $name { + impl $crate::sp_wasm_interface::Function for $name { fn name(&self) -> &str { stringify!($name) } - fn signature(&self) -> $crate::wasm_interface::Signature { + fn signature(&self) -> $crate::sp_wasm_interface::Signature { gen_signature!( ( $( $params ),* ) $( -> $returns )? ) } fn execute( &self, - context: &mut dyn $crate::wasm_interface::FunctionContext, - args: &mut dyn Iterator, - ) -> ::std::result::Result, String> { + context: &mut dyn $crate::sp_wasm_interface::FunctionContext, + args: &mut dyn Iterator, + ) -> ::std::result::Result, String> { let mut $context = context; marshall! { args, @@ -83,7 +83,7 @@ macro_rules! gen_functions { } } - &$name as &dyn $crate::wasm_interface::Function + &$name as &dyn $crate::sp_wasm_interface::Function }, } $context, @@ -103,7 +103,7 @@ macro_rules! unmarshall_args { $( let $names : $params = $args_iter.next() - .and_then(|val| <$params as $crate::wasm_interface::TryFromValue>::try_from_value(val)) + .and_then(|val| <$params as $crate::sp_wasm_interface::TryFromValue>::try_from_value(val)) .expect( "`$args_iter` comes from an argument of Externals::execute_function; args to an external call always matches the signature of the external; @@ -140,7 +140,7 @@ macro_rules! marshall { unmarshall_args!($body, $args_iter, $( $names : $params ),*) }); let r = body()?; - return Ok(Some($crate::wasm_interface::IntoValue::into_value(r))) + return Ok(Some($crate::sp_wasm_interface::IntoValue::into_value(r))) }); ( $args_iter:ident, ( $( $names:ident : $params:ty ),* ) => $body:tt ) => ({ let body = $crate::wasm_utils::constrain_closure::<(), _>(|| { @@ -162,9 +162,9 @@ macro_rules! impl_wasm_host_interface { )* } ) => ( - impl $crate::wasm_interface::HostFunctions for $interface_name { + impl $crate::sp_wasm_interface::HostFunctions for $interface_name { #[allow(non_camel_case_types)] - fn host_functions() -> Vec<&'static dyn $crate::wasm_interface::Function> { + fn host_functions() -> Vec<&'static dyn $crate::sp_wasm_interface::Function> { gen_functions!( $context, $( $name( $( $names: $params ),* ) $( -> $returns )? { $( $body )* } )* diff --git a/client/executor/src/wasmi_execution.rs b/client/executor/src/wasmi_execution.rs index 7f480695798fa99ed4ebf4a0674ca5abd39bb258..cdead6cee1fe0c83e21f224d1c479eabcfb94158 100644 --- a/client/executor/src/wasmi_execution.rs +++ b/client/executor/src/wasmi_execution.rs @@ -23,14 +23,14 @@ use wasmi::{ }; use crate::error::{Error, WasmError}; use codec::{Encode, Decode}; -use primitives::{sandbox as sandbox_primitives, traits::Externalities}; +use sp_core::{sandbox as sandbox_primitives, traits::Externalities}; use crate::sandbox; use crate::allocator; use crate::wasm_utils::interpret_runtime_api_result; use crate::wasm_runtime::WasmRuntime; use log::{error, trace}; use parity_wasm::elements::{deserialize_buffer, DataSegment, Instruction, Module as RawModule}; -use wasm_interface::{ +use sp_wasm_interface::{ FunctionContext, Pointer, WordSize, Sandbox, MemoryId, Result as WResult, Function, }; @@ -206,7 +206,7 @@ impl<'a> Sandbox for FunctionExecutor<'a> { return_val_len: WordSize, state: u32, ) -> WResult { - trace!(target: "sr-sandbox", "invoke, instance_idx={}", instance_id); + trace!(target: "sp-sandbox", "invoke, instance_idx={}", instance_id); // Deserialize arguments and convert them into wasmi types. let args = Vec::::decode(&mut &args[..]) @@ -273,7 +273,7 @@ impl<'a> wasmi::ModuleImportResolver for Resolver<'a> { fn resolve_func(&self, name: &str, signature: &wasmi::Signature) -> std::result::Result { - let signature = wasm_interface::Signature::from(signature); + let signature = sp_wasm_interface::Signature::from(signature); for (function_index, function) in self.0.iter().enumerate() { if name == function.name() { if signature == function.signature() { @@ -364,7 +364,7 @@ fn call_in_wasm_module( let offset = fec.allocate_memory(data.len() as u32)?; fec.write_memory(offset, data)?; - let result = externalities::set_and_run_with_externalities( + let result = sp_externalities::set_and_run_with_externalities( ext, || module_instance.invoke_export( method, diff --git a/client/executor/src/wasmtime/function_executor.rs b/client/executor/src/wasmtime/function_executor.rs index 5dc8f42b280c45a53ef7c4829e03bd086c19e64d..4db7adc83a1072511ebd0de05317eb99c453cc26 100644 --- a/client/executor/src/wasmtime/function_executor.rs +++ b/client/executor/src/wasmtime/function_executor.rs @@ -25,12 +25,12 @@ use codec::{Decode, Encode}; use cranelift_codegen::ir; use cranelift_codegen::isa::TargetFrontendConfig; use log::trace; -use primitives::sandbox as sandbox_primitives; +use sp_core::sandbox as sandbox_primitives; use std::{cmp, mem, ptr}; use wasmtime_environ::translate_signature; use wasmtime_jit::{ActionError, Compiler}; use wasmtime_runtime::{Export, VMCallerCheckedAnyfunc, VMContext, wasmtime_call_trampoline}; -use wasm_interface::{ +use sp_wasm_interface::{ FunctionContext, MemoryId, Pointer, Result as WResult, Sandbox, Signature, Value, ValueType, WordSize, }; @@ -283,7 +283,7 @@ impl<'a> Sandbox for FunctionExecutor<'a> { return_val_len: u32, state: u32, ) -> WResult { - trace!(target: "sr-sandbox", "invoke, instance_idx={}", instance_id); + trace!(target: "sp-sandbox", "invoke, instance_idx={}", instance_id); // Deserialize arguments and convert them into wasmi types. let args = Vec::::decode(&mut &args[..]) diff --git a/client/executor/src/wasmtime/runtime.rs b/client/executor/src/wasmtime/runtime.rs index 1a7385cc46025cae86f780ce83c71fdf726812ce..6fdf9f0e9e91a01d8f89e279b152a4a1f2dbb9a7 100644 --- a/client/executor/src/wasmtime/runtime.rs +++ b/client/executor/src/wasmtime/runtime.rs @@ -33,7 +33,7 @@ use std::cell::RefCell; use std::collections::HashMap; use std::convert::TryFrom; use std::rc::Rc; -use wasm_interface::{Pointer, WordSize, Function}; +use sp_wasm_interface::{Pointer, WordSize, Function}; use wasmtime_environ::{Module, translate_signature}; use wasmtime_jit::{ ActionOutcome, ActionError, CodeMemory, CompilationStrategy, CompiledModule, Compiler, Context, @@ -175,7 +175,7 @@ fn call_method( let args = [RuntimeValue::I32(u32::from(data_ptr) as i32), RuntimeValue::I32(data_len as i32)]; // Invoke the function in the runtime. - let outcome = externalities::set_and_run_with_externalities(ext, || { + let outcome = sp_externalities::set_and_run_with_externalities(ext, || { context .invoke(&mut instance, method, &args[..]) .map_err(Error::Wasmtime) diff --git a/client/executor/src/wasmtime/trampoline.rs b/client/executor/src/wasmtime/trampoline.rs index 25b3fefbfa2c738f2467307bd0c6a151634fafd2..125112525129b407a061c481f829fcc591a96f72 100644 --- a/client/executor/src/wasmtime/trampoline.rs +++ b/client/executor/src/wasmtime/trampoline.rs @@ -26,7 +26,7 @@ use cranelift_codegen::print_errors::pretty_error; use wasmtime_jit::{CodeMemory, Compiler}; use wasmtime_environ::CompiledFunction; use wasmtime_runtime::{VMContext, VMFunctionBody}; -use wasm_interface::{Function, Value, ValueType}; +use sp_wasm_interface::{Function, Value, ValueType}; use std::{cmp, panic::{self, AssertUnwindSafe}, ptr}; use crate::error::{Error, WasmError}; diff --git a/client/executor/src/wasmtime/util.rs b/client/executor/src/wasmtime/util.rs index 874ccc8c85fbe2073b3633513237e38681c48297..55cb5ecc500fb3c6f9577ac98b009c6f38df178c 100644 --- a/client/executor/src/wasmtime/util.rs +++ b/client/executor/src/wasmtime/util.rs @@ -18,7 +18,7 @@ use crate::error::{Error, Result}; use cranelift_codegen::{ir, isa}; use std::ops::Range; -use wasm_interface::{Pointer, Signature, ValueType}; +use sp_wasm_interface::{Pointer, Signature, ValueType}; /// Read data from a slice of memory into a destination buffer. /// diff --git a/client/finality-grandpa/Cargo.toml b/client/finality-grandpa/Cargo.toml index efeac4097407c5712efe9ba671aa7b120a5ff65e..9f90834e0df3cd77309e5e461d5cc24ea9b1df19 100644 --- a/client/finality-grandpa/Cargo.toml +++ b/client/finality-grandpa/Cargo.toml @@ -1,42 +1,43 @@ [package] -name = "substrate-finality-grandpa" +name = "sc-finality-grandpa" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" [dependencies] -fork-tree = { path = "../../utils/fork-tree" } +fork-tree = { version = "2.0.0", path = "../../utils/fork-tree" } futures = "0.1.29" futures03 = { package = "futures", version = "0.3.1", features = ["compat"] } +futures-timer = "2.0.2" log = "0.4.8" parking_lot = "0.9.0" -tokio-executor = "0.1.8" -tokio-timer = "0.2.11" rand = "0.7.2" -codec = { package = "parity-scale-codec", version = "1.0.0", features = ["derive"] } -sr-primitives = { path = "../../primitives/sr-primitives" } -consensus_common = { package = "substrate-consensus-common", path = "../../primitives/consensus/common" } -primitives = { package = "substrate-primitives", path = "../../primitives/core" } -substrate-telemetry = { path = "../telemetry" } -keystore = { package = "substrate-keystore", path = "../keystore" } +parity-scale-codec = { version = "1.0.0", features = ["derive"] } +sp-runtime = { version = "2.0.0", path = "../../primitives/runtime" } +sp-consensus = { version = "0.8", path = "../../primitives/consensus/common" } +sp-core = { version = "2.0.0", path = "../../primitives/core" } +sc-telemetry = { version = "2.0.0", path = "../telemetry" } +sc-keystore = { version = "2.0.0", path = "../keystore" } serde_json = "1.0.41" -client-api = { package = "substrate-client-api", path = "../api" } -client = { package = "substrate-client", path = "../" } -header-metadata = { package = "substrate-header-metadata", path = "../header-metadata" } -inherents = { package = "substrate-inherents", path = "../../primitives/inherents" } -network = { package = "substrate-network", path = "../network" } -sp-finality-tracker = { path = "../../primitives/finality-tracker" } -fg_primitives = { package = "substrate-finality-grandpa-primitives", path = "../../primitives/finality-grandpa" } -grandpa = { package = "finality-grandpa", version = "0.10.0", features = ["derive-codec"] } +sc-client-api = { version = "2.0.0", path = "../api" } +sc-client = { version = "2.0.0", path = "../" } +sp-inherents = { version = "2.0.0", path = "../../primitives/inherents" } +sp-blockchain = { version = "2.0.0", path = "../../primitives/blockchain" } +sc-network = { version = "0.8", path = "../network" } +sc-network-gossip = { version = "2.0.0", path = "../network-gossip" } +sp-finality-tracker = { version = "2.0.0", path = "../../primitives/finality-tracker" } +sp-finality-grandpa = { version = "2.0.0", path = "../../primitives/finality-grandpa" } +finality-grandpa = { version = "0.10.1", features = ["derive-codec"] } [dev-dependencies] -grandpa = { package = "finality-grandpa", version = "0.10.0", features = ["derive-codec", "test-helpers"] } -network = { package = "substrate-network", path = "../network", features = ["test-helpers"] } -keyring = { package = "substrate-keyring", path = "../../primitives/keyring" } -test-client = { package = "substrate-test-runtime-client", path = "../../test/utils/runtime/client"} -babe_primitives = { package = "substrate-consensus-babe-primitives", path = "../../primitives/consensus/babe" } -state_machine = { package = "substrate-state-machine", path = "../../primitives/state-machine" } +finality-grandpa = { version = "0.10.1", features = ["derive-codec", "test-helpers"] } +sc-network = { version = "0.8", path = "../network" } +sc-network-test = { version = "2.0.0", path = "../network/test" } +sp-keyring = { version = "2.0.0", path = "../../primitives/keyring" } +substrate-test-runtime-client = { version = "2.0.0", path = "../../test-utils/runtime/client" } +sp-consensus-babe = { version = "0.8", path = "../../primitives/consensus/babe" } +sp-state-machine = { version = "2.0.0", path = "../../primitives/state-machine" } env_logger = "0.7.0" tokio = "0.1.22" tempfile = "3.1.0" -sr-api = { path = "../../primitives/sr-api" } +sp-api = { version = "2.0.0", path = "../../primitives/api" } diff --git a/client/finality-grandpa/src/authorities.rs b/client/finality-grandpa/src/authorities.rs index 263f2dc076e39991da9509bddfce2c3b84752cb2..2f01ce53b859d1f8da70965450e5f70cc2634eeb 100644 --- a/client/finality-grandpa/src/authorities.rs +++ b/client/finality-grandpa/src/authorities.rs @@ -18,11 +18,11 @@ use fork_tree::ForkTree; use parking_lot::RwLock; -use grandpa::voter_set::VoterSet; -use codec::{Encode, Decode}; +use finality_grandpa::voter_set::VoterSet; +use parity_scale_codec::{Encode, Decode}; use log::{debug, info}; -use substrate_telemetry::{telemetry, CONSENSUS_INFO}; -use fg_primitives::{AuthorityId, AuthorityList}; +use sc_telemetry::{telemetry, CONSENSUS_INFO}; +use sp_finality_grandpa::{AuthorityId, AuthorityList}; use std::cmp::Ord; use std::fmt::Debug; @@ -258,7 +258,7 @@ where // check if the given best block is in the same branch as the block that signaled the change. if is_descendent_of(&change.canon_hash, &best_hash)? { // apply this change: make the set canonical - info!(target: "finality", "Applying authority set change forced at block #{:?}", + info!(target: "afg", "Applying authority set change forced at block #{:?}", change.canon_height); telemetry!(CONSENSUS_INFO; "afg.applying_forced_authority_set_change"; "block" => ?change.canon_height @@ -324,7 +324,7 @@ where self.pending_forced_changes.clear(); if let Some(change) = change { - info!(target: "finality", "Applying authority set change scheduled at block #{:?}", + info!(target: "afg", "Applying authority set change scheduled at block #{:?}", change.canon_height); telemetry!(CONSENSUS_INFO; "afg.applying_scheduled_authority_set_change"; "block" => ?change.canon_height @@ -403,7 +403,7 @@ pub(crate) struct PendingChange { } impl Decode for PendingChange { - fn decode(value: &mut I) -> Result { + fn decode(value: &mut I) -> Result { let next_authorities = Decode::decode(value)?; let delay = Decode::decode(value)?; let canon_height = Decode::decode(value)?; @@ -431,7 +431,7 @@ impl + Clone> PendingChange { #[cfg(test)] mod tests { use super::*; - use primitives::crypto::Public; + use sp_core::crypto::Public; fn static_is_descendent_of(value: bool) -> impl Fn(&A, &A) -> Result diff --git a/client/finality-grandpa/src/aux_schema.rs b/client/finality-grandpa/src/aux_schema.rs index 9857367dc99e6c85aeca6942fbebc52ca956a28c..63394dcbe1a8c1f657f1b3d5c4a390cfed4f12e0 100644 --- a/client/finality-grandpa/src/aux_schema.rs +++ b/client/finality-grandpa/src/aux_schema.rs @@ -18,14 +18,14 @@ use std::fmt::Debug; use std::sync::Arc; -use codec::{Encode, Decode}; -use client_api::backend::AuxStore; -use client_api::error::{Result as ClientResult, Error as ClientError}; +use parity_scale_codec::{Encode, Decode}; +use sc_client_api::backend::AuxStore; +use sp_blockchain::{Result as ClientResult, Error as ClientError}; use fork_tree::ForkTree; -use grandpa::round::State as RoundState; -use sr_primitives::traits::{Block as BlockT, NumberFor}; +use finality_grandpa::round::State as RoundState; +use sp_runtime::traits::{Block as BlockT, NumberFor}; use log::{info, warn}; -use fg_primitives::{AuthorityList, SetId, RoundNumber}; +use sp_finality_grandpa::{AuthorityList, SetId, RoundNumber}; use crate::authorities::{AuthoritySet, SharedAuthoritySet, PendingChange, DelayKind}; use crate::consensus_changes::{SharedConsensusChanges, ConsensusChanges}; @@ -36,6 +36,7 @@ use crate::NewAuthoritySet; const VERSION_KEY: &[u8] = b"grandpa_schema_version"; const SET_STATE_KEY: &[u8] = b"grandpa_completed_round"; +const CONCLUDED_ROUNDS: &[u8] = b"grandpa_concluded_rounds"; const AUTHORITY_SET_KEY: &[u8] = b"grandpa_voters"; const CONSENSUS_CHANGES_KEY: &[u8] = b"grandpa_consensus_changes"; @@ -405,6 +406,18 @@ pub(crate) fn write_voter_set_state( ) } +/// Write concluded round. +pub(crate) fn write_concluded_round( + backend: &B, + round_data: &CompletedRound, +) -> ClientResult<()> { + let mut key = CONCLUDED_ROUNDS.to_vec(); + let round_number = round_data.number; + round_number.using_encoded(|n| key.extend(n)); + + backend.insert_aux(&[(&key[..], round_data.encode().as_slice())], &[]) +} + /// Update the consensus changes. pub(crate) fn update_consensus_changes( set: &ConsensusChanges, @@ -426,14 +439,14 @@ pub(crate) fn load_authorities(backend: &B) #[cfg(test)] mod test { - use fg_primitives::AuthorityId; - use primitives::H256; - use test_client; + use sp_finality_grandpa::AuthorityId; + use sp_core::H256; + use substrate_test_runtime_client; use super::*; #[test] fn load_decode_from_v0_migrates_data_format() { - let client = test_client::new(); + let client = substrate_test_runtime_client::new(); let authorities = vec![(AuthorityId::default(), 100)]; let set_id = 3; @@ -469,7 +482,7 @@ mod test { ); // should perform the migration - load_persistent::( + load_persistent::( &client, H256::random(), 0, @@ -481,7 +494,7 @@ mod test { Some(2), ); - let PersistentData { authority_set, set_state, .. } = load_persistent::( + let PersistentData { authority_set, set_state, .. } = load_persistent::( &client, H256::random(), 0, @@ -521,7 +534,7 @@ mod test { #[test] fn load_decode_from_v1_migrates_data_format() { - let client = test_client::new(); + let client = substrate_test_runtime_client::new(); let authorities = vec![(AuthorityId::default(), 100)]; let set_id = 3; @@ -559,7 +572,7 @@ mod test { ); // should perform the migration - load_persistent::( + load_persistent::( &client, H256::random(), 0, @@ -571,7 +584,7 @@ mod test { Some(2), ); - let PersistentData { authority_set, set_state, .. } = load_persistent::( + let PersistentData { authority_set, set_state, .. } = load_persistent::( &client, H256::random(), 0, @@ -608,4 +621,29 @@ mod test { }, ); } + + #[test] + fn write_read_concluded_rounds() { + let client = substrate_test_runtime_client::new(); + let hash = H256::random(); + let round_state = RoundState::genesis((hash, 0)); + + let completed_round = CompletedRound:: { + number: 42, + state: round_state.clone(), + base: round_state.prevote_ghost.unwrap(), + votes: vec![], + }; + + assert!(write_concluded_round(&client, &completed_round).is_ok()); + + let round_number = completed_round.number; + let mut key = CONCLUDED_ROUNDS.to_vec(); + round_number.using_encoded(|n| key.extend(n)); + + assert_eq!( + load_decode::<_, CompletedRound::>(&client, &key).unwrap(), + Some(completed_round), + ); + } } diff --git a/client/finality-grandpa/src/communication/gossip.rs b/client/finality-grandpa/src/communication/gossip.rs index 9a07d010e0936fb134fe00c02fc4406eaf3f1927..2ac6c9cf492c43e3be17bb1d635511bc31f49fd7 100644 --- a/client/finality-grandpa/src/communication/gossip.rs +++ b/client/finality-grandpa/src/communication/gossip.rs @@ -82,22 +82,22 @@ //! //! We only send polite messages to peers, -use sr_primitives::traits::{NumberFor, Block as BlockT, Zero}; -use network::consensus_gossip::{self as network_gossip, MessageIntent, ValidatorContext}; -use network::{config::Roles, PeerId}; -use codec::{Encode, Decode}; -use fg_primitives::AuthorityId; +use sp_runtime::traits::{NumberFor, Block as BlockT, Zero}; +use sc_network_gossip::{GossipEngine, MessageIntent, ValidatorContext}; +use sc_network::{config::Roles, PeerId, ReputationChange}; +use parity_scale_codec::{Encode, Decode}; +use sp_finality_grandpa::AuthorityId; -use substrate_telemetry::{telemetry, CONSENSUS_DEBUG}; +use sc_telemetry::{telemetry, CONSENSUS_DEBUG}; use log::{trace, debug, warn}; use futures::prelude::*; use futures::sync::mpsc; -use rand::Rng; +use rand::seq::SliceRandom; use crate::{environment, CatchUp, CompactCommit, SignedMessage}; use super::{cost, benefit, Round, SetId}; -use std::collections::{HashMap, VecDeque}; +use std::collections::{HashMap, VecDeque, HashSet}; use std::time::{Duration, Instant}; const REBROADCAST_AFTER: Duration = Duration::from_secs(60 * 5); @@ -107,7 +107,14 @@ const CATCH_UP_PROCESS_TIMEOUT: Duration = Duration::from_secs(30); /// catch up request. const CATCH_UP_THRESHOLD: u64 = 2; -type Report = (PeerId, i32); +const PROPAGATION_ALL: u32 = 4; //in rounds; +const PROPAGATION_ALL_AUTHORITIES: u32 = 2; //in rounds; +const PROPAGATION_SOME_NON_AUTHORITIES: u32 = 3; //in rounds; +const ROUND_DURATION: u32 = 4; // measured in gossip durations + +const MIN_LUCKY: usize = 5; + +type Report = (PeerId, ReputationChange); /// An outcome of examining a message. #[derive(Debug, PartialEq, Clone, Copy)] @@ -377,14 +384,19 @@ pub(super) enum Misbehavior { } impl Misbehavior { - pub(super) fn cost(&self) -> i32 { + pub(super) fn cost(&self) -> ReputationChange { use Misbehavior::*; match *self { InvalidViewChange => cost::INVALID_VIEW_CHANGE, - UndecodablePacket(bytes) => bytes.saturating_mul(cost::PER_UNDECODABLE_BYTE), - BadCatchUpMessage { signatures_checked } => + UndecodablePacket(bytes) => ReputationChange::new( + bytes.saturating_mul(cost::PER_UNDECODABLE_BYTE), + "Grandpa: Bad packet", + ), + BadCatchUpMessage { signatures_checked } => ReputationChange::new( cost::PER_SIGNATURE_CHECKED.saturating_mul(signatures_checked), + "Grandpa: Bad cath-up message", + ), BadCommitMessage { signatures_checked, blocks_loaded, equivocations_caught } => { let cost = cost::PER_SIGNATURE_CHECKED .saturating_mul(signatures_checked) @@ -392,7 +404,7 @@ impl Misbehavior { let benefit = equivocations_caught.saturating_mul(benefit::PER_EQUIVOCATION); - (benefit as i32).saturating_add(cost as i32) + ReputationChange::new((benefit as i32).saturating_add(cost as i32), "Grandpa: Bad commit") }, FutureMessage => cost::FUTURE_MESSAGE, OutOfScopeMessage => cost::OUT_OF_SCOPE_MESSAGE, @@ -417,21 +429,37 @@ impl PeerInfo { /// The peers we're connected do in gossip. struct Peers { inner: HashMap>, + lucky_peers: HashSet, + lucky_authorities: HashSet, } impl Default for Peers { fn default() -> Self { - Peers { inner: HashMap::new() } + Peers { + inner: HashMap::new(), + lucky_peers: HashSet::new(), + lucky_authorities: HashSet::new(), + } } } impl Peers { fn new_peer(&mut self, who: PeerId, roles: Roles) { + if roles.is_authority() && self.lucky_authorities.len() < MIN_LUCKY { + self.lucky_authorities.insert(who.clone()); + } + if !roles.is_authority() && self.lucky_peers.len() < MIN_LUCKY { + self.lucky_peers.insert(who.clone()); + } self.inner.insert(who, PeerInfo::new(roles)); } fn peer_disconnected(&mut self, who: &PeerId) { self.inner.remove(who); + // This does not happen often enough compared to round duration, + // so we don't reshuffle. + self.lucky_peers.remove(who); + self.lucky_authorities.remove(who); } // returns a reference to the new view, if the peer is known. @@ -492,16 +520,47 @@ impl Peers { fn non_authorities(&self) -> usize { self.inner.iter().filter(|(_, info)| !info.roles.is_authority()).count() } + + fn reshuffle(&mut self) { + let mut lucky_peers: Vec<_> = self.inner + .iter() + .filter_map(|(id, info)| if !info.roles.is_authority() { Some(id.clone()) } else { None }) + .collect(); + let mut lucky_authorities: Vec<_> = self.inner + .iter() + .filter_map(|(id, info)| if info.roles.is_authority() { Some(id.clone()) } else { None }) + .collect(); + + let num_non_authorities = ((lucky_peers.len() as f32).sqrt() as usize) + .max(MIN_LUCKY) + .min(lucky_peers.len()); + + let num_authorities = ((lucky_authorities.len() as f32).sqrt() as usize) + .max(MIN_LUCKY) + .min(lucky_authorities.len()); + + lucky_peers.partial_shuffle(&mut rand::thread_rng(), num_non_authorities); + lucky_peers.truncate(num_non_authorities); + + lucky_authorities.partial_shuffle(&mut rand::thread_rng(), num_authorities); + lucky_authorities.truncate(num_authorities); + + self.lucky_peers.clear(); + self.lucky_peers.extend(lucky_peers.into_iter()); + + self.lucky_authorities.clear(); + self.lucky_authorities.extend(lucky_authorities.into_iter()); + } } #[derive(Debug, PartialEq)] pub(super) enum Action { // repropagate under given topic, to the given peers, applying cost/benefit to originator. - Keep(H, i32), + Keep(H, ReputationChange), // discard and process. - ProcessAndDiscard(H, i32), + ProcessAndDiscard(H, ReputationChange), // discard, applying cost/benefit to originator. - Discard(i32), + Discard(ReputationChange), } /// State of catch up request handling. @@ -559,6 +618,7 @@ struct Inner { local_view: Option>>, peers: Peers>, live_topics: KeepTopics, + round_start: Instant, authorities: Vec, config: crate::Config, next_rebroadcast: Instant, @@ -591,6 +651,7 @@ impl Inner { local_view: None, peers: Peers::default(), live_topics: KeepTopics::new(), + round_start: Instant::now(), next_rebroadcast: Instant::now() + REBROADCAST_AFTER, authorities: Vec::new(), pending_catch_up: PendingCatchUp::None, @@ -614,11 +675,13 @@ impl Inner { let set_id = local_view.set_id; debug!(target: "afg", "Voter {} noting beginning of round {:?} to network.", - self.config.name(), (round,set_id)); + self.config.name(), (round, set_id)); local_view.round = round; self.live_topics.push(round, set_id); + self.round_start = Instant::now(); + self.peers.reshuffle(); } self.multicast_neighbor_packet() } @@ -673,7 +736,7 @@ impl Inner { .unwrap_or(Consider::RejectOutOfScope) } - fn cost_past_rejection(&self, _who: &PeerId, _round: Round, _set_id: SetId) -> i32 { + fn cost_past_rejection(&self, _who: &PeerId, _round: Round, _set_id: SetId) -> ReputationChange { // hardcoded for now. cost::PAST_REJECTION } @@ -725,7 +788,6 @@ impl Inner { return Action::Discard(self.cost_past_rejection(who, full.round, full.set_id)), Consider::RejectOutOfScope => return Action::Discard(Misbehavior::OutOfScopeMessage.cost()), Consider::Accept => {}, - } if full.message.precommits.len() != full.message.auth_data.len() || full.message.precommits.is_empty() { @@ -846,15 +908,15 @@ impl Inner { // too many equivocations (we exceed the fault-tolerance bound). for vote in last_completed_round.votes { match vote.message { - grandpa::Message::Prevote(prevote) => { - prevotes.push(grandpa::SignedPrevote { + finality_grandpa::Message::Prevote(prevote) => { + prevotes.push(finality_grandpa::SignedPrevote { prevote, signature: vote.signature, id: vote.id, }); }, - grandpa::Message::Precommit(precommit) => { - precommits.push(grandpa::SignedPrecommit { + finality_grandpa::Message::Precommit(precommit) => { + precommits.push(finality_grandpa::SignedPrecommit { precommit, signature: vote.signature, id: vote.id, @@ -1001,10 +1063,14 @@ impl Inner { /// /// Transitions will be triggered on repropagation attempts by the /// underlying gossip layer, which should happen every 30 seconds. - fn round_message_allowed(&self, peer: &PeerInfo, mut previous_attempts: usize) -> bool { - const MIN_AUTHORITIES: usize = 5; + fn round_message_allowed(&self, who: &PeerId, peer: &PeerInfo) -> bool { + let round_duration = self.config.gossip_duration * ROUND_DURATION; + let round_elapsed = self.round_start.elapsed(); - if !self.config.is_authority && previous_attempts == 0 { + + if !self.config.is_authority + && round_elapsed < round_duration * PROPAGATION_ALL + { // non-authority nodes don't gossip any messages right away. we // assume that authorities (and sentries) are strongly connected, so // it should be unnecessary for non-authorities to gossip all @@ -1012,24 +1078,16 @@ impl Inner { return false; } - if !self.config.is_authority { - // since the node is not an authority we skipped the initial attempt - // to gossip the message, therefore we decrement `previous_attempts` - // so that the state machine below works the same way it does for - // authority nodes. - previous_attempts -= 1; - } - if peer.roles.is_authority() { let authorities = self.peers.authorities(); - // the target node is an authority, on the first attempt we start by + // the target node is an authority, on the first round duration we start by // sending the message to only `sqrt(authorities)` (if we're - // connected to at least `MIN_AUTHORITIES`). - if previous_attempts == 0 && authorities > MIN_AUTHORITIES { - let authorities = authorities as f64; - let p = (authorities.sqrt()).max(MIN_AUTHORITIES as f64) / authorities; - rand::thread_rng().gen_bool(p) + // connected to at least `MIN_LUCKY`). + if round_elapsed < round_duration * PROPAGATION_ALL_AUTHORITIES + && authorities > MIN_LUCKY + { + self.peers.lucky_authorities.contains(who) } else { // otherwise we already went through the step above, so // we won't filter the message and send it to all @@ -1038,15 +1096,13 @@ impl Inner { } } else { // the node is not an authority so we apply stricter filters - if previous_attempts >= 3 { - // if we previously tried to send this message 3 (or more) - // times, then it is allowed to be sent to all peers. + if round_elapsed >= round_duration * PROPAGATION_ALL { + // if we waited for 3 (or more) rounds + // then it is allowed to be sent to all peers. true - } else if previous_attempts == 2 { + } else if round_elapsed >= round_duration * PROPAGATION_SOME_NON_AUTHORITIES { // otherwise we only send it to `sqrt(non-authorities)`. - let non_authorities = self.peers.non_authorities() as f64; - let p = non_authorities.sqrt() / non_authorities; - rand::thread_rng().gen_bool(p) + self.peers.lucky_peers.contains(who) } else { false } @@ -1067,19 +1123,20 @@ impl Inner { /// /// Transitions will be triggered on repropagation attempts by the /// underlying gossip layer, which should happen every 30 seconds. - fn global_message_allowed(&self, peer: &PeerInfo, previous_attempts: usize) -> bool { - const MIN_PEERS: usize = 5; + fn global_message_allowed(&self, who: &PeerId, peer: &PeerInfo) -> bool { + let round_duration = self.config.gossip_duration * ROUND_DURATION; + let round_elapsed = self.round_start.elapsed(); if peer.roles.is_authority() { let authorities = self.peers.authorities(); - // the target node is an authority, on the first attempt we start by + // the target node is an authority, on the first round duration we start by // sending the message to only `sqrt(authorities)` (if we're - // connected to at least `MIN_PEERS`). - if previous_attempts == 0 && authorities > MIN_PEERS { - let authorities = authorities as f64; - let p = (authorities.sqrt()).max(MIN_PEERS as f64) / authorities; - rand::thread_rng().gen_bool(p) + // connected to at least `MIN_LUCKY`). + if round_elapsed < round_duration * PROPAGATION_ALL_AUTHORITIES + && authorities > MIN_LUCKY + { + self.peers.lucky_authorities.contains(who) } else { // otherwise we already went through the step above, so // we won't filter the message and send it to all @@ -1090,13 +1147,13 @@ impl Inner { let non_authorities = self.peers.non_authorities(); // the target node is not an authority, on the first and second - // attempt we start by sending the message to only + // round duration we start by sending the message to only // `sqrt(non_authorities)` (if we're connected to at least - // `MIN_PEERS`). - if previous_attempts <= 1 && non_authorities > MIN_PEERS { - let non_authorities = non_authorities as f64; - let p = (non_authorities.sqrt()).max(MIN_PEERS as f64) / non_authorities ; - rand::thread_rng().gen_bool(p) + // `MIN_LUCKY`). + if round_elapsed < round_duration * PROPAGATION_SOME_NON_AUTHORITIES + && non_authorities > MIN_LUCKY + { + self.peers.lucky_peers.contains(who) } else { // otherwise we already went through the step above, so // we won't filter the message and send it to all @@ -1168,7 +1225,7 @@ impl GossipValidator { self.inner.write().note_catch_up_message_processed(); } - fn report(&self, who: PeerId, cost_benefit: i32) { + fn report(&self, who: PeerId, cost_benefit: ReputationChange) { let _ = self.report_sender.unbounded_send(PeerReport { who, cost_benefit }); } @@ -1223,7 +1280,7 @@ impl GossipValidator { } } -impl network_gossip::Validator for GossipValidator { +impl sc_network_gossip::Validator for GossipValidator { fn new_peer(&self, context: &mut dyn ValidatorContext, who: &PeerId, roles: Roles) { let packet = { let mut inner = self.inner.write(); @@ -1249,7 +1306,7 @@ impl network_gossip::Validator for GossipValidator } fn validate(&self, context: &mut dyn ValidatorContext, who: &PeerId, data: &[u8]) - -> network_gossip::ValidationResult + -> sc_network_gossip::ValidationResult { let (action, broadcast_topics, peer_reply) = self.do_validate(who, data); @@ -1266,15 +1323,15 @@ impl network_gossip::Validator for GossipValidator Action::Keep(topic, cb) => { self.report(who.clone(), cb); context.broadcast_message(topic, data.to_vec(), false); - network_gossip::ValidationResult::ProcessAndKeep(topic) + sc_network_gossip::ValidationResult::ProcessAndKeep(topic) } Action::ProcessAndDiscard(topic, cb) => { self.report(who.clone(), cb); - network_gossip::ValidationResult::ProcessAndDiscard(topic) + sc_network_gossip::ValidationResult::ProcessAndDiscard(topic) } Action::Discard(cb) => { self.report(who.clone(), cb); - network_gossip::ValidationResult::Discard + sc_network_gossip::ValidationResult::Discard } } } @@ -1315,14 +1372,14 @@ impl network_gossip::Validator for GossipValidator Some(x) => x, }; - if let MessageIntent::Broadcast { previous_attempts } = intent { + if let MessageIntent::Broadcast = intent { if maybe_round.is_some() { - if !inner.round_message_allowed(peer, previous_attempts) { + if !inner.round_message_allowed(who, peer) { // early return if the vote message isn't allowed at this stage. return false; } } else { - if !inner.global_message_allowed(peer, previous_attempts) { + if !inner.global_message_allowed(who, peer) { // early return if the global message isn't allowed at this stage. return false; } @@ -1390,7 +1447,7 @@ impl network_gossip::Validator for GossipValidator struct PeerReport { who: PeerId, - cost_benefit: i32, + cost_benefit: ReputationChange, } // wrapper around a stream of reports. @@ -1402,29 +1459,26 @@ pub(super) struct ReportStream { impl ReportStream { /// Consume the report stream, converting it into a future that /// handles all reports. - pub(super) fn consume(self, net: N) + pub(super) fn consume(self, net: GossipEngine) -> impl Future + Send + 'static where B: BlockT, - N: super::Network + Send + 'static, { ReportingTask { reports: self.reports, net, - _marker: Default::default(), } } } /// A future for reporting peers. #[must_use = "Futures do nothing unless polled"] -struct ReportingTask { +struct ReportingTask { reports: mpsc::UnboundedReceiver, - net: N, - _marker: std::marker::PhantomData, + net: GossipEngine, } -impl> Future for ReportingTask { +impl Future for ReportingTask { type Item = (); type Error = (); @@ -1448,9 +1502,9 @@ impl> Future for ReportingTask { mod tests { use super::*; use super::environment::SharedVoterSetState; - use network_gossip::Validator as GossipValidatorT; - use network::test::Block; - use primitives::{crypto::Public, H256}; + use sc_network_gossip::Validator as GossipValidatorT; + use sc_network_test::Block; + use sp_core::{crypto::Public, H256}; // some random config (not really needed) fn config() -> crate::Config { @@ -1672,7 +1726,7 @@ mod tests { round: Round(1), set_id: SetId(set_id), message: SignedMessage:: { - message: grandpa::Message::Prevote(grandpa::Prevote { + message: finality_grandpa::Message::Prevote(finality_grandpa::Prevote { target_hash: Default::default(), target_number: 10, }), @@ -1685,7 +1739,7 @@ mod tests { round: Round(1), set_id: SetId(set_id), message: SignedMessage:: { - message: grandpa::Message::Prevote(grandpa::Prevote { + message: finality_grandpa::Message::Prevote(finality_grandpa::Prevote { target_hash: Default::default(), target_number: 10, }), @@ -1716,7 +1770,7 @@ mod tests { let mut inner = val.inner.write(); inner.validate_catch_up_message(&peer, &FullCatchUpMessage { set_id: SetId(set_id), - message: grandpa::CatchUp { + message: finality_grandpa::CatchUp { round_number: 10, prevotes: Default::default(), precommits: Default::default(), @@ -1752,7 +1806,7 @@ mod tests { completed_rounds.push(environment::CompletedRound { number: 2, - state: grandpa::round::State::genesis(Default::default()), + state: finality_grandpa::round::State::genesis(Default::default()), base: Default::default(), votes: Default::default(), }); @@ -2132,8 +2186,12 @@ mod tests { #[test] fn progressively_gossips_to_more_peers() { + let mut config = config(); + config.gossip_duration = Duration::from_secs(300); // Set to high value to prevent test race + let round_duration = config.gossip_duration * ROUND_DURATION; + let (val, _) = GossipValidator::::new( - config(), + config, voter_set_state(), ); @@ -2152,7 +2210,9 @@ mod tests { val.inner.write().peers.new_peer(full_nodes[i].clone(), Roles::FULL); } - let test = |previous_attempts, peers| { + let test = |num_round, peers| { + // rewind n round durations + val.inner.write().round_start = Instant::now() - round_duration * num_round; let mut message_allowed = val.message_allowed(); move || { @@ -2160,7 +2220,7 @@ mod tests { for peer in peers { if message_allowed( peer, - MessageIntent::Broadcast { previous_attempts }, + MessageIntent::Broadcast, &crate::communication::round_topic::(1, 0), &[], ) { @@ -2187,22 +2247,22 @@ mod tests { // on the first attempt we will only gossip to `sqrt(authorities)`, // which should average out to 5 peers after a couple of trials - assert_eq!(trial(test(0, &authorities)), 5); + assert_eq!(trial(test(1, &authorities)), 5); // on the second (and subsequent attempts) we should gossip to all // authorities we're connected to. - assert_eq!(trial(test(1, &authorities)), 30); assert_eq!(trial(test(2, &authorities)), 30); + assert_eq!(trial(test(3, &authorities)), 30); // we should only gossip to non-authorities after the third attempt - assert_eq!(trial(test(0, &full_nodes)), 0); assert_eq!(trial(test(1, &full_nodes)), 0); + assert_eq!(trial(test(2, &full_nodes)), 0); // and only to `sqrt(non-authorities)` - assert_eq!(trial(test(2, &full_nodes)), 5); + assert_eq!(trial(test(3, &full_nodes)), 5); // only on the fourth attempt should we gossip to all non-authorities - assert_eq!(trial(test(3, &full_nodes)), 30); + assert_eq!(trial(test(4, &full_nodes)), 30); } #[test] @@ -2231,7 +2291,7 @@ mod tests { assert!( message_allowed( authority, - MessageIntent::Broadcast { previous_attempts: 0 }, + MessageIntent::Broadcast, &crate::communication::round_topic::(1, 0), &[], ) @@ -2240,9 +2300,11 @@ mod tests { } #[test] - fn non_authorities_never_gossip_messages_on_first_attempt() { + fn non_authorities_never_gossip_messages_on_first_round_duration() { let mut config = config(); + config.gossip_duration = Duration::from_secs(300); // Set to high value to prevent test race config.is_authority = false; + let round_duration = config.gossip_duration * ROUND_DURATION; let (val, _) = GossipValidator::::new( config, @@ -2259,32 +2321,37 @@ mod tests { authorities.push(peer_id); } - let mut message_allowed = val.message_allowed(); - - // since our node is not an authority we should **never** gossip any - // messages on the first attempt. - for authority in &authorities { - assert!( - !message_allowed( - authority, - MessageIntent::Broadcast { previous_attempts: 0 }, - &crate::communication::round_topic::(1, 0), - &[], - ) - ); + { + let mut message_allowed = val.message_allowed(); + // since our node is not an authority we should **never** gossip any + // messages on the first attempt. + for authority in &authorities { + assert!( + !message_allowed( + authority, + MessageIntent::Broadcast, + &crate::communication::round_topic::(1, 0), + &[], + ) + ); + } } - // on the third attempt we should allow messages to authorities - // (on the second attempt we would do `sqrt(authorities)`) - for authority in &authorities { - assert!( - message_allowed( - authority, - MessageIntent::Broadcast { previous_attempts: 2 }, - &crate::communication::round_topic::(1, 0), - &[], - ) - ); + { + val.inner.write().round_start = Instant::now() - round_duration * 4; + let mut message_allowed = val.message_allowed(); + // on the fourth round duration we should allow messages to authorities + // (on the second we would do `sqrt(authorities)`) + for authority in &authorities { + assert!( + message_allowed( + authority, + MessageIntent::Broadcast, + &crate::communication::round_topic::(1, 0), + &[], + ) + ); + } } } } diff --git a/client/finality-grandpa/src/communication/mod.rs b/client/finality-grandpa/src/communication/mod.rs index 247f9efd2df186e335b698ba8bc715e23c749be2..cfd1bfdbb382b12eeb8a6f1e8d2b7dfdd843c43e 100644 --- a/client/finality-grandpa/src/communication/mod.rs +++ b/client/finality-grandpa/src/communication/mod.rs @@ -29,19 +29,17 @@ use std::sync::Arc; -use futures::prelude::*; -use futures::sync::{oneshot, mpsc}; -use futures03::stream::{StreamExt, TryStreamExt}; -use grandpa::Message::{Prevote, Precommit, PrimaryPropose}; -use grandpa::{voter, voter_set::VoterSet}; +use futures::{prelude::*, future::Executor as _, sync::mpsc}; +use futures03::{compat::Compat, stream::StreamExt, future::FutureExt as _, future::TryFutureExt as _}; +use finality_grandpa::Message::{Prevote, Precommit, PrimaryPropose}; +use finality_grandpa::{voter, voter_set::VoterSet}; use log::{debug, trace}; -use network::{consensus_gossip as network_gossip, NetworkService}; -use network_gossip::ConsensusMessage; -use codec::{Encode, Decode}; -use primitives::Pair; -use sr_primitives::traits::{Block as BlockT, Hash as HashT, Header as HeaderT, NumberFor}; -use substrate_telemetry::{telemetry, CONSENSUS_DEBUG, CONSENSUS_INFO}; -use tokio_executor::Executor; +use sc_network::{NetworkService, ReputationChange}; +use sc_network_gossip::{GossipEngine, Network as GossipNetwork}; +use parity_scale_codec::{Encode, Decode}; +use sp_core::Pair; +use sp_runtime::traits::{Block as BlockT, Hash as HashT, Header as HeaderT, NumberFor}; +use sc_telemetry::{telemetry, CONSENSUS_DEBUG, CONSENSUS_INFO}; use crate::{ CatchUp, Commit, CommunicationIn, CommunicationOut, CompactCommit, Error, @@ -51,7 +49,7 @@ use crate::environment::HasVoted; use gossip::{ GossipMessage, FullCatchUpMessage, FullCommitMessage, VoteMessage, GossipValidator }; -use fg_primitives::{ +use sp_finality_grandpa::{ AuthorityPair, AuthorityId, AuthoritySignature, SetId as SetIdNumber, RoundNumber, }; @@ -61,245 +59,103 @@ mod periodic; #[cfg(test)] mod tests; -pub use fg_primitives::GRANDPA_ENGINE_ID; +pub use sp_finality_grandpa::GRANDPA_ENGINE_ID; // cost scalars for reporting peers. mod cost { - pub(super) const PAST_REJECTION: i32 = -50; - pub(super) const BAD_SIGNATURE: i32 = -100; - pub(super) const MALFORMED_CATCH_UP: i32 = -1000; - pub(super) const MALFORMED_COMMIT: i32 = -1000; - pub(super) const FUTURE_MESSAGE: i32 = -500; - pub(super) const UNKNOWN_VOTER: i32 = -150; - - pub(super) const INVALID_VIEW_CHANGE: i32 = -500; + use sc_network::ReputationChange as Rep; + pub(super) const PAST_REJECTION: Rep = Rep::new(-50, "Grandpa: Past message"); + pub(super) const BAD_SIGNATURE: Rep = Rep::new(-100, "Grandpa: Bad signature"); + pub(super) const MALFORMED_CATCH_UP: Rep = Rep::new(-1000, "Grandpa: Malformed cath-up"); + pub(super) const MALFORMED_COMMIT: Rep = Rep::new(-1000, "Grandpa: Malformed commit"); + pub(super) const FUTURE_MESSAGE: Rep = Rep::new(-500, "Grandpa: Future message"); + pub(super) const UNKNOWN_VOTER: Rep = Rep::new(-150, "Grandpa: Uknown voter"); + + pub(super) const INVALID_VIEW_CHANGE: Rep = Rep::new(-500, "Grandpa: Invalid view change"); pub(super) const PER_UNDECODABLE_BYTE: i32 = -5; pub(super) const PER_SIGNATURE_CHECKED: i32 = -25; pub(super) const PER_BLOCK_LOADED: i32 = -10; - pub(super) const INVALID_CATCH_UP: i32 = -5000; - pub(super) const INVALID_COMMIT: i32 = -5000; - pub(super) const OUT_OF_SCOPE_MESSAGE: i32 = -500; - pub(super) const CATCH_UP_REQUEST_TIMEOUT: i32 = -200; + pub(super) const INVALID_CATCH_UP: Rep = Rep::new(-5000, "Grandpa: Invalid catch-up"); + pub(super) const INVALID_COMMIT: Rep = Rep::new(-5000, "Grandpa: Invalid commit"); + pub(super) const OUT_OF_SCOPE_MESSAGE: Rep = Rep::new(-500, "Grandpa: Out-of-scope message"); + pub(super) const CATCH_UP_REQUEST_TIMEOUT: Rep = Rep::new(-200, "Grandpa: Catch-up reqeust timeout"); // cost of answering a catch up request - pub(super) const CATCH_UP_REPLY: i32 = -200; - pub(super) const HONEST_OUT_OF_SCOPE_CATCH_UP: i32 = -200; + pub(super) const CATCH_UP_REPLY: Rep = Rep::new(-200, "Grandpa: Catch-up reply"); + pub(super) const HONEST_OUT_OF_SCOPE_CATCH_UP: Rep = Rep::new(-200, "Grandpa: Out-of-scope catch-up"); } // benefit scalars for reporting peers. mod benefit { - pub(super) const NEIGHBOR_MESSAGE: i32 = 100; - pub(super) const ROUND_MESSAGE: i32 = 100; - pub(super) const BASIC_VALIDATED_CATCH_UP: i32 = 200; - pub(super) const BASIC_VALIDATED_COMMIT: i32 = 100; + use sc_network::ReputationChange as Rep; + pub(super) const NEIGHBOR_MESSAGE: Rep = Rep::new(100, "Grandpa: Neighbor message"); + pub(super) const ROUND_MESSAGE: Rep = Rep::new(100, "Grandpa: Round message"); + pub(super) const BASIC_VALIDATED_CATCH_UP: Rep = Rep::new(200, "Grandpa: Catch-up message"); + pub(super) const BASIC_VALIDATED_COMMIT: Rep = Rep::new(100, "Grandpa: Commit"); pub(super) const PER_EQUIVOCATION: i32 = 10; } -/// A handle to the network. This is generally implemented by providing some -/// handle to a gossip service or similar. +/// A handle to the network. /// -/// Intended to be a lightweight handle such as an `Arc`. -pub trait Network: Clone + Send + 'static { - /// A stream of input messages for a topic. - type In: Stream; - - /// Get a stream of messages for a specific gossip topic. - fn messages_for(&self, topic: Block::Hash) -> Self::In; - - /// Register a gossip validator. - fn register_validator(&self, validator: Arc>); - - /// Gossip a message out to all connected peers. - /// - /// Force causes it to be sent to all peers, even if they've seen it already. - /// Only should be used in case of consensus stall. - fn gossip_message(&self, topic: Block::Hash, data: Vec, force: bool); - - /// Register a message with the gossip service, it isn't broadcast right - /// away to any peers, but may be sent to new peers joining or when asked to - /// broadcast the topic. Useful to register previous messages on node - /// startup. - fn register_gossip_message(&self, topic: Block::Hash, data: Vec); - - /// Send a message to a bunch of specific peers, even if they've seen it already. - fn send_message(&self, who: Vec, data: Vec); - - /// Report a peer's cost or benefit after some action. - fn report(&self, who: network::PeerId, cost_benefit: i32); - - /// Inform peers that a block with given hash should be downloaded. - fn announce(&self, block: Block::Hash, associated_data: Vec); - +/// Something that provides both the capabilities needed for the `gossip_network::Network` trait as +/// well as the ability to set a fork sync request for a particular block. +pub trait Network: GossipNetwork + Clone + Send + 'static { /// Notifies the sync service to try and sync the given block from the given /// peers. /// /// If the given vector of peers is empty then the underlying implementation /// should make a best effort to fetch the block from any peers it is /// connected to (NOTE: this assumption will change in the future #3629). - fn set_sync_fork_request(&self, peers: Vec, hash: Block::Hash, number: NumberFor); -} - -/// Create a unique topic for a round and set-id combo. -pub(crate) fn round_topic(round: RoundNumber, set_id: SetIdNumber) -> B::Hash { - <::Hashing as HashT>::hash(format!("{}-{}", set_id, round).as_bytes()) -} - -/// Create a unique topic for global messages on a set ID. -pub(crate) fn global_topic(set_id: SetIdNumber) -> B::Hash { - <::Hashing as HashT>::hash(format!("{}-GLOBAL", set_id).as_bytes()) + fn set_sync_fork_request(&self, peers: Vec, hash: Block::Hash, number: NumberFor); } impl Network for Arc> where B: BlockT, - S: network::specialization::NetworkSpecialization, - H: network::ExHashT, + S: sc_network::specialization::NetworkSpecialization, + H: sc_network::ExHashT, { - type In = NetworkStream< - Box + Send + 'static>, - >; - - fn messages_for(&self, topic: B::Hash) -> Self::In { - // Given that one can only communicate with the Substrate network via the `NetworkService` via message-passing, - // and given that methods on the network consensus gossip are not exposed but only reachable by passing a - // closure into `with_gossip` on the `NetworkService` this function needs to make use of the `NetworkStream` - // construction. - // - // We create a oneshot channel and pass the sender within a closure to the network. At some point in the future - // the network passes the message channel back through the oneshot channel. But the consumer of this function - // expects a stream, not a stream within a oneshot. This complexity is abstracted within `NetworkStream`, - // waiting for the oneshot to resolve and from there on acting like a normal message channel. - let (tx, rx) = oneshot::channel(); - self.with_gossip(move |gossip, _| { - let inner_rx: Box + Send> = Box::new(gossip - .messages_for(GRANDPA_ENGINE_ID, topic) - .map(|x| Ok(x)) - .compat() - ); - let _ = tx.send(inner_rx); - }); - NetworkStream::PollingOneshot(rx) - } - - fn register_validator(&self, validator: Arc>) { - self.with_gossip( - move |gossip, context| gossip.register_validator(context, GRANDPA_ENGINE_ID, validator) - ) - } - - fn gossip_message(&self, topic: B::Hash, data: Vec, force: bool) { - let msg = ConsensusMessage { - engine_id: GRANDPA_ENGINE_ID, - data, - }; - - self.with_gossip( - move |gossip, ctx| gossip.multicast(ctx, topic, msg, force) - ) - } - - fn register_gossip_message(&self, topic: B::Hash, data: Vec) { - let msg = ConsensusMessage { - engine_id: GRANDPA_ENGINE_ID, - data, - }; - - self.with_gossip(move |gossip, _| gossip.register_message(topic, msg)) - } - - fn send_message(&self, who: Vec, data: Vec) { - let msg = ConsensusMessage { - engine_id: GRANDPA_ENGINE_ID, - data, - }; - - self.with_gossip(move |gossip, ctx| for who in &who { - gossip.send_message(ctx, who, msg.clone()) - }) - } - - fn report(&self, who: network::PeerId, cost_benefit: i32) { - self.report_peer(who, cost_benefit) - } - - fn announce(&self, block: B::Hash, associated_data: Vec) { - self.announce_block(block, associated_data) - } - - fn set_sync_fork_request(&self, peers: Vec, hash: B::Hash, number: NumberFor) { + fn set_sync_fork_request(&self, peers: Vec, hash: B::Hash, number: NumberFor) { NetworkService::set_sync_fork_request(self, peers, hash, number) } } -/// A stream used by NetworkBridge in its implementation of Network. Given a oneshot that eventually returns a channel -/// which eventually returns messages, instead of: -/// -/// 1. polling the oneshot until it returns a message channel -/// -/// 2. polling the message channel for messages -/// -/// `NetworkStream` combines the two steps into one, requiring a consumer to only poll `NetworkStream` to retrieve -/// messages directly. -pub enum NetworkStream { - PollingOneshot(oneshot::Receiver), - PollingTopicNotifications(R), +/// Create a unique topic for a round and set-id combo. +pub(crate) fn round_topic(round: RoundNumber, set_id: SetIdNumber) -> B::Hash { + <::Hashing as HashT>::hash(format!("{}-{}", set_id, round).as_bytes()) } -impl Stream for NetworkStream -where - R: Stream, -{ - type Item = R::Item; - type Error = (); - - fn poll(&mut self) -> Poll, Self::Error> { - match self { - NetworkStream::PollingOneshot(oneshot) => { - match oneshot.poll() { - Ok(futures::Async::Ready(mut stream)) => { - let poll_result = stream.poll(); - *self = NetworkStream::PollingTopicNotifications(stream); - poll_result - }, - Ok(futures::Async::NotReady) => Ok(futures::Async::NotReady), - Err(_) => Err(()) - } - }, - NetworkStream::PollingTopicNotifications(stream) => { - stream.poll() - }, - } - } +/// Create a unique topic for global messages on a set ID. +pub(crate) fn global_topic(set_id: SetIdNumber) -> B::Hash { + <::Hashing as HashT>::hash(format!("{}-GLOBAL", set_id).as_bytes()) } /// Bridge between the underlying network service, gossiping consensus messages and Grandpa pub(crate) struct NetworkBridge> { service: N, + gossip_engine: GossipEngine, validator: Arc>, neighbor_sender: periodic::NeighborPacketSender, } impl> NetworkBridge { /// Create a new NetworkBridge to the given NetworkService. Returns the service - /// handle and a future that must be polled to completion to finish startup. + /// handle. /// On creation it will register previous rounds' votes with the gossip /// service taken from the VoterSetState. pub(crate) fn new( service: N, config: crate::Config, set_state: crate::environment::SharedVoterSetState, - on_exit: impl Future + Clone + Send + 'static, - ) -> ( - Self, - impl Future + Send + 'static, - ) { - + executor: &impl futures03::task::Spawn, + on_exit: impl futures03::Future + Clone + Send + Unpin + 'static, + ) -> Self { let (validator, report_stream) = GossipValidator::new( config, set_state.clone(), ); let validator = Arc::new(validator); - service.register_validator(validator.clone()); + let gossip_engine = GossipEngine::new(service.clone(), executor, GRANDPA_ENGINE_ID, validator.clone()); { // register all previous votes with the gossip service so that they're @@ -323,7 +179,7 @@ impl> NetworkBridge { } ); - service.register_gossip_message( + gossip_engine.register_gossip_message( topic, message.encode(), ); @@ -339,23 +195,18 @@ impl> NetworkBridge { } } - let (rebroadcast_job, neighbor_sender) = periodic::neighbor_packet_worker(service.clone()); - let reporting_job = report_stream.consume(service.clone()); + let (rebroadcast_job, neighbor_sender) = periodic::neighbor_packet_worker(gossip_engine.clone()); + let reporting_job = report_stream.consume(gossip_engine.clone()); - let bridge = NetworkBridge { service, validator, neighbor_sender }; + let bridge = NetworkBridge { service, gossip_engine, validator, neighbor_sender }; - let startup_work = futures::future::lazy(move || { - // lazily spawn these jobs onto their own tasks. the lazy future has access - // to tokio globals, which aren't available outside. - let mut executor = tokio_executor::DefaultExecutor::current(); - executor.spawn(Box::new(rebroadcast_job.select(on_exit.clone()).then(|_| Ok(())))) - .expect("failed to spawn grandpa rebroadcast job task"); - executor.spawn(Box::new(reporting_job.select(on_exit.clone()).then(|_| Ok(())))) - .expect("failed to spawn grandpa reporting job task"); - Ok(()) - }); + let executor = Compat::new(executor); + executor.execute(Box::new(rebroadcast_job.select(on_exit.clone().map(Ok).compat()).then(|_| Ok(())))) + .expect("failed to spawn grandpa rebroadcast job task"); + executor.execute(Box::new(reporting_job.select(on_exit.clone().map(Ok).compat()).then(|_| Ok(())))) + .expect("failed to spawn grandpa reporting job task"); - (bridge, startup_work) + bridge } /// Note the beginning of a new round to the `GossipValidator`. @@ -407,7 +258,8 @@ impl> NetworkBridge { }); let topic = round_topic::(round.0, set_id.0); - let incoming = self.service.messages_for(topic) + let incoming = Compat::new(self.gossip_engine.messages_for(topic) + .map(|item| Ok::<_, ()>(item))) .filter_map(|notification| { let decoded = GossipMessage::::decode(&mut ¬ification.message[..]); if let Err(ref e) = decoded { @@ -460,10 +312,10 @@ impl> NetworkBridge { .map_err(|()| Error::Network(format!("Failed to receive message on unbounded stream"))); let (tx, out_rx) = mpsc::unbounded(); - let outgoing = OutgoingMessages:: { + let outgoing = OutgoingMessages:: { round: round.0, set_id: set_id.0, - network: self.service.clone(), + network: self.gossip_engine.clone(), locals, sender: tx, has_voted, @@ -497,7 +349,7 @@ impl> NetworkBridge { |to, neighbor| self.neighbor_sender.send(to, neighbor), ); - let service = self.service.clone(); + let service = self.gossip_engine.clone(); let topic = global_topic::(set_id.0); let incoming = incoming_global( service, @@ -507,8 +359,8 @@ impl> NetworkBridge { self.neighbor_sender.clone(), ); - let outgoing = CommitsOut::::new( - self.service.clone(), + let outgoing = CommitsOut::::new( + self.gossip_engine.clone(), set_id.0, is_voter, self.validator.clone(), @@ -529,13 +381,18 @@ impl> NetworkBridge { /// If the given vector of peers is empty then the underlying implementation /// should make a best effort to fetch the block from any peers it is /// connected to (NOTE: this assumption will change in the future #3629). - pub(crate) fn set_sync_fork_request(&self, peers: Vec, hash: B::Hash, number: NumberFor) { - self.service.set_sync_fork_request(peers, hash, number) + pub(crate) fn set_sync_fork_request( + &self, + peers: Vec, + hash: B::Hash, + number: NumberFor + ) { + Network::set_sync_fork_request(&self.service, peers, hash, number) } } -fn incoming_global>( - mut service: N, +fn incoming_global( + mut gossip_engine: GossipEngine, topic: B::Hash, voters: Arc>, gossip_validator: Arc>, @@ -543,8 +400,8 @@ fn incoming_global>( ) -> impl Stream, Error = Error> { let process_commit = move | msg: FullCommitMessage, - mut notification: network_gossip::TopicNotification, - service: &mut N, + mut notification: sc_network_gossip::TopicNotification, + gossip_engine: &mut GossipEngine, gossip_validator: &Arc>, voters: &VoterSet, | { @@ -566,7 +423,7 @@ fn incoming_global>( msg.set_id, ) { if let Some(who) = notification.sender { - service.report(who, cost); + gossip_engine.report(who, cost); } return None; @@ -576,7 +433,7 @@ fn incoming_global>( let commit = msg.message; let finalized_number = commit.target_number; let gossip_validator = gossip_validator.clone(); - let service = service.clone(); + let gossip_engine = gossip_engine.clone(); let neighbor_sender = neighbor_sender.clone(); let cb = move |outcome| match outcome { voter::CommitProcessingOutcome::Good(_) => { @@ -588,12 +445,12 @@ fn incoming_global>( |to, neighbor| neighbor_sender.send(to, neighbor), ); - service.gossip_message(topic, notification.message.clone(), false); + gossip_engine.gossip_message(topic, notification.message.clone(), false); } voter::CommitProcessingOutcome::Bad(_) => { // report peer and do not gossip. if let Some(who) = notification.sender.take() { - service.report(who, cost::INVALID_COMMIT); + gossip_engine.report(who, cost::INVALID_COMMIT); } } }; @@ -605,13 +462,13 @@ fn incoming_global>( let process_catch_up = move | msg: FullCatchUpMessage, - mut notification: network_gossip::TopicNotification, - service: &mut N, + mut notification: sc_network_gossip::TopicNotification, + gossip_engine: &mut GossipEngine, gossip_validator: &Arc>, voters: &VoterSet, | { let gossip_validator = gossip_validator.clone(); - let service = service.clone(); + let gossip_engine = gossip_engine.clone(); if let Err(cost) = check_catch_up::( &msg.message, @@ -619,7 +476,7 @@ fn incoming_global>( msg.set_id, ) { if let Some(who) = notification.sender { - service.report(who, cost); + gossip_engine.report(who, cost); } return None; @@ -629,7 +486,7 @@ fn incoming_global>( if let voter::CatchUpProcessingOutcome::Bad(_) = outcome { // report peer if let Some(who) = notification.sender.take() { - service.report(who, cost::INVALID_CATCH_UP); + gossip_engine.report(who, cost::INVALID_CATCH_UP); } } @@ -641,7 +498,8 @@ fn incoming_global>( Some(voter::CommunicationIn::CatchUp(msg.message, cb)) }; - service.messages_for(topic) + Compat::new(gossip_engine.messages_for(topic) + .map(|m| Ok::<_, ()>(m))) .filter_map(|notification| { // this could be optimized by decoding piecewise. let decoded = GossipMessage::::decode(&mut ¬ification.message[..]); @@ -653,9 +511,9 @@ fn incoming_global>( .filter_map(move |(notification, msg)| { match msg { GossipMessage::Commit(msg) => - process_commit(msg, notification, &mut service, &gossip_validator, &*voters), + process_commit(msg, notification, &mut gossip_engine, &gossip_validator, &*voters), GossipMessage::CatchUp(msg) => - process_catch_up(msg, notification, &mut service, &gossip_validator, &*voters), + process_catch_up(msg, notification, &mut gossip_engine, &gossip_validator, &*voters), _ => { debug!(target: "afg", "Skipping unknown message type"); return None; @@ -669,6 +527,7 @@ impl> Clone for NetworkBridge { fn clone(&self) -> Self { NetworkBridge { service: self.service.clone(), + gossip_engine: self.gossip_engine.clone(), validator: Arc::clone(&self.validator), neighbor_sender: self.neighbor_sender.clone(), } @@ -712,16 +571,16 @@ pub(crate) fn check_message_sig( /// use the same raw message and key to sign. This is currently true for /// `ed25519` and `BLS` signatures (which we might use in the future), care must /// be taken when switching to different key types. -struct OutgoingMessages> { +struct OutgoingMessages { round: RoundNumber, set_id: SetIdNumber, locals: Option<(AuthorityPair, AuthorityId)>, sender: mpsc::UnboundedSender>, - network: N, + network: GossipEngine, has_voted: HasVoted, } -impl> Sink for OutgoingMessages +impl Sink for OutgoingMessages { type SinkItem = Message; type SinkError = Error; @@ -729,15 +588,15 @@ impl> Sink for OutgoingMessages fn start_send(&mut self, mut msg: Message) -> StartSend, Error> { // if we've voted on this round previously under the same key, send that vote instead match &mut msg { - grandpa::Message::PrimaryPropose(ref mut vote) => + finality_grandpa::Message::PrimaryPropose(ref mut vote) => if let Some(propose) = self.has_voted.propose() { *vote = propose.clone(); }, - grandpa::Message::Prevote(ref mut vote) => + finality_grandpa::Message::Prevote(ref mut vote) => if let Some(prevote) = self.has_voted.prevote() { *vote = prevote.clone(); }, - grandpa::Message::Precommit(ref mut vote) => + finality_grandpa::Message::Precommit(ref mut vote) => if let Some(precommit) = self.has_voted.precommit() { *vote = precommit.clone(); }, @@ -803,7 +662,7 @@ fn check_compact_commit( voters: &VoterSet, round: Round, set_id: SetId, -) -> Result<(), i32> { +) -> Result<(), ReputationChange> { // 4f + 1 = equivocations from f voters. let f = voters.total_weight() - voters.threshold(); let full_threshold = voters.total_weight() + f; @@ -832,7 +691,7 @@ fn check_compact_commit( .enumerate() { use crate::communication::gossip::Misbehavior; - use grandpa::Message as GrandpaMessage; + use finality_grandpa::Message as GrandpaMessage; if let Err(()) = check_message_sig::( &GrandpaMessage::Precommit(precommit.clone()), @@ -862,7 +721,7 @@ fn check_catch_up( msg: &CatchUp, voters: &VoterSet, set_id: SetId, -) -> Result<(), i32> { +) -> Result<(), ReputationChange> { // 4f + 1 = equivocations from f voters. let f = voters.total_weight() - voters.threshold(); let full_threshold = voters.total_weight() + f; @@ -872,7 +731,7 @@ fn check_catch_up( voters: &'a VoterSet, votes: impl Iterator, full_threshold: u64, - ) -> Result<(), i32> { + ) -> Result<(), ReputationChange> { let mut total_weight = 0; for id in votes { @@ -911,7 +770,7 @@ fn check_catch_up( round: RoundNumber, set_id: SetIdNumber, mut signatures_checked: usize, - ) -> Result where + ) -> Result where B: BlockT, I: Iterator, &'a AuthorityId, &'a AuthoritySignature)>, { @@ -944,7 +803,7 @@ fn check_catch_up( // check signatures on all contained prevotes. let signatures_checked = check_signatures::( msg.prevotes.iter().map(|vote| { - (grandpa::Message::Prevote(vote.prevote.clone()), &vote.id, &vote.signature) + (finality_grandpa::Message::Prevote(vote.prevote.clone()), &vote.id, &vote.signature) }), msg.round_number, set_id.0, @@ -954,7 +813,7 @@ fn check_catch_up( // check signatures on all contained precommits. let _ = check_signatures::( msg.precommits.iter().map(|vote| { - (grandpa::Message::Precommit(vote.precommit.clone()), &vote.id, &vote.signature) + (finality_grandpa::Message::Precommit(vote.precommit.clone()), &vote.id, &vote.signature) }), msg.round_number, set_id.0, @@ -965,18 +824,18 @@ fn check_catch_up( } /// An output sink for commit messages. -struct CommitsOut> { - network: N, +struct CommitsOut { + network: GossipEngine, set_id: SetId, is_voter: bool, gossip_validator: Arc>, neighbor_sender: periodic::NeighborPacketSender, } -impl> CommitsOut { +impl CommitsOut { /// Create a new commit output stream. pub(crate) fn new( - network: N, + network: GossipEngine, set_id: SetIdNumber, is_voter: bool, gossip_validator: Arc>, @@ -992,7 +851,7 @@ impl> CommitsOut { } } -impl> Sink for CommitsOut { +impl Sink for CommitsOut { type SinkItem = (RoundNumber, Commit); type SinkError = Error; diff --git a/client/finality-grandpa/src/communication/periodic.rs b/client/finality-grandpa/src/communication/periodic.rs index 9dd662ce43461c2c8b88fe43316e145f51a504d2..318c84c22c672b02a3d17165627d786af21efbba 100644 --- a/client/finality-grandpa/src/communication/periodic.rs +++ b/client/finality-grandpa/src/communication/periodic.rs @@ -18,15 +18,17 @@ use std::time::{Instant, Duration}; -use codec::Encode; +use parity_scale_codec::Encode; use futures::prelude::*; use futures::sync::mpsc; +use futures_timer::Delay; +use futures03::future::{FutureExt as _, TryFutureExt as _}; use log::{debug, warn}; -use tokio_timer::Delay; -use network::PeerId; -use sr_primitives::traits::{NumberFor, Block as BlockT}; -use super::{gossip::{NeighborPacket, GossipMessage}, Network}; +use sc_network::PeerId; +use sc_network_gossip::GossipEngine; +use sp_runtime::traits::{NumberFor, Block as BlockT}; +use super::gossip::{NeighborPacket, GossipMessage}; // how often to rebroadcast, if no other const REBROADCAST_AFTER: Duration = Duration::from_secs(2 * 60); @@ -45,7 +47,7 @@ impl NeighborPacketSender { /// Send a neighbor packet for the background worker to gossip to peers. pub fn send( &self, - who: Vec, + who: Vec, neighbor_packet: NeighborPacket>, ) { if let Err(err) = self.0.unbounded_send((who, neighbor_packet)) { @@ -58,16 +60,15 @@ impl NeighborPacketSender { /// /// It may rebroadcast the last neighbor packet periodically when no /// progress is made. -pub(super) fn neighbor_packet_worker(net: N) -> ( +pub(super) fn neighbor_packet_worker(net: GossipEngine) -> ( impl Future + Send + 'static, NeighborPacketSender, ) where B: BlockT, - N: Network, { let mut last = None; let (tx, mut rx) = mpsc::unbounded::<(Vec, NeighborPacket>)>(); - let mut delay = Delay::new(rebroadcast_instant()); + let mut delay = Delay::new(REBROADCAST_AFTER); let work = futures::future::poll_fn(move || { loop { @@ -88,7 +89,7 @@ pub(super) fn neighbor_packet_worker(net: N) -> ( // has to be done in a loop because it needs to be polled after // re-scheduling. loop { - match delay.poll() { + match (&mut delay).unit_error().compat().poll() { Err(e) => { warn!(target: "afg", "Could not rebroadcast neighbor packets: {:?}", e); delay.reset(rebroadcast_instant()); diff --git a/client/finality-grandpa/src/communication/tests.rs b/client/finality-grandpa/src/communication/tests.rs index e8b399aef39b625d8846433818d3465f7ccc7f37..3e99d14de63e2679c157afd60ba86d3f2d4e603c 100644 --- a/client/finality-grandpa/src/communication/tests.rs +++ b/client/finality-grandpa/src/communication/tests.rs @@ -18,26 +18,24 @@ use futures::sync::mpsc; use futures::prelude::*; -use network::consensus_gossip as network_gossip; -use network::test::{Block, Hash}; -use network_gossip::Validator; +use sc_network::{Event as NetworkEvent, PeerId, config::Roles}; +use sc_network_test::{Block, Hash}; +use sc_network_gossip::Validator; use tokio::runtime::current_thread; use std::sync::Arc; -use keyring::Ed25519Keyring; -use codec::Encode; -use sr_primitives::traits::NumberFor; - +use sp_keyring::Ed25519Keyring; +use parity_scale_codec::Encode; +use sp_runtime::{ConsensusEngineId, traits::NumberFor}; +use std::{pin::Pin, task::{Context, Poll}}; use crate::environment::SharedVoterSetState; -use fg_primitives::AuthorityList; +use sp_finality_grandpa::{AuthorityList, GRANDPA_ENGINE_ID}; use super::gossip::{self, GossipValidator}; use super::{AuthorityId, VoterSet, Round, SetId}; enum Event { - MessagesFor(Hash, mpsc::UnboundedSender), - RegisterValidator(Arc>), - GossipMessage(Hash, Vec, bool), - SendMessage(Vec, Vec), - Report(network::PeerId, i32), + EventStream(mpsc::UnboundedSender), + WriteNotification(sc_network::PeerId, Vec), + Report(sc_network::PeerId, sc_network::ReputationChange), Announce(Hash), } @@ -46,68 +44,55 @@ struct TestNetwork { sender: mpsc::UnboundedSender, } -impl super::Network for TestNetwork { - type In = mpsc::UnboundedReceiver; - - /// Get a stream of messages for a specific gossip topic. - fn messages_for(&self, topic: Hash) -> Self::In { +impl sc_network_gossip::Network for TestNetwork { + fn event_stream(&self) + -> Box + Send> { let (tx, rx) = mpsc::unbounded(); - let _ = self.sender.unbounded_send(Event::MessagesFor(topic, tx)); - - rx + let _ = self.sender.unbounded_send(Event::EventStream(tx)); + Box::new(rx) } - /// Register a gossip validator. - fn register_validator(&self, validator: Arc>) { - let _ = self.sender.unbounded_send(Event::RegisterValidator(validator)); - } - - /// Gossip a message out to all connected peers. - /// - /// Force causes it to be sent to all peers, even if they've seen it already. - /// Only should be used in case of consensus stall. - fn gossip_message(&self, topic: Hash, data: Vec, force: bool) { - let _ = self.sender.unbounded_send(Event::GossipMessage(topic, data, force)); + fn report_peer(&self, who: sc_network::PeerId, cost_benefit: sc_network::ReputationChange) { + let _ = self.sender.unbounded_send(Event::Report(who, cost_benefit)); } - /// Send a message to a bunch of specific peers, even if they've seen it already. - fn send_message(&self, who: Vec, data: Vec) { - let _ = self.sender.unbounded_send(Event::SendMessage(who, data)); - } + fn disconnect_peer(&self, _: PeerId) {} - /// Register a message with the gossip service, it isn't broadcast right - /// away to any peers, but may be sent to new peers joining or when asked to - /// broadcast the topic. Useful to register previous messages on node - /// startup. - fn register_gossip_message(&self, _topic: Hash, _data: Vec) { - // NOTE: only required to restore previous state on startup - // not required for tests currently + fn write_notification(&self, who: PeerId, _: ConsensusEngineId, message: Vec) { + let _ = self.sender.unbounded_send(Event::WriteNotification(who, message)); } - /// Report a peer's cost or benefit after some action. - fn report(&self, who: network::PeerId, cost_benefit: i32) { - let _ = self.sender.unbounded_send(Event::Report(who, cost_benefit)); - } + fn register_notifications_protocol(&self, _: ConsensusEngineId) {} - /// Inform peers that a block with given hash should be downloaded. fn announce(&self, block: Hash, _associated_data: Vec) { let _ = self.sender.unbounded_send(Event::Announce(block)); } +} - /// Notify the sync service to try syncing the given chain. - fn set_sync_fork_request(&self, _peers: Vec, _hash: Hash, _number: NumberFor) {} +impl super::Network for TestNetwork { + fn set_sync_fork_request( + &self, + _peers: Vec, + _hash: Hash, + _number: NumberFor, + ) {} } -impl network_gossip::ValidatorContext for TestNetwork { +impl sc_network_gossip::ValidatorContext for TestNetwork { fn broadcast_topic(&mut self, _: Hash, _: bool) { } fn broadcast_message(&mut self, _: Hash, _: Vec, _: bool) { } - fn send_message(&mut self, who: &network::PeerId, data: Vec) { - >::send_message(self, vec![who.clone()], data); + fn send_message(&mut self, who: &sc_network::PeerId, data: Vec) { + >::write_notification( + self, + who.clone(), + GRANDPA_ENGINE_ID, + data, + ); } - fn send_topic(&mut self, _: &network::PeerId, _: Hash, _: bool) { } + fn send_topic(&mut self, _: &sc_network::PeerId, _: Hash, _: bool) { } } struct Tester { @@ -149,8 +134,8 @@ fn config() -> crate::Config { fn voter_set_state() -> SharedVoterSetState { use crate::authorities::AuthoritySet; use crate::environment::VoterSetState; - use grandpa::round::State as RoundState; - use primitives::H256; + use finality_grandpa::round::State as RoundState; + use sp_core::H256; let state = RoundState::genesis((H256::zero(), 0)); let base = state.prevote_ghost.unwrap(); @@ -165,7 +150,7 @@ fn voter_set_state() -> SharedVoterSetState { } // needs to run in a tokio runtime. -fn make_test_network() -> ( +fn make_test_network(executor: &impl futures03::task::Spawn) -> ( impl Future, TestNetwork, ) { @@ -175,24 +160,24 @@ fn make_test_network() -> ( #[derive(Clone)] struct Exit; - impl Future for Exit { - type Item = (); - type Error = (); + impl futures03::Future for Exit { + type Output = (); - fn poll(&mut self) -> Poll<(), ()> { - Ok(Async::NotReady) + fn poll(self: Pin<&mut Self>, _: &mut Context) -> Poll<()> { + Poll::Pending } } - let (bridge, startup_work) = super::NetworkBridge::new( + let bridge = super::NetworkBridge::new( net.clone(), config(), voter_set_state(), + executor, Exit, ); ( - startup_work.map(move |()| Tester { + futures::future::ok(Tester { gossip_validator: bridge.validator.clone(), net_handle: bridge, events: rx, @@ -210,11 +195,11 @@ fn make_ids(keys: &[Ed25519Keyring]) -> AuthorityList { struct NoopContext; -impl network_gossip::ValidatorContext for NoopContext { +impl sc_network_gossip::ValidatorContext for NoopContext { fn broadcast_topic(&mut self, _: Hash, _: bool) { } fn broadcast_message(&mut self, _: Hash, _: Vec, _: bool) { } - fn send_message(&mut self, _: &network::PeerId, _: Vec) { } - fn send_topic(&mut self, _: &network::PeerId, _: Hash, _: bool) { } + fn send_message(&mut self, _: &sc_network::PeerId, _: Vec) { } + fn send_topic(&mut self, _: &sc_network::PeerId, _: Hash, _: bool) { } } #[test] @@ -230,9 +215,9 @@ fn good_commit_leads_to_relay() { let target_hash: Hash = [1; 32].into(); let target_number = 500; - let precommit = grandpa::Precommit { target_hash: target_hash.clone(), target_number }; + let precommit = finality_grandpa::Precommit { target_hash: target_hash.clone(), target_number }; let payload = super::localized_payload( - round, set_id, &grandpa::Message::Precommit(precommit.clone()) + round, set_id, &finality_grandpa::Message::Precommit(precommit.clone()) ); let mut precommits = Vec::new(); @@ -241,11 +226,11 @@ fn good_commit_leads_to_relay() { for (i, key) in private.iter().enumerate() { precommits.push(precommit.clone()); - let signature = fg_primitives::AuthoritySignature::from(key.sign(&payload[..])); + let signature = sp_finality_grandpa::AuthoritySignature::from(key.sign(&payload[..])); auth_data.push((signature, public[i].0.clone())) } - grandpa::CompactCommit { + finality_grandpa::CompactCommit { target_hash, target_number, precommits, @@ -259,13 +244,14 @@ fn good_commit_leads_to_relay() { message: commit, }).encode(); - let id = network::PeerId::random(); + let id = sc_network::PeerId::random(); let global_topic = super::global_topic::(set_id); - let test = make_test_network().0 + let threads_pool = futures03::executor::ThreadPool::new().unwrap(); + let test = make_test_network(&threads_pool).0 .and_then(move |tester| { // register a peer. - tester.gossip_validator.new_peer(&mut NoopContext, &id, network::config::Roles::FULL); + tester.gossip_validator.new_peer(&mut NoopContext, &id, sc_network::config::Roles::FULL); Ok((tester, id)) }) .and_then(move |(tester, id)| { @@ -287,11 +273,24 @@ fn good_commit_leads_to_relay() { // send a message. let sender_id = id.clone(); let send_message = tester.filter_network_events(move |event| match event { - Event::MessagesFor(topic, sender) => { - if topic != global_topic { return false } - let _ = sender.unbounded_send(network_gossip::TopicNotification { - message: commit_to_send.clone(), - sender: Some(sender_id.clone()), + Event::EventStream(sender) => { + // Add the sending peer and send the commit + let _ = sender.unbounded_send(NetworkEvent::NotificationStreamOpened { + remote: sender_id.clone(), + engine_id: GRANDPA_ENGINE_ID, + roles: Roles::FULL, + }); + + let _ = sender.unbounded_send(NetworkEvent::NotificationsReceived { + remote: sender_id.clone(), + messages: vec![(GRANDPA_ENGINE_ID, commit_to_send.clone().into())], + }); + + // Add a random peer which will be the recipient of this message + let _ = sender.unbounded_send(NetworkEvent::NotificationStreamOpened { + remote: sc_network::PeerId::random(), + engine_id: GRANDPA_ENGINE_ID, + roles: Roles::FULL, }); true @@ -303,8 +302,8 @@ fn good_commit_leads_to_relay() { let handle_commit = commits_in.into_future() .map(|(item, _)| { match item.unwrap() { - grandpa::voter::CommunicationIn::Commit(_, _, mut callback) => { - callback.run(grandpa::voter::CommitProcessingOutcome::good()); + finality_grandpa::voter::CommunicationIn::Commit(_, _, mut callback) => { + callback.run(finality_grandpa::voter::CommitProcessingOutcome::good()); }, _ => panic!("commit expected"), } @@ -315,12 +314,8 @@ fn good_commit_leads_to_relay() { // a repropagation event coming from the network. send_message.join(handle_commit).and_then(move |(tester, ())| { tester.filter_network_events(move |event| match event { - Event::GossipMessage(topic, data, false) => { - if topic == global_topic && data == encoded_commit { - true - } else { - panic!("Trying to gossip something strange") - } + Event::WriteNotification(_, data) => { + data == encoded_commit } _ => false, }) @@ -329,11 +324,12 @@ fn good_commit_leads_to_relay() { .map(|_| ()) }); - current_thread::block_on_all(test).unwrap(); + current_thread::Runtime::new().unwrap().block_on(test).unwrap(); } #[test] fn bad_commit_leads_to_report() { + env_logger::init(); let private = [Ed25519Keyring::Alice, Ed25519Keyring::Bob, Ed25519Keyring::Charlie]; let public = make_ids(&private[..]); let voter_set = Arc::new(public.iter().cloned().collect::>()); @@ -345,9 +341,9 @@ fn bad_commit_leads_to_report() { let target_hash: Hash = [1; 32].into(); let target_number = 500; - let precommit = grandpa::Precommit { target_hash: target_hash.clone(), target_number }; + let precommit = finality_grandpa::Precommit { target_hash: target_hash.clone(), target_number }; let payload = super::localized_payload( - round, set_id, &grandpa::Message::Precommit(precommit.clone()) + round, set_id, &finality_grandpa::Message::Precommit(precommit.clone()) ); let mut precommits = Vec::new(); @@ -356,11 +352,11 @@ fn bad_commit_leads_to_report() { for (i, key) in private.iter().enumerate() { precommits.push(precommit.clone()); - let signature = fg_primitives::AuthoritySignature::from(key.sign(&payload[..])); + let signature = sp_finality_grandpa::AuthoritySignature::from(key.sign(&payload[..])); auth_data.push((signature, public[i].0.clone())) } - grandpa::CompactCommit { + finality_grandpa::CompactCommit { target_hash, target_number, precommits, @@ -374,13 +370,14 @@ fn bad_commit_leads_to_report() { message: commit, }).encode(); - let id = network::PeerId::random(); + let id = sc_network::PeerId::random(); let global_topic = super::global_topic::(set_id); - let test = make_test_network().0 + let threads_pool = futures03::executor::ThreadPool::new().unwrap(); + let test = make_test_network(&threads_pool).0 .and_then(move |tester| { // register a peer. - tester.gossip_validator.new_peer(&mut NoopContext, &id, network::config::Roles::FULL); + tester.gossip_validator.new_peer(&mut NoopContext, &id, sc_network::config::Roles::FULL); Ok((tester, id)) }) .and_then(move |(tester, id)| { @@ -402,11 +399,15 @@ fn bad_commit_leads_to_report() { // send a message. let sender_id = id.clone(); let send_message = tester.filter_network_events(move |event| match event { - Event::MessagesFor(topic, sender) => { - if topic != global_topic { return false } - let _ = sender.unbounded_send(network_gossip::TopicNotification { - message: commit_to_send.clone(), - sender: Some(sender_id.clone()), + Event::EventStream(sender) => { + let _ = sender.unbounded_send(NetworkEvent::NotificationStreamOpened { + remote: sender_id.clone(), + engine_id: GRANDPA_ENGINE_ID, + roles: Roles::FULL, + }); + let _ = sender.unbounded_send(NetworkEvent::NotificationsReceived { + remote: sender_id.clone(), + messages: vec![(GRANDPA_ENGINE_ID, commit_to_send.clone().into())], }); true @@ -418,8 +419,8 @@ fn bad_commit_leads_to_report() { let handle_commit = commits_in.into_future() .map(|(item, _)| { match item.unwrap() { - grandpa::voter::CommunicationIn::Commit(_, _, mut callback) => { - callback.run(grandpa::voter::CommitProcessingOutcome::bad()); + finality_grandpa::voter::CommunicationIn::Commit(_, _, mut callback) => { + callback.run(finality_grandpa::voter::CommitProcessingOutcome::bad()); }, _ => panic!("commit expected"), } @@ -431,11 +432,7 @@ fn bad_commit_leads_to_report() { send_message.join(handle_commit).and_then(move |(tester, ())| { tester.filter_network_events(move |event| match event { Event::Report(who, cost_benefit) => { - if who == id && cost_benefit == super::cost::INVALID_COMMIT { - true - } else { - panic!("reported unknown peer or unexpected cost"); - } + who == id && cost_benefit == super::cost::INVALID_COMMIT } _ => false, }) @@ -444,18 +441,19 @@ fn bad_commit_leads_to_report() { .map(|_| ()) }); - current_thread::block_on_all(test).unwrap(); + current_thread::Runtime::new().unwrap().block_on(test).unwrap(); } #[test] fn peer_with_higher_view_leads_to_catch_up_request() { - let id = network::PeerId::random(); + let id = sc_network::PeerId::random(); - let (tester, mut net) = make_test_network(); + let threads_pool = futures03::executor::ThreadPool::new().unwrap(); + let (tester, mut net) = make_test_network(&threads_pool); let test = tester .and_then(move |tester| { // register a peer with authority role. - tester.gossip_validator.new_peer(&mut NoopContext, &id, network::config::Roles::AUTHORITY); + tester.gossip_validator.new_peer(&mut NoopContext, &id, sc_network::config::Roles::AUTHORITY); Ok((tester, id)) }) .and_then(move |(tester, id)| { @@ -472,16 +470,16 @@ fn peer_with_higher_view_leads_to_catch_up_request() { // neighbor packets are always discard match result { - network_gossip::ValidationResult::Discard => {}, + sc_network_gossip::ValidationResult::Discard => {}, _ => panic!("wrong expected outcome from neighbor validation"), } // a catch up request should be sent to the peer for round - 1 tester.filter_network_events(move |event| match event { - Event::SendMessage(peers, message) => { + Event::WriteNotification(peer, message) => { assert_eq!( - peers, - vec![id.clone()], + peer, + id, ); assert_eq!( @@ -502,5 +500,5 @@ fn peer_with_higher_view_leads_to_catch_up_request() { .map(|_| ()) }); - current_thread::block_on_all(test).unwrap(); + current_thread::Runtime::new().unwrap().block_on(test).unwrap(); } diff --git a/client/finality-grandpa/src/consensus_changes.rs b/client/finality-grandpa/src/consensus_changes.rs index e276b287dd18f7a4b14c890a9e4e239aef0f475a..c89335e34c75e162923ae9b00a4bb077fdeb1056 100644 --- a/client/finality-grandpa/src/consensus_changes.rs +++ b/client/finality-grandpa/src/consensus_changes.rs @@ -15,7 +15,7 @@ // along with Substrate. If not, see . use std::sync::Arc; -use codec::{Encode, Decode}; +use parity_scale_codec::{Encode, Decode}; /// Consensus-related data changes tracker. #[derive(Clone, Debug, Encode, Decode)] @@ -47,11 +47,11 @@ impl ConsensusChanges { /// Finalize all pending consensus changes that are finalized by given block. /// Returns true if there any changes were finalized. - pub(crate) fn finalize ::client_api::error::Result>>( + pub(crate) fn finalize ::sp_blockchain::Result>>( &mut self, block: (N, H), canonical_at_height: F, - ) -> ::client_api::error::Result<(bool, bool)> { + ) -> ::sp_blockchain::Result<(bool, bool)> { let (split_idx, has_finalized_changes) = self.pending_changes.iter() .enumerate() .take_while(|(_, &(at_height, _))| at_height <= block.0) diff --git a/client/finality-grandpa/src/environment.rs b/client/finality-grandpa/src/environment.rs index 214e8bc79883c6b671ca1cfc5aa16371141dcecd..efc8052ab89c836baf50af949e660a77d646ad92 100644 --- a/client/finality-grandpa/src/environment.rs +++ b/client/finality-grandpa/src/environment.rs @@ -17,51 +17,53 @@ use std::collections::BTreeMap; use std::iter::FromIterator; use std::sync::Arc; -use std::time::{Duration, Instant}; +use std::time::Duration; use log::{debug, warn, info}; -use codec::{Decode, Encode}; +use parity_scale_codec::{Decode, Encode}; use futures::prelude::*; -use tokio_timer::Delay; +use futures03::future::{FutureExt as _, TryFutureExt as _}; +use futures_timer::Delay; use parking_lot::RwLock; +use sp_blockchain::{HeaderBackend, Error as ClientError}; -use client_api::{ - HeaderBackend, BlockchainEvents, +use sc_client_api::{ + BlockchainEvents, backend::{Backend}, Finalizer, call_executor::CallExecutor, - error::Error as ClientError, utils::is_descendent_of, }; -use client::{ +use sc_client::{ apply_aux, Client, }; -use grandpa::{ +use finality_grandpa::{ BlockNumberOps, Equivocation, Error as GrandpaError, round::State as RoundState, voter, voter_set::VoterSet, }; -use primitives::{Blake2Hasher, H256, Pair}; -use sr_primitives::generic::BlockId; -use sr_primitives::traits::{ +use sp_core::{Blake2Hasher, H256, Pair}; +use sp_runtime::generic::BlockId; +use sp_runtime::traits::{ Block as BlockT, Header as HeaderT, NumberFor, One, Zero, }; -use substrate_telemetry::{telemetry, CONSENSUS_INFO}; +use sc_telemetry::{telemetry, CONSENSUS_INFO}; use crate::{ - CommandOrError, Commit, Config, Error, Network, Precommit, Prevote, + CommandOrError, Commit, Config, Error, Precommit, Prevote, PrimaryPropose, SignedMessage, NewAuthoritySet, VoterCommand, }; -use consensus_common::SelectChain; +use sp_consensus::SelectChain; use crate::authorities::{AuthoritySet, SharedAuthoritySet}; +use crate::communication::Network as NetworkT; use crate::consensus_changes::SharedConsensusChanges; use crate::justification::GrandpaJustification; use crate::until_imported::UntilVoteTargetImported; use crate::voting_rule::VotingRule; -use fg_primitives::{AuthorityId, AuthoritySignature, SetId, RoundNumber}; +use sp_finality_grandpa::{AuthorityId, AuthoritySignature, SetId, RoundNumber}; -type HistoricalVotes = grandpa::HistoricalVotes< +type HistoricalVotes = finality_grandpa::HistoricalVotes< ::Hash, NumberFor, AuthoritySignature, @@ -104,10 +106,10 @@ impl Encode for CompletedRounds { } } -impl codec::EncodeLike for CompletedRounds {} +impl parity_scale_codec::EncodeLike for CompletedRounds {} impl Decode for CompletedRounds { - fn decode(value: &mut I) -> Result { + fn decode(value: &mut I) -> Result { <(Vec>, SetId, Vec)>::decode(value) .map(|(rounds, set_id, voters)| CompletedRounds { rounds: rounds.into(), @@ -375,7 +377,7 @@ impl SharedVoterSetState { } /// The environment we run GRANDPA in. -pub(crate) struct Environment, RA, SC, VR> { +pub(crate) struct Environment, RA, SC, VR> { pub(crate) client: Arc>, pub(crate) select_chain: SC, pub(crate) voters: Arc>, @@ -388,7 +390,7 @@ pub(crate) struct Environment, RA, SC, VR pub(crate) voting_rule: VR, } -impl, RA, SC, VR> Environment { +impl, RA, SC, VR> Environment { /// Updates the voter set state using the given closure. The write lock is /// held during evaluation of the closure and the environment's voter set /// state is set to its result if successful. @@ -405,14 +407,13 @@ impl, RA, SC, VR> Environment, B, E, N, RA, SC, VR> - grandpa::Chain> + finality_grandpa::Chain> for Environment where Block: 'static, B: Backend + 'static, E: CallExecutor + Send + Sync + 'static, - N: Network + 'static, - N::In: 'static, + N: NetworkT + 'static + Send, SC: SelectChain + 'static, VR: VotingRule>, RA: Send + Sync, @@ -534,7 +535,7 @@ pub(crate) fn ancestry, E, RA>( { if base == block { return Err(GrandpaError::NotDescendent) } - let tree_route_res = header_metadata::tree_route(client, block, base); + let tree_route_res = sp_blockchain::tree_route(client, block, base); let tree_route = match tree_route_res { Ok(tree_route) => tree_route, @@ -562,8 +563,7 @@ where Block: 'static, B: Backend + 'static, E: CallExecutor + 'static + Send + Sync, - N: Network + 'static + Send, - N::In: 'static + Send, + N: NetworkT + 'static + Send, RA: 'static + Send + Sync, SC: SelectChain + 'static, VR: VotingRule>, @@ -575,11 +575,11 @@ where // regular round message streams type In = Box, Self::Signature, Self::Id>, + Item = ::finality_grandpa::SignedMessage, Self::Signature, Self::Id>, Error = Self::Error, > + Send>; type Out = Box>, + SinkItem = ::finality_grandpa::Message>, SinkError = Self::Error, > + Send>; @@ -589,9 +589,8 @@ where &self, round: RoundNumber, ) -> voter::RoundData { - let now = Instant::now(); - let prevote_timer = Delay::new(now + self.config.gossip_duration * 2); - let precommit_timer = Delay::new(now + self.config.gossip_duration * 4); + let prevote_timer = Delay::new(self.config.gossip_duration * 2); + let precommit_timer = Delay::new(self.config.gossip_duration * 4); let local_key = crate::is_voter(&self.voters, &self.config.keystore); @@ -629,8 +628,8 @@ where voter::RoundData { voter_id: local_key.map(|pair| pair.public()), - prevote_timer: Box::new(prevote_timer.map_err(|e| Error::Timer(e).into())), - precommit_timer: Box::new(precommit_timer.map_err(|e| Error::Timer(e).into())), + prevote_timer: Box::new(prevote_timer.map(Ok).compat()), + precommit_timer: Box::new(precommit_timer.map(Ok).compat()), incoming, outgoing, } @@ -865,6 +864,7 @@ where historical_votes.seen().iter().skip(n_existing_votes).cloned() ); already_completed.state = state; + crate::aux_schema::write_concluded_round(&*self.client, &already_completed)?; } let set_state = VoterSetState::::Live { @@ -903,15 +903,13 @@ where //random between 0-1 seconds. let delay: u64 = thread_rng().gen_range(0, 1000); - Box::new(Delay::new( - Instant::now() + Duration::from_millis(delay) - ).map_err(|e| Error::Timer(e).into())) + Box::new(Delay::new(Duration::from_millis(delay)).map(Ok).compat()) } fn prevote_equivocation( &self, _round: RoundNumber, - equivocation: ::grandpa::Equivocation, Self::Signature> + equivocation: ::finality_grandpa::Equivocation, Self::Signature> ) { warn!(target: "afg", "Detected prevote equivocation in the finality worker: {:?}", equivocation); // nothing yet; this could craft misbehavior reports of some kind. @@ -1012,8 +1010,8 @@ pub(crate) fn finalize_block, E, RA>( ); if let Err(e) = write_result { - warn!(target: "finality", "Failed to write updated consensus changes to disk. Bailing."); - warn!(target: "finality", "Node is in a potentially inconsistent state."); + warn!(target: "afg", "Failed to write updated consensus changes to disk. Bailing."); + warn!(target: "afg", "Node is in a potentially inconsistent state."); return Err(e.into()); } @@ -1065,7 +1063,7 @@ pub(crate) fn finalize_block, E, RA>( // ideally some handle to a synchronization oracle would be used // to avoid unconditionally notifying. client.apply_finality(import_op, BlockId::Hash(hash), justification, true).map_err(|e| { - warn!(target: "finality", "Error applying finality to block {:?}: {:?}", (hash, number), e); + warn!(target: "afg", "Error applying finality to block {:?}: {:?}", (hash, number), e); e })?; telemetry!(CONSENSUS_INFO; "afg.finalized_blocks_up_to"; @@ -1105,8 +1103,8 @@ pub(crate) fn finalize_block, E, RA>( ); if let Err(e) = write_result { - warn!(target: "finality", "Failed to write updated authority set to disk. Bailing."); - warn!(target: "finality", "Node is in a potentially inconsistent state."); + warn!(target: "afg", "Failed to write updated authority set to disk. Bailing."); + warn!(target: "afg", "Node is in a potentially inconsistent state."); return Err(e.into()); } diff --git a/client/finality-grandpa/src/finality_proof.rs b/client/finality-grandpa/src/finality_proof.rs index c675a4d1f36da1695537891ace9163b225be1c2b..69d4c77e5f8236d485a2e732273c16124d8debda 100644 --- a/client/finality-grandpa/src/finality_proof.rs +++ b/client/finality-grandpa/src/finality_proof.rs @@ -38,22 +38,21 @@ use std::iter; use std::sync::Arc; use log::{trace, warn}; -use client_api::{ - backend::Backend, blockchain::Backend as BlockchainBackend, CallExecutor, - error::{Error as ClientError, Result as ClientResult}, +use sp_blockchain::{Backend as BlockchainBackend, Error as ClientError, Result as ClientResult}; +use sc_client_api::{ + backend::Backend, CallExecutor, StorageProof, light::{FetchChecker, RemoteReadRequest}, - StorageProof, }; -use client::Client; -use codec::{Encode, Decode}; -use grandpa::BlockNumberOps; -use sr_primitives::{ +use sc_client::Client; +use parity_scale_codec::{Encode, Decode}; +use finality_grandpa::BlockNumberOps; +use sp_runtime::{ Justification, generic::BlockId, traits::{NumberFor, Block as BlockT, Header as HeaderT, One}, }; -use primitives::{H256, Blake2Hasher, storage::StorageKey}; -use substrate_telemetry::{telemetry, CONSENSUS_INFO}; -use fg_primitives::{AuthorityId, AuthorityList, VersionedAuthorityList, GRANDPA_AUTHORITIES_KEY}; +use sp_core::{H256, Blake2Hasher, storage::StorageKey}; +use sc_telemetry::{telemetry, CONSENSUS_INFO}; +use sp_finality_grandpa::{AuthorityId, AuthorityList, VersionedAuthorityList, GRANDPA_AUTHORITIES_KEY}; use crate::justification::GrandpaJustification; @@ -155,7 +154,7 @@ impl> FinalityProofProvider } } -impl network::FinalityProofProvider for FinalityProofProvider +impl sc_network::FinalityProofProvider for FinalityProofProvider where Block: BlockT, NumberFor: BlockNumberOps, @@ -168,7 +167,7 @@ impl network::FinalityProofProvider for FinalityProofProvider Result>, ClientError> { let request: FinalityProofRequest = Decode::decode(&mut &request[..]) .map_err(|e| { - warn!(target: "finality", "Unable to decode finality proof request: {}", e.what()); + warn!(target: "afg", "Unable to decode finality proof request: {}", e.what()); ClientError::Backend(format!("Invalid finality proof request")) })?; match request { @@ -259,7 +258,7 @@ pub(crate) fn prove_finality, B: BlockchainBackend ::client_api::error::Result>> +) -> ::sp_blockchain::Result>> where J: ProvableJustification, { @@ -270,7 +269,7 @@ pub(crate) fn prove_finality, B: BlockchainBackend, B: BlockchainBackend, B: BlockchainBackend, B: BlockchainBackend> ProvableJustification for GrandpaJ #[cfg(test)] pub(crate) mod tests { - use test_client::runtime::{Block, Header, H256}; - use client_api::NewBlockState; - use test_client::client::in_mem::Blockchain as InMemoryBlockchain; + use substrate_test_runtime_client::runtime::{Block, Header, H256}; + use sc_client_api::NewBlockState; + use substrate_test_runtime_client::sc_client::in_mem::Blockchain as InMemoryBlockchain; use super::*; - use primitives::crypto::Public; + use sp_core::crypto::Public; type FinalityProof = super::FinalityProof

; diff --git a/client/finality-grandpa/src/import.rs b/client/finality-grandpa/src/import.rs index d6a3ea6e94bbfe3b50eec6409fe11d47d1d043b9..17d2f1f8d8dc0f1ede175e01cca90a5fdf7bea76 100644 --- a/client/finality-grandpa/src/import.rs +++ b/client/finality-grandpa/src/import.rs @@ -17,28 +17,25 @@ use std::{sync::Arc, collections::HashMap}; use log::{debug, trace, info}; -use codec::Encode; +use parity_scale_codec::Encode; use futures::sync::mpsc; use parking_lot::RwLockWriteGuard; -use client_api::{ - backend::Backend, blockchain, - CallExecutor, blockchain::HeaderBackend, well_known_cache_keys, - utils::is_descendent_of, -}; -use client::Client; -use consensus_common::{ +use sp_blockchain::{HeaderBackend, BlockStatus, well_known_cache_keys}; +use sc_client_api::{backend::Backend, CallExecutor, utils::is_descendent_of}; +use sc_client::Client; +use sp_consensus::{ BlockImport, Error as ConsensusError, BlockCheckParams, BlockImportParams, ImportResult, JustificationImport, SelectChain, }; -use fg_primitives::{GRANDPA_ENGINE_ID, ScheduledChange, ConsensusLog}; -use sr_primitives::Justification; -use sr_primitives::generic::{BlockId, OpaqueDigestItemId}; -use sr_primitives::traits::{ +use sp_finality_grandpa::{GRANDPA_ENGINE_ID, ScheduledChange, ConsensusLog}; +use sp_runtime::Justification; +use sp_runtime::generic::{BlockId, OpaqueDigestItemId}; +use sp_runtime::traits::{ Block as BlockT, DigestFor, Header as HeaderT, NumberFor, Zero, }; -use primitives::{H256, Blake2Hasher}; +use sp_core::{H256, Blake2Hasher}; use crate::{Error, CommandOrError, NewAuthoritySet, VoterCommand}; use crate::authorities::{AuthoritySet, SharedAuthoritySet, DelayKind, PendingChange}; @@ -79,7 +76,7 @@ impl, RA, SC: Clone> Clone for impl, RA, SC> JustificationImport for GrandpaBlockImport where - NumberFor: grandpa::BlockNumberOps, + NumberFor: finality_grandpa::BlockNumberOps, B: Backend + 'static, E: CallExecutor + 'static + Clone + Send + Sync, DigestFor: Encode, @@ -207,7 +204,7 @@ fn find_forced_change(header: &B::Header) impl, RA, SC> GrandpaBlockImport where - NumberFor: grandpa::BlockNumberOps, + NumberFor: finality_grandpa::BlockNumberOps, B: Backend + 'static, E: CallExecutor + 'static + Clone + Send + Sync, DigestFor: Encode, @@ -384,7 +381,7 @@ where impl, RA, SC> BlockImport for GrandpaBlockImport where - NumberFor: grandpa::BlockNumberOps, + NumberFor: finality_grandpa::BlockNumberOps, B: Backend + 'static, E: CallExecutor + 'static + Clone + Send + Sync, DigestFor: Encode, @@ -403,8 +400,8 @@ impl, RA, SC> BlockImport // early exit if block already in chain, otherwise the check for // authority changes will error when trying to re-import a change block match self.inner.status(BlockId::Hash(hash)) { - Ok(blockchain::BlockStatus::InChain) => return Ok(ImportResult::AlreadyInChain), - Ok(blockchain::BlockStatus::Unknown) => {}, + Ok(BlockStatus::InChain) => return Ok(ImportResult::AlreadyInChain), + Ok(BlockStatus::Unknown) => {}, Err(e) => return Err(ConsensusError::ClientImport(e.to_string()).into()), } @@ -475,7 +472,7 @@ impl, RA, SC> BlockImport Some(justification) => { self.import_justification(hash, number, justification, needs_justification).unwrap_or_else(|err| { if needs_justification || enacts_consensus_change { - debug!(target: "finality", "Imported block #{} that enacts authority set change with \ + debug!(target: "afg", "Imported block #{} that enacts authority set change with \ invalid justification: {:?}, requesting justification from peers.", number, err); imported_aux.bad_justification = true; imported_aux.needs_justification = true; @@ -485,7 +482,7 @@ impl, RA, SC> BlockImport None => { if needs_justification { trace!( - target: "finality", + target: "afg", "Imported unjustified block #{} that enacts authority set change, waiting for finality for enactment.", number, ); @@ -535,7 +532,7 @@ impl, RA, SC> impl, RA, SC> GrandpaBlockImport where - NumberFor: grandpa::BlockNumberOps, + NumberFor: finality_grandpa::BlockNumberOps, B: Backend + 'static, E: CallExecutor + 'static + Clone + Send + Sync, RA: Send + Sync, @@ -576,7 +573,7 @@ where match result { Err(CommandOrError::VoterCommand(command)) => { - info!(target: "finality", "Imported justification for block #{} that triggers \ + info!(target: "afg", "Imported justification for block #{} that triggers \ command {}, signaling voter.", number, command); // send the command to the voter diff --git a/client/finality-grandpa/src/justification.rs b/client/finality-grandpa/src/justification.rs index eff06776bdb92f1102a358dfbd4f4e5e551096d2..d7650a39f8736bec292acfca41f247ba8736a3b8 100644 --- a/client/finality-grandpa/src/justification.rs +++ b/client/finality-grandpa/src/justification.rs @@ -16,15 +16,16 @@ use std::collections::{HashMap, HashSet}; -use client::Client; -use client_api::{CallExecutor, backend::Backend, error::Error as ClientError}; -use codec::{Encode, Decode}; -use grandpa::voter_set::VoterSet; -use grandpa::{Error as GrandpaError}; -use sr_primitives::generic::BlockId; -use sr_primitives::traits::{NumberFor, Block as BlockT, Header as HeaderT}; -use primitives::{H256, Blake2Hasher}; -use fg_primitives::AuthorityId; +use sc_client::Client; +use sc_client_api::{CallExecutor, backend::Backend}; +use sp_blockchain::Error as ClientError; +use parity_scale_codec::{Encode, Decode}; +use finality_grandpa::voter_set::VoterSet; +use finality_grandpa::{Error as GrandpaError}; +use sp_runtime::generic::BlockId; +use sp_runtime::traits::{NumberFor, Block as BlockT, Header as HeaderT}; +use sp_core::{H256, Blake2Hasher}; +use sp_finality_grandpa::AuthorityId; use crate::{Commit, Error}; use crate::communication; @@ -97,7 +98,7 @@ impl> GrandpaJustification { set_id: u64, voters: &VoterSet, ) -> Result, ClientError> where - NumberFor: grandpa::BlockNumberOps, + NumberFor: finality_grandpa::BlockNumberOps, { let justification = GrandpaJustification::::decode(&mut &*encoded) @@ -114,13 +115,13 @@ impl> GrandpaJustification { /// Validate the commit and the votes' ancestry proofs. pub(crate) fn verify(&self, set_id: u64, voters: &VoterSet) -> Result<(), ClientError> where - NumberFor: grandpa::BlockNumberOps, + NumberFor: finality_grandpa::BlockNumberOps, { - use grandpa::Chain; + use finality_grandpa::Chain; let ancestry_chain = AncestryChain::::new(&self.votes_ancestries); - match grandpa::validate_commit( + match finality_grandpa::validate_commit( &self.commit, voters, &ancestry_chain, @@ -135,7 +136,7 @@ impl> GrandpaJustification { let mut visited_hashes = HashSet::new(); for signed in self.commit.precommits.iter() { if let Err(_) = communication::check_message_sig::( - &grandpa::Message::Precommit(signed.precommit.clone()), + &finality_grandpa::Message::Precommit(signed.precommit.clone()), &signed.id, &signed.signature, self.round, @@ -178,7 +179,7 @@ impl> GrandpaJustification { } } -/// A utility trait implementing `grandpa::Chain` using a given set of headers. +/// A utility trait implementing `finality_grandpa::Chain` using a given set of headers. /// This is useful when validating commits, using the given set of headers to /// verify a valid ancestry route to the target commit block. struct AncestryChain { @@ -197,8 +198,8 @@ impl AncestryChain { } } -impl grandpa::Chain> for AncestryChain where - NumberFor: grandpa::BlockNumberOps +impl finality_grandpa::Chain> for AncestryChain where + NumberFor: finality_grandpa::BlockNumberOps { fn ancestry(&self, base: Block::Hash, block: Block::Hash) -> Result, GrandpaError> { let mut route = Vec::new(); diff --git a/client/finality-grandpa/src/lib.rs b/client/finality-grandpa/src/lib.rs index 8355f7c93ece91f03e3da456a3e23d34766412a8..b6745baf699552ad361323d03bd8c4320b4296e3 100644 --- a/client/finality-grandpa/src/lib.rs +++ b/client/finality-grandpa/src/lib.rs @@ -55,27 +55,25 @@ use futures::prelude::*; use log::{debug, error, info}; use futures::sync::mpsc; -use client_api::{ - BlockchainEvents, CallExecutor, backend::Backend, error::Error as ClientError, - ExecutionStrategy, HeaderBackend -}; -use client::Client; -use codec::{Decode, Encode}; -use sr_primitives::generic::BlockId; -use sr_primitives::traits::{NumberFor, Block as BlockT, DigestFor, Zero}; -use keystore::KeyStorePtr; -use inherents::InherentDataProviders; -use consensus_common::SelectChain; -use primitives::{H256, Blake2Hasher, Pair}; -use substrate_telemetry::{telemetry, CONSENSUS_INFO, CONSENSUS_DEBUG, CONSENSUS_WARN}; +use sc_client_api::{BlockchainEvents, CallExecutor, backend::Backend, ExecutionStrategy}; +use sp_blockchain::{HeaderBackend, Error as ClientError}; +use sc_client::Client; +use parity_scale_codec::{Decode, Encode}; +use sp_runtime::generic::BlockId; +use sp_runtime::traits::{NumberFor, Block as BlockT, DigestFor, Zero}; +use sc_keystore::KeyStorePtr; +use sp_inherents::InherentDataProviders; +use sp_consensus::SelectChain; +use sp_core::{H256, Blake2Hasher, Pair}; +use sc_telemetry::{telemetry, CONSENSUS_INFO, CONSENSUS_DEBUG, CONSENSUS_WARN}; use serde_json; use sp_finality_tracker; -use grandpa::Error as GrandpaError; -use grandpa::{voter, BlockNumberOps, voter_set::VoterSet}; +use finality_grandpa::Error as GrandpaError; +use finality_grandpa::{voter, BlockNumberOps, voter_set::VoterSet}; -use std::fmt; +use std::{fmt, io}; use std::sync::Arc; use std::time::Duration; @@ -92,7 +90,6 @@ mod observer; mod until_imported; mod voting_rule; -pub use communication::Network; pub use finality_proof::FinalityProofProvider; pub use justification::GrandpaJustification; pub use light_import::light_block_import; @@ -105,19 +102,19 @@ use aux_schema::PersistentData; use environment::{Environment, VoterSetState}; use import::GrandpaBlockImport; use until_imported::UntilGlobalMessageBlocksImported; -use communication::NetworkBridge; -use fg_primitives::{AuthorityList, AuthorityPair, AuthoritySignature, SetId}; +use communication::{NetworkBridge, Network as NetworkT}; +use sp_finality_grandpa::{AuthorityList, AuthorityPair, AuthoritySignature, SetId}; // Re-export these two because it's just so damn convenient. -pub use fg_primitives::{AuthorityId, ScheduledChange}; +pub use sp_finality_grandpa::{AuthorityId, ScheduledChange}; #[cfg(test)] mod tests; /// A GRANDPA message for a substrate chain. -pub type Message = grandpa::Message<::Hash, NumberFor>; +pub type Message = finality_grandpa::Message<::Hash, NumberFor>; /// A signed message. -pub type SignedMessage = grandpa::SignedMessage< +pub type SignedMessage = finality_grandpa::SignedMessage< ::Hash, NumberFor, AuthoritySignature, @@ -125,27 +122,27 @@ pub type SignedMessage = grandpa::SignedMessage< >; /// A primary propose message for this chain's block type. -pub type PrimaryPropose = grandpa::PrimaryPropose<::Hash, NumberFor>; +pub type PrimaryPropose = finality_grandpa::PrimaryPropose<::Hash, NumberFor>; /// A prevote message for this chain's block type. -pub type Prevote = grandpa::Prevote<::Hash, NumberFor>; +pub type Prevote = finality_grandpa::Prevote<::Hash, NumberFor>; /// A precommit message for this chain's block type. -pub type Precommit = grandpa::Precommit<::Hash, NumberFor>; +pub type Precommit = finality_grandpa::Precommit<::Hash, NumberFor>; /// A catch up message for this chain's block type. -pub type CatchUp = grandpa::CatchUp< +pub type CatchUp = finality_grandpa::CatchUp< ::Hash, NumberFor, AuthoritySignature, AuthorityId, >; /// A commit message for this chain's block type. -pub type Commit = grandpa::Commit< +pub type Commit = finality_grandpa::Commit< ::Hash, NumberFor, AuthoritySignature, AuthorityId, >; /// A compact commit message for this chain's block type. -pub type CompactCommit = grandpa::CompactCommit< +pub type CompactCommit = finality_grandpa::CompactCommit< ::Hash, NumberFor, AuthoritySignature, @@ -154,7 +151,7 @@ pub type CompactCommit = grandpa::CompactCommit< /// A global communication input stream for commits and catch up messages. Not /// exposed publicly, used internally to simplify types in the communication /// layer. -type CommunicationIn = grandpa::voter::CommunicationIn< +type CommunicationIn = finality_grandpa::voter::CommunicationIn< ::Hash, NumberFor, AuthoritySignature, @@ -164,7 +161,7 @@ type CommunicationIn = grandpa::voter::CommunicationIn< /// Global communication input stream for commits and catch up messages, with /// the hash type not being derived from the block, useful for forcing the hash /// to some type (e.g. `H256`) when the compiler can't do the inference. -type CommunicationInH = grandpa::voter::CommunicationIn< +type CommunicationInH = finality_grandpa::voter::CommunicationIn< H, NumberFor, AuthoritySignature, @@ -173,7 +170,7 @@ type CommunicationInH = grandpa::voter::CommunicationIn< /// A global communication sink for commits. Not exposed publicly, used /// internally to simplify types in the communication layer. -type CommunicationOut = grandpa::voter::CommunicationOut< +type CommunicationOut = finality_grandpa::voter::CommunicationOut< ::Hash, NumberFor, AuthoritySignature, @@ -183,7 +180,7 @@ type CommunicationOut = grandpa::voter::CommunicationOut< /// Global communication sink for commits with the hash type not being derived /// from the block, useful for forcing the hash to some type (e.g. `H256`) when /// the compiler can't do the inference. -type CommunicationOutH = grandpa::voter::CommunicationOut< +type CommunicationOutH = finality_grandpa::voter::CommunicationOut< H, NumberFor, AuthoritySignature, @@ -209,7 +206,7 @@ pub struct Config { /// Some local identifier of the voter. pub name: Option, /// The keystore that manages the keys of this node. - pub keystore: Option, + pub keystore: Option, } impl Config { @@ -232,7 +229,7 @@ pub enum Error { /// An invariant has been violated (e.g. not finalizing pending change blocks in-order) Safety(String), /// A timer failed to fire. - Timer(tokio_timer::Error), + Timer(io::Error), } impl From for Error { @@ -275,14 +272,14 @@ pub(crate) trait BlockSyncRequester { /// If the given vector of peers is empty then the underlying implementation /// should make a best effort to fetch the block from any peers it is /// connected to (NOTE: this assumption will change in the future #3629). - fn set_sync_fork_request(&self, peers: Vec, hash: Block::Hash, number: NumberFor); + fn set_sync_fork_request(&self, peers: Vec, hash: Block::Hash, number: NumberFor); } -impl BlockSyncRequester for NetworkBridge where +impl BlockSyncRequester for NetworkBridge where Block: BlockT, - N: communication::Network, + Network: NetworkT, { - fn set_sync_fork_request(&self, peers: Vec, hash: Block::Hash, number: NumberFor) { + fn set_sync_fork_request(&self, peers: Vec, hash: Block::Hash, number: NumberFor) { NetworkBridge::set_sync_fork_request(self, peers, hash, number) } } @@ -335,8 +332,8 @@ impl From for CommandOrError { } } -impl From for CommandOrError { - fn from(e: grandpa::Error) -> Self { +impl From for CommandOrError { + fn from(e: finality_grandpa::Error) -> Self { CommandOrError::Error(Error::from(e)) } } @@ -467,7 +464,7 @@ fn global_communication, B, E, N, RA>( ) where B: Backend, E: CallExecutor + Send + Sync, - N: Network, + N: NetworkT, RA: Send + Sync, NumberFor: BlockNumberOps, { @@ -500,7 +497,7 @@ fn global_communication, B, E, N, RA>( fn register_finality_tracker_inherent_data_provider, RA>( client: Arc>, inherent_data_providers: &InherentDataProviders, -) -> Result<(), consensus_common::Error> where +) -> Result<(), sp_consensus::Error> where B: Backend + 'static, E: CallExecutor + Send + Sync + 'static, RA: Send + Sync + 'static, @@ -518,14 +515,14 @@ fn register_finality_tracker_inherent_data_provider, N, RA, SC, VR, X> { +pub struct GrandpaParams, N, RA, SC, VR, X, Sp> { /// Configuration for the GRANDPA service. pub config: Config, /// A link to the block import worker. @@ -540,24 +537,26 @@ pub struct GrandpaParams, N, RA, SC, VR, X> { pub telemetry_on_connect: Option>, /// A voting rule used to potentially restrict target votes. pub voting_rule: VR, + /// How to spawn background tasks. + pub executor: Sp, } /// Run a GRANDPA voter as a task. Provide configuration and a link to a /// block import worker that has already been instantiated with `block_import`. -pub fn run_grandpa_voter, N, RA, SC, VR, X>( - grandpa_params: GrandpaParams, -) -> client_api::error::Result + Send + 'static> where +pub fn run_grandpa_voter, N, RA, SC, VR, X, Sp>( + grandpa_params: GrandpaParams, +) -> sp_blockchain::Result + Send + 'static> where Block::Hash: Ord, B: Backend + 'static, E: CallExecutor + Send + Sync + 'static, - N: Network + Send + Sync + 'static, - N::In: Send + 'static, + N: NetworkT + Send + Sync + Clone + 'static, SC: SelectChain + 'static, VR: VotingRule> + Clone + 'static, NumberFor: BlockNumberOps, DigestFor: Encode, RA: Send + Sync + 'static, - X: Future + Clone + Send + 'static, + X: futures03::Future + Clone + Send + Unpin + 'static, + Sp: futures03::task::Spawn + 'static, { let GrandpaParams { config, @@ -567,6 +566,7 @@ pub fn run_grandpa_voter, N, RA, SC, VR, X>( on_exit, telemetry_on_connect, voting_rule, + executor, } = grandpa_params; let LinkHalf { @@ -576,10 +576,11 @@ pub fn run_grandpa_voter, N, RA, SC, VR, X>( voter_commands_rx, } = link; - let (network, network_startup) = NetworkBridge::new( + let network = NetworkBridge::new( network, config.clone(), persistent_data.set_state.clone(), + &executor, on_exit.clone(), ); @@ -630,18 +631,18 @@ pub fn run_grandpa_voter, N, RA, SC, VR, X>( telemetry!(CONSENSUS_WARN; "afg.voter_failed"; "e" => ?e); }); - let voter_work = network_startup.and_then(move |()| voter_work); - // Make sure that `telemetry_task` doesn't accidentally finish and kill grandpa. let telemetry_task = telemetry_task .then(|_| futures::future::empty::<(), ()>()); - Ok(voter_work.select(on_exit).select2(telemetry_task).then(|_| Ok(()))) + use futures03::{FutureExt, TryFutureExt}; + + Ok(voter_work.select(on_exit.map(Ok).compat()).select2(telemetry_task).then(|_| Ok(()))) } /// Future that powers the voter. #[must_use] -struct VoterWork, RA, SC, VR> { +struct VoterWork, RA, SC, VR> { voter: Box>> + Send>, env: Arc>, voter_commands_rx: mpsc::UnboundedReceiver>>, @@ -650,8 +651,7 @@ struct VoterWork, RA, SC, VR> { impl VoterWork where Block: BlockT, - N: Network + Sync, - N::In: Send + 'static, + N: NetworkT + Sync, NumberFor: BlockNumberOps, RA: 'static + Send + Sync, E: CallExecutor + Send + Sync + 'static, @@ -826,8 +826,7 @@ where impl Future for VoterWork where Block: BlockT, - N: Network + Sync, - N::In: Send + 'static, + N: NetworkT + Sync, NumberFor: BlockNumberOps, RA: 'static + Send + Sync, E: CallExecutor + Send + Sync + 'static, @@ -878,20 +877,20 @@ where } #[deprecated(since = "1.1.0", note = "Please switch to run_grandpa_voter.")] -pub fn run_grandpa, N, RA, SC, VR, X>( - grandpa_params: GrandpaParams, -) -> ::client_api::error::Result + Send + 'static> where +pub fn run_grandpa, N, RA, SC, VR, X, Sp>( + grandpa_params: GrandpaParams, +) -> ::sp_blockchain::Result + Send + 'static> where Block::Hash: Ord, B: Backend + 'static, E: CallExecutor + Send + Sync + 'static, - N: Network + Send + Sync + 'static, - N::In: Send + 'static, + N: NetworkT + Send + Sync + Clone + 'static, SC: SelectChain + 'static, NumberFor: BlockNumberOps, DigestFor: Encode, RA: Send + Sync + 'static, VR: VotingRule> + Clone + 'static, - X: Future + Clone + Send + 'static, + X: futures03::Future + Clone + Send + Unpin + 'static, + Sp: futures03::task::Spawn + 'static, { run_grandpa_voter(grandpa_params) } @@ -906,19 +905,21 @@ pub fn setup_disabled_grandpa, RA, N>( client: Arc>, inherent_data_providers: &InherentDataProviders, network: N, -) -> Result<(), consensus_common::Error> where +) -> Result<(), sp_consensus::Error> where B: Backend + 'static, E: CallExecutor + Send + Sync + 'static, RA: Send + Sync + 'static, - N: Network + Send + Sync + 'static, - N::In: Send + 'static, + N: NetworkT + Send + Clone + 'static, { register_finality_tracker_inherent_data_provider( client, inherent_data_providers, )?; - network.register_validator(Arc::new(network::consensus_gossip::DiscardAll)); + // We register the GRANDPA protocol so that we don't consider it an anomaly + // to receive GRANDPA messages on the network. We don't process the + // messages. + network.register_notifications_protocol(communication::GRANDPA_ENGINE_ID); Ok(()) } diff --git a/client/finality-grandpa/src/light_import.rs b/client/finality-grandpa/src/light_import.rs index 6212f853e8392c28e262146552c1b41e476c270a..fe05f6dc46abe2a7e977c76f3f6f077203b5d468 100644 --- a/client/finality-grandpa/src/light_import.rs +++ b/client/finality-grandpa/src/light_import.rs @@ -18,26 +18,21 @@ use std::collections::HashMap; use std::sync::Arc; use log::{info, trace, warn}; use parking_lot::RwLock; -use client::Client; -use client_api::{ - CallExecutor, - backend::{AuxStore, Backend, Finalizer}, - blockchain::HeaderBackend, - error::Error as ClientError, - well_known_cache_keys, -}; -use codec::{Encode, Decode}; -use consensus_common::{ +use sc_client::Client; +use sc_client_api::{CallExecutor, backend::{AuxStore, Backend, Finalizer}}; +use sp_blockchain::{HeaderBackend, Error as ClientError, well_known_cache_keys}; +use parity_scale_codec::{Encode, Decode}; +use sp_consensus::{ import_queue::Verifier, BlockOrigin, BlockImport, FinalityProofImport, BlockImportParams, ImportResult, ImportedAux, BlockCheckParams, Error as ConsensusError, }; -use network::config::{BoxFinalityProofRequestBuilder, FinalityProofRequestBuilder}; -use sr_primitives::Justification; -use sr_primitives::traits::{NumberFor, Block as BlockT, Header as HeaderT, DigestFor}; -use fg_primitives::{self, AuthorityList}; -use sr_primitives::generic::BlockId; -use primitives::{H256, Blake2Hasher}; +use sc_network::config::{BoxFinalityProofRequestBuilder, FinalityProofRequestBuilder}; +use sp_runtime::Justification; +use sp_runtime::traits::{NumberFor, Block as BlockT, Header as HeaderT, DigestFor}; +use sp_finality_grandpa::{self, AuthorityList}; +use sp_runtime::generic::BlockId; +use sp_core::{H256, Blake2Hasher}; use crate::GenesisAuthoritySetProvider; use crate::aux_schema::load_decode; @@ -125,7 +120,7 @@ impl, RA> GrandpaLightBlockImport, RA> BlockImport for GrandpaLightBlockImport where - NumberFor: grandpa::BlockNumberOps, + NumberFor: finality_grandpa::BlockNumberOps, B: Backend + 'static, E: CallExecutor + 'static + Clone + Send + Sync, DigestFor: Encode, @@ -153,7 +148,7 @@ impl, RA> BlockImport impl, RA> FinalityProofImport for GrandpaLightBlockImport where - NumberFor: grandpa::BlockNumberOps, + NumberFor: finality_grandpa::BlockNumberOps, B: Backend + 'static, E: CallExecutor + 'static + Clone + Send + Sync, DigestFor: Encode, @@ -199,7 +194,7 @@ impl LightAuthoritySet { /// Get a genesis set with given authorities. pub fn genesis(initial: AuthorityList) -> Self { LightAuthoritySet { - set_id: fg_primitives::SetId::default(), + set_id: sp_finality_grandpa::SetId::default(), authorities: initial, } } @@ -247,7 +242,7 @@ fn do_import_block, J>( + BlockImport + Clone, B: Backend + 'static, - NumberFor: grandpa::BlockNumberOps, + NumberFor: finality_grandpa::BlockNumberOps, DigestFor: Encode, J: ProvableJustification, { @@ -268,7 +263,7 @@ fn do_import_block, J>( match justification { Some(justification) => { trace!( - target: "finality", + target: "afg", "Imported block {}{}. Importing justification.", if enacts_consensus_change { " which enacts consensus changes" } else { "" }, hash, @@ -278,7 +273,7 @@ fn do_import_block, J>( }, None if enacts_consensus_change => { trace!( - target: "finality", + target: "afg", "Imported block {} which enacts consensus changes. Requesting finality proof.", hash, ); @@ -311,7 +306,7 @@ fn do_import_finality_proof, J>( + Clone, B: Backend + 'static, DigestFor: Encode, - NumberFor: grandpa::BlockNumberOps, + NumberFor: finality_grandpa::BlockNumberOps, J: ProvableJustification, { let authority_set_id = data.authority_set.set_id(); @@ -374,7 +369,7 @@ fn do_import_justification, J>( + Finalizer + Clone, B: Backend + 'static, - NumberFor: grandpa::BlockNumberOps, + NumberFor: finality_grandpa::BlockNumberOps, J: ProvableJustification, { // with justification, we have two cases @@ -398,7 +393,7 @@ fn do_import_justification, J>( let justification = match justification { Err(ClientError::BadJustification(_)) => { trace!( - target: "finality", + target: "afg", "Justification for {} is not valid within current authorities set. Requesting finality proof.", hash, ); @@ -409,7 +404,7 @@ fn do_import_justification, J>( }, Err(e) => { trace!( - target: "finality", + target: "afg", "Justification for {} is not valid. Bailing.", hash, ); @@ -418,7 +413,7 @@ fn do_import_justification, J>( }, Ok(justification) => { trace!( - target: "finality", + target: "afg", "Justification for {} is valid. Finalizing the block.", hash, ); @@ -445,11 +440,11 @@ fn do_finalize_block>( + Finalizer + Clone, B: Backend + 'static, - NumberFor: grandpa::BlockNumberOps, + NumberFor: finality_grandpa::BlockNumberOps, { // finalize the block client.finalize_block(BlockId::Hash(hash), Some(justification), true).map_err(|e| { - warn!(target: "finality", "Error applying finality to block {:?}: {:?}", (hash, number), e); + warn!(target: "afg", "Error applying finality to block {:?}: {:?}", (hash, number), e); ConsensusError::ClientImport(e.to_string()) })?; @@ -537,19 +532,19 @@ fn require_insert_aux( /// Display inconsistency warning. fn on_post_finalization_error(error: ClientError, value_type: &str) -> ConsensusError { - warn!(target: "finality", "Failed to write updated {} to disk. Bailing.", value_type); - warn!(target: "finality", "Node is in a potentially inconsistent state."); + warn!(target: "afg", "Failed to write updated {} to disk. Bailing.", value_type); + warn!(target: "afg", "Node is in a potentially inconsistent state."); ConsensusError::ClientImport(error.to_string()) } #[cfg(test)] pub mod tests { use super::*; - use consensus_common::ForkChoiceStrategy; - use fg_primitives::AuthorityId; - use primitives::{H256, crypto::Public}; - use test_client::client::in_mem::Blockchain as InMemoryAuxStore; - use test_client::runtime::{Block, Header}; + use sp_consensus::ForkChoiceStrategy; + use sp_finality_grandpa::AuthorityId; + use sp_core::{H256, crypto::Public}; + use substrate_test_runtime_client::sc_client::in_mem::Blockchain as InMemoryAuxStore; + use substrate_test_runtime_client::runtime::{Block, Header}; use crate::tests::TestApi; use crate::finality_proof::tests::TestJustification; @@ -559,7 +554,7 @@ pub mod tests { impl, RA> Clone for NoJustificationsImport where - NumberFor: grandpa::BlockNumberOps, + NumberFor: finality_grandpa::BlockNumberOps, B: Backend + 'static, E: CallExecutor + 'static + Clone + Send + Sync, DigestFor: Encode, @@ -572,7 +567,7 @@ pub mod tests { impl, RA> BlockImport for NoJustificationsImport where - NumberFor: grandpa::BlockNumberOps, + NumberFor: finality_grandpa::BlockNumberOps, B: Backend + 'static, E: CallExecutor + 'static + Clone + Send + Sync, DigestFor: Encode, @@ -599,7 +594,7 @@ pub mod tests { impl, RA> FinalityProofImport for NoJustificationsImport where - NumberFor: grandpa::BlockNumberOps, + NumberFor: finality_grandpa::BlockNumberOps, B: Backend + 'static, E: CallExecutor + 'static + Clone + Send + Sync, DigestFor: Encode, @@ -642,7 +637,7 @@ pub mod tests { new_cache: HashMap>, justification: Option, ) -> ImportResult { - let (client, _backend) = test_client::new_light(); + let (client, _backend) = substrate_test_runtime_client::new_light(); let mut import_data = LightImportData { last_finalized: Default::default(), authority_set: LightAuthoritySet::genesis(vec![(AuthorityId::from_slice(&[1; 32]), 1)]), @@ -664,6 +659,7 @@ pub mod tests { auxiliary: Vec::new(), fork_choice: ForkChoiceStrategy::LongestChain, allow_missing_state: true, + import_existing: false, }; do_import_block::<_, _, _, TestJustification>( &client, diff --git a/client/finality-grandpa/src/observer.rs b/client/finality-grandpa/src/observer.rs index b182eaaaa5e61d4e59ae732addfccea4e205eae0..2cb3c18045ea313ce5c1897eb64503ad37d97c31 100644 --- a/client/finality-grandpa/src/observer.rs +++ b/client/finality-grandpa/src/observer.rs @@ -19,29 +19,29 @@ use std::sync::Arc; use futures::prelude::*; use futures::{future, sync::mpsc}; -use grandpa::{ +use finality_grandpa::{ BlockNumberOps, Error as GrandpaError, voter, voter_set::VoterSet }; use log::{debug, info, warn}; -use consensus_common::SelectChain; -use client_api::{CallExecutor, backend::Backend}; -use client::Client; -use sr_primitives::traits::{NumberFor, Block as BlockT}; -use primitives::{H256, Blake2Hasher}; +use sp_consensus::SelectChain; +use sc_client_api::{CallExecutor, backend::Backend}; +use sc_client::Client; +use sp_runtime::traits::{NumberFor, Block as BlockT}; +use sp_core::{H256, Blake2Hasher}; use crate::{ global_communication, CommandOrError, CommunicationIn, Config, environment, - LinkHalf, Network, Error, aux_schema::PersistentData, VoterCommand, VoterSetState, + LinkHalf, Error, aux_schema::PersistentData, VoterCommand, VoterSetState, }; use crate::authorities::SharedAuthoritySet; -use crate::communication::NetworkBridge; +use crate::communication::{Network as NetworkT, NetworkBridge}; use crate::consensus_changes::SharedConsensusChanges; -use fg_primitives::AuthorityId; +use sp_finality_grandpa::AuthorityId; struct ObserverChain<'a, Block: BlockT, B, E, RA>(&'a Client); -impl<'a, Block: BlockT, B, E, RA> grandpa::Chain> +impl<'a, Block: BlockT, B, E, RA> finality_grandpa::Chain> for ObserverChain<'a, Block, B, E, RA> where B: Backend, E: CallExecutor, @@ -84,7 +84,7 @@ fn grandpa_observer, RA, S, F>( let observer = commits.fold(last_finalized_number, move |last_finalized_number, global| { let (round, commit, callback) = match global { voter::CommunicationIn::Commit(round, commit, callback) => { - let commit = grandpa::Commit::from(commit); + let commit = finality_grandpa::Commit::from(commit); (round, commit, callback) }, voter::CommunicationIn::CatchUp(..) => { @@ -99,7 +99,7 @@ fn grandpa_observer, RA, S, F>( return future::ok(last_finalized_number); } - let validation_result = match grandpa::validate_commit( + let validation_result = match finality_grandpa::validate_commit( &commit, &voters, &ObserverChain(&*client), @@ -130,14 +130,14 @@ fn grandpa_observer, RA, S, F>( // and that implies that the next round has started. note_round(round + 1); - grandpa::process_commit_validation_result(validation_result, callback); + finality_grandpa::process_commit_validation_result(validation_result, callback); // proceed processing with new finalized block number future::ok(finalized_number) } else { debug!(target: "afg", "Received invalid commit: ({:?}, {:?})", round, commit); - grandpa::process_commit_validation_result(validation_result, callback); + finality_grandpa::process_commit_validation_result(validation_result, callback); // commit is invalid, continue processing commits with the current state future::ok(last_finalized_number) @@ -151,19 +151,20 @@ fn grandpa_observer, RA, S, F>( /// listening for and validating GRANDPA commits instead of following the full /// protocol. Provide configuration and a link to a block import worker that has /// already been instantiated with `block_import`. -pub fn run_grandpa_observer, N, RA, SC>( +pub fn run_grandpa_observer, N, RA, SC, Sp>( config: Config, link: LinkHalf, network: N, - on_exit: impl Future + Clone + Send + 'static, -) -> ::client_api::error::Result + Send + 'static> where + on_exit: impl futures03::Future + Clone + Send + Unpin + 'static, + executor: Sp, +) -> ::sp_blockchain::Result + Send + 'static> where B: Backend + 'static, E: CallExecutor + Send + Sync + 'static, - N: Network + Send + Sync + 'static, - N::In: Send + 'static, + N: NetworkT + Send + Clone + 'static, SC: SelectChain + 'static, NumberFor: BlockNumberOps, RA: Send + Sync + 'static, + Sp: futures03::task::Spawn + 'static, { let LinkHalf { client, @@ -172,10 +173,11 @@ pub fn run_grandpa_observer, N, RA, SC>( voter_commands_rx, } = link; - let (network, network_startup) = NetworkBridge::new( + let network = NetworkBridge::new( network, config.clone(), persistent_data.set_state.clone(), + &executor, on_exit.clone(), ); @@ -193,27 +195,26 @@ pub fn run_grandpa_observer, N, RA, SC>( warn!("GRANDPA Observer failed: {:?}", e); }); - let observer_work = network_startup.and_then(move |()| observer_work); + use futures03::{FutureExt, TryFutureExt}; - Ok(observer_work.select(on_exit).map(|_| ()).map_err(|_| ())) + Ok(observer_work.select(on_exit.map(Ok).compat()).map(|_| ()).map_err(|_| ())) } /// Future that powers the observer. #[must_use] -struct ObserverWork, N: Network, E, Backend, RA> { +struct ObserverWork, N: NetworkT, E, Backend, RA> { observer: Box>> + Send>, client: Arc>, network: NetworkBridge, persistent_data: PersistentData, - keystore: Option, + keystore: Option, voter_commands_rx: mpsc::UnboundedReceiver>>, } impl ObserverWork where B: BlockT, - N: Network, - N::In: Send + 'static, + N: NetworkT, NumberFor: BlockNumberOps, RA: 'static + Send + Sync, E: CallExecutor + Send + Sync + 'static, @@ -223,7 +224,7 @@ where client: Arc>, network: NetworkBridge, persistent_data: PersistentData, - keystore: Option, + keystore: Option, voter_commands_rx: mpsc::UnboundedReceiver>>, ) -> Self { @@ -328,8 +329,7 @@ where impl Future for ObserverWork where B: BlockT, - N: Network, - N::In: Send + 'static, + N: NetworkT, NumberFor: BlockNumberOps, RA: 'static + Send + Sync, E: CallExecutor + Send + Sync + 'static, diff --git a/client/finality-grandpa/src/tests.rs b/client/finality-grandpa/src/tests.rs index abcd44635cc2bf0233eb997f805311c2b0813ab3..7b52aad6e3fc162e11560387020b74bc5a16ac82 100644 --- a/client/finality-grandpa/src/tests.rs +++ b/client/finality-grandpa/src/tests.rs @@ -18,27 +18,29 @@ use super::*; use environment::HasVoted; -use network::test::{Block, DummySpecialization, Hash, TestNetFactory, Peer, PeersClient}; -use network::test::{PassThroughVerifier}; -use network::config::{ProtocolConfig, Roles, BoxFinalityProofRequestBuilder}; +use sc_network_test::{Block, DummySpecialization, Hash, TestNetFactory, Peer, PeersClient}; +use sc_network_test::{PassThroughVerifier}; +use sc_network::config::{ProtocolConfig, Roles, BoxFinalityProofRequestBuilder}; use parking_lot::Mutex; +use futures_timer::Delay; use futures03::{StreamExt as _, TryStreamExt as _}; use tokio::runtime::current_thread; -use keyring::Ed25519Keyring; -use client::LongestChain; -use client_api::error::Result; -use sr_api::{Core, RuntimeVersion, ApiExt, StorageProof}; -use test_client::{self, runtime::BlockNumber}; -use consensus_common::{BlockOrigin, ForkChoiceStrategy, ImportedAux, BlockImportParams, ImportResult}; -use consensus_common::import_queue::{BoxBlockImport, BoxJustificationImport, BoxFinalityProofImport}; +use sp_keyring::Ed25519Keyring; +use sc_client::LongestChain; +use sp_blockchain::Result; +use sp_api::{Core, RuntimeVersion, ApiExt, StorageProof}; +use substrate_test_runtime_client::{self, runtime::BlockNumber}; +use sp_consensus::{BlockOrigin, ForkChoiceStrategy, ImportedAux, BlockImportParams, ImportResult}; +use sp_consensus::import_queue::{BoxBlockImport, BoxJustificationImport, BoxFinalityProofImport}; use std::collections::{HashMap, HashSet}; use std::result; -use codec::Decode; -use sr_primitives::traits::{ApiRef, ProvideRuntimeApi, Header as HeaderT}; -use sr_primitives::generic::{BlockId, DigestItem}; -use primitives::{NativeOrEncoded, ExecutionContext, crypto::Public}; -use fg_primitives::{GRANDPA_ENGINE_ID, AuthorityList, GrandpaApi}; -use state_machine::{backend::InMemory, prove_read, read_proof_check}; +use parity_scale_codec::Decode; +use sp_runtime::traits::{ApiRef, ProvideRuntimeApi, Header as HeaderT}; +use sp_runtime::generic::{BlockId, DigestItem}; +use sp_core::{NativeOrEncoded, ExecutionContext, crypto::Public}; +use sp_finality_grandpa::{GRANDPA_ENGINE_ID, AuthorityList, GrandpaApi}; +use sp_state_machine::{backend::InMemory, prove_read, read_proof_check}; +use std::{pin::Pin, task}; use authorities::AuthoritySet; use finality_proof::{FinalityProofProvider, AuthoritySetForFinalityProver, AuthoritySetForFinalityChecker}; @@ -48,11 +50,11 @@ type PeerData = Mutex< Option< LinkHalf< - test_client::Backend, - test_client::Executor, + substrate_test_runtime_client::Backend, + substrate_test_runtime_client::Executor, Block, - test_client::runtime::RuntimeApi, - LongestChain + substrate_test_runtime_client::runtime::RuntimeApi, + LongestChain > > >; @@ -149,7 +151,7 @@ impl TestNetFactory for GrandpaTestNet { fn make_finality_proof_provider( &self, client: PeersClient - ) -> Option>> { + ) -> Option>> { match client { PeersClient::Full(_, ref backend) => { let authorities_provider = Arc::new(self.test_config.clone()); @@ -175,12 +177,11 @@ impl TestNetFactory for GrandpaTestNet { #[derive(Clone)] struct Exit; -impl Future for Exit { - type Item = (); - type Error = (); +impl futures03::Future for Exit { + type Output = (); - fn poll(&mut self) -> Poll<(), ()> { - Ok(Async::NotReady) + fn poll(self: Pin<&mut Self>, _: &mut task::Context) -> task::Poll<()> { + task::Poll::Pending } } @@ -242,7 +243,7 @@ impl Core for RuntimeApi { } impl ApiExt for RuntimeApi { - type Error = client_api::error::Error; + type Error = sp_blockchain::Error; fn map_api_result result::Result, R, E>( &self, @@ -290,7 +291,7 @@ impl AuthoritySetForFinalityProver for TestApi { fn prove_authorities(&self, block: &BlockId) -> Result { let authorities = self.authorities(block)?; let backend = >::from(vec![ - (None, b"authorities".to_vec(), Some(authorities.encode())) + (None, vec![(b"authorities".to_vec(), Some(authorities.encode()))]) ]); let proof = prove_read(backend, vec![b"authorities"]) .expect("failure proving read from in-memory storage backend"); @@ -327,7 +328,7 @@ fn make_ids(keys: &[Ed25519Keyring]) -> AuthorityList { fn create_keystore(authority: Ed25519Keyring) -> (KeyStorePtr, tempfile::TempDir) { let keystore_path = tempfile::tempdir().expect("Creates keystore path"); - let keystore = keystore::Store::open(keystore_path.path(), None).expect("Creates keystore"); + let keystore = sc_keystore::Store::open(keystore_path.path(), None).expect("Creates keystore"); keystore.write().insert_ephemeral_from_seed::(&authority.to_seed()) .expect("Creates authority key"); @@ -338,6 +339,7 @@ fn create_keystore(authority: Ed25519Keyring) -> (KeyStorePtr, tempfile::TempDir // the voters are spawned but before blocking on them. fn run_to_completion_with( runtime: &mut current_thread::Runtime, + threads_pool: &futures03::executor::ThreadPool, blocks: u64, net: Arc>, peers: &[Ed25519Keyring], @@ -405,6 +407,7 @@ fn run_to_completion_with( on_exit: Exit, telemetry_on_connect: None, voting_rule: (), + executor: threads_pool.clone(), }; let voter = run_grandpa_voter(grandpa_params).expect("all in order with client and network"); @@ -427,17 +430,18 @@ fn run_to_completion_with( fn run_to_completion( runtime: &mut current_thread::Runtime, + threads_pool: &futures03::executor::ThreadPool, blocks: u64, net: Arc>, peers: &[Ed25519Keyring] ) -> u64 { - run_to_completion_with(runtime, blocks, net, peers, |_| None) + run_to_completion_with(runtime, threads_pool, blocks, net, peers, |_| None) } fn add_scheduled_change(block: &mut Block, change: ScheduledChange) { block.header.digest_mut().push(DigestItem::Consensus( GRANDPA_ENGINE_ID, - fg_primitives::ConsensusLog::ScheduledChange(change).encode(), + sp_finality_grandpa::ConsensusLog::ScheduledChange(change).encode(), )); } @@ -448,7 +452,7 @@ fn add_forced_change( ) { block.header.digest_mut().push(DigestItem::Consensus( GRANDPA_ENGINE_ID, - fg_primitives::ConsensusLog::ForcedChange(median_last_finalized, change).encode(), + sp_finality_grandpa::ConsensusLog::ForcedChange(median_last_finalized, change).encode(), )); } @@ -456,6 +460,7 @@ fn add_forced_change( fn finalize_3_voters_no_observers() { let _ = env_logger::try_init(); let mut runtime = current_thread::Runtime::new().unwrap(); + let threads_pool = futures03::executor::ThreadPool::new().unwrap(); let peers = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob, Ed25519Keyring::Charlie]; let voters = make_ids(peers); @@ -469,7 +474,7 @@ fn finalize_3_voters_no_observers() { } let net = Arc::new(Mutex::new(net)); - run_to_completion(&mut runtime, 20, net.clone(), peers); + run_to_completion(&mut runtime, &threads_pool, 20, net.clone(), peers); // normally there's no justification for finalized blocks assert!( @@ -481,6 +486,7 @@ fn finalize_3_voters_no_observers() { #[test] fn finalize_3_voters_1_full_observer() { let mut runtime = current_thread::Runtime::new().unwrap(); + let threads_pool = futures03::executor::ThreadPool::new().unwrap(); let peers = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob, Ed25519Keyring::Charlie]; let voters = make_ids(peers); @@ -499,6 +505,8 @@ fn finalize_3_voters_1_full_observer() { let mut keystore_paths = Vec::new(); + let mut voters = Vec::new(); + for (peer_id, local_key) in all_peers.enumerate() { let (client, net_service, link) = { let net = net.lock(); @@ -539,9 +547,13 @@ fn finalize_3_voters_1_full_observer() { on_exit: Exit, telemetry_on_connect: None, voting_rule: (), + executor: threads_pool.clone(), }; - let voter = run_grandpa_voter(grandpa_params).expect("all in order with client and network"); + voters.push(run_grandpa_voter(grandpa_params).expect("all in order with client and network")); + } + + for voter in voters { runtime.spawn(voter); } @@ -583,6 +595,7 @@ fn transition_3_voters_twice_1_full_observer() { let net = Arc::new(Mutex::new(GrandpaTestNet::new(api, 8))); let mut runtime = current_thread::Runtime::new().unwrap(); + let threads_pool = futures03::executor::ThreadPool::new().unwrap(); net.lock().peer(0).push_blocks(1, false); net.lock().block_until_sync(&mut runtime); @@ -687,6 +700,7 @@ fn transition_3_voters_twice_1_full_observer() { assert_eq!(set.pending_changes().count(), 0); }) ); + let grandpa_params = GrandpaParams { config: Config { gossip_duration: TEST_GOSSIP_DURATION, @@ -702,6 +716,7 @@ fn transition_3_voters_twice_1_full_observer() { on_exit: Exit, telemetry_on_connect: None, voting_rule: (), + executor: threads_pool.clone(), }; let voter = run_grandpa_voter(grandpa_params).expect("all in order with client and network"); @@ -720,15 +735,16 @@ fn transition_3_voters_twice_1_full_observer() { #[test] fn justification_is_emitted_when_consensus_data_changes() { let mut runtime = current_thread::Runtime::new().unwrap(); + let threads_pool = futures03::executor::ThreadPool::new().unwrap(); let peers = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob, Ed25519Keyring::Charlie]; let mut net = GrandpaTestNet::new(TestApi::new(make_ids(peers)), 3); // import block#1 WITH consensus data change - let new_authorities = vec![babe_primitives::AuthorityId::from_slice(&[42; 32])]; + let new_authorities = vec![sp_consensus_babe::AuthorityId::from_slice(&[42; 32])]; net.peer(0).push_authorities_change_block(new_authorities); net.block_until_sync(&mut runtime); let net = Arc::new(Mutex::new(net)); - run_to_completion(&mut runtime, 1, net.clone(), peers); + run_to_completion(&mut runtime, &threads_pool, 1, net.clone(), peers); // ... and check that there's justification for block#1 assert!(net.lock().peer(0).client().justification(&BlockId::Number(1)).unwrap().is_some(), @@ -738,6 +754,7 @@ fn justification_is_emitted_when_consensus_data_changes() { #[test] fn justification_is_generated_periodically() { let mut runtime = current_thread::Runtime::new().unwrap(); + let threads_pool = futures03::executor::ThreadPool::new().unwrap(); let peers = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob, Ed25519Keyring::Charlie]; let voters = make_ids(peers); @@ -746,7 +763,7 @@ fn justification_is_generated_periodically() { net.block_until_sync(&mut runtime); let net = Arc::new(Mutex::new(net)); - run_to_completion(&mut runtime, 32, net.clone(), peers); + run_to_completion(&mut runtime, &threads_pool, 32, net.clone(), peers); // when block#32 (justification_period) is finalized, justification // is required => generated @@ -777,6 +794,7 @@ fn consensus_changes_works() { #[test] fn sync_justifications_on_change_blocks() { let mut runtime = current_thread::Runtime::new().unwrap(); + let threads_pool = futures03::executor::ThreadPool::new().unwrap(); let peers_a = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob, Ed25519Keyring::Charlie]; let peers_b = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob]; let voters = make_ids(peers_b); @@ -808,7 +826,7 @@ fn sync_justifications_on_change_blocks() { } let net = Arc::new(Mutex::new(net)); - run_to_completion(&mut runtime, 25, net.clone(), peers_a); + run_to_completion(&mut runtime, &threads_pool, 25, net.clone(), peers_a); // the first 3 peers are grandpa voters and therefore have already finalized // block 21 and stored a justification @@ -831,6 +849,7 @@ fn sync_justifications_on_change_blocks() { fn finalizes_multiple_pending_changes_in_order() { let _ = env_logger::try_init(); let mut runtime = current_thread::Runtime::new().unwrap(); + let threads_pool = futures03::executor::ThreadPool::new().unwrap(); let peers_a = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob, Ed25519Keyring::Charlie]; let peers_b = &[Ed25519Keyring::Dave, Ed25519Keyring::Eve, Ed25519Keyring::Ferdie]; @@ -884,13 +903,14 @@ fn finalizes_multiple_pending_changes_in_order() { } let net = Arc::new(Mutex::new(net)); - run_to_completion(&mut runtime, 30, net.clone(), all_peers); + run_to_completion(&mut runtime, &threads_pool, 30, net.clone(), all_peers); } #[test] fn force_change_to_new_set() { let _ = env_logger::try_init(); let mut runtime = current_thread::Runtime::new().unwrap(); + let threads_pool = futures03::executor::ThreadPool::new().unwrap(); // two of these guys are offline. let genesis_authorities = &[ Ed25519Keyring::Alice, @@ -941,7 +961,7 @@ fn force_change_to_new_set() { // it will only finalize if the forced transition happens. // we add_blocks after the voters are spawned because otherwise // the link-halfs have the wrong AuthoritySet - run_to_completion(&mut runtime, 25, net, peers_a); + run_to_completion(&mut runtime, &threads_pool, 25, net, peers_a); } #[test] @@ -975,6 +995,7 @@ fn allows_reimporting_change_blocks() { auxiliary: Vec::new(), fork_choice: ForkChoiceStrategy::LongestChain, allow_missing_state: false, + import_existing: false, } }; @@ -1028,6 +1049,7 @@ fn test_bad_justification() { auxiliary: Vec::new(), fork_choice: ForkChoiceStrategy::LongestChain, allow_missing_state: false, + import_existing: false, } }; @@ -1057,6 +1079,7 @@ fn voter_persists_its_votes() { let _ = env_logger::try_init(); let mut runtime = current_thread::Runtime::new().unwrap(); + let threads_pool = futures03::executor::ThreadPool::new().unwrap(); // we have two authorities but we'll only be running the voter for alice // we are going to be listening for the prevotes it casts @@ -1095,6 +1118,7 @@ fn voter_persists_its_votes() { net: Arc>, client: PeersClient, keystore: KeyStorePtr, + threads_pool: futures03::executor::ThreadPool, } impl Future for ResettableVoter { @@ -1130,6 +1154,7 @@ fn voter_persists_its_votes() { on_exit: Exit, telemetry_on_connect: None, voting_rule: VotingRulesBuilder::default().build(), + executor: self.threads_pool.clone(), }; let voter = run_grandpa_voter(grandpa_params) @@ -1161,6 +1186,7 @@ fn voter_persists_its_votes() { net: net.clone(), client: client.clone(), keystore, + threads_pool: threads_pool.clone(), }); } @@ -1189,13 +1215,13 @@ fn voter_persists_its_votes() { set_state }; - let (network, routing_work) = communication::NetworkBridge::new( + let network = communication::NetworkBridge::new( net.lock().peers[1].network_service().clone(), config.clone(), set_state, + &threads_pool, Exit, ); - runtime.block_on(routing_work).unwrap(); let (round_rx, round_tx) = network.round_communication( communication::Round(1), @@ -1215,7 +1241,7 @@ fn voter_persists_its_votes() { if state.compare_and_swap(0, 1, Ordering::SeqCst) == 0 { // the first message we receive should be a prevote from alice. let prevote = match signed.message { - grandpa::Message::Prevote(prevote) => prevote, + finality_grandpa::Message::Prevote(prevote) => prevote, _ => panic!("voter should prevote."), }; @@ -1230,7 +1256,14 @@ fn voter_persists_its_votes() { let net = net.clone(); let voter_tx = voter_tx.clone(); let round_tx = round_tx.clone(); - future::Either::A(tokio_timer::Interval::new_interval(Duration::from_millis(200)) + + let interval = futures03::stream::unfold(Delay::new(Duration::from_millis(200)), |delay| + Box::pin(async move { + delay.await; + Some(((), Delay::new(Duration::from_millis(200)))) + })).map(Ok::<_, ()>).compat(); + + future::Either::A(interval .take_while(move |_| { Ok(net2.lock().peer(1).client().info().chain.best_number != 40) }) @@ -1243,19 +1276,19 @@ fn voter_persists_its_votes() { voter_tx.unbounded_send(()).unwrap(); // and we push our own prevote for block 30 - let prevote = grandpa::Prevote { + let prevote = finality_grandpa::Prevote { target_number: 30, target_hash: block_30_hash, }; - round_tx.lock().start_send(grandpa::Message::Prevote(prevote)).unwrap(); + round_tx.lock().start_send(finality_grandpa::Message::Prevote(prevote)).unwrap(); Ok(()) }).map_err(|_| panic!())) } else if state.compare_and_swap(1, 2, Ordering::SeqCst) == 1 { // the next message we receive should be our own prevote let prevote = match signed.message { - grandpa::Message::Prevote(prevote) => prevote, + finality_grandpa::Message::Prevote(prevote) => prevote, _ => panic!("We should receive our own prevote."), }; @@ -1272,7 +1305,7 @@ fn voter_persists_its_votes() { // we then receive a precommit from alice for block 15 // even though we casted a prevote for block 30 let precommit = match signed.message { - grandpa::Message::Precommit(precommit) => precommit, + finality_grandpa::Message::Precommit(precommit) => precommit, _ => panic!("voter should precommit."), }; @@ -1300,6 +1333,7 @@ fn voter_persists_its_votes() { fn finalize_3_voters_1_light_observer() { let _ = env_logger::try_init(); let mut runtime = current_thread::Runtime::new().unwrap(); + let threads_pool = futures03::executor::ThreadPool::new().unwrap(); let authorities = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob, Ed25519Keyring::Charlie]; let voters = make_ids(authorities); @@ -1320,7 +1354,7 @@ fn finalize_3_voters_1_light_observer() { .take_while(|n| Ok(n.header.number() < &20)) .collect(); - run_to_completion_with(&mut runtime, 20, net.clone(), authorities, |executor| { + run_to_completion_with(&mut runtime, &threads_pool, 20, net.clone(), authorities, |executor| { executor.spawn( run_grandpa_observer( Config { @@ -1334,6 +1368,7 @@ fn finalize_3_voters_1_light_observer() { link, net.lock().peers[3].network_service().clone(), Exit, + threads_pool.clone(), ).unwrap() ).unwrap(); @@ -1345,6 +1380,7 @@ fn finalize_3_voters_1_light_observer() { fn finality_proof_is_fetched_by_light_client_when_consensus_data_changes() { let _ = ::env_logger::try_init(); let mut runtime = current_thread::Runtime::new().unwrap(); + let threads_pool = futures03::executor::ThreadPool::new().unwrap(); let peers = &[Ed25519Keyring::Alice]; let mut net = GrandpaTestNet::new(TestApi::new(make_ids(peers)), 1); @@ -1352,9 +1388,9 @@ fn finality_proof_is_fetched_by_light_client_when_consensus_data_changes() { // import block#1 WITH consensus data change. Light client ignores justification // && instead fetches finality proof for block #1 - net.peer(0).push_authorities_change_block(vec![babe_primitives::AuthorityId::from_slice(&[42; 32])]); + net.peer(0).push_authorities_change_block(vec![sp_consensus_babe::AuthorityId::from_slice(&[42; 32])]); let net = Arc::new(Mutex::new(net)); - run_to_completion(&mut runtime, 1, net.clone(), peers); + run_to_completion(&mut runtime, &threads_pool, 1, net.clone(), peers); net.lock().block_until_sync(&mut runtime); // check that the block#1 is finalized on light client @@ -1375,6 +1411,7 @@ fn empty_finality_proof_is_returned_to_light_client_when_authority_set_is_differ let _ = ::env_logger::try_init(); let mut runtime = current_thread::Runtime::new().unwrap(); + let threads_pool = futures03::executor::ThreadPool::new().unwrap(); // two of these guys are offline. let genesis_authorities = if FORCE_CHANGE { @@ -1416,13 +1453,13 @@ fn empty_finality_proof_is_returned_to_light_client_when_authority_set_is_differ // normally it will reach light client, but because of the forced change, it will not net.lock().peer(0).push_blocks(8, false); // best is #9 net.lock().peer(0).push_authorities_change_block( - vec![babe_primitives::AuthorityId::from_slice(&[42; 32])] + vec![sp_consensus_babe::AuthorityId::from_slice(&[42; 32])] ); // #10 net.lock().peer(0).push_blocks(1, false); // best is #11 net.lock().block_until_sync(&mut runtime); // finalize block #11 on full clients - run_to_completion(&mut runtime, 11, net.clone(), peers_a); + run_to_completion(&mut runtime, &threads_pool, 11, net.clone(), peers_a); // request finalization by light client net.lock().add_light_peer(&GrandpaTestNet::default_config()); @@ -1439,6 +1476,7 @@ fn empty_finality_proof_is_returned_to_light_client_when_authority_set_is_differ fn voter_catches_up_to_latest_round_when_behind() { let _ = env_logger::try_init(); let mut runtime = current_thread::Runtime::new().unwrap(); + let threads_pool = futures03::executor::ThreadPool::new().unwrap(); let peers = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob]; let voters = make_ids(peers); @@ -1466,6 +1504,7 @@ fn voter_catches_up_to_latest_round_when_behind() { on_exit: Exit, telemetry_on_connect: None, voting_rule: (), + executor: threads_pool.clone(), }; Box::new(run_grandpa_voter(grandpa_params).expect("all in order with client and network")) @@ -1550,8 +1589,10 @@ fn voter_catches_up_to_latest_round_when_behind() { #[test] fn grandpa_environment_respects_voting_rules() { - use grandpa::Chain; - use network::test::TestClient; + use finality_grandpa::Chain; + use sc_network_test::TestClient; + + let threads_pool = futures03::executor::ThreadPool::new().unwrap(); let peers = &[Ed25519Keyring::Alice]; let voters = make_ids(peers); @@ -1579,10 +1620,11 @@ fn grandpa_environment_respects_voting_rules() { observer_enabled: true, }; - let (network, _) = NetworkBridge::new( + let network = NetworkBridge::new( network_service.clone(), config.clone(), set_state.clone(), + &threads_pool, Exit, ); @@ -1699,22 +1741,22 @@ fn imports_justification_for_regular_blocks_on_import() { let round = 1; let set_id = 0; - let precommit = grandpa::Precommit { + let precommit = finality_grandpa::Precommit { target_hash: block_hash, target_number: *block.header.number(), }; - let msg = grandpa::Message::Precommit(precommit.clone()); + let msg = finality_grandpa::Message::Precommit(precommit.clone()); let encoded = communication::localized_payload(round, set_id, &msg); let signature = peers[0].sign(&encoded[..]).into(); - let precommit = grandpa::SignedPrecommit { + let precommit = finality_grandpa::SignedPrecommit { precommit, signature, id: peers[0].public().into(), }; - let commit = grandpa::Commit { + let commit = finality_grandpa::Commit { target_hash: block_hash, target_number: *block.header.number(), precommits: vec![precommit], @@ -1738,6 +1780,7 @@ fn imports_justification_for_regular_blocks_on_import() { auxiliary: Vec::new(), fork_choice: ForkChoiceStrategy::LongestChain, allow_missing_state: false, + import_existing: false, }; assert_eq!( diff --git a/client/finality-grandpa/src/until_imported.rs b/client/finality-grandpa/src/until_imported.rs index fca67ab195e5495e3408cc66f187dc7dc23700e9..23ab5c5daadcba4f958c19c38dfbefd9fac7e165 100644 --- a/client/finality-grandpa/src/until_imported.rs +++ b/client/finality-grandpa/src/until_imported.rs @@ -29,19 +29,19 @@ use super::{ }; use log::{debug, warn}; -use client_api::{BlockImportNotification, ImportNotifications}; +use sc_client_api::{BlockImportNotification, ImportNotifications}; use futures::prelude::*; use futures::stream::Fuse; +use futures_timer::Delay; use futures03::{StreamExt as _, TryStreamExt as _}; -use grandpa::voter; +use finality_grandpa::voter; use parking_lot::Mutex; -use sr_primitives::traits::{Block as BlockT, Header as HeaderT, NumberFor}; -use tokio_timer::Interval; +use sp_runtime::traits::{Block as BlockT, Header as HeaderT, NumberFor}; use std::collections::{HashMap, VecDeque}; use std::sync::{atomic::{AtomicUsize, Ordering}, Arc}; use std::time::{Duration, Instant}; -use fg_primitives::AuthorityId; +use sp_finality_grandpa::AuthorityId; const LOG_PENDING_INTERVAL: Duration = Duration::from_secs(15); @@ -76,7 +76,7 @@ pub(crate) struct UntilImported, ready: VecDeque, - check_pending: Interval, + check_pending: Box + Send>, /// Mapping block hashes to their block number, the point in time it was /// first encountered (Instant) and a list of GRANDPA messages referencing /// the block hash. @@ -104,9 +104,13 @@ impl UntilImported _>(|v| Ok::<_, ()>(v)).compat(); @@ -116,7 +120,7 @@ impl UntilImported for TestBlockSyncRequester { - fn set_sync_fork_request(&self, _peers: Vec, hash: Hash, number: NumberFor) { + fn set_sync_fork_request(&self, _peers: Vec, hash: Hash, number: NumberFor) { self.requests.lock().push((hash, number)); } } @@ -628,7 +632,7 @@ mod tests { let inner_chain_state = chain_state.clone(); let work = until_imported .into_future() - .select2(Delay::new(Instant::now() + Duration::from_millis(100))) + .select2(Delay::new(Duration::from_millis(100)).unit_error().compat()) .then(move |res| match res { Err(_) => panic!("neither should have had error"), Ok(Either::A(_)) => panic!("timeout should have fired first"), @@ -737,10 +741,10 @@ mod tests { let h3 = make_header(7); let signed_prevote = |header: &Header| { - grandpa::SignedPrevote { + finality_grandpa::SignedPrevote { id: Default::default(), signature: Default::default(), - prevote: grandpa::Prevote { + prevote: finality_grandpa::Prevote { target_hash: header.hash(), target_number: *header.number(), }, @@ -748,10 +752,10 @@ mod tests { }; let signed_precommit = |header: &Header| { - grandpa::SignedPrecommit { + finality_grandpa::SignedPrecommit { id: Default::default(), signature: Default::default(), - precommit: grandpa::Precommit { + precommit: finality_grandpa::Precommit { target_hash: header.hash(), target_number: *header.number(), }, @@ -768,7 +772,7 @@ mod tests { signed_precommit(&h2), ]; - let unknown_catch_up = grandpa::CatchUp { + let unknown_catch_up = finality_grandpa::CatchUp { round_number: 1, prevotes, precommits, @@ -803,10 +807,10 @@ mod tests { let h3 = make_header(7); let signed_prevote = |header: &Header| { - grandpa::SignedPrevote { + finality_grandpa::SignedPrevote { id: Default::default(), signature: Default::default(), - prevote: grandpa::Prevote { + prevote: finality_grandpa::Prevote { target_hash: header.hash(), target_number: *header.number(), }, @@ -814,10 +818,10 @@ mod tests { }; let signed_precommit = |header: &Header| { - grandpa::SignedPrecommit { + finality_grandpa::SignedPrecommit { id: Default::default(), signature: Default::default(), - precommit: grandpa::Precommit { + precommit: finality_grandpa::Precommit { target_hash: header.hash(), target_number: *header.number(), }, @@ -834,7 +838,7 @@ mod tests { signed_precommit(&h2), ]; - let unknown_catch_up = grandpa::CatchUp { + let unknown_catch_up = finality_grandpa::CatchUp { round_number: 1, prevotes, precommits, @@ -929,7 +933,7 @@ mod tests { // the `until_imported` stream doesn't request the blocks immediately, // but it should request them after a small timeout - let timeout = Delay::new(Instant::now() + Duration::from_secs(60)); + let timeout = Delay::new(Duration::from_secs(60)).unit_error().compat(); let test = assert.select2(timeout).map(|res| match res { Either::A(_) => {}, Either::B(_) => panic!("timed out waiting for block sync request"), diff --git a/client/finality-grandpa/src/voting_rule.rs b/client/finality-grandpa/src/voting_rule.rs index 790751507446661ce80082d56b4546450f8e0901..424677433f05ecb4e9ab554270bbb0f99288d45f 100644 --- a/client/finality-grandpa/src/voting_rule.rs +++ b/client/finality-grandpa/src/voting_rule.rs @@ -22,9 +22,9 @@ use std::sync::Arc; -use client_api::blockchain::HeaderBackend; -use sr_primitives::generic::BlockId; -use sr_primitives::traits::{Block as BlockT, Header, NumberFor, One, Zero}; +use sc_client_api::blockchain::HeaderBackend; +use sp_runtime::generic::BlockId; +use sp_runtime::traits::{Block as BlockT, Header, NumberFor, One, Zero}; /// A trait for custom voting rules in GRANDPA. pub trait VotingRule: Send + Sync where diff --git a/client/grafana-data-source/src/util.rs b/client/grafana-data-source/src/util.rs deleted file mode 100644 index cd27c440f7ded406709ca24db64b530db75b3047..0000000000000000000000000000000000000000 --- a/client/grafana-data-source/src/util.rs +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2019 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate 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. - -// Substrate 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 Substrate. If not, see . - -/// Get the current unix timestamp in milliseconds. -pub fn now_millis() -> i64 { - chrono::Utc::now().timestamp_millis() -} - -// find the index of a timestamp -pub fn find_index(slice: &[(f32, i64)], timestamp: i64) -> usize { - slice.binary_search_by_key(×tamp, |&(_, timestamp)| timestamp) - .unwrap_or_else(|index| index) -} - -// Evenly select up to `num_points` points from a slice -pub fn select_points(slice: &[T], num_points: usize) -> Vec { - if num_points == 0 { - return Vec::new(); - } else if num_points >= slice.len() { - return slice.to_owned(); - } - - (0 .. num_points - 1) - .map(|i| slice[i * slice.len() / (num_points - 1)]) - .chain(slice.last().cloned()) - .collect() -} - -#[test] -fn test_select_points() { - let array = [1, 2, 3, 4, 5]; - assert_eq!(select_points(&array, 0), Vec::::new()); - assert_eq!(select_points(&array, 1), vec![5]); - assert_eq!(select_points(&array, 2), vec![1, 5]); - assert_eq!(select_points(&array, 3), vec![1, 3, 5]); - assert_eq!(select_points(&array, 4), vec![1, 2, 4, 5]); - assert_eq!(select_points(&array, 5), vec![1, 2, 3, 4, 5]); - assert_eq!(select_points(&array, 6), vec![1, 2, 3, 4, 5]); -} diff --git a/client/header-metadata/Cargo.toml b/client/header-metadata/Cargo.toml deleted file mode 100644 index b321685c6c215446149dc911cee23b2f6ebaf58c..0000000000000000000000000000000000000000 --- a/client/header-metadata/Cargo.toml +++ /dev/null @@ -1,10 +0,0 @@ -[package] -name = "substrate-header-metadata" -version = "2.0.0" -authors = ["Parity Technologies "] -edition = "2018" - -[dependencies] -lru = { version = "0.4.0" } -parking_lot = { version = "0.9.0" } -sr-primitives = { path = "../../primitives/sr-primitives" } diff --git a/client/keystore/Cargo.toml b/client/keystore/Cargo.toml index 9923a7f357d1fbfcf40dbe912123bd5a6f724944..cdc69349fb8b8cb41b0784fe0dbea49e0bea130c 100644 --- a/client/keystore/Cargo.toml +++ b/client/keystore/Cargo.toml @@ -1,18 +1,18 @@ [package] -name = "substrate-keystore" +name = "sc-keystore" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" [dependencies] -derive_more = "0.15.0" -primitives = { package = "substrate-primitives", path = "../../primitives/core" } -app-crypto = { package = "substrate-application-crypto", path = "../../primitives/application-crypto" } -hex = "0.3.2" +derive_more = "0.99.2" +sp-core = { version = "2.0.0", path = "../../primitives/core" } +sp-application-crypto = { version = "2.0.0", path = "../../primitives/application-crypto" } +hex = "0.4.0" rand = "0.7.2" serde_json = "1.0.41" subtle = "2.1.1" parking_lot = "0.9.0" [dev-dependencies] -tempdir = "0.3.7" +tempfile = "3.1.0" diff --git a/client/keystore/src/lib.rs b/client/keystore/src/lib.rs index c86e9f8b8850ce6d64da82f3bd6fcfb06c4f8694..b51ab5a0a08dd8043e1e1b0634195060f5bcce4b 100644 --- a/client/keystore/src/lib.rs +++ b/client/keystore/src/lib.rs @@ -20,11 +20,11 @@ use std::{collections::HashMap, path::PathBuf, fs::{self, File}, io::{self, Write}, sync::Arc}; -use primitives::{ +use sp_core::{ crypto::{KeyTypeId, Pair as PairT, Public, IsWrappedBy, Protected}, traits::BareCryptoStore, }; -use app_crypto::{AppKey, AppPublic, AppPair, ed25519, sr25519}; +use sp_application_crypto::{AppKey, AppPublic, AppPair, ed25519, sr25519}; use parking_lot::RwLock; @@ -226,7 +226,7 @@ impl Store { // skip directories and non-unicode file names (hex is unicode) if let Some(name) = path.file_name().and_then(|n| n.to_str()) { match hex::decode(name) { - Ok(ref hex) => { + Ok(ref hex) if hex.len() > 4 => { if &hex[0..4] != &key_type.0 { continue } let public = TPublic::from_slice(&hex[4..]); public_keys.push(public); @@ -317,12 +317,12 @@ impl BareCryptoStore for Store { #[cfg(test)] mod tests { use super::*; - use tempdir::TempDir; - use primitives::{testing::{SR25519}, crypto::{Ss58Codec}}; + use tempfile::TempDir; + use sp_core::{testing::{SR25519}, crypto::{Ss58Codec}}; #[test] fn basic_store() { - let temp_dir = TempDir::new("keystore").unwrap(); + let temp_dir = TempDir::new().unwrap(); let store = Store::open(temp_dir.path(), None).unwrap(); assert!(store.read().public_keys::().unwrap().is_empty()); @@ -337,7 +337,7 @@ mod tests { #[test] fn test_insert_ephemeral_from_seed() { - let temp_dir = TempDir::new("keystore").unwrap(); + let temp_dir = TempDir::new().unwrap(); let store = Store::open(temp_dir.path(), None).unwrap(); let pair: ed25519::AppPair = store @@ -358,7 +358,7 @@ mod tests { #[test] fn password_being_used() { let password = String::from("password"); - let temp_dir = TempDir::new("keystore").unwrap(); + let temp_dir = TempDir::new().unwrap(); let store = Store::open(temp_dir.path(), Some(password.clone().into())).unwrap(); let pair: ed25519::AppPair = store.write().generate().unwrap(); @@ -380,7 +380,7 @@ mod tests { #[test] fn public_keys_are_returned() { - let temp_dir = TempDir::new("keystore").unwrap(); + let temp_dir = TempDir::new().unwrap(); let store = Store::open(temp_dir.path(), None).unwrap(); let mut public_keys = Vec::new(); @@ -403,7 +403,7 @@ mod tests { #[test] fn store_unknown_and_extract_it() { - let temp_dir = TempDir::new("keystore").unwrap(); + let temp_dir = TempDir::new().unwrap(); let store = Store::open(temp_dir.path(), None).unwrap(); let secret_uri = "//Alice"; @@ -422,4 +422,17 @@ mod tests { assert_eq!(key_pair.public(), store_key_pair.public()); } + + #[test] + fn store_ignores_files_with_invalid_name() { + let temp_dir = TempDir::new().unwrap(); + let store = Store::open(temp_dir.path(), None).unwrap(); + + let file_name = temp_dir.path().join(hex::encode(&SR25519.0[..2])); + fs::write(file_name, "test").expect("Invalid file is written"); + + assert!( + store.read().public_keys_by_type::(SR25519).unwrap().is_empty(), + ); + } } diff --git a/client/network-gossip/Cargo.toml b/client/network-gossip/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..79246151c363caa9651083cdea061ee623415ae0 --- /dev/null +++ b/client/network-gossip/Cargo.toml @@ -0,0 +1,18 @@ +[package] +description = "Gossiping for the Substrate network protocol" +name = "sc-network-gossip" +version = "2.0.0" +license = "GPL-3.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +log = "0.4.8" +futures01 = { package = "futures", version = "0.1.29" } +futures = { version = "0.3.1", features = ["compat"] } +futures-timer = "0.4.0" +lru = "0.1.2" +libp2p = { version = "0.13.0", default-features = false, features = ["libp2p-websocket"] } +sc-network = { version = "0.8", path = "../network" } +parking_lot = "0.9.0" +sp-runtime = { version = "2.0.0", path = "../../primitives/runtime" } diff --git a/client/network-gossip/src/bridge.rs b/client/network-gossip/src/bridge.rs new file mode 100644 index 0000000000000000000000000000000000000000..70b0f78cf31949764bfbb9cffe5fde413a86fb48 --- /dev/null +++ b/client/network-gossip/src/bridge.rs @@ -0,0 +1,283 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +use crate::Network; +use crate::state_machine::{ConsensusGossip, Validator, TopicNotification}; + +use sc_network::Context; +use sc_network::message::generic::ConsensusMessage; +use sc_network::{Event, ReputationChange}; + +use futures::{prelude::*, channel::mpsc, compat::Compat01As03, task::SpawnExt as _}; +use libp2p::PeerId; +use parking_lot::Mutex; +use sp_runtime::{traits::Block as BlockT, ConsensusEngineId}; +use std::{sync::Arc, time::Duration}; + +/// Wraps around an implementation of the `Network` crate and provides gossiping capabilities on +/// top of it. +pub struct GossipEngine { + inner: Arc>>, + engine_id: ConsensusEngineId, +} + +struct GossipEngineInner { + state_machine: ConsensusGossip, + context: Box + Send>, + context_ext: Box + Send>, +} + +impl GossipEngine { + /// Create a new instance. + pub fn new + Send + Clone + 'static>( + network: N, + executor: &impl futures::task::Spawn, + engine_id: ConsensusEngineId, + validator: Arc>, + ) -> Self where B: 'static { + let mut state_machine = ConsensusGossip::new(); + let mut context = Box::new(ContextOverService { + network: network.clone(), + }); + let context_ext = Box::new(ContextOverService { + network: network.clone(), + }); + + // We grab the event stream before registering the notifications protocol, otherwise we + // might miss events. + let event_stream = network.event_stream(); + + network.register_notifications_protocol(engine_id); + state_machine.register_validator(&mut *context, engine_id, validator); + + let inner = Arc::new(Mutex::new(GossipEngineInner { + state_machine, + context, + context_ext, + })); + + let gossip_engine = GossipEngine { + inner: inner.clone(), + engine_id, + }; + + let res = executor.spawn({ + let inner = Arc::downgrade(&inner); + async move { + loop { + let _ = futures_timer::Delay::new(Duration::from_millis(1100)).await; + if let Some(inner) = inner.upgrade() { + let mut inner = inner.lock(); + let inner = &mut *inner; + inner.state_machine.tick(&mut *inner.context); + } else { + // We reach this branch if the `Arc` has no reference + // left. We can now let the task end. + break; + } + } + } + }); + + // Note: we consider the chances of an error to spawn a background task almost null. + if res.is_err() { + log::error!(target: "gossip", "Failed to spawn background task"); + } + + let res = executor.spawn(async move { + let mut stream = Compat01As03::new(event_stream); + while let Some(Ok(event)) = stream.next().await { + match event { + Event::NotificationStreamOpened { remote, engine_id: msg_engine_id, roles } => { + if msg_engine_id != engine_id { + continue; + } + let mut inner = inner.lock(); + let inner = &mut *inner; + inner.state_machine.new_peer(&mut *inner.context, remote, roles); + } + Event::NotificationsStreamClosed { remote, engine_id: msg_engine_id } => { + if msg_engine_id != engine_id { + continue; + } + let mut inner = inner.lock(); + let inner = &mut *inner; + inner.state_machine.peer_disconnected(&mut *inner.context, remote); + }, + Event::NotificationsReceived { remote, messages } => { + let mut inner = inner.lock(); + let inner = &mut *inner; + inner.state_machine.on_incoming( + &mut *inner.context, + remote, + messages.into_iter() + .filter_map(|(engine, data)| if engine == engine_id { + Some(ConsensusMessage { engine_id: engine, data: data.to_vec() }) + } else { None }) + .collect() + ); + }, + Event::Dht(_) => {} + } + } + }); + + // Note: we consider the chances of an error to spawn a background task almost null. + if res.is_err() { + log::error!(target: "gossip", "Failed to spawn background task"); + } + + gossip_engine + } + + /// Closes all notification streams. + pub fn abort(&self) { + self.inner.lock().state_machine.abort(); + } + + pub fn report(&self, who: PeerId, reputation: ReputationChange) { + self.inner.lock().context.report_peer(who, reputation); + } + + /// Registers a message without propagating it to any peers. The message + /// becomes available to new peers or when the service is asked to gossip + /// the message's topic. No validation is performed on the message, if the + /// message is already expired it should be dropped on the next garbage + /// collection. + pub fn register_gossip_message( + &self, + topic: B::Hash, + message: Vec, + ) { + let message = ConsensusMessage { + engine_id: self.engine_id, + data: message, + }; + + self.inner.lock().state_machine.register_message(topic, message); + } + + /// Broadcast all messages with given topic. + pub fn broadcast_topic(&self, topic: B::Hash, force: bool) { + let mut inner = self.inner.lock(); + let inner = &mut *inner; + inner.state_machine.broadcast_topic(&mut *inner.context, topic, force); + } + + /// Get data of valid, incoming messages for a topic (but might have expired meanwhile). + pub fn messages_for(&self, topic: B::Hash) + -> mpsc::UnboundedReceiver + { + self.inner.lock().state_machine.messages_for(self.engine_id, topic) + } + + /// Send all messages with given topic to a peer. + pub fn send_topic( + &self, + who: &PeerId, + topic: B::Hash, + force: bool + ) { + let mut inner = self.inner.lock(); + let inner = &mut *inner; + inner.state_machine.send_topic(&mut *inner.context, who, topic, self.engine_id, force) + } + + /// Multicast a message to all peers. + pub fn gossip_message( + &self, + topic: B::Hash, + message: Vec, + force: bool, + ) { + let message = ConsensusMessage { + engine_id: self.engine_id, + data: message, + }; + + let mut inner = self.inner.lock(); + let inner = &mut *inner; + inner.state_machine.multicast(&mut *inner.context, topic, message, force) + } + + /// Send addressed message to the given peers. The message is not kept or multicast + /// later on. + pub fn send_message(&self, who: Vec, data: Vec) { + let mut inner = self.inner.lock(); + let inner = &mut *inner; + + for who in &who { + inner.state_machine.send_message(&mut *inner.context, who, ConsensusMessage { + engine_id: self.engine_id, + data: data.clone(), + }); + } + } + + /// Notify everyone we're connected to that we have the given block. + /// + /// Note: this method isn't strictly related to gossiping and should eventually be moved + /// somewhere else. + pub fn announce(&self, block: B::Hash, associated_data: Vec) { + self.inner.lock().context_ext.announce(block, associated_data); + } +} + +impl Clone for GossipEngine { + fn clone(&self) -> Self { + GossipEngine { + inner: self.inner.clone(), + engine_id: self.engine_id.clone(), + } + } +} + +struct ContextOverService { + network: N, +} + +impl> Context for ContextOverService { + fn report_peer(&mut self, who: PeerId, reputation: ReputationChange) { + self.network.report_peer(who, reputation); + } + + fn disconnect_peer(&mut self, who: PeerId) { + self.network.disconnect_peer(who) + } + + fn send_consensus(&mut self, who: PeerId, messages: Vec) { + for message in messages { + self.network.write_notification(who.clone(), message.engine_id, message.data); + } + } + + fn send_chain_specific(&mut self, _: PeerId, _: Vec) { + log::error!( + target: "sub-libp2p", + "send_chain_specific has been called in a context where it shouldn't" + ); + } +} + +trait ContextExt { + fn announce(&self, block: B::Hash, associated_data: Vec); +} + +impl> ContextExt for ContextOverService { + fn announce(&self, block: B::Hash, associated_data: Vec) { + Network::announce(&self.network, block, associated_data) + } +} diff --git a/client/network-gossip/src/lib.rs b/client/network-gossip/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..86bc41af4b9411808f45b713ff7443fff752e75e --- /dev/null +++ b/client/network-gossip/src/lib.rs @@ -0,0 +1,125 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Polite gossiping. +//! +//! This crate provides gossiping capabilities on top of a network. +//! +//! Gossip messages are separated by two categories: "topics" and consensus engine ID. +//! The consensus engine ID is sent over the wire with the message, while the topic is not, +//! with the expectation that the topic can be derived implicitly from the content of the +//! message, assuming it is valid. +//! +//! Topics are a single 32-byte tag associated with a message, used to group those messages +//! in an opaque way. Consensus code can invoke `broadcast_topic` to attempt to send all messages +//! under a single topic to all peers who don't have them yet, and `send_topic` to +//! send all messages under a single topic to a specific peer. +//! +//! # Usage +//! +//! - Implement the `Network` trait, representing the low-level networking primitives. It is +//! already implemented on `sc_network::NetworkService`. +//! - Implement the `Validator` trait. See the section below. +//! - Decide on a `ConsensusEngineId`. Each gossiping protocol should have a different one. +//! - Build a `GossipEngine` using these three elements. +//! - Use the methods of the `GossipEngine` in order to send out messages and receive incoming +//! messages. +//! +//! # What is a validator? +//! +//! The primary role of a `Validator` is to process incoming messages from peers, and decide +//! whether to discard them or process them. It also decides whether to re-broadcast the message. +//! +//! The secondary role of the `Validator` is to check if a message is allowed to be sent to a given +//! peer. All messages, before being sent, will be checked against this filter. +//! This enables the validator to use information it's aware of about connected peers to decide +//! whether to send messages to them at any given moment in time - In particular, to wait until +//! peers can accept and process the message before sending it. +//! +//! Lastly, the fact that gossip validators can decide not to rebroadcast messages +//! opens the door for neighbor status packets to be baked into the gossip protocol. +//! These status packets will typically contain light pieces of information +//! used to inform peers of a current view of protocol state. + +pub use self::bridge::GossipEngine; +pub use self::state_machine::{TopicNotification, MessageIntent}; +pub use self::state_machine::{Validator, ValidatorContext, ValidationResult}; +pub use self::state_machine::DiscardAll; + +use sc_network::{specialization::NetworkSpecialization, Event, ExHashT, NetworkService, PeerId, ReputationChange}; +use sp_runtime::{traits::Block as BlockT, ConsensusEngineId}; +use std::sync::Arc; + +mod bridge; +mod state_machine; + +/// Abstraction over a network. +pub trait Network { + /// Returns a stream of events representing what happens on the network. + fn event_stream(&self) -> Box + Send>; + + /// Adjust the reputation of a node. + fn report_peer(&self, peer_id: PeerId, reputation: ReputationChange); + + /// Force-disconnect a peer. + fn disconnect_peer(&self, who: PeerId); + + /// Send a notification to a peer. + fn write_notification(&self, who: PeerId, engine_id: ConsensusEngineId, message: Vec); + + /// Registers a notifications protocol. + /// + /// See the documentation of [`NetworkService:register_notifications_protocol`] for more information. + fn register_notifications_protocol( + &self, + engine_id: ConsensusEngineId + ); + + /// Notify everyone we're connected to that we have the given block. + /// + /// Note: this method isn't strictly related to gossiping and should eventually be moved + /// somewhere else. + fn announce(&self, block: B::Hash, associated_data: Vec); +} + +impl, H: ExHashT> Network for Arc> { + fn event_stream(&self) -> Box + Send> { + Box::new(NetworkService::event_stream(self)) + } + + fn report_peer(&self, peer_id: PeerId, reputation: ReputationChange) { + NetworkService::report_peer(self, peer_id, reputation); + } + + fn disconnect_peer(&self, who: PeerId) { + NetworkService::disconnect_peer(self, who) + } + + fn write_notification(&self, who: PeerId, engine_id: ConsensusEngineId, message: Vec) { + NetworkService::write_notification(self, who, engine_id, message) + } + + fn register_notifications_protocol( + &self, + engine_id: ConsensusEngineId, + ) { + NetworkService::register_notifications_protocol(self, engine_id) + } + + fn announce(&self, block: B::Hash, associated_data: Vec) { + NetworkService::announce_block(self, block, associated_data) + } +} diff --git a/client/network/src/protocol/consensus_gossip.rs b/client/network-gossip/src/state_machine.rs similarity index 74% rename from client/network/src/protocol/consensus_gossip.rs rename to client/network-gossip/src/state_machine.rs index b1f56bc8f50ea2353f61c932ff0db8ee33e6e021..e2d1ebc8ebd3b31376c33467716db27374fdaee2 100644 --- a/client/network/src/protocol/consensus_gossip.rs +++ b/client/network-gossip/src/state_machine.rs @@ -14,66 +14,40 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! Utility for gossip of network messages between nodes. -//! Handles chain-specific and standard BFT messages. -//! -//! Gossip messages are separated by two categories: "topics" and consensus engine ID. -//! The consensus engine ID is sent over the wire with the message, while the topic is not, -//! with the expectation that the topic can be derived implicitly from the content of the -//! message, assuming it is valid. -//! -//! Topics are a single 32-byte tag associated with a message, used to group those messages -//! in an opaque way. Consensus code can invoke `broadcast_topic` to attempt to send all messages -//! under a single topic to all peers who don't have them yet, and `send_topic` to -//! send all messages under a single topic to a specific peer. -//! -//! Each consensus engine ID must have an associated, -//! registered `Validator` for all gossip messages. The primary role of this `Validator` is -//! to process incoming messages from peers, and decide whether to discard them or process -//! them. It also decides whether to re-broadcast the message. -//! -//! The secondary role of the `Validator` is to check if a message is allowed to be sent to a given -//! peer. All messages, before being sent, will be checked against this filter. -//! This enables the validator to use information it's aware of about connected peers to decide -//! whether to send messages to them at any given moment in time - In particular, to wait until -//! peers can accept and process the message before sending it. -//! -//! Lastly, the fact that gossip validators can decide not to rebroadcast messages -//! opens the door for neighbor status packets to be baked into the gossip protocol. -//! These status packets will typically contain light pieces of information -//! used to inform peers of a current view of protocol state. - use std::collections::{HashMap, HashSet, hash_map::Entry}; use std::sync::Arc; use std::iter; use std::time; use log::{trace, debug}; -use futures03::channel::mpsc; +use futures::channel::mpsc; use lru::LruCache; use libp2p::PeerId; -use sr_primitives::traits::{Block as BlockT, Hash, HashFor}; -use sr_primitives::ConsensusEngineId; -pub use crate::message::generic::{Message, ConsensusMessage}; -use crate::protocol::Context; -use crate::config::Roles; +use sp_runtime::traits::{Block as BlockT, Hash, HashFor}; +use sp_runtime::ConsensusEngineId; +pub use sc_network::message::generic::{Message, ConsensusMessage}; +use sc_network::Context; +use sc_network::config::Roles; // FIXME: Add additional spam/DoS attack protection: https://github.com/paritytech/substrate/issues/1115 const KNOWN_MESSAGES_CACHE_SIZE: usize = 4096; const REBROADCAST_INTERVAL: time::Duration = time::Duration::from_secs(30); -/// Reputation change when a peer sends us a gossip message that we didn't know about. -const GOSSIP_SUCCESS_REPUTATION_CHANGE: i32 = 1 << 4; -/// Reputation change when a peer sends us a gossip message that we already knew about. -const DUPLICATE_GOSSIP_REPUTATION_CHANGE: i32 = -(1 << 2); -/// Reputation change when a peer sends us a gossip message for an unknown engine, whatever that -/// means. -const UNKNOWN_GOSSIP_REPUTATION_CHANGE: i32 = -(1 << 6); -/// Reputation change when a peer sends a message from a topic it isn't registered on. -const UNREGISTERED_TOPIC_REPUTATION_CHANGE: i32 = -(1 << 10); + +mod rep { + use sc_network::ReputationChange as Rep; + /// Reputation change when a peer sends us a gossip message that we didn't know about. + pub const GOSSIP_SUCCESS: Rep = Rep::new(1 << 4, "Successfull gossip"); + /// Reputation change when a peer sends us a gossip message that we already knew about. + pub const DUPLICATE_GOSSIP: Rep = Rep::new(-(1 << 2), "Duplicate gossip"); + /// Reputation change when a peer sends us a gossip message for an unknown engine, whatever that + /// means. + pub const UNKNOWN_GOSSIP: Rep = Rep::new(-(1 << 6), "Unknown gossup message engine id"); + /// Reputation change when a peer sends a message from a topic it isn't registered on. + pub const UNREGISTERED_TOPIC: Rep = Rep::new(-(1 << 10), "Unregistered gossip message topic"); +} struct PeerConsensus { known_messages: HashSet, - filtered_messages: HashMap, roles: Roles, } @@ -93,26 +67,12 @@ struct MessageEntry { sender: Option, } -/// Consensus message destination. -pub enum MessageRecipient { - /// Send to all peers. - BroadcastToAll, - /// Send to peers that don't have that message already. - BroadcastNew, - /// Send to specific peer. - Peer(PeerId), -} - /// The reason for sending out the message. #[derive(Eq, PartialEq, Copy, Clone)] #[cfg_attr(test, derive(Debug))] pub enum MessageIntent { /// Requested broadcast. - Broadcast { - /// How many times this message was previously filtered by the gossip - /// validator when trying to propagate to a given peer. - previous_attempts: usize - }, + Broadcast, /// Requested broadcast to all peers. ForcedBroadcast, /// Periodic rebroadcast of all messages to all peers. @@ -131,7 +91,7 @@ pub enum ValidationResult { impl MessageIntent { fn broadcast() -> MessageIntent { - MessageIntent::Broadcast { previous_attempts: 0 } + MessageIntent::Broadcast } } @@ -190,7 +150,8 @@ fn propagate<'a, B: BlockT, I>( peers: &mut HashMap>, validators: &HashMap>>, ) - where I: Clone + IntoIterator, // (msg_hash, topic, message) + // (msg_hash, topic, message) + where I: Clone + IntoIterator, { let mut check_fns = HashMap::new(); let mut message_allowed = move |who: &PeerId, intent: MessageIntent, topic: &B::Hash, message: &ConsensusMessage| { @@ -209,17 +170,12 @@ fn propagate<'a, B: BlockT, I>( for (id, ref mut peer) in peers.iter_mut() { let mut batch = Vec::new(); for (message_hash, topic, message) in messages.clone() { - let previous_attempts = peer.filtered_messages - .get(&message_hash) - .cloned() - .unwrap_or(0); - let intent = match intent { MessageIntent::Broadcast { .. } => if peer.known_messages.contains(&message_hash) { continue; } else { - MessageIntent::Broadcast { previous_attempts } + MessageIntent::Broadcast }, MessageIntent::PeriodicRebroadcast => if peer.known_messages.contains(&message_hash) { @@ -227,22 +183,15 @@ fn propagate<'a, B: BlockT, I>( } else { // peer doesn't know message, so the logic should treat it as an // initial broadcast. - MessageIntent::Broadcast { previous_attempts } + MessageIntent::Broadcast }, other => other, }; if !message_allowed(id, intent, &topic, &message) { - let count = peer.filtered_messages - .entry(message_hash.clone()) - .or_insert(0); - - *count += 1; - continue; } - peer.filtered_messages.remove(message_hash); peer.known_messages.insert(message_hash.clone()); trace!(target: "gossip", "Propagating to {}: {:?}", id, message); @@ -338,7 +287,6 @@ impl ConsensusGossip { trace!(target:"gossip", "Registering {:?} {}", roles, who); self.peers.insert(who.clone(), PeerConsensus { known_messages: HashSet::new(), - filtered_messages: HashMap::new(), roles, }); for (engine_id, v) in self.validators.clone() { @@ -448,7 +396,6 @@ impl ConsensusGossip { for (_, ref mut peer) in self.peers.iter_mut() { peer.known_messages.retain(|h| known_messages.contains(h)); - peer.filtered_messages.retain(|h, _| known_messages.contains(h)); } } @@ -488,7 +435,7 @@ impl ConsensusGossip { if self.known_messages.contains(&message_hash) { trace!(target:"gossip", "Ignored already known message from {}", who); - protocol.report_peer(who.clone(), DUPLICATE_GOSSIP_REPUTATION_CHANGE); + protocol.report_peer(who.clone(), rep::DUPLICATE_GOSSIP); continue; } @@ -507,14 +454,14 @@ impl ConsensusGossip { Some(ValidationResult::Discard) => None, None => { trace!(target:"gossip", "Unknown message engine id {:?} from {}", engine_id, who); - protocol.report_peer(who.clone(), UNKNOWN_GOSSIP_REPUTATION_CHANGE); + protocol.report_peer(who.clone(), rep::UNKNOWN_GOSSIP); protocol.disconnect_peer(who.clone()); continue; } }; if let Some((topic, keep)) = validation_result { - protocol.report_peer(who.clone(), GOSSIP_SUCCESS_REPUTATION_CHANGE); + protocol.report_peer(who.clone(), rep::GOSSIP_SUCCESS); if let Some(ref mut peer) = self.peers.get_mut(&who) { peer.known_messages.insert(message_hash); if let Entry::Occupied(mut entry) = self.live_message_sinks.entry((engine_id, topic)) { @@ -537,7 +484,7 @@ impl ConsensusGossip { } } else { trace!(target:"gossip", "Ignored statement from unregistered peer {}", who); - protocol.report_peer(who.clone(), UNREGISTERED_TOPIC_REPUTATION_CHANGE); + protocol.report_peer(who.clone(), rep::UNREGISTERED_TOPIC); } } else { trace!(target:"gossip", "Handled valid one hop message from peer {}", who); @@ -566,12 +513,7 @@ impl ConsensusGossip { let intent = if force { MessageIntent::ForcedBroadcast } else { - let previous_attempts = peer.filtered_messages - .get(&entry.message_hash) - .cloned() - .unwrap_or(0); - - MessageIntent::Broadcast { previous_attempts } + MessageIntent::Broadcast }; if !force && peer.known_messages.contains(&entry.message_hash) { @@ -579,16 +521,9 @@ impl ConsensusGossip { } if !message_allowed(who, intent, &entry.topic, &entry.message.data) { - let count = peer.filtered_messages - .entry(entry.message_hash) - .or_insert(0); - - *count += 1; - continue; } - peer.filtered_messages.remove(&entry.message_hash); peer.known_messages.insert(entry.message_hash.clone()); trace!(target: "gossip", "Sending topic message to {}: {:?}", who, entry.message); @@ -632,7 +567,6 @@ impl ConsensusGossip { trace!(target: "gossip", "Sending direct to {}: {:?}", who, message); - peer.filtered_messages.remove(&message_hash); peer.known_messages.insert(message_hash); protocol.send_consensus(who.clone(), vec![message.clone()]); } @@ -662,10 +596,9 @@ impl Validator for DiscardAll { #[cfg(test)] mod tests { - use std::sync::{Arc, atomic::{AtomicBool, Ordering}}; - use parking_lot::Mutex; - use sr_primitives::testing::{H256, Block as RawBlock, ExtrinsicWrapper}; - use futures03::executor::block_on_stream; + use std::sync::Arc; + use sp_runtime::testing::{H256, Block as RawBlock, ExtrinsicWrapper}; + use futures::executor::block_on_stream; use super::*; @@ -812,109 +745,4 @@ mod tests { let _ = consensus.live_message_sinks.remove(&([0, 0, 0, 0], topic)); assert_eq!(stream.next(), None); } - - #[test] - fn keeps_track_of_broadcast_attempts() { - struct DummyNetworkContext; - impl Context for DummyNetworkContext { - fn report_peer(&mut self, _who: PeerId, _reputation: i32) {} - fn disconnect_peer(&mut self, _who: PeerId) {} - fn send_consensus(&mut self, _who: PeerId, _consensus: Vec) {} - fn send_chain_specific(&mut self, _who: PeerId, _message: Vec) {} - } - - // A mock gossip validator that never expires any message, allows - // setting whether messages should be allowed and keeps track of any - // messages passed to `message_allowed`. - struct MockValidator { - allow: AtomicBool, - messages: Arc, MessageIntent)>>>, - } - - impl MockValidator { - fn new() -> MockValidator { - MockValidator { - allow: AtomicBool::new(false), - messages: Arc::new(Mutex::new(Vec::new())), - } - } - } - - impl Validator for MockValidator { - fn validate( - &self, - _context: &mut dyn ValidatorContext, - _sender: &PeerId, - _data: &[u8], - ) -> ValidationResult { - ValidationResult::ProcessAndKeep(H256::default()) - } - - fn message_expired<'a>(&'a self) -> Box bool + 'a> { - Box::new(move |_topic, _data| false) - } - - fn message_allowed<'a>(&'a self) -> Box bool + 'a> { - let messages = self.messages.clone(); - Box::new(move |_, intent, _, data| { - messages.lock().push((data.to_vec(), intent)); - self.allow.load(Ordering::SeqCst) - }) - } - } - - // we setup an instance of the mock gossip validator, add a new peer to - // it and register a message. - let mut consensus = ConsensusGossip::::new(); - let validator = Arc::new(MockValidator::new()); - consensus.register_validator_internal([0, 0, 0, 0], validator.clone()); - consensus.new_peer( - &mut DummyNetworkContext, - PeerId::random(), - Roles::AUTHORITY, - ); - - let data = vec![1, 2, 3]; - let msg = ConsensusMessage { data: data.clone(), engine_id: [0, 0, 0, 0] }; - consensus.register_message(H256::default(), msg); - - // tick the gossip handler and make sure it triggers a message rebroadcast - let mut tick = || { - consensus.next_broadcast = std::time::Instant::now(); - consensus.tick(&mut DummyNetworkContext); - }; - - // by default we won't allow the message we registered, so everytime we - // tick the gossip handler, the message intent should be kept as - // `Broadcast` but the previous attempts should be incremented. - tick(); - assert_eq!( - validator.messages.lock().pop().unwrap(), - (data.clone(), MessageIntent::Broadcast { previous_attempts: 0 }), - ); - - tick(); - assert_eq!( - validator.messages.lock().pop().unwrap(), - (data.clone(), MessageIntent::Broadcast { previous_attempts: 1 }), - ); - - // we set the validator to allow the message to go through - validator.allow.store(true, Ordering::SeqCst); - - // we still get the same message intent but it should be delivered now - tick(); - assert_eq!( - validator.messages.lock().pop().unwrap(), - (data.clone(), MessageIntent::Broadcast { previous_attempts: 2 }), - ); - - // ticking the gossip handler again the message intent should change to - // `PeriodicRebroadcast` since it was sent. - tick(); - assert_eq!( - validator.messages.lock().pop().unwrap(), - (data.clone(), MessageIntent::PeriodicRebroadcast), - ); - } } diff --git a/client/network/Cargo.toml b/client/network/Cargo.toml index 2feea5fe9dc7f17921213efe96365dd4a8b89a67..73b180b780cf3b07cb5ced58cbacc66a71225f71 100644 --- a/client/network/Cargo.toml +++ b/client/network/Cargo.toml @@ -1,14 +1,14 @@ [package] description = "Substrate network protocol" -name = "substrate-network" -version = "2.0.0" +name = "sc-network" +version = "0.8.0" license = "GPL-3.0" authors = ["Parity Technologies "] edition = "2018" [dependencies] bytes = "0.4.12" -derive_more = "0.15.0" +derive_more = "0.99.2" either = "1.5.3" log = "0.4.8" parking_lot = "0.9.0" @@ -23,43 +23,42 @@ lru = "0.4.0" rustc-hex = "2.0.1" rand = "0.7.2" libp2p = { version = "0.13.0", default-features = false, features = ["libp2p-websocket"] } -fork-tree = { path = "../../utils/fork-tree" } -consensus = { package = "substrate-consensus-common", path = "../../primitives/consensus/common" } -client = { package = "substrate-client", path = "../" } -client-api = { package = "substrate-client-api", path = "../api" } -header_metadata = { package = "substrate-header-metadata", path = "../header-metadata" } -sr-primitives = { path = "../../primitives/sr-primitives" } -sr-arithmetic = { path = "../../primitives/sr-arithmetic" } -primitives = { package = "substrate-primitives", path = "../../primitives/core" } -block-builder = { package = "substrate-block-builder", path = "../block-builder" } +fork-tree = { version = "2.0.0", path = "../../utils/fork-tree" } +sp-consensus = { version = "0.8", path = "../../primitives/consensus/common" } +sc-client = { version = "2.0.0", path = "../" } +sc-client-api = { version = "2.0.0", path = "../api" } +sp-blockchain = { version = "2.0.0", path = "../../primitives/blockchain" } +sp-runtime = { version = "2.0.0", path = "../../primitives/runtime" } +sp-arithmetic = { version = "2.0.0", path = "../../primitives/arithmetic" } +sp-core = { version = "2.0.0", path = "../../primitives/core" } +sc-block-builder = { version = "2.0.0", path = "../block-builder" } codec = { package = "parity-scale-codec", version = "1.0.0", features = ["derive"] } -peerset = { package = "substrate-peerset", path = "../../primitives/peerset" } +sc-peerset = { version = "2.0.0", path = "../peerset" } serde = { version = "1.0.101", features = ["derive"] } serde_json = "1.0.41" slog = { version = "2.5.2", features = ["nested-values"] } -slog_derive = "0.1.1" +slog_derive = "0.2.0" smallvec = "0.6.10" tokio-io = "0.1.12" tokio = { version = "0.1.22", optional = true } unsigned-varint = { version = "0.2.2", features = ["codec"] } -keyring = { package = "substrate-keyring", path = "../../primitives/keyring", optional = true } -test_client = { package = "substrate-test-client", path = "../../test/utils/client", optional = true } -test-client = { package = "substrate-test-runtime-client", path = "../../test/utils/runtime/client", optional = true } +sp-keyring = { version = "2.0.0", optional = true, path = "../../primitives/keyring" } +substrate-test-client = { version = "2.0.0", optional = true, path = "../../test-utils/client" } +substrate-test-runtime-client = { version = "2.0.0", optional = true, path = "../../test-utils/runtime/client" } erased-serde = "0.3.9" void = "1.0.2" zeroize = "1.0.0" -babe-primitives = { package = "substrate-consensus-babe-primitives", path = "../../primitives/consensus/babe" } +sp-consensus-babe = { version = "0.8", path = "../../primitives/consensus/babe" } [dev-dependencies] +sp-test-primitives = { version = "2.0.0", path = "../../primitives/test-primitives" } env_logger = "0.7.0" -keyring = { package = "substrate-keyring", path = "../../primitives/keyring" } +sp-keyring = { version = "2.0.0", path = "../../primitives/keyring" } quickcheck = "0.9.0" rand = "0.7.2" -test-client = { package = "substrate-test-runtime-client", path = "../../test/utils/runtime/client" } -test_runtime = { package = "substrate-test-runtime", path = "../../test/utils/runtime" } -tempdir = "0.3.7" +tempfile = "3.1.0" tokio = "0.1.22" [features] default = [] -test-helpers = ["keyring", "test-client", "tokio"] +test-helpers = ["sp-keyring", "substrate-test-runtime-client", "tokio"] diff --git a/client/network/src/behaviour.rs b/client/network/src/behaviour.rs index a0299bc340ce2cd714a8a547269c61ec3a206968..705fa2a27a4d17d4a074499ff197af1b5be8404e 100644 --- a/client/network/src/behaviour.rs +++ b/client/network/src/behaviour.rs @@ -16,7 +16,7 @@ use crate::{ debug_info, discovery::DiscoveryBehaviour, discovery::DiscoveryOut, DiscoveryNetBehaviour, - protocol::event::DhtEvent + Event, protocol::event::DhtEvent }; use crate::{ExHashT, specialization::NetworkSpecialization}; use crate::protocol::{CustomMessageOutcome, Protocol}; @@ -27,7 +27,8 @@ use libp2p::kad::record; use libp2p::swarm::{NetworkBehaviourAction, NetworkBehaviourEventProcess}; use libp2p::core::{nodes::Substream, muxing::StreamMuxerBox}; use log::{debug, warn}; -use sr_primitives::traits::Block as BlockT; +use sp_consensus::{BlockOrigin, import_queue::{IncomingBlock, Origin}}; +use sp_runtime::{traits::{Block as BlockT, NumberFor}, Justification}; use std::iter; use void; @@ -50,8 +51,10 @@ pub struct Behaviour, H: ExHashT> { /// Event generated by `Behaviour`. pub enum BehaviourOut { - SubstrateAction(CustomMessageOutcome), - Dht(DhtEvent), + BlockImport(BlockOrigin, Vec>), + JustificationImport(Origin, B::Hash, NumberFor, Justification), + FinalityProofImport(Origin, B::Hash, NumberFor, Vec), + Event(Event), } impl, H: ExHashT> Behaviour { @@ -127,7 +130,34 @@ Behaviour { impl, H: ExHashT> NetworkBehaviourEventProcess> for Behaviour { fn inject_event(&mut self, event: CustomMessageOutcome) { - self.events.push(BehaviourOut::SubstrateAction(event)); + match event { + CustomMessageOutcome::BlockImport(origin, blocks) => + self.events.push(BehaviourOut::BlockImport(origin, blocks)), + CustomMessageOutcome::JustificationImport(origin, hash, nb, justification) => + self.events.push(BehaviourOut::JustificationImport(origin, hash, nb, justification)), + CustomMessageOutcome::FinalityProofImport(origin, hash, nb, proof) => + self.events.push(BehaviourOut::FinalityProofImport(origin, hash, nb, proof)), + CustomMessageOutcome::NotificationStreamOpened { remote, protocols, roles } => + for engine_id in protocols { + self.events.push(BehaviourOut::Event(Event::NotificationStreamOpened { + remote: remote.clone(), + engine_id, + roles, + })); + }, + CustomMessageOutcome::NotificationsStreamClosed { remote, protocols } => + for engine_id in protocols { + self.events.push(BehaviourOut::Event(Event::NotificationsStreamClosed { + remote: remote.clone(), + engine_id, + })); + }, + CustomMessageOutcome::NotificationsReceived { remote, messages } => { + let ev = Event::NotificationsReceived { remote, messages }; + self.events.push(BehaviourOut::Event(ev)); + }, + CustomMessageOutcome::None => {} + } } } @@ -166,16 +196,16 @@ impl, H: ExHashT> NetworkBehaviourEventPr self.substrate.add_discovered_nodes(iter::once(peer_id)); } DiscoveryOut::ValueFound(results) => { - self.events.push(BehaviourOut::Dht(DhtEvent::ValueFound(results))); + self.events.push(BehaviourOut::Event(Event::Dht(DhtEvent::ValueFound(results)))); } DiscoveryOut::ValueNotFound(key) => { - self.events.push(BehaviourOut::Dht(DhtEvent::ValueNotFound(key))); + self.events.push(BehaviourOut::Event(Event::Dht(DhtEvent::ValueNotFound(key)))); } DiscoveryOut::ValuePut(key) => { - self.events.push(BehaviourOut::Dht(DhtEvent::ValuePut(key))); + self.events.push(BehaviourOut::Event(Event::Dht(DhtEvent::ValuePut(key)))); } DiscoveryOut::ValuePutFailed(key) => { - self.events.push(BehaviourOut::Dht(DhtEvent::ValuePutFailed(key))); + self.events.push(BehaviourOut::Event(Event::Dht(DhtEvent::ValuePutFailed(key)))); } } } diff --git a/client/network/src/chain.rs b/client/network/src/chain.rs index 5207a24bf9d30200ccaa383bab414dbf8ba99b3a..8231f3bb53c50a59e1391fc1a2f8d23428dd39d9 100644 --- a/client/network/src/chain.rs +++ b/client/network/src/chain.rs @@ -16,14 +16,15 @@ //! Blockchain access trait -use client::Client as SubstrateClient; -use client_api::error::Error; -use client_api::{ChangesProof, StorageProof, ClientInfo, CallExecutor}; -use consensus::{BlockImport, BlockStatus, Error as ConsensusError}; -use sr_primitives::traits::{Block as BlockT, Header as HeaderT}; -use sr_primitives::generic::{BlockId}; -use sr_primitives::Justification; -use primitives::{H256, Blake2Hasher, storage::StorageKey}; +use sc_client::Client as SubstrateClient; +use sp_blockchain::Error; +use sc_client_api::{ChangesProof, StorageProof, ClientInfo, CallExecutor}; +use sp_consensus::{BlockImport, BlockStatus, Error as ConsensusError}; +use sp_runtime::traits::{Block as BlockT, Header as HeaderT}; +use sp_runtime::generic::{BlockId}; +use sp_runtime::Justification; +use sp_core::{H256, Blake2Hasher}; +use sp_core::storage::{StorageKey, ChildInfo}; /// Local client abstraction for the network. pub trait Client: Send + Sync { @@ -57,6 +58,7 @@ pub trait Client: Send + Sync { &self, block: &Block::Hash, storage_key: &[u8], + child_info: ChildInfo, keys: &[Vec], ) -> Result; @@ -91,7 +93,7 @@ impl FinalityProofProvider for () { } impl Client for SubstrateClient where - B: client_api::backend::Backend + Send + Sync + 'static, + B: sc_client_api::backend::Backend + Send + Sync + 'static, E: CallExecutor + Send + Sync + 'static, Self: BlockImport, Block: BlockT, @@ -135,10 +137,11 @@ impl Client for SubstrateClient where &self, block: &Block::Hash, storage_key: &[u8], + child_info: ChildInfo, keys: &[Vec], ) -> Result { (self as &SubstrateClient) - .read_child_proof(&BlockId::Hash(block.clone()), storage_key, keys) + .read_child_proof(&BlockId::Hash(block.clone()), storage_key, child_info, keys) } fn execution_proof(&self, block: &Block::Hash, method: &str, data: &[u8]) -> Result<(Vec, StorageProof), Error> { @@ -162,7 +165,7 @@ impl Client for SubstrateClient where return Ok(false); } - let ancestor = header_metadata::lowest_common_ancestor(self, *block, *base)?; + let ancestor = sp_blockchain::lowest_common_ancestor(self, *block, *base)?; Ok(ancestor.hash == *base) } diff --git a/client/network/src/config.rs b/client/network/src/config.rs index d10345c2f3817a9f1263e96fa7254903890ab84b..199b4abd9d403bfc37a35bbac80b19d464c6c456 100644 --- a/client/network/src/config.rs +++ b/client/network/src/config.rs @@ -26,8 +26,8 @@ use crate::chain::{Client, FinalityProofProvider}; use crate::on_demand_layer::OnDemand; use crate::service::{ExHashT, TransactionPool}; use bitflags::bitflags; -use consensus::{block_validation::BlockAnnounceValidator, import_queue::ImportQueue}; -use sr_primitives::traits::{Block as BlockT}; +use sp_consensus::{block_validation::BlockAnnounceValidator, import_queue::ImportQueue}; +use sp_runtime::traits::{Block as BlockT}; use libp2p::identity::{Keypair, ed25519}; use libp2p::wasm_ext; use libp2p::{PeerId, Multiaddr, multiaddr}; @@ -171,7 +171,7 @@ impl ProtocolId { /// # Example /// /// ``` -/// # use substrate_network::{Multiaddr, PeerId, config::parse_str_addr}; +/// # use sc_network::{Multiaddr, PeerId, config::parse_str_addr}; /// let (peer_id, addr) = parse_str_addr( /// "/ip4/198.51.100.19/tcp/30333/p2p/QmSk5HQbn6LhUwDiNMseVUjuRYhEtYj4aUZ6WfWoGURpdV" /// ).unwrap(); @@ -255,6 +255,8 @@ pub struct NetworkConfiguration { pub reserved_nodes: Vec, /// The non-reserved peer mode. pub non_reserved_mode: NonReservedPeerMode, + /// List of sentry node public addresses. + pub sentry_nodes: Vec, /// Client identifier. Sent over the wire for debugging purposes. pub client_version: String, /// Name of the node. Sent over the wire for debugging purposes. @@ -278,6 +280,7 @@ impl Default for NetworkConfiguration { out_peers: 75, reserved_nodes: Vec::new(), non_reserved_mode: NonReservedPeerMode::Accept, + sentry_nodes: Vec::new(), client_version: "unknown".into(), node_name: "unknown".into(), transport: TransportConfig::Normal { @@ -502,7 +505,11 @@ where #[cfg(test)] mod tests { use super::*; - use tempdir::TempDir; + use tempfile::TempDir; + + fn tempdir_with_prefix(prefix: &str) -> TempDir { + tempfile::Builder::new().prefix(prefix).tempdir().unwrap() + } fn secret_bytes(kp: &Keypair) -> Vec { match kp { @@ -514,7 +521,7 @@ mod tests { #[test] fn test_secret_file() { - let tmp = TempDir::new("x").unwrap(); + let tmp = tempdir_with_prefix("x"); std::fs::remove_dir(tmp.path()).unwrap(); // should be recreated let file = tmp.path().join("x").to_path_buf(); let kp1 = NodeKeyConfig::Ed25519(Secret::File(file.clone())).into_keypair().unwrap(); diff --git a/client/network/src/discovery.rs b/client/network/src/discovery.rs index 2e0a6fe2447ea7ac9e142e2fe3c6e3d51d113014..0e05ff8b035f21885b3a5bea9f4d47669d551c84 100644 --- a/client/network/src/discovery.rs +++ b/client/network/src/discovery.rs @@ -63,7 +63,7 @@ use libp2p::multiaddr::Protocol; use log::{debug, info, trace, warn}; use std::{cmp, collections::VecDeque, time::Duration}; use tokio_io::{AsyncRead, AsyncWrite}; -use primitives::hexdisplay::HexDisplay; +use sp_core::hexdisplay::HexDisplay; /// Implementation of `NetworkBehaviour` that discovers the nodes on the network. pub struct DiscoveryBehaviour { diff --git a/client/network/src/error.rs b/client/network/src/error.rs index a33f0280abd4247d60dd1b8132f50545bfa85819..8f15e318ce61f03998eb3b8fc15f9a105cdcc572 100644 --- a/client/network/src/error.rs +++ b/client/network/src/error.rs @@ -16,8 +16,6 @@ //! Substrate network possible errors. -use client_api; - use libp2p::{PeerId, Multiaddr}; use std::fmt; @@ -31,7 +29,7 @@ pub enum Error { /// Io error Io(std::io::Error), /// Client error - Client(client_api::error::Error), + Client(sp_blockchain::Error), /// The same bootnode (based on address) is registered with two different peer ids. #[display( fmt = "The same bootnode (`{}`) is registered with two different peer ids: `{}` and `{}`", diff --git a/client/network/src/lib.rs b/client/network/src/lib.rs index 96efd49958763821188b2eb1a94eb711b9c76467..a60087751f4da7ff78eb89c2c2d7c4509532c03a 100644 --- a/client/network/src/lib.rs +++ b/client/network/src/lib.rs @@ -118,7 +118,7 @@ //! if necessary and open a unique substream for Substrate-based communications. If the PSM decides //! that we should disconnect a node, then that substream is closed. //! -//! For more information about the PSM, see the *substrate-peerset* crate. +//! For more information about the PSM, see the *sc-peerset* crate. //! //! Note that at the moment there is no mechanism in place to solve the issues that arise where the //! two sides of a connection open the unique substream simultaneously. In order to not run into @@ -151,7 +151,7 @@ //! //! # Usage //! -//! Using the `substrate-network` crate is done through the [`NetworkWorker`] struct. Create this +//! Using the `sc-network` crate is done through the [`NetworkWorker`] struct. Create this //! struct by passing a [`config::Params`], then poll it as if it was a `Future`. You can extract an //! `Arc` from the `NetworkWorker`, which can be shared amongst multiple places //! in order to give orders to the networking. @@ -170,7 +170,6 @@ mod behaviour; mod chain; -mod legacy_proto; mod debug_info; mod discovery; mod on_demand_layer; @@ -182,15 +181,12 @@ mod utils; pub mod config; pub mod error; -#[cfg(any(test, feature = "test-helpers"))] -pub mod test; - pub use chain::{Client as ClientHandle, FinalityProofProvider}; pub use service::{ NetworkService, NetworkWorker, TransactionPool, ExHashT, ReportHandle, NetworkStateInfo, }; -pub use protocol::{PeerInfo, Context, consensus_gossip, message, specialization}; +pub use protocol::{PeerInfo, Context, ProtocolConfig, message, specialization}; pub use protocol::event::{Event, DhtEvent}; pub use protocol::sync::SyncState; pub use libp2p::{Multiaddr, PeerId}; @@ -199,10 +195,11 @@ pub use libp2p::multiaddr; pub use message::{generic as generic_message, RequestId, Status as StatusMessage}; pub use on_demand_layer::{OnDemand, RemoteResponse}; +pub use sc_peerset::ReputationChange; // Used by the `construct_simple_protocol!` macro. #[doc(hidden)] -pub use sr_primitives::traits::Block as BlockT; +pub use sp_runtime::traits::Block as BlockT; use libp2p::core::ConnectedPoint; use serde::{Deserialize, Serialize}; diff --git a/client/network/src/on_demand_layer.rs b/client/network/src/on_demand_layer.rs index 4a5ec4adcfb40678b0483149504025c29d0062f4..db75de5e34710fc4fef3b67d0360c17e8736c963 100644 --- a/client/network/src/on_demand_layer.rs +++ b/client/network/src/on_demand_layer.rs @@ -22,11 +22,11 @@ use std::sync::Arc; use futures::{prelude::*, sync::mpsc, sync::oneshot}; use futures03::compat::{Compat01As03, Future01CompatExt as _}; use parking_lot::Mutex; -use client_api::error::Error as ClientError; -use client_api::{Fetcher, FetchChecker, RemoteHeaderRequest, +use sp_blockchain::Error as ClientError; +use sc_client_api::{Fetcher, FetchChecker, RemoteHeaderRequest, RemoteCallRequest, RemoteReadRequest, RemoteChangesRequest, RemoteReadChildRequest, RemoteBodyRequest}; -use sr_primitives::traits::{Block as BlockT, Header as HeaderT, NumberFor}; +use sp_runtime::traits::{Block as BlockT, Header as HeaderT, NumberFor}; /// Implements the `Fetcher` trait of the client. Makes it possible for the light client to perform /// network requests for some state. diff --git a/client/network/src/protocol.rs b/client/network/src/protocol.rs index 35e3d2453fcb9e0691cc31710dd74c7d00386b3f..165cef0c686f61a6653dbfd1b7d4abd787e5c275 100644 --- a/client/network/src/protocol.rs +++ b/client/network/src/protocol.rs @@ -15,30 +15,29 @@ // along with Substrate. If not, see . use crate::{DiscoveryNetBehaviour, config::ProtocolId}; -use crate::legacy_proto::{LegacyProto, LegacyProtoOut}; +use legacy_proto::{LegacyProto, LegacyProtoOut}; use crate::utils::interval; -use bytes::BytesMut; +use bytes::{Bytes, BytesMut}; use futures::prelude::*; use futures03::{StreamExt as _, TryStreamExt as _}; use libp2p::{Multiaddr, PeerId}; use libp2p::core::{ConnectedPoint, nodes::Substream, muxing::StreamMuxerBox}; use libp2p::swarm::{ProtocolsHandler, IntoProtocolsHandler}; use libp2p::swarm::{NetworkBehaviour, NetworkBehaviourAction, PollParameters}; -use primitives::storage::StorageKey; -use consensus::{ +use sp_core::storage::{StorageKey, ChildInfo}; +use sp_consensus::{ BlockOrigin, block_validation::BlockAnnounceValidator, import_queue::{BlockImportResult, BlockImportError, IncomingBlock, Origin} }; use codec::{Decode, Encode}; -use sr_primitives::{generic::BlockId, ConsensusEngineId, Justification}; -use sr_primitives::traits::{ +use sp_runtime::{generic::BlockId, ConsensusEngineId, Justification}; +use sp_runtime::traits::{ Block as BlockT, Header as HeaderT, NumberFor, One, Zero, CheckedSub }; -use sr_arithmetic::traits::SaturatedConversion; +use sp_arithmetic::traits::SaturatedConversion; use message::{BlockAnnounce, BlockAttributes, Direction, FromBlock, Message, RequestId}; use message::generic::{Message as GenericMessage, ConsensusMessage}; -use consensus_gossip::{ConsensusGossip, MessageRecipient as GossipMessageRecipient}; use light_dispatch::{LightDispatch, LightDispatchNetwork, RequestData}; use specialization::NetworkSpecialization; use sync::{ChainSync, SyncState}; @@ -51,12 +50,13 @@ use std::fmt::Write; use std::{cmp, num::NonZeroUsize, time}; use log::{log, Level, trace, debug, warn, error}; use crate::chain::{Client, FinalityProofProvider}; -use client_api::{FetchChecker, ChangesProof, StorageProof}; +use sc_client_api::{FetchChecker, ChangesProof, StorageProof}; use crate::error; use util::LruHashSet; +mod legacy_proto; mod util; -pub mod consensus_gossip; + pub mod message; pub mod event; pub mod light_dispatch; @@ -88,23 +88,38 @@ const MAX_CONSENSUS_MESSAGES: usize = 256; /// and disconnect to free connection slot. const LIGHT_MAXIMAL_BLOCKS_DIFFERENCE: u64 = 8192; -/// Reputation change when a peer is "clogged", meaning that it's not fast enough to process our -/// messages. -const CLOGGED_PEER_REPUTATION_CHANGE: i32 = -(1 << 12); -/// Reputation change when a peer doesn't respond in time to our messages. -const TIMEOUT_REPUTATION_CHANGE: i32 = -(1 << 10); -/// Reputation change when a peer sends us a status message while we already received one. -const UNEXPECTED_STATUS_REPUTATION_CHANGE: i32 = -(1 << 20); -/// Reputation change when we are a light client and a peer is behind us. -const PEER_BEHIND_US_LIGHT_REPUTATION_CHANGE: i32 = -(1 << 8); -/// Reputation change when a peer sends us an extrinsic that we didn't know about. -const GOOD_EXTRINSIC_REPUTATION_CHANGE: i32 = 1 << 7; -/// Reputation change when a peer sends us a bad extrinsic. -const BAD_EXTRINSIC_REPUTATION_CHANGE: i32 = -(1 << 12); -/// We sent an RPC query to the given node, but it failed. -const RPC_FAILED_REPUTATION_CHANGE: i32 = -(1 << 12); -/// We received a message that failed to decode. -const BAD_MESSAGE_REPUTATION_CHANGE: i32 = -(1 << 12); +mod rep { + use sc_peerset::ReputationChange as Rep; + /// Reputation change when a peer is "clogged", meaning that it's not fast enough to process our + /// messages. + pub const CLOGGED_PEER: Rep = Rep::new(-(1 << 12), "Clogged message queue"); + /// Reputation change when a peer doesn't respond in time to our messages. + pub const TIMEOUT: Rep = Rep::new(-(1 << 10), "Request timeout"); + /// Reputation change when a peer sends us a status message while we already received one. + pub const UNEXPECTED_STATUS: Rep = Rep::new(-(1 << 20), "Unexpected status message"); + /// Reputation change when we are a light client and a peer is behind us. + pub const PEER_BEHIND_US_LIGHT: Rep = Rep::new(-(1 << 8), "Useless for a light peer"); + /// Reputation change when a peer sends us an extrinsic that we didn't know about. + pub const GOOD_EXTRINSIC: Rep = Rep::new(1 << 7, "Good extrinsic"); + /// Reputation change when a peer sends us a bad extrinsic. + pub const BAD_EXTRINSIC: Rep = Rep::new(-(1 << 12), "Bad extrinsic"); + /// We sent an RPC query to the given node, but it failed. + pub const RPC_FAILED: Rep = Rep::new(-(1 << 12), "Remote call failed"); + /// We received a message that failed to decode. + pub const BAD_MESSAGE: Rep = Rep::new(-(1 << 12), "Bad message"); + /// We received an unexpected response. + pub const UNEXPECTED_RESPONSE: Rep = Rep::new_fatal("Unexpected response packet"); + /// We received an unexpected extrinsic packet. + pub const UNEXPECTED_EXTRINSICS: Rep = Rep::new_fatal("Unexpected extrinsics packet"); + /// We received an unexpected light node request. + pub const UNEXPECTED_REQUEST: Rep = Rep::new_fatal("Unexpected block request packet"); + /// Peer has different genesis. + pub const GENESIS_MISMATCH: Rep = Rep::new_fatal("Genesis mismatch"); + /// Peer is on unsupported protocol version. + pub const BAD_PROTOCOL: Rep = Rep::new_fatal("Unsupported protocol"); + /// Peer role does not match (e.g. light peer connecting to another light peer). + pub const BAD_ROLE: Rep = Rep::new_fatal("Unsupported role"); +} // Lock must always be taken in order declared here. pub struct Protocol, H: ExHashT> { @@ -118,7 +133,6 @@ pub struct Protocol, H: ExHashT> { genesis_hash: B::Hash, sync: ChainSync, specialization: S, - consensus_gossip: ConsensusGossip, context_data: ContextData, /// List of nodes for which we perform additional logging because they are important for the /// user. @@ -126,12 +140,14 @@ pub struct Protocol, H: ExHashT> { // Connected peers pending Status message. handshaking_peers: HashMap, /// Used to report reputation changes. - peerset_handle: peerset::PeersetHandle, + peerset_handle: sc_peerset::PeersetHandle, transaction_pool: Arc>, /// When asked for a proof of finality, we use this struct to build one. finality_proof_provider: Option>>, /// Handles opening the unique substream and sending and receiving raw messages. behaviour: LegacyProto>, + /// List of notification protocols that have been registered. + registered_notif_protocols: HashSet, } #[derive(Default)] @@ -179,11 +195,11 @@ pub struct PeerInfo { struct LightDispatchIn<'a> { behaviour: &'a mut LegacyProto>, - peerset: peerset::PeersetHandle, + peerset: sc_peerset::PeersetHandle, } impl<'a, B: BlockT> LightDispatchNetwork for LightDispatchIn<'a> { - fn report_peer(&mut self, who: &PeerId, reputation: i32) { + fn report_peer(&mut self, who: &PeerId, reputation: sc_peerset::ReputationChange) { self.peerset.report_peer(who.clone(), reputation) } @@ -222,12 +238,16 @@ impl<'a, B: BlockT> LightDispatchNetwork for LightDispatchIn<'a> { id: RequestId, block: ::Hash, storage_key: Vec, + child_info: Vec, + child_type: u32, keys: Vec>, ) { let message: Message = message::generic::Message::RemoteReadChildRequest(message::RemoteReadChildRequest { id, block, storage_key, + child_info, + child_type, keys, }); @@ -303,7 +323,7 @@ impl<'a, B: BlockT> LightDispatchNetwork for LightDispatchIn<'a> { pub trait Context { /// Adjusts the reputation of the peer. Use this to point out that a peer has been malign or /// irresponsible or appeared lazy. - fn report_peer(&mut self, who: PeerId, reputation: i32); + fn report_peer(&mut self, who: PeerId, reputation: sc_peerset::ReputationChange); /// Force disconnecting from a peer. Use this when a peer misbehaved. fn disconnect_peer(&mut self, who: PeerId); @@ -319,21 +339,21 @@ pub trait Context { struct ProtocolContext<'a, B: 'a + BlockT, H: 'a + ExHashT> { behaviour: &'a mut LegacyProto>, context_data: &'a mut ContextData, - peerset_handle: &'a peerset::PeersetHandle, + peerset_handle: &'a sc_peerset::PeersetHandle, } impl<'a, B: BlockT + 'a, H: 'a + ExHashT> ProtocolContext<'a, B, H> { fn new( context_data: &'a mut ContextData, behaviour: &'a mut LegacyProto>, - peerset_handle: &'a peerset::PeersetHandle, + peerset_handle: &'a sc_peerset::PeersetHandle, ) -> Self { ProtocolContext { context_data, peerset_handle, behaviour } } } impl<'a, B: BlockT + 'a, H: ExHashT + 'a> Context for ProtocolContext<'a, B, H> { - fn report_peer(&mut self, who: PeerId, reputation: i32) { + fn report_peer(&mut self, who: PeerId, reputation: sc_peerset::ReputationChange) { self.peerset_handle.report_peer(who, reputation) } @@ -417,9 +437,9 @@ impl, H: ExHashT> Protocol { finality_proof_provider: Option>>, finality_proof_request_builder: Option>, protocol_id: ProtocolId, - peerset_config: peerset::PeersetConfig, + peerset_config: sc_peerset::PeersetConfig, block_announce_validator: Box + Send> - ) -> error::Result<(Protocol, peerset::PeersetHandle)> { + ) -> error::Result<(Protocol, sc_peerset::PeersetHandle)> { let info = chain.info(); let sync = ChainSync::new( config.roles, @@ -439,7 +459,7 @@ impl, H: ExHashT> Protocol { imp_p }; - let (peerset, peerset_handle) = peerset::Peerset::from_config(peerset_config); + let (peerset, peerset_handle) = sc_peerset::Peerset::from_config(peerset_config); let versions = &((MIN_VERSION as u8)..=(CURRENT_VERSION as u8)).collect::>(); let behaviour = LegacyProto::new(protocol_id, versions, peerset); @@ -456,13 +476,13 @@ impl, H: ExHashT> Protocol { genesis_hash: info.chain.genesis_hash, sync, specialization, - consensus_gossip: ConsensusGossip::new(), handshaking_peers: HashMap::new(), important_peers, transaction_pool, finality_proof_provider, peerset_handle: peerset_handle.clone(), behaviour, + registered_notif_protocols: HashSet::new(), }; Ok((protocol, peerset_handle)) @@ -557,7 +577,7 @@ impl, H: ExHashT> Protocol { return request.map(|(_, r)| r) } trace!(target: "sync", "Unexpected response packet from {} ({})", who, response.id); - self.peerset_handle.report_peer(who.clone(), i32::min_value()); + self.peerset_handle.report_peer(who.clone(), rep::UNEXPECTED_RESPONSE); self.behaviour.disconnect_peer(&who); } None @@ -587,7 +607,7 @@ impl, H: ExHashT> Protocol { Ok(message) => message, Err(err) => { debug!(target: "sync", "Couldn't decode packet sent by {}: {:?}: {}", who, data, err.what()); - self.peerset_handle.report_peer(who.clone(), BAD_MESSAGE_REPUTATION_CHANGE); + self.peerset_handle.report_peer(who.clone(), rep::BAD_MESSAGE); return CustomMessageOutcome::None; } }; @@ -597,7 +617,7 @@ impl, H: ExHashT> Protocol { stats.count_in += 1; match message { - GenericMessage::Status(s) => self.on_status_message(who, s), + GenericMessage::Status(s) => return self.on_status_message(who, s), GenericMessage::BlockRequest(r) => self.on_block_request(who, r), GenericMessage::BlockResponse(r) => { // Note, this is safe because only `ordinary bodies` and `remote bodies` are received in this matter. @@ -639,20 +659,38 @@ impl, H: ExHashT> Protocol { return self.on_finality_proof_response(who, response), GenericMessage::RemoteReadChildRequest(request) => self.on_remote_read_child_request(who, request), - GenericMessage::Consensus(msg) => { - self.consensus_gossip.on_incoming( - &mut ProtocolContext::new(&mut self.context_data, &mut self.behaviour, &self.peerset_handle), - who, - vec![msg], - ); - } + GenericMessage::Consensus(msg) => + return if self.registered_notif_protocols.contains(&msg.engine_id) { + CustomMessageOutcome::NotificationsReceived { + remote: who.clone(), + messages: vec![(msg.engine_id, From::from(msg.data))], + } + } else { + warn!(target: "sync", "Received message on non-registered protocol: {:?}", msg.engine_id); + CustomMessageOutcome::None + }, GenericMessage::ConsensusBatch(messages) => { - self.consensus_gossip.on_incoming( - &mut ProtocolContext::new(&mut self.context_data, &mut self.behaviour, &self.peerset_handle), - who, - messages, - ); - } + let messages = messages + .into_iter() + .filter_map(|msg| { + if self.registered_notif_protocols.contains(&msg.engine_id) { + Some((msg.engine_id, From::from(msg.data))) + } else { + warn!(target: "sync", "Received message on non-registered protocol: {:?}", msg.engine_id); + None + } + }) + .collect::>(); + + return if !messages.is_empty() { + CustomMessageOutcome::NotificationsReceived { + remote: who.clone(), + messages, + } + } else { + CustomMessageOutcome::None + }; + }, GenericMessage::ChainSpecific(msg) => self.specialization.on_message( &mut ProtocolContext::new(&mut self.context_data, &mut self.behaviour, &self.peerset_handle), who, @@ -682,14 +720,6 @@ impl, H: ExHashT> Protocol { ); } - /// Locks `self` and returns a context plus the `ConsensusGossip` struct. - pub fn consensus_gossip_lock<'a>( - &'a mut self, - ) -> (impl Context + 'a, &'a mut ConsensusGossip) { - let context = ProtocolContext::new(&mut self.context_data, &mut self.behaviour, &self.peerset_handle); - (context, &mut self.consensus_gossip) - } - /// Locks `self` and returns a context plus the network specialization. pub fn specialization_lock<'a>( &'a mut self, @@ -698,26 +728,6 @@ impl, H: ExHashT> Protocol { (context, &mut self.specialization) } - /// Gossip a consensus message to the network. - pub fn gossip_consensus_message( - &mut self, - topic: B::Hash, - engine_id: ConsensusEngineId, - message: Vec, - recipient: GossipMessageRecipient, - ) { - let mut context = ProtocolContext::new(&mut self.context_data, &mut self.behaviour, &self.peerset_handle); - let message = ConsensusMessage { data: message, engine_id }; - match recipient { - GossipMessageRecipient::BroadcastToAll => - self.consensus_gossip.multicast(&mut context, topic, message, true), - GossipMessageRecipient::BroadcastNew => - self.consensus_gossip.multicast(&mut context, topic, message, false), - GossipMessageRecipient::Peer(who) => - self.send_message(&who, GenericMessage::Consensus(message)), - } - } - /// Called when a new peer is connected pub fn on_peer_connected(&mut self, who: PeerId) { trace!(target: "sync", "Connecting {}", who); @@ -738,11 +748,8 @@ impl, H: ExHashT> Protocol { self.handshaking_peers.remove(&peer); self.context_data.peers.remove(&peer) }; - if let Some(peer_data) = removed { + if let Some(_peer_data) = removed { let mut context = ProtocolContext::new(&mut self.context_data, &mut self.behaviour, &self.peerset_handle); - if peer_data.info.protocol_version > 2 { - self.consensus_gossip.peer_disconnected(&mut context, peer.clone()); - } self.sync.peer_disconnected(peer.clone()); self.specialization.on_disconnect(&mut context, peer.clone()); self.light_dispatch.on_disconnect(LightDispatchIn { @@ -755,7 +762,7 @@ impl, H: ExHashT> Protocol { /// Called as a back-pressure mechanism if the networking detects that the peer cannot process /// our messaging rate fast enough. pub fn on_clogged_peer(&self, who: PeerId, _msg: Option>) { - self.peerset_handle.report_peer(who.clone(), CLOGGED_PEER_REPUTATION_CHANGE); + self.peerset_handle.report_peer(who.clone(), rep::CLOGGED_PEER); // Print some diagnostics. if let Some(peer) = self.context_data.peers.get(&who) { @@ -784,7 +791,7 @@ impl, H: ExHashT> Protocol { if !self.config.roles.is_full() { trace!(target: "sync", "Peer {} is trying to sync from the light node", peer); self.behaviour.disconnect_peer(&peer); - self.peerset_handle.report_peer(peer, i32::min_value()); + self.peerset_handle.report_peer(peer, rep::UNEXPECTED_REQUEST); return; } @@ -846,7 +853,7 @@ impl, H: ExHashT> Protocol { } /// Adjusts the reputation of a node. - pub fn report_peer(&self, who: PeerId, reputation: i32) { + pub fn report_peer(&self, who: PeerId, reputation: sc_peerset::ReputationChange) { self.peerset_handle.report_peer(who, reputation) } @@ -905,9 +912,6 @@ impl, H: ExHashT> Protocol { /// /// > **Note**: This method normally doesn't have to be called except for testing purposes. pub fn tick(&mut self) { - self.consensus_gossip.tick( - &mut ProtocolContext::new(&mut self.context_data, &mut self.behaviour, &self.peerset_handle) - ); self.maintain_peers(); self.light_dispatch.maintain_peers(LightDispatchIn { behaviour: &mut self.behaviour, @@ -953,22 +957,22 @@ impl, H: ExHashT> Protocol { ); for p in aborting { self.behaviour.disconnect_peer(&p); - self.peerset_handle.report_peer(p, TIMEOUT_REPUTATION_CHANGE); + self.peerset_handle.report_peer(p, rep::TIMEOUT); } } /// Called by peer to report status - fn on_status_message(&mut self, who: PeerId, status: message::Status) { + fn on_status_message(&mut self, who: PeerId, status: message::Status) -> CustomMessageOutcome { trace!(target: "sync", "New peer {} {:?}", who, status); - let protocol_version = { + let _protocol_version = { if self.context_data.peers.contains_key(&who) { log!( target: "sync", if self.important_peers.contains(&who) { Level::Warn } else { Level::Debug }, "Unexpected status packet from {}", who ); - self.peerset_handle.report_peer(who, UNEXPECTED_STATUS_REPUTATION_CHANGE); - return; + self.peerset_handle.report_peer(who, rep::UNEXPECTED_STATUS); + return CustomMessageOutcome::None; } if status.genesis_hash != self.genesis_hash { log!( @@ -977,9 +981,9 @@ impl, H: ExHashT> Protocol { "Peer is on different chain (our genesis: {} theirs: {})", self.genesis_hash, status.genesis_hash ); - self.peerset_handle.report_peer(who.clone(), i32::min_value()); + self.peerset_handle.report_peer(who.clone(), rep::GENESIS_MISMATCH); self.behaviour.disconnect_peer(&who); - return; + return CustomMessageOutcome::None; } if status.version < MIN_VERSION && CURRENT_VERSION < status.min_supported_version { log!( @@ -987,18 +991,18 @@ impl, H: ExHashT> Protocol { if self.important_peers.contains(&who) { Level::Warn } else { Level::Trace }, "Peer {:?} using unsupported protocol version {}", who, status.version ); - self.peerset_handle.report_peer(who.clone(), i32::min_value()); + self.peerset_handle.report_peer(who.clone(), rep::BAD_PROTOCOL); self.behaviour.disconnect_peer(&who); - return; + return CustomMessageOutcome::None; } if self.config.roles.is_light() { // we're not interested in light peers if status.roles.is_light() { debug!(target: "sync", "Peer {} is unable to serve light requests", who); - self.peerset_handle.report_peer(who.clone(), i32::min_value()); + self.peerset_handle.report_peer(who.clone(), rep::BAD_ROLE); self.behaviour.disconnect_peer(&who); - return; + return CustomMessageOutcome::None; } // we don't interested in peers that are far behind us @@ -1013,9 +1017,9 @@ impl, H: ExHashT> Protocol { .saturated_into::(); if blocks_difference > LIGHT_MAXIMAL_BLOCKS_DIFFERENCE { debug!(target: "sync", "Peer {} is far behind us and will unable to serve light requests", who); - self.peerset_handle.report_peer(who.clone(), PEER_BEHIND_US_LIGHT_REPUTATION_CHANGE); + self.peerset_handle.report_peer(who.clone(), rep::PEER_BEHIND_US_LIGHT); self.behaviour.disconnect_peer(&who); - return; + return CustomMessageOutcome::None; } } @@ -1030,7 +1034,7 @@ impl, H: ExHashT> Protocol { }, None => { error!(target: "sync", "Received status from previously unconnected node {}", who); - return; + return CustomMessageOutcome::None; }, }; @@ -1065,11 +1069,64 @@ impl, H: ExHashT> Protocol { } } } + let mut context = ProtocolContext::new(&mut self.context_data, &mut self.behaviour, &self.peerset_handle); - if protocol_version > 2 { - self.consensus_gossip.new_peer(&mut context, who.clone(), status.roles); + self.specialization.on_connect(&mut context, who.clone(), status); + + // Notify all the notification protocols as open. + CustomMessageOutcome::NotificationStreamOpened { + remote: who, + protocols: self.registered_notif_protocols.iter().cloned().collect(), + roles: info.roles, } - self.specialization.on_connect(&mut context, who, status); + } + + /// Send a notification to the given peer we're connected to. + /// + /// Doesn't do anything if we don't have a notifications substream for that protocol with that + /// peer. + pub fn write_notification( + &mut self, + target: PeerId, + engine_id: ConsensusEngineId, + message: impl Into> + ) { + if !self.registered_notif_protocols.contains(&engine_id) { + error!( + target: "sub-libp2p", + "Sending a notification with a protocol that wasn't registered: {:?}", + engine_id + ); + } + + self.send_message(&target, GenericMessage::Consensus(ConsensusMessage { + engine_id, + data: message.into(), + })); + } + + /// Registers a new notifications protocol. + /// + /// You are very strongly encouraged to call this method very early on. Any connection open + /// will retain the protocols that were registered then, and not any new one. + pub fn register_notifications_protocol( + &mut self, + engine_id: ConsensusEngineId, + ) -> Vec { + if !self.registered_notif_protocols.insert(engine_id) { + error!(target: "sub-libp2p", "Notifications protocol already registered: {:?}", engine_id); + } + + // Registering a protocol while we already have open connections isn't great, but for now + // we handle it by notifying that we opened channels with everyone. + self.context_data.peers.iter() + .map(|(peer_id, peer)| + event::Event::NotificationStreamOpened { + remote: peer_id.clone(), + engine_id, + roles: peer.info.roles, + }) + .collect() } /// Called when peer sends us new extrinsics @@ -1082,7 +1139,7 @@ impl, H: ExHashT> Protocol { if !self.config.roles.is_full() { trace!(target: "sync", "Peer {} is trying to send extrinsic to the light node", who); self.behaviour.disconnect_peer(&who); - self.peerset_handle.report_peer(who, i32::min_value()); + self.peerset_handle.report_peer(who, rep::UNEXPECTED_EXTRINSICS); return; } @@ -1100,8 +1157,8 @@ impl, H: ExHashT> Protocol { self.transaction_pool.import( self.peerset_handle.clone().into(), who.clone(), - GOOD_EXTRINSIC_REPUTATION_CHANGE, - BAD_EXTRINSIC_REPUTATION_CHANGE, + rep::GOOD_EXTRINSIC, + rep::BAD_EXTRINSIC, t, ); } @@ -1351,7 +1408,7 @@ impl, H: ExHashT> Protocol { request.block, error ); - self.peerset_handle.report_peer(who.clone(), RPC_FAILED_REPUTATION_CHANGE); + self.peerset_handle.report_peer(who.clone(), rep::RPC_FAILED); StorageProof::empty() } }; @@ -1501,23 +1558,37 @@ impl, H: ExHashT> Protocol { trace!(target: "sync", "Remote read child request {} from {} ({} {} at {})", request.id, who, request.storage_key.to_hex::(), keys_str(), request.block); - let proof = match self.context_data.chain.read_child_proof( - &request.block, - &request.storage_key, - &request.keys, - ) { - Ok(proof) => proof, - Err(error) => { - trace!(target: "sync", "Remote read child request {} from {} ({} {} at {}) failed with: {}", - request.id, - who, - request.storage_key.to_hex::(), - keys_str(), - request.block, - error - ); - StorageProof::empty() + let proof = if let Some(child_info) = ChildInfo::resolve_child_info(request.child_type, &request.child_info[..]) { + match self.context_data.chain.read_child_proof( + &request.block, + &request.storage_key, + child_info, + &request.keys, + ) { + Ok(proof) => proof, + Err(error) => { + trace!(target: "sync", "Remote read child request {} from {} ({} {} at {}) failed with: {}", + request.id, + who, + request.storage_key.to_hex::(), + keys_str(), + request.block, + error + ); + StorageProof::empty() + } } + } else { + trace!(target: "sync", "Remote read child request {} from {} ({} {} at {}) failed with: {}", + request.id, + who, + request.storage_key.to_hex::(), + keys_str(), + request.block, + "invalid child info and type", + ); + + StorageProof::empty() }; self.send_message( &who, @@ -1679,7 +1750,7 @@ impl, H: ExHashT> Protocol { None }, }; - self.send_message( + self.send_message( &who, GenericMessage::FinalityProofResponse(message::FinalityProofResponse { id: 0, @@ -1741,6 +1812,12 @@ pub enum CustomMessageOutcome { BlockImport(BlockOrigin, Vec>), JustificationImport(Origin, B::Hash, NumberFor, Justification), FinalityProofImport(Origin, B::Hash, NumberFor, Vec), + /// Notification protocols have been opened with a remote. + NotificationStreamOpened { remote: PeerId, protocols: Vec, roles: Roles }, + /// Notification protocols have been closed with a remote. + NotificationsStreamClosed { remote: PeerId, protocols: Vec }, + /// Messages have been received on one or more notifications protocols. + NotificationsReceived { remote: PeerId, messages: Vec<(ConsensusEngineId, Bytes)> }, None, } @@ -1870,12 +1947,16 @@ Protocol { version <= CURRENT_VERSION as u8 && version >= MIN_VERSION as u8 ); - self.on_peer_connected(peer_id); + self.on_peer_connected(peer_id.clone()); CustomMessageOutcome::None } LegacyProtoOut::CustomProtocolClosed { peer_id, .. } => { - self.on_peer_disconnected(peer_id); - CustomMessageOutcome::None + self.on_peer_disconnected(peer_id.clone()); + // Notify all the notification protocols as closed. + CustomMessageOutcome::NotificationsStreamClosed { + remote: peer_id, + protocols: self.registered_notif_protocols.iter().cloned().collect(), + } }, LegacyProtoOut::CustomMessage { peer_id, message } => self.on_custom_message(peer_id, message), diff --git a/client/network/src/protocol/event.rs b/client/network/src/protocol/event.rs index c8bee5588c704f09a9c2c14d1b5b8245cf6bd1cc..98aad8c76c804095bb897be1e929d70fe48f3796 100644 --- a/client/network/src/protocol/event.rs +++ b/client/network/src/protocol/event.rs @@ -17,10 +17,15 @@ //! Network event types. These are are not the part of the protocol, but rather //! events that happen on the network like DHT get/put results received. +use crate::config::Roles; +use bytes::Bytes; +use libp2p::core::PeerId; use libp2p::kad::record::Key; +use sp_runtime::ConsensusEngineId; /// Events generated by DHT as a response to get_value and put_value requests. #[derive(Debug, Clone)] +#[must_use] pub enum DhtEvent { /// The value was found. ValueFound(Vec<(Key, Vec)>), @@ -37,7 +42,37 @@ pub enum DhtEvent { /// Type for events generated by networking layer. #[derive(Debug, Clone)] +#[must_use] pub enum Event { /// Event generated by a DHT. Dht(DhtEvent), + + /// Opened a substream with the given node with the given notifications protocol. + /// + /// The protocol is always one of the notification protocols that have been registered. + NotificationStreamOpened { + /// Node we opened the substream with. + remote: PeerId, + /// The concerned protocol. Each protocol uses a different substream. + engine_id: ConsensusEngineId, + /// Roles that the remote . + roles: Roles, + }, + + /// Closed a substream with the given node. Always matches a corresponding previous + /// `NotificationStreamOpened` message. + NotificationsStreamClosed { + /// Node we closed the substream with. + remote: PeerId, + /// The concerned protocol. Each protocol uses a different substream. + engine_id: ConsensusEngineId, + }, + + /// Received one or more messages from the given node using the given protocol. + NotificationsReceived { + /// Node we received the message from. + remote: PeerId, + /// Concerned protocol and associated message. + messages: Vec<(ConsensusEngineId, Bytes)>, + }, } diff --git a/client/network/src/protocol/legacy_proto.rs b/client/network/src/protocol/legacy_proto.rs new file mode 100644 index 0000000000000000000000000000000000000000..eee30117d95f8c63fef72bd45a485119f9741748 --- /dev/null +++ b/client/network/src/protocol/legacy_proto.rs @@ -0,0 +1,28 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Implementation of libp2p's `NetworkBehaviour` trait that opens a single substream with the +//! remote and then allows any communication with them. +//! +//! The `Protocol` struct uses `LegacyProto` in order to open substreams with the rest of the +//! network, then performs the Substrate protocol handling on top. + +pub use self::behaviour::{LegacyProto, LegacyProtoOut}; + +mod behaviour; +mod handler; +mod upgrade; +mod tests; diff --git a/client/network/src/legacy_proto/behaviour.rs b/client/network/src/protocol/legacy_proto/behaviour.rs similarity index 97% rename from client/network/src/legacy_proto/behaviour.rs rename to client/network/src/protocol/legacy_proto/behaviour.rs index d1d378174a21b0ec7b35923b0eee7f1c841d31bc..31e162a5899e54520dafccbc6f5eef2ab3de7efd 100644 --- a/client/network/src/legacy_proto/behaviour.rs +++ b/client/network/src/protocol/legacy_proto/behaviour.rs @@ -15,8 +15,8 @@ // along with Substrate. If not, see . use crate::{DiscoveryNetBehaviour, config::ProtocolId}; -use crate::legacy_proto::handler::{CustomProtoHandlerProto, CustomProtoHandlerOut, CustomProtoHandlerIn}; -use crate::legacy_proto::upgrade::RegisteredProtocol; +use crate::protocol::legacy_proto::handler::{CustomProtoHandlerProto, CustomProtoHandlerOut, CustomProtoHandlerIn}; +use crate::protocol::legacy_proto::upgrade::RegisteredProtocol; use bytes::BytesMut; use fnv::FnvHashMap; use futures::prelude::*; @@ -65,7 +65,7 @@ pub struct LegacyProto< TSubstream> { protocol: RegisteredProtocol, /// Receiver for instructions about who to connect to or disconnect from. - peerset: peerset::Peerset, + peerset: sc_peerset::Peerset, /// List of peers in our state. peers: FnvHashMap, @@ -76,7 +76,7 @@ pub struct LegacyProto< TSubstream> { /// We generate indices to identify incoming connections. This is the next value for the index /// to use when a connection is incoming. - next_incoming_index: peerset::IncomingIndex, + next_incoming_index: sc_peerset::IncomingIndex, /// Events to produce from `poll()`. events: SmallVec<[NetworkBehaviourAction; 4]>, @@ -183,7 +183,7 @@ struct IncomingPeer { /// connection corresponding to it has been closed or replaced already. alive: bool, /// Id that the we sent to the peerset. - incoming_id: peerset::IncomingIndex, + incoming_id: sc_peerset::IncomingIndex, } /// Event that can be emitted by the `LegacyProto`. @@ -230,7 +230,7 @@ impl LegacyProto { pub fn new( protocol: impl Into, versions: &[u8], - peerset: peerset::Peerset, + peerset: sc_peerset::Peerset, ) -> Self { let protocol = RegisteredProtocol::new(protocol, versions); @@ -239,7 +239,7 @@ impl LegacyProto { peerset, peers: FnvHashMap::default(), incoming: SmallVec::new(), - next_incoming_index: peerset::IncomingIndex(0), + next_incoming_index: sc_peerset::IncomingIndex(0), events: SmallVec::new(), marker: PhantomData, } @@ -520,7 +520,7 @@ impl LegacyProto { } /// Function that is called when the peerset wants us to accept an incoming node. - fn peerset_report_accept(&mut self, index: peerset::IncomingIndex) { + fn peerset_report_accept(&mut self, index: sc_peerset::IncomingIndex) { let incoming = if let Some(pos) = self.incoming.iter().position(|i| i.incoming_id == index) { self.incoming.remove(pos) } else { @@ -564,7 +564,7 @@ impl LegacyProto { } /// Function that is called when the peerset wants us to reject an incoming node. - fn peerset_report_reject(&mut self, index: peerset::IncomingIndex) { + fn peerset_report_reject(&mut self, index: sc_peerset::IncomingIndex) { let incoming = if let Some(pos) = self.incoming.iter().position(|i| i.incoming_id == index) { self.incoming.remove(pos) } else { @@ -940,7 +940,10 @@ where // a different chain, or a node that doesn't speak the same protocol(s). We // decrease the node's reputation, hence lowering the chances we try this node // again in the short term. - self.peerset.report_peer(source.clone(), i32::min_value()); + self.peerset.report_peer( + source.clone(), + sc_peerset::ReputationChange::new(i32::min_value(), "Protocol error") + ); self.disconnect_peer_inner(&source, Some(Duration::from_secs(5))); } } @@ -962,16 +965,16 @@ where futures03::Stream::poll_next(Pin::new(&mut self.peerset), cx) ).map(|v| Ok::<_, ()>(v)).compat(); match peerset01.poll() { - Ok(Async::Ready(Some(peerset::Message::Accept(index)))) => { + Ok(Async::Ready(Some(sc_peerset::Message::Accept(index)))) => { self.peerset_report_accept(index); } - Ok(Async::Ready(Some(peerset::Message::Reject(index)))) => { + Ok(Async::Ready(Some(sc_peerset::Message::Reject(index)))) => { self.peerset_report_reject(index); } - Ok(Async::Ready(Some(peerset::Message::Connect(id)))) => { + Ok(Async::Ready(Some(sc_peerset::Message::Connect(id)))) => { self.peerset_report_connect(id); } - Ok(Async::Ready(Some(peerset::Message::Drop(id)))) => { + Ok(Async::Ready(Some(sc_peerset::Message::Drop(id)))) => { self.peerset_report_disconnect(id); } Ok(Async::Ready(None)) => { diff --git a/client/network/src/legacy_proto/handler.rs b/client/network/src/protocol/legacy_proto/handler.rs similarity index 99% rename from client/network/src/legacy_proto/handler.rs rename to client/network/src/protocol/legacy_proto/handler.rs index 7bdbe4a31ff7cdab0d74ade7d1a3812494010aa1..cbd0385734a80b6af73566d13cbdb89e3b1023e3 100644 --- a/client/network/src/legacy_proto/handler.rs +++ b/client/network/src/protocol/legacy_proto/handler.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use crate::legacy_proto::upgrade::{RegisteredProtocol, RegisteredProtocolEvent, RegisteredProtocolSubstream}; +use super::upgrade::{RegisteredProtocol, RegisteredProtocolEvent, RegisteredProtocolSubstream}; use bytes::BytesMut; use futures::prelude::*; use futures03::{compat::Compat, TryFutureExt as _}; diff --git a/client/network/src/legacy_proto/tests.rs b/client/network/src/protocol/legacy_proto/tests.rs similarity index 98% rename from client/network/src/legacy_proto/tests.rs rename to client/network/src/protocol/legacy_proto/tests.rs index dc6d40eb040d70f189d3b46dccdffceeb8492428..eaf25e5119d60214e888d7962b8504062609be80 100644 --- a/client/network/src/legacy_proto/tests.rs +++ b/client/network/src/protocol/legacy_proto/tests.rs @@ -26,8 +26,8 @@ use libp2p::{PeerId, Multiaddr, Transport}; use rand::seq::SliceRandom; use std::{io, time::Duration, time::Instant}; use crate::message::Message; -use crate::legacy_proto::{LegacyProto, LegacyProtoOut}; -use test_client::runtime::Block; +use crate::protocol::legacy_proto::{LegacyProto, LegacyProtoOut}; +use sp_test_primitives::Block; /// Builds two nodes that have each other as bootstrap nodes. /// This is to be used only for testing, and a panic will happen if something goes wrong. @@ -68,7 +68,7 @@ fn build_nodes() .map_err(|err| io::Error::new(io::ErrorKind::Other, err)) .boxed(); - let (peerset, _) = peerset::Peerset::from_config(peerset::PeersetConfig { + let (peerset, _) = sc_peerset::Peerset::from_config(sc_peerset::PeersetConfig { in_peers: 25, out_peers: 25, bootnodes: if index == 0 { diff --git a/client/network/src/legacy_proto/upgrade.rs b/client/network/src/protocol/legacy_proto/upgrade.rs similarity index 100% rename from client/network/src/legacy_proto/upgrade.rs rename to client/network/src/protocol/legacy_proto/upgrade.rs diff --git a/client/network/src/protocol/light_dispatch.rs b/client/network/src/protocol/light_dispatch.rs index 280495c0c41b65ce5eba8f0c606e5ce67bbed4e0..83e0331325119d4f4616782f801c9368c7eb7f4a 100644 --- a/client/network/src/protocol/light_dispatch.rs +++ b/client/network/src/protocol/light_dispatch.rs @@ -25,14 +25,15 @@ use std::time::{Instant, Duration}; use log::{trace, info}; use futures::sync::oneshot::{Sender as OneShotSender}; use linked_hash_map::{Entry, LinkedHashMap}; -use client_api::error::Error as ClientError; -use client_api::{FetchChecker, RemoteHeaderRequest, +use sp_blockchain::Error as ClientError; +use sc_client_api::{FetchChecker, RemoteHeaderRequest, RemoteCallRequest, RemoteReadRequest, RemoteChangesRequest, ChangesProof, RemoteReadChildRequest, RemoteBodyRequest, StorageProof}; use crate::message::{self, BlockAttributes, Direction, FromBlock, RequestId}; use libp2p::PeerId; use crate::config::Roles; -use sr_primitives::traits::{Block as BlockT, Header as HeaderT, NumberFor}; +use sp_runtime::traits::{Block as BlockT, Header as HeaderT, NumberFor}; +use sc_peerset::ReputationChange; /// Remote request timeout. const REQUEST_TIMEOUT: Duration = Duration::from_secs(15); @@ -44,7 +45,7 @@ const TIMEOUT_REPUTATION_CHANGE: i32 = -(1 << 8); /// Trait used by the `LightDispatch` service to communicate messages back to the network. pub trait LightDispatchNetwork { /// Adjusts the reputation of the given peer. - fn report_peer(&mut self, who: &PeerId, reputation_change: i32); + fn report_peer(&mut self, who: &PeerId, reputation_change: ReputationChange); /// Disconnect from the given peer. Used in case of misbehaviour. fn disconnect_peer(&mut self, who: &PeerId); @@ -68,6 +69,8 @@ pub trait LightDispatchNetwork { id: RequestId, block: ::Hash, storage_key: Vec, + child_info: Vec, + child_type: u32, keys: Vec>, ); @@ -267,7 +270,7 @@ impl LightDispatch where Some(request) => request, None => { info!("Invalid remote {} response from peer {}", rtype, peer); - network.report_peer(&peer, i32::min_value()); + network.report_peer(&peer, ReputationChange::new_fatal("Invalid remote response")); network.disconnect_peer(&peer); self.remove_peer(peer); return; @@ -279,7 +282,7 @@ impl LightDispatch where Accept::Ok => (retry_count, None), Accept::CheckFailed(error, retry_request_data) => { info!("Failed to check remote {} response from peer {}: {}", rtype, peer, error); - network.report_peer(&peer, i32::min_value()); + network.report_peer(&peer, ReputationChange::new_fatal("Failed remote response check")); network.disconnect_peer(&peer); self.remove_peer(peer); @@ -293,7 +296,7 @@ impl LightDispatch where }, Accept::Unexpected(retry_request_data) => { info!("Unexpected response to remote {} from peer", rtype); - network.report_peer(&peer, i32::min_value()); + network.report_peer(&peer, ReputationChange::new_fatal("Unexpected remote response")); network.disconnect_peer(&peer); self.remove_peer(peer); @@ -350,7 +353,7 @@ impl LightDispatch where let (bad_peer, request) = self.active_peers.pop_front().expect("front() is Some as checked above"); self.pending_requests.push_front(request); - network.report_peer(&bad_peer, TIMEOUT_REPUTATION_CHANGE); + network.report_peer(&bad_peer, ReputationChange::new(TIMEOUT_REPUTATION_CHANGE, "Light request timeout")); network.disconnect_peer(&bad_peer); } @@ -621,6 +624,8 @@ impl Request { self.id, data.block, data.storage_key.clone(), + data.child_info.clone(), + data.child_type, data.keys.clone(), ), RequestData::RemoteCall(ref data, _) => @@ -676,16 +681,17 @@ pub mod tests { use std::sync::Arc; use std::time::Instant; use futures::{Future, sync::oneshot}; - use sr_primitives::traits::{Block as BlockT, NumberFor, Header as HeaderT}; - use client_api::{error::{Error as ClientError, Result as ClientResult}}; - use client_api::{FetchChecker, RemoteHeaderRequest, + use sp_core::storage::ChildInfo; + use sp_runtime::traits::{Block as BlockT, NumberFor, Header as HeaderT}; + use sp_blockchain::{Error as ClientError, Result as ClientResult}; + use sc_client_api::{FetchChecker, RemoteHeaderRequest, ChangesProof, RemoteCallRequest, RemoteReadRequest, RemoteReadChildRequest, RemoteChangesRequest, RemoteBodyRequest}; use crate::config::Roles; use crate::message::{self, BlockAttributes, Direction, FromBlock, RequestId}; use libp2p::PeerId; use super::{REQUEST_TIMEOUT, LightDispatch, LightDispatchNetwork, RequestData, StorageProof}; - use test_client::runtime::{changes_trie_config, Block, Extrinsic, Header}; + use sp_test_primitives::{changes_trie_config, Block, Extrinsic, Header}; struct DummyFetchChecker { ok: bool } @@ -800,14 +806,14 @@ pub mod tests { } impl<'a, B: BlockT> LightDispatchNetwork for &'a mut DummyNetwork { - fn report_peer(&mut self, _: &PeerId, _: i32) {} + fn report_peer(&mut self, _: &PeerId, _: crate::ReputationChange) {} fn disconnect_peer(&mut self, who: &PeerId) { self.disconnected_peers.insert(who.clone()); } fn send_header_request(&mut self, _: &PeerId, _: RequestId, _: <::Header as HeaderT>::Number) {} fn send_read_request(&mut self, _: &PeerId, _: RequestId, _: ::Hash, _: Vec>) {} fn send_read_child_request(&mut self, _: &PeerId, _: RequestId, _: ::Hash, _: Vec, - _: Vec>) {} + _: Vec, _: u32, _: Vec>) {} fn send_call_request(&mut self, _: &PeerId, _: RequestId, _: ::Hash, _: String, _: Vec) {} fn send_changes_request(&mut self, _: &PeerId, _: RequestId, _: ::Hash, _: ::Hash, _: ::Hash, _: ::Hash, _: Option>, _: Vec) {} @@ -1026,10 +1032,14 @@ pub mod tests { light_dispatch.on_connect(&mut network_interface, peer0.clone(), Roles::FULL, 1000); let (tx, response) = oneshot::channel(); + let child_info = ChildInfo::new_default(b"unique_id_1"); + let (child_info, child_type) = child_info.info(); light_dispatch.add_request(&mut network_interface, RequestData::RemoteReadChild(RemoteReadChildRequest { header: dummy_header(), block: Default::default(), storage_key: b":child_storage:sub".to_vec(), + child_info: child_info.to_vec(), + child_type, keys: vec![b":key".to_vec()], retry_count: None, }, tx)); @@ -1223,7 +1233,7 @@ pub mod tests { assert_eq!(light_dispatch.active_peers.len(), 1); let block = message::BlockData:: { - hash: primitives::H256::random(), + hash: sp_core::H256::random(), header: None, body: Some(Vec::new()), message_queue: None, @@ -1261,7 +1271,7 @@ pub mod tests { let response = { let blocks: Vec<_> = (0..3).map(|_| message::BlockData:: { - hash: primitives::H256::random(), + hash: sp_core::H256::random(), header: None, body: Some(Vec::new()), message_queue: None, diff --git a/client/network/src/protocol/message.rs b/client/network/src/protocol/message.rs index 847c03f680d7c9bfb338540b41b4cc3d76a19ef8..0bb9d8c64f4166b29dd7ab6f26358b12d5b6f60d 100644 --- a/client/network/src/protocol/message.rs +++ b/client/network/src/protocol/message.rs @@ -17,7 +17,7 @@ //! Network packet message types. These get serialized and put into the lower level protocol payload. use bitflags::bitflags; -use sr_primitives::{ConsensusEngineId, traits::{Block as BlockT, Header as HeaderT}}; +use sp_runtime::{ConsensusEngineId, traits::{Block as BlockT, Header as HeaderT}}; use codec::{Encode, Decode, Input, Output, Error}; pub use self::generic::{ BlockAnnounce, RemoteCallRequest, RemoteReadRequest, @@ -26,7 +26,7 @@ pub use self::generic::{ FinalityProofRequest, FinalityProofResponse, FromBlock, RemoteReadChildRequest, }; -use client_api::StorageProof; +use sc_client_api::StorageProof; /// A unique ID of a request. pub type RequestId = u64; @@ -138,7 +138,7 @@ pub struct RemoteReadResponse { /// Generic types. pub mod generic { use codec::{Encode, Decode, Input, Output}; - use sr_primitives::Justification; + use sp_runtime::Justification; use crate::config::Roles; use super::{ RemoteReadResponse, Transactions, Direction, @@ -368,6 +368,11 @@ pub mod generic { pub block: H, /// Child Storage key. pub storage_key: Vec, + /// Child trie source information. + pub child_info: Vec, + /// Child type, its required to resolve `child_info` + /// content and choose child implementation. + pub child_type: u32, /// Storage key. pub keys: Vec>, } diff --git a/client/network/src/protocol/specialization.rs b/client/network/src/protocol/specialization.rs index 1a15c47c87d3a45d9653e029831367c56c33efff..7ccd38740a921ded18f4ae97ea40cb714fa226e4 100644 --- a/client/network/src/protocol/specialization.rs +++ b/client/network/src/protocol/specialization.rs @@ -20,7 +20,7 @@ pub use crate::protocol::event::{DhtEvent, Event}; use crate::protocol::Context; use libp2p::PeerId; -use sr_primitives::traits::Block as BlockT; +use sp_runtime::traits::Block as BlockT; /// A specialization of the substrate network protocol. Handles events and sends messages. pub trait NetworkSpecialization: Send + Sync + 'static { diff --git a/client/network/src/protocol/sync.rs b/client/network/src/protocol/sync.rs index 6f1255cd8ab9f3a07d073676e3ac4dd4e0eec498..4e248b7fe480f1d0e81ba9de09e9de61cc003c2e 100644 --- a/client/network/src/protocol/sync.rs +++ b/client/network/src/protocol/sync.rs @@ -28,8 +28,9 @@ //! use blocks::BlockCollection; -use client_api::{ClientInfo, error::Error as ClientError}; -use consensus::{BlockOrigin, BlockStatus, +use sc_client_api::ClientInfo; +use sp_blockchain::Error as ClientError; +use sp_consensus::{BlockOrigin, BlockStatus, block_validation::{BlockAnnounceValidator, Validation}, import_queue::{IncomingBlock, BlockImportResult, BlockImportError} }; @@ -42,7 +43,7 @@ use either::Either; use extra_requests::ExtraRequests; use libp2p::PeerId; use log::{debug, trace, warn, info, error}; -use sr_primitives::{ +use sp_runtime::{ Justification, generic::BlockId, traits::{Block as BlockT, Header, NumberFor, Zero, One, CheckedSub, SaturatedConversion} @@ -71,29 +72,34 @@ const MAJOR_SYNC_BLOCKS: u8 = 5; /// Number of recently announced blocks to track for each peer. const ANNOUNCE_HISTORY_SIZE: usize = 64; -/// Reputation change when a peer sent us a status message that led to a -/// database read error. -const BLOCKCHAIN_STATUS_READ_ERROR_REPUTATION_CHANGE: i32 = -(1 << 16); +mod rep { + use sc_peerset::ReputationChange as Rep; + /// Reputation change when a peer sent us a message that led to a + /// database read error. + pub const BLOCKCHAIN_READ_ERROR: Rep = Rep::new(-(1 << 16), "DB Error"); -/// Reputation change when a peer failed to answer our legitimate ancestry -/// block search. -const ANCESTRY_BLOCK_ERROR_REPUTATION_CHANGE: i32 = -(1 << 9); + /// Reputation change when a peer sent us a status message with a different + /// genesis than us. + pub const GENESIS_MISMATCH: Rep = Rep::new(i32::min_value(), "Genesis mismatch"); -/// Reputation change when a peer sent us a status message with a different -/// genesis than us. -const GENESIS_MISMATCH_REPUTATION_CHANGE: i32 = i32::min_value() + 1; + /// Reputation change for peers which send us a block with an incomplete header. + pub const INCOMPLETE_HEADER: Rep = Rep::new(-(1 << 20), "Incomplete header"); -/// Reputation change for peers which send us a block with an incomplete header. -const INCOMPLETE_HEADER_REPUTATION_CHANGE: i32 = -(1 << 20); + /// Reputation change for peers which send us a block which we fail to verify. + pub const VERIFICATION_FAIL: Rep = Rep::new(-(1 << 20), "Block verification failed"); -/// Reputation change for peers which send us a block which we fail to verify. -const VERIFICATION_FAIL_REPUTATION_CHANGE: i32 = -(1 << 20); + /// Reputation change for peers which send us a known bad block. + pub const BAD_BLOCK: Rep = Rep::new(-(1 << 29), "Bad block"); -/// Reputation change for peers which send us a bad block. -const BAD_BLOCK_REPUTATION_CHANGE: i32 = -(1 << 29); + /// Reputation change for peers which send us a block with bad justifications. + pub const BAD_JUSTIFICATION: Rep = Rep::new(-(1 << 16), "Bad justification"); -/// Reputation change for peers which send us a block with bad justifications. -const BAD_JUSTIFICATION_REPUTATION_CHANGE: i32 = -(1 << 16); + /// Reputation change for peers which send us a block with bad finality proof. + pub const BAD_FINALITY_PROOF: Rep = Rep::new(-(1 << 16), "Bad finality proof"); + + /// Reputation change when a peer sent us invlid ancestry result. + pub const UNKNOWN_ANCESTOR:Rep = Rep::new(-(1 << 16), "DB Error"); +} /// The main data structure which contains all the state for a chains /// active syncing strategy. @@ -224,11 +230,11 @@ pub struct Status { /// A peer did not behave as expected and should be reported. #[derive(Debug, Clone, PartialEq, Eq)] -pub struct BadPeer(pub PeerId, pub i32); +pub struct BadPeer(pub PeerId, pub sc_peerset::ReputationChange); impl fmt::Display for BadPeer { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "bad peer {}; reputation change: {}", self.0, self.1) + write!(f, "Bad peer {}; Reputation change: {:?}", self.0, self.1) } } @@ -357,16 +363,16 @@ impl ChainSync { match self.block_status(&best_hash) { Err(e) => { debug!(target:"sync", "Error reading blockchain: {:?}", e); - Err(BadPeer(who, BLOCKCHAIN_STATUS_READ_ERROR_REPUTATION_CHANGE)) + Err(BadPeer(who, rep::BLOCKCHAIN_READ_ERROR)) } Ok(BlockStatus::KnownBad) => { info!("New peer with known bad best block {} ({}).", best_hash, best_number); - Err(BadPeer(who, i32::min_value())) + Err(BadPeer(who, rep::BAD_BLOCK)) } Ok(BlockStatus::Unknown) => { if best_number.is_zero() { info!("New peer with unknown genesis hash {} ({}).", best_hash, best_number); - return Err(BadPeer(who, i32::min_value())) + return Err(BadPeer(who, rep::GENESIS_MISMATCH)); } // If there are more than `MAJOR_SYNC_BLOCKS` in the import queue then we have // enough to do in the import queue that it's not worth kicking off @@ -661,6 +667,7 @@ impl ChainSync { justification: block_data.block.justification, origin: block_data.origin, allow_missing_state: false, + import_existing: false, } }).collect() } @@ -674,6 +681,7 @@ impl ChainSync { justification: b.justification, origin: Some(who.clone()), allow_missing_state: true, + import_existing: false, } }).collect() } @@ -685,11 +693,11 @@ impl ChainSync { }, (None, _) => { debug!(target: "sync", "Invalid response when searching for ancestor from {}", who); - return Err(BadPeer(who, i32::min_value())) + return Err(BadPeer(who, rep::UNKNOWN_ANCESTOR)) }, (_, Err(e)) => { info!("Error answering legitimate blockchain query: {:?}", e); - return Err(BadPeer(who, ANCESTRY_BLOCK_ERROR_REPUTATION_CHANGE)) + return Err(BadPeer(who, rep::BLOCKCHAIN_READ_ERROR)) } }; if matching_hash.is_some() && peer.common_number < *num { @@ -697,7 +705,7 @@ impl ChainSync { } if matching_hash.is_none() && num.is_zero() { trace!(target:"sync", "Ancestry search: genesis mismatch for peer {}", who); - return Err(BadPeer(who, GENESIS_MISMATCH_REPUTATION_CHANGE)) + return Err(BadPeer(who, rep::GENESIS_MISMATCH)) } if let Some((next_state, next_num)) = handle_ancestor_search_state(state, *num, matching_hash.is_some()) { peer.state = PeerSyncState::AncestorSearch(next_num, next_state); @@ -787,9 +795,10 @@ impl ChainSync { if let Some(block) = response.blocks.into_iter().next() { if hash != block.hash { info!( + target: "sync", "Invalid block justification provided by {}: requested: {:?} got: {:?}", who, hash, block.hash ); - return Err(BadPeer(who, i32::min_value())) + return Err(BadPeer(who, rep::BAD_JUSTIFICATION)); } if let Some((peer, hash, number, j)) = self.extra_justifications.on_response(who, block.justification) { return Ok(OnBlockJustification::Import { peer, hash, number, justification: j }) @@ -822,8 +831,13 @@ impl ChainSync { // We only request one finality proof at a time. if hash != resp.block { - info!("Invalid block finality proof provided: requested: {:?} got: {:?}", hash, resp.block); - return Err(BadPeer(who, i32::min_value())) + info!( + target: "sync", + "Invalid block finality proof provided: requested: {:?} got: {:?}", + hash, + resp.block + ); + return Err(BadPeer(who, rep::BAD_FINALITY_PROOF)); } if let Some((peer, hash, number, p)) = self.extra_finality_proofs.on_response(who, resp.proof) { @@ -884,7 +898,7 @@ impl ChainSync { if aux.bad_justification { if let Some(peer) = who { info!("Sent block with bad justification to import"); - output.push(Err(BadPeer(peer, BAD_JUSTIFICATION_REPUTATION_CHANGE))); + output.push(Err(BadPeer(peer, rep::BAD_JUSTIFICATION))); } } @@ -900,21 +914,21 @@ impl ChainSync { Err(BlockImportError::IncompleteHeader(who)) => { if let Some(peer) = who { info!("Peer sent block with incomplete header to import"); - output.push(Err(BadPeer(peer, INCOMPLETE_HEADER_REPUTATION_CHANGE))); + output.push(Err(BadPeer(peer, rep::INCOMPLETE_HEADER))); output.extend(self.restart()); } }, Err(BlockImportError::VerificationFailed(who, e)) => { if let Some(peer) = who { info!("Verification failed from peer: {}", e); - output.push(Err(BadPeer(peer, VERIFICATION_FAIL_REPUTATION_CHANGE))); + output.push(Err(BadPeer(peer, rep::VERIFICATION_FAIL))); output.extend(self.restart()); } }, Err(BlockImportError::BadBlock(who)) => { if let Some(peer) = who { info!("Bad block"); - output.push(Err(BadPeer(peer, BAD_BLOCK_REPUTATION_CHANGE))); + output.push(Err(BadPeer(peer, rep::BAD_BLOCK))); output.extend(self.restart()); } }, diff --git a/client/network/src/protocol/sync/blocks.rs b/client/network/src/protocol/sync/blocks.rs index 70e9889e1e83fd4ceaca9ed653eaac9661f7d8c7..ef08d7320dbb4589eff657d8bab5422ed93b4223 100644 --- a/client/network/src/protocol/sync/blocks.rs +++ b/client/network/src/protocol/sync/blocks.rs @@ -21,7 +21,7 @@ use std::collections::{HashMap, BTreeMap}; use std::collections::hash_map::Entry; use log::trace; use libp2p::PeerId; -use sr_primitives::traits::{Block as BlockT, NumberFor, One}; +use sp_runtime::traits::{Block as BlockT, NumberFor, One}; use crate::message; /// Block data with origin. @@ -215,8 +215,8 @@ impl BlockCollection { mod test { use super::{BlockCollection, BlockData, BlockRangeState}; use crate::{message, PeerId}; - use sr_primitives::testing::{Block as RawBlock, ExtrinsicWrapper}; - use primitives::H256; + use sp_runtime::testing::{Block as RawBlock, ExtrinsicWrapper}; + use sp_core::H256; type Block = RawBlock>; diff --git a/client/network/src/protocol/sync/extra_requests.rs b/client/network/src/protocol/sync/extra_requests.rs index 5bfeeba2a5c3a4c745b97730e8b146645c4c1605..ecd6fdca99adb4591b92367f1ad5bcb515083546 100644 --- a/client/network/src/protocol/sync/extra_requests.rs +++ b/client/network/src/protocol/sync/extra_requests.rs @@ -14,12 +14,12 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use client_api::error::Error as ClientError; +use sp_blockchain::Error as ClientError; use crate::protocol::sync::{PeerSync, PeerSyncState}; use fork_tree::ForkTree; use libp2p::PeerId; use log::{debug, warn}; -use sr_primitives::traits::{Block as BlockT, NumberFor, Zero}; +use sp_runtime::traits::{Block as BlockT, NumberFor, Zero}; use std::collections::{HashMap, HashSet, VecDeque}; use std::time::{Duration, Instant}; @@ -283,12 +283,12 @@ impl<'a, B: BlockT> Matcher<'a, B> { #[cfg(test)] mod tests { use crate::protocol::sync::PeerSync; - use client_api::error::Error as ClientError; + use sp_blockchain::Error as ClientError; use quickcheck::{Arbitrary, Gen, QuickCheck, StdThreadGen}; use rand::Rng; use std::collections::{HashMap, HashSet}; use super::*; - use test_client::runtime::{Block, BlockNumber, Hash}; + use sp_test_primitives::{Block, BlockNumber, Hash}; #[test] fn requests_are_processed_in_order() { diff --git a/client/network/src/service.rs b/client/network/src/service.rs index 437e978f4bd47ee5b114020ec8a675a1d3335369..d945bb0e2671f11661f5e4314f2e79765290e78f 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! Main entry point of the substrate-network crate. +//! Main entry point of the sc-network crate. //! //! There are two main structs in this module: [`NetworkWorker`] and [`NetworkService`]. //! The [`NetworkWorker`] *is* the network and implements the `Future` trait. It must be polled in @@ -28,8 +28,8 @@ use std::{collections::{HashMap, HashSet}, fs, marker::PhantomData, io, path::Path}; use std::sync::{Arc, atomic::{AtomicBool, AtomicUsize, Ordering}}; -use consensus::import_queue::{ImportQueue, Link}; -use consensus::import_queue::{BlockImportResult, BlockImportError}; +use sp_consensus::import_queue::{ImportQueue, Link}; +use sp_consensus::import_queue::{BlockImportResult, BlockImportError}; use futures::{prelude::*, sync::mpsc}; use futures03::TryFutureExt as _; use log::{warn, error, info}; @@ -37,16 +37,15 @@ use libp2p::{PeerId, Multiaddr, kad::record}; use libp2p::core::{transport::boxed::Boxed, muxing::StreamMuxerBox}; use libp2p::swarm::NetworkBehaviour; use parking_lot::Mutex; -use peerset::PeersetHandle; -use sr_primitives::{traits::{Block as BlockT, NumberFor}, ConsensusEngineId}; +use sc_peerset::PeersetHandle; +use sp_runtime::{traits::{Block as BlockT, NumberFor}, ConsensusEngineId}; use crate::{behaviour::{Behaviour, BehaviourOut}, config::{parse_str_addr, parse_addr}}; use crate::{NetworkState, NetworkStateNotConnectedPeer, NetworkStatePeer}; -use crate::{transport, config::NonReservedPeerMode}; +use crate::{transport, config::NonReservedPeerMode, ReputationChange}; use crate::config::{Params, TransportConfig}; use crate::error::Error; -use crate::protocol::{self, Protocol, Context, CustomMessageOutcome, PeerInfo}; -use crate::protocol::consensus_gossip::{ConsensusGossip, MessageRecipient as GossipMessageRecipient}; +use crate::protocol::{self, Protocol, Context, PeerInfo}; use crate::protocol::{event::Event, light_dispatch::{AlwaysBadChecker, RequestData}}; use crate::protocol::specialization::NetworkSpecialization; use crate::protocol::sync::SyncState; @@ -71,8 +70,8 @@ pub trait TransactionPool: Send + Sync { &self, report_handle: ReportHandle, who: PeerId, - reputation_change_good: i32, - reputation_change_bad: i32, + reputation_change_good: ReputationChange, + reputation_change_bad: ReputationChange, transaction: B::Extrinsic, ); /// Notify the pool about transactions broadcast. @@ -94,7 +93,7 @@ impl From for ReportHandle { impl ReportHandle { /// Report a given peer as either beneficial (+) or costly (-) according to the /// given scalar. - pub fn report_peer(&self, who: PeerId, cost_benefit: i32) { + pub fn report_peer(&self, who: PeerId, cost_benefit: ReputationChange) { self.inner.report_peer(who, cost_benefit); } } @@ -177,7 +176,7 @@ impl, H: ExHashT> NetworkWorker } } - let peerset_config = peerset::PeersetConfig { + let peerset_config = sc_peerset::PeersetConfig { in_peers: params.network_config.in_peers, out_peers: params.network_config.out_peers, bootnodes, @@ -276,6 +275,7 @@ impl, H: ExHashT> NetworkWorker import_queue: params.import_queue, from_worker, light_client_rqs: params.on_demand.and_then(|od| od.extract_receiver()), + event_streams: Vec::new(), }) } @@ -408,6 +408,17 @@ impl, H: ExHashT> NetworkWorker .map(|(id, info)| (id.clone(), info.clone())) .collect() } + + /// Removes a `PeerId` from the list of reserved peers. + pub fn remove_reserved_peer(&self, peer: PeerId) { + self.service.remove_reserved_peer(peer); + } + + /// Adds a `PeerId` and its address as reserved. The string should encode the address + /// and peer ID of the remote node. + pub fn add_reserved_peer(&self, peer: String) -> Result<(), String> { + self.service.add_reserved_peer(peer) + } } impl, H: ExHashT> NetworkService { @@ -416,6 +427,55 @@ impl, H: ExHashT> NetworkServic self.local_peer_id.clone() } + /// Writes a message on an open notifications channel. Has no effect if the notifications + /// channel with this protocol name is closed. + /// + /// > **Note**: The reason why this is a no-op in the situation where we have no channel is + /// > that we don't guarantee message delivery anyway. Networking issues can cause + /// > connections to drop at any time, and higher-level logic shouldn't differentiate + /// > between the remote voluntarily closing a substream or a network error + /// > preventing the message from being delivered. + /// + /// The protocol must have been registered with `register_notifications_protocol`. + /// + pub fn write_notification(&self, target: PeerId, engine_id: ConsensusEngineId, message: Vec) { + let _ = self.to_worker.unbounded_send(ServerToWorkerMsg::WriteNotification { + target, + engine_id, + message, + }); + } + + /// Returns a stream containing the events that happen on the network. + /// + /// If this method is called multiple times, the events are duplicated. + /// + /// The stream never ends (unless the `NetworkWorker` gets shut down). + pub fn event_stream(&self) -> impl Stream { + // Note: when transitioning to stable futures, remove the `Error` entirely + let (tx, rx) = mpsc::unbounded(); + let _ = self.to_worker.unbounded_send(ServerToWorkerMsg::EventStream(tx)); + rx + } + + /// Registers a new notifications protocol. + /// + /// After that, you can call `write_notifications`. + /// + /// Please call `event_stream` before registering a protocol, otherwise you may miss events + /// about the protocol that you have registered. + /// + /// You are very strongly encouraged to call this method very early on. Any connection open + /// will retain the protocols that were registered then, and not any new one. + pub fn register_notifications_protocol( + &self, + engine_id: ConsensusEngineId, + ) { + let _ = self.to_worker.unbounded_send(ServerToWorkerMsg::RegisterNotifProtocol { + engine_id, + }); + } + /// You must call this when new transactons are imported by the transaction pool. /// /// The latest transactions will be fetched from the `TransactionPool` that was passed at @@ -432,27 +492,19 @@ impl, H: ExHashT> NetworkServic let _ = self.to_worker.unbounded_send(ServerToWorkerMsg::AnnounceBlock(hash, data)); } - /// Send a consensus message through the gossip - pub fn gossip_consensus_message( - &self, - topic: B::Hash, - engine_id: ConsensusEngineId, - message: Vec, - recipient: GossipMessageRecipient, - ) { - let _ = self - .to_worker - .unbounded_send(ServerToWorkerMsg::GossipConsensusMessage( - topic, engine_id, message, recipient, - )); - } - /// Report a given peer as either beneficial (+) or costly (-) according to the /// given scalar. - pub fn report_peer(&self, who: PeerId, cost_benefit: i32) { + pub fn report_peer(&self, who: PeerId, cost_benefit: ReputationChange) { self.peerset.report_peer(who, cost_benefit); } + /// Disconnect from a node as soon as possible. + /// + /// This triggers the same effects as if the connection had closed itself spontaneously. + pub fn disconnect_peer(&self, who: PeerId) { + let _ = self.to_worker.unbounded_send(ServerToWorkerMsg::DisconnectPeer(who)); + } + /// Request a justification for the given block from the network. /// /// On success, the justification will be passed to the import queue that was part at @@ -472,15 +524,6 @@ impl, H: ExHashT> NetworkServic .unbounded_send(ServerToWorkerMsg::ExecuteWithSpec(Box::new(f))); } - /// Execute a closure with the consensus gossip. - pub fn with_gossip(&self, f: F) - where F: FnOnce(&mut ConsensusGossip, &mut dyn Context) + Send + 'static - { - let _ = self - .to_worker - .unbounded_send(ServerToWorkerMsg::ExecuteWithGossip(Box::new(f))); - } - /// Are we in the process of downloading the chain? pub fn is_major_syncing(&self) -> bool { self.is_major_syncing.load(Ordering::Relaxed) @@ -521,7 +564,8 @@ impl, H: ExHashT> NetworkServic self.peerset.remove_reserved_peer(peer); } - /// Adds a `PeerId` and its address as reserved. + /// Adds a `PeerId` and its address as reserved. The string should encode the address + /// and peer ID of the remote node. pub fn add_reserved_peer(&self, peer: String) -> Result<(), String> { let (peer_id, addr) = parse_str_addr(&peer).map_err(|e| format!("{:?}", e))?; self.peerset.add_reserved_peer(peer_id.clone()); @@ -572,7 +616,7 @@ impl, H: ExHashT> NetworkServic } } -impl, H: ExHashT> consensus::SyncOracle +impl, H: ExHashT> sp_consensus::SyncOracle for NetworkService { fn is_major_syncing(&mut self) -> bool { @@ -584,7 +628,7 @@ impl, H: ExHashT> consensus::Sy } } -impl<'a, B: BlockT + 'static, S: NetworkSpecialization, H: ExHashT> consensus::SyncOracle +impl<'a, B: BlockT + 'static, S: NetworkSpecialization, H: ExHashT> sp_consensus::SyncOracle for &'a NetworkService { fn is_major_syncing(&mut self) -> bool { @@ -607,7 +651,7 @@ pub trait NetworkStateInfo { impl NetworkStateInfo for NetworkService where - B: sr_primitives::traits::Block, + B: sp_runtime::traits::Block, S: NetworkSpecialization, H: ExHashT, { @@ -630,12 +674,20 @@ enum ServerToWorkerMsg> { RequestJustification(B::Hash, NumberFor), AnnounceBlock(B::Hash, Vec), ExecuteWithSpec(Box) + Send>), - ExecuteWithGossip(Box, &mut dyn Context) + Send>), - GossipConsensusMessage(B::Hash, ConsensusEngineId, Vec, GossipMessageRecipient), GetValue(record::Key), PutValue(record::Key, Vec), AddKnownAddress(PeerId, Multiaddr), SyncFork(Vec, B::Hash, NumberFor), + EventStream(mpsc::UnboundedSender), + WriteNotification { + message: Vec, + engine_id: ConsensusEngineId, + target: PeerId, + }, + RegisterNotifProtocol { + engine_id: ConsensusEngineId, + }, + DisconnectPeer(PeerId), } /// Main network worker. Must be polled in order for the network to advance. @@ -659,13 +711,15 @@ pub struct NetworkWorker, H: Ex from_worker: mpsc::UnboundedReceiver>, /// Receiver for queries from the light client that must be processed. light_client_rqs: Option>>, + /// Senders for events that happen on the network. + event_streams: Vec>, } -impl, H: ExHashT> Stream for NetworkWorker { - type Item = Event; +impl, H: ExHashT> Future for NetworkWorker { + type Item = (); type Error = io::Error; - fn poll(&mut self) -> Poll, Self::Error> { + fn poll(&mut self) -> Poll { // Poll the import queue for actions to perform. let _ = futures03::future::poll_fn(|cx| { self.import_queue.poll_actions(cx, &mut NetworkLink { @@ -685,7 +739,7 @@ impl, H: ExHashT> Stream for Ne // Process the next message coming from the `NetworkService`. let msg = match self.from_worker.poll() { Ok(Async::Ready(Some(msg))) => msg, - Ok(Async::Ready(None)) | Err(_) => return Ok(Async::Ready(None)), + Ok(Async::Ready(None)) | Err(_) => return Ok(Async::Ready(())), Ok(Async::NotReady) => break, }; @@ -695,13 +749,6 @@ impl, H: ExHashT> Stream for Ne let (mut context, spec) = protocol.specialization_lock(); task(spec, &mut context); }, - ServerToWorkerMsg::ExecuteWithGossip(task) => { - let protocol = self.network_service.user_protocol_mut(); - let (mut context, gossip) = protocol.consensus_gossip_lock(); - task(gossip, &mut context); - } - ServerToWorkerMsg::GossipConsensusMessage(topic, engine_id, message, recipient) => - self.network_service.user_protocol_mut().gossip_consensus_message(topic, engine_id, message, recipient), ServerToWorkerMsg::AnnounceBlock(hash, data) => self.network_service.user_protocol_mut().announce_block(hash, data), ServerToWorkerMsg::RequestJustification(hash, number) => @@ -716,6 +763,18 @@ impl, H: ExHashT> Stream for Ne self.network_service.add_known_address(peer_id, addr), ServerToWorkerMsg::SyncFork(peer_ids, hash, number) => self.network_service.user_protocol_mut().set_sync_fork_request(peer_ids, &hash, number), + ServerToWorkerMsg::EventStream(sender) => + self.event_streams.push(sender), + ServerToWorkerMsg::WriteNotification { message, engine_id, target } => + self.network_service.user_protocol_mut().write_notification(target, engine_id, message), + ServerToWorkerMsg::RegisterNotifProtocol { engine_id } => { + let events = self.network_service.user_protocol_mut().register_notifications_protocol(engine_id); + for event in events { + self.event_streams.retain(|sender| sender.unbounded_send(event.clone()).is_ok()); + } + }, + ServerToWorkerMsg::DisconnectPeer(who) => + self.network_service.user_protocol_mut().disconnect_peer(&who), } } @@ -723,27 +782,23 @@ impl, H: ExHashT> Stream for Ne // Process the next action coming from the network. let poll_value = self.network_service.poll(); - let outcome = match poll_value { + match poll_value { Ok(Async::NotReady) => break, - Ok(Async::Ready(Some(BehaviourOut::SubstrateAction(outcome)))) => outcome, - Ok(Async::Ready(Some(BehaviourOut::Dht(ev)))) => - return Ok(Async::Ready(Some(Event::Dht(ev)))), - Ok(Async::Ready(None)) => CustomMessageOutcome::None, + Ok(Async::Ready(Some(BehaviourOut::BlockImport(origin, blocks)))) => + self.import_queue.import_blocks(origin, blocks), + Ok(Async::Ready(Some(BehaviourOut::JustificationImport(origin, hash, nb, justification)))) => + self.import_queue.import_justification(origin, hash, nb, justification), + Ok(Async::Ready(Some(BehaviourOut::FinalityProofImport(origin, hash, nb, proof)))) => + self.import_queue.import_finality_proof(origin, hash, nb, proof), + Ok(Async::Ready(Some(BehaviourOut::Event(ev)))) => { + self.event_streams.retain(|sender| sender.unbounded_send(ev.clone()).is_ok()); + }, + Ok(Async::Ready(None)) => {}, Err(err) => { error!(target: "sync", "Error in the network: {:?}", err); return Err(err) } }; - - match outcome { - CustomMessageOutcome::BlockImport(origin, blocks) => - self.import_queue.import_blocks(origin, blocks), - CustomMessageOutcome::JustificationImport(origin, hash, nb, justification) => - self.import_queue.import_justification(origin, hash, nb, justification), - CustomMessageOutcome::FinalityProofImport(origin, hash, nb, proof) => - self.import_queue.import_finality_proof(origin, hash, nb, proof), - CustomMessageOutcome::None => {} - } } // Update the variables shared with the `NetworkService`. @@ -786,7 +841,7 @@ impl<'a, B: BlockT, S: NetworkSpecialization, H: ExHashT> Link for Network if !success { info!("Invalid justification provided by {} for #{}", who, hash); self.protocol.user_protocol_mut().disconnect_peer(&who); - self.protocol.user_protocol_mut().report_peer(who, i32::min_value()); + self.protocol.user_protocol_mut().report_peer(who, ReputationChange::new_fatal("Invalid justification")); } } fn request_justification(&mut self, hash: &B::Hash, number: NumberFor) { @@ -806,7 +861,7 @@ impl<'a, B: BlockT, S: NetworkSpecialization, H: ExHashT> Link for Network if !success { info!("Invalid finality proof provided by {} for #{}", who, request_block.0); self.protocol.user_protocol_mut().disconnect_peer(&who); - self.protocol.user_protocol_mut().report_peer(who, i32::min_value()); + self.protocol.user_protocol_mut().report_peer(who, ReputationChange::new_fatal("Invalid finality proof")); } } } diff --git a/client/network/test/Cargo.toml b/client/network/test/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..c935843d77cdbb21ef1bf2b9b8a091bc30a457e8 --- /dev/null +++ b/client/network/test/Cargo.toml @@ -0,0 +1,30 @@ +[package] +description = "Integration tests for Substrate network protocol" +name = "sc-network-test" +version = "2.0.0" +license = "GPL-3.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +sc-network = { version = "0.8", path = "../" } +log = "0.4.8" +parking_lot = "0.9.0" +futures = "0.1.29" +futures03 = { package = "futures", version = "0.3.1", features = ["compat"] } +futures-timer = "0.4.0" +rand = "0.7.2" +libp2p = { version = "0.13.0", default-features = false, features = ["libp2p-websocket"] } +sp-consensus = { version = "0.8", path = "../../../primitives/consensus/common" } +sc-client = { version = "2.0.0", path = "../../" } +sc-client-api = { version = "2.0.0", path = "../../api" } +sp-blockchain = { version = "2.0.0", path = "../../../primitives/blockchain" } +sp-runtime = { version = "2.0.0", path = "../../../primitives/runtime" } +sp-core = { version = "2.0.0", path = "../../../primitives/core" } +sc-block-builder = { version = "2.0.0", path = "../../block-builder" } +sp-consensus-babe = { version = "0.8", path = "../../../primitives/consensus/babe" } +env_logger = "0.7.0" +substrate-test-runtime-client = { version = "2.0.0", path = "../../../test-utils/runtime/client" } +substrate-test-runtime = { version = "2.0.0", path = "../../../test-utils/runtime" } +tempfile = "3.1.0" +tokio = "0.1.22" diff --git a/client/network/src/test/block_import.rs b/client/network/test/src/block_import.rs similarity index 80% rename from client/network/src/test/block_import.rs rename to client/network/test/src/block_import.rs index 6d077dcc6bba719af33b438842bfb5969c0021ea..7ea317c2b4691cb7cd8b9a8526b3793f707be44b 100644 --- a/client/network/src/test/block_import.rs +++ b/client/network/test/src/block_import.rs @@ -16,17 +16,17 @@ //! Testing block import logic. -use consensus::ImportedAux; -use consensus::import_queue::{ +use sp_consensus::ImportedAux; +use sp_consensus::import_queue::{ import_single_block, BasicQueue, BlockImportError, BlockImportResult, IncomingBlock, }; -use test_client::{self, prelude::*}; -use test_client::runtime::{Block, Hash}; -use sr_primitives::generic::BlockId; +use substrate_test_runtime_client::{self, prelude::*}; +use substrate_test_runtime_client::runtime::{Block, Hash}; +use sp_runtime::generic::BlockId; use super::*; fn prepare_good_block() -> (TestClient, Hash, u64, PeerId, IncomingBlock) { - let client = test_client::new(); + let client = substrate_test_runtime_client::new(); let block = client.new_block(Default::default()).unwrap().bake().unwrap(); client.import(BlockOrigin::File, block).unwrap(); @@ -41,6 +41,7 @@ fn prepare_good_block() -> (TestClient, Hash, u64, PeerId, IncomingBlock) justification, origin: Some(peer_id.clone()), allow_missing_state: false, + import_existing: false, }) } @@ -51,7 +52,7 @@ fn import_single_good_block_works() { let mut expected_aux = ImportedAux::default(); expected_aux.is_new_best = true; - match import_single_block(&mut test_client::new(), BlockOrigin::File, block, &mut PassThroughVerifier(true)) { + match import_single_block(&mut substrate_test_runtime_client::new(), BlockOrigin::File, block, &mut PassThroughVerifier(true)) { Ok(BlockImportResult::ImportedUnknown(ref num, ref aux, ref org)) if *num == number && *aux == expected_aux && *org == Some(peer_id) => {} r @ _ => panic!("{:?}", r) @@ -71,7 +72,7 @@ fn import_single_good_known_block_is_ignored() { fn import_single_good_block_without_header_fails() { let (_, _, _, peer_id, mut block) = prepare_good_block(); block.header = None; - match import_single_block(&mut test_client::new(), BlockOrigin::File, block, &mut PassThroughVerifier(true)) { + match import_single_block(&mut substrate_test_runtime_client::new(), BlockOrigin::File, block, &mut PassThroughVerifier(true)) { Err(BlockImportError::IncompleteHeader(ref org)) if *org == Some(peer_id) => {} _ => panic!() } @@ -82,7 +83,7 @@ fn async_import_queue_drops() { // Perform this test multiple times since it exhibits non-deterministic behavior. for _ in 0..100 { let verifier = PassThroughVerifier(true); - let queue = BasicQueue::new(verifier, Box::new(test_client::new()), None, None); + let queue = BasicQueue::new(verifier, Box::new(substrate_test_runtime_client::new()), None, None); drop(queue); } } diff --git a/client/network/src/test/mod.rs b/client/network/test/src/lib.rs similarity index 90% rename from client/network/src/test/mod.rs rename to client/network/test/src/lib.rs index 964f27051a47da3e19f8378ec384916a56b08c6a..8e598c95a376831c8e1ea763333bcd5e241e4935 100644 --- a/client/network/src/test/mod.rs +++ b/client/network/test/src/lib.rs @@ -24,55 +24,54 @@ mod sync; use std::collections::HashMap; use std::sync::Arc; -use crate::config::build_multiaddr; +use libp2p::build_multiaddr; use log::trace; -use crate::chain::FinalityProofProvider; -use client_api::{ +use sc_network::FinalityProofProvider; +use sp_blockchain::{ + Result as ClientResult, well_known_cache_keys::{self, Id as CacheKeyId}, +}; +use sc_client_api::{ ClientInfo, BlockchainEvents, BlockImportNotification, FinalityNotifications, ImportNotifications, FinalityNotification, - error::Result as ClientResult, - well_known_cache_keys::{self, Id as CacheKeyId}, backend::{AuxStore, Backend, Finalizer} }; -use block_builder::BlockBuilder; -use client::LongestChain; -use crate::config::Roles; -use consensus::block_validation::DefaultBlockAnnounceValidator; -use consensus::import_queue::BasicQueue; -use consensus::import_queue::{ +use sc_block_builder::BlockBuilder; +use sc_client::LongestChain; +use sc_network::config::Roles; +use sp_consensus::block_validation::DefaultBlockAnnounceValidator; +use sp_consensus::import_queue::BasicQueue; +use sp_consensus::import_queue::{ BoxBlockImport, BoxJustificationImport, Verifier, BoxFinalityProofImport, }; -use consensus::block_import::{BlockImport, ImportResult}; -use consensus::Error as ConsensusError; -use consensus::{BlockOrigin, ForkChoiceStrategy, BlockImportParams, BlockCheckParams, JustificationImport}; +use sp_consensus::block_import::{BlockImport, ImportResult}; +use sp_consensus::Error as ConsensusError; +use sp_consensus::{BlockOrigin, ForkChoiceStrategy, BlockImportParams, BlockCheckParams, JustificationImport}; use futures::prelude::*; use futures03::{StreamExt as _, TryStreamExt as _}; -use crate::{NetworkWorker, NetworkService, ReportHandle, config::ProtocolId}; -use crate::config::{NetworkConfiguration, TransportConfig, BoxFinalityProofRequestBuilder}; +use sc_network::{NetworkWorker, NetworkService, ReportHandle, config::ProtocolId}; +use sc_network::config::{NetworkConfiguration, TransportConfig, BoxFinalityProofRequestBuilder}; use libp2p::PeerId; use parking_lot::Mutex; -use primitives::H256; -use crate::protocol::{Context, ProtocolConfig}; -use sr_primitives::generic::{BlockId, OpaqueDigestItemId}; -use sr_primitives::traits::{Block as BlockT, Header, NumberFor}; -use sr_primitives::Justification; -use crate::service::TransactionPool; -use crate::specialization::NetworkSpecialization; -use test_client::{self, AccountKeyring}; +use sp_core::H256; +use sc_network::{Context, ProtocolConfig}; +use sp_runtime::generic::{BlockId, OpaqueDigestItemId}; +use sp_runtime::traits::{Block as BlockT, Header, NumberFor}; +use sp_runtime::Justification; +use sc_network::TransactionPool; +use sc_network::specialization::NetworkSpecialization; +use substrate_test_runtime_client::{self, AccountKeyring}; -pub use test_client::runtime::{Block, Extrinsic, Hash, Transfer}; -pub use test_client::{TestClient, TestClientBuilder, TestClientBuilderExt}; +pub use substrate_test_runtime_client::runtime::{Block, Extrinsic, Hash, Transfer}; +pub use substrate_test_runtime_client::{TestClient, TestClientBuilder, TestClientBuilderExt}; -type AuthorityId = babe_primitives::AuthorityId; +type AuthorityId = sp_consensus_babe::AuthorityId; -#[cfg(any(test, feature = "test-helpers"))] /// A Verifier that accepts all blocks and passes them on with the configured /// finality to be imported. #[derive(Clone)] pub struct PassThroughVerifier(pub bool); -#[cfg(any(test, feature = "test-helpers"))] /// This `Verifier` accepts all data as valid. impl Verifier for PassThroughVerifier { fn verify( @@ -98,6 +97,7 @@ impl Verifier for PassThroughVerifier { auxiliary: Vec::new(), fork_choice: ForkChoiceStrategy::LongestChain, allow_missing_state: false, + import_existing: false, }, maybe_keys)) } } @@ -115,7 +115,7 @@ impl NetworkSpecialization for DummySpecialization { &mut self, _ctx: &mut dyn Context, _peer_id: PeerId, - _status: crate::message::Status + _status: sc_network::message::Status ) {} fn on_disconnect(&mut self, _ctx: &mut dyn Context, _peer_id: PeerId) {} @@ -129,14 +129,14 @@ impl NetworkSpecialization for DummySpecialization { } pub type PeersFullClient = - client::Client; + sc_client::Client; pub type PeersLightClient = - client::Client; + sc_client::Client; #[derive(Clone)] pub enum PeersClient { - Full(Arc, Arc), - Light(Arc, Arc), + Full(Arc, Arc), + Light(Arc, Arc), } impl PeersClient { @@ -218,8 +218,8 @@ pub struct Peer> { /// We keep a copy of the block_import so that we can invoke it for locally-generated blocks, /// instead of going through the import queue. block_import: Box>, - select_chain: Option>, - backend: Option>, + select_chain: Option>, + backend: Option>, network: NetworkWorker::Hash>, imported_blocks_stream: Box, Error = ()> + Send>, finality_notification_stream: Box, Error = ()> + Send>, @@ -237,7 +237,7 @@ impl> Peer { } // Returns a clone of the local SelectChain, only available on full nodes - pub fn select_chain(&self) -> Option> { + pub fn select_chain(&self) -> Option> { self.select_chain.clone() } @@ -399,8 +399,8 @@ impl TransactionPool for EmptyTransactionPool { &self, _report_handle: ReportHandle, _who: PeerId, - _rep_change_good: i32, - _rep_change_bad: i32, + _rep_change_good: sc_network::ReputationChange, + _rep_change_bad: sc_network::ReputationChange, _transaction: Extrinsic ) {} @@ -561,7 +561,7 @@ pub trait TestNetFactory: Sized { let listen_addr = build_multiaddr![Memory(rand::random::())]; - let network = NetworkWorker::new(crate::config::Params { + let network = NetworkWorker::new(sc_network::config::Params { roles: config.roles, network_config: NetworkConfiguration { listen_addresses: vec![listen_addr.clone()], @@ -608,7 +608,7 @@ pub trait TestNetFactory: Sized { let mut config = config.clone(); config.roles = Roles::LIGHT; - let (c, backend) = test_client::new_light(); + let (c, backend) = substrate_test_runtime_client::new_light(); let client = Arc::new(c); let ( block_import, @@ -635,7 +635,7 @@ pub trait TestNetFactory: Sized { let listen_addr = build_multiaddr![Memory(rand::random::())]; - let network = NetworkWorker::new(crate::config::Params { + let network = NetworkWorker::new(sc_network::config::Params { roles: config.roles, network_config: NetworkConfiguration { listen_addresses: vec![listen_addr.clone()], diff --git a/client/network/src/test/sync.rs b/client/network/test/src/sync.rs similarity index 99% rename from client/network/src/test/sync.rs rename to client/network/test/src/sync.rs index 9868bd0ed2bd9bba2c09646b94fe4eac110402d7..0160c081e3e4b8b33d433176a3bd19863152babf 100644 --- a/client/network/src/test/sync.rs +++ b/client/network/test/src/sync.rs @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use crate::config::Roles; -use consensus::BlockOrigin; +use sc_network::config::Roles; +use sp_consensus::BlockOrigin; use futures03::TryFutureExt as _; use std::time::Duration; use tokio::runtime::current_thread; diff --git a/client/offchain/Cargo.toml b/client/offchain/Cargo.toml index 0f78b6804b49d65e83f68791314fb71f8c398365..8048d10dc34fcb2ff04f2c62801288165a9e7fa9 100644 --- a/client/offchain/Cargo.toml +++ b/client/offchain/Cargo.toml @@ -1,6 +1,6 @@ [package] description = "Substrate offchain workers" -name = "substrate-offchain" +name = "sc-offchain" version = "2.0.0" license = "GPL-3.0" authors = ["Parity Technologies "] @@ -8,8 +8,8 @@ edition = "2018" [dependencies] bytes = "0.4.12" -client-api = { package = "substrate-client-api", path = "../api" } -sr-api = { path = "../../primitives/sr-api" } +sc-client-api = { version = "2.0.0", path = "../api" } +sp-api = { version = "2.0.0", path = "../../primitives/api" } fnv = "1.0.6" futures01 = { package = "futures", version = "0.1" } futures = "0.3.1" @@ -17,25 +17,26 @@ futures-timer = "2.0" log = "0.4.8" threadpool = "1.7" num_cpus = "1.10" -offchain-primitives = { package = "substrate-offchain-primitives", path = "../../primitives/offchain" } +sp-offchain = { version = "2.0.0", path = "../../primitives/offchain" } codec = { package = "parity-scale-codec", version = "1.0.0", features = ["derive"] } parking_lot = "0.9.0" -primitives = { package = "substrate-primitives", path = "../../primitives/core" } +sp-core = { version = "2.0.0", path = "../../primitives/core" } rand = "0.7.2" -sr-primitives = { path = "../../primitives/sr-primitives" } -network = { package = "substrate-network", path = "../network" } -keystore = { package = "substrate-keystore", path = "../keystore" } +sp-runtime = { version = "2.0.0", path = "../../primitives/runtime" } +sc-network = { version = "0.8", path = "../network" } +sc-keystore = { version = "2.0.0", path = "../keystore" } [target.'cfg(not(target_os = "unknown"))'.dependencies] hyper = "0.12.35" hyper-rustls = "0.17.1" [dev-dependencies] -client-db = { package = "substrate-client-db", path = "../db/", default-features = true } +sc-client-db = { version = "2.0.0", default-features = true, path = "../db/" } env_logger = "0.7.0" -test-client = { package = "substrate-test-runtime-client", path = "../../test/utils/runtime/client" } +substrate-test-runtime-client = { version = "2.0.0", path = "../../test-utils/runtime/client" } tokio = "0.1.22" -transaction_pool = { package = "substrate-transaction-pool", path = "../transaction-pool" } +sc-transaction-pool = { version = "2.0.0", path = "../../client/transaction-pool" } +sp-transaction-pool = { version = "2.0.0", path = "../../primitives/transaction-pool" } [features] default = [] diff --git a/client/offchain/src/api.rs b/client/offchain/src/api.rs index ff2a5a433a354845bc54128d9ed3f75661fa5301..4db08c145d2a402df495715e587a422b5b61e459 100644 --- a/client/offchain/src/api.rs +++ b/client/offchain/src/api.rs @@ -21,16 +21,16 @@ use std::{ thread::sleep, }; -use primitives::offchain::OffchainStorage; +use sp_core::offchain::OffchainStorage; use futures::Future; use log::error; -use network::{PeerId, Multiaddr, NetworkStateInfo}; +use sc_network::{PeerId, Multiaddr, NetworkStateInfo}; use codec::{Encode, Decode}; -use primitives::offchain::{ +use sp_core::offchain::{ Externalities as OffchainExt, HttpRequestId, Timestamp, HttpRequestStatus, HttpError, OpaqueNetworkState, OpaquePeerId, OpaqueMultiaddr, StorageKind, }; -pub use offchain_primitives::STORAGE_PREFIX; +pub use sp_offchain::STORAGE_PREFIX; #[cfg(not(target_os = "unknown"))] mod http; @@ -282,8 +282,8 @@ impl AsyncApi { mod tests { use super::*; use std::{convert::{TryFrom, TryInto}, time::SystemTime}; - use client_db::offchain::LocalStorage; - use network::PeerId; + use sc_client_db::offchain::LocalStorage; + use sc_network::PeerId; struct MockNetworkStateInfo(); @@ -331,7 +331,7 @@ mod tests { // Arrange. let now = api.timestamp(); - let delta = primitives::offchain::Duration::from_millis(100); + let delta = sp_core::offchain::Duration::from_millis(100); let deadline = now.add(delta); // Act. diff --git a/client/offchain/src/api/http.rs b/client/offchain/src/api/http.rs index 30cadf091869f446bcf234a3329872cbdec5b273..6744e1b90fae7208bbb01c82271f6f0645780ac6 100644 --- a/client/offchain/src/api/http.rs +++ b/client/offchain/src/api/http.rs @@ -30,7 +30,7 @@ use bytes::Buf as _; use fnv::FnvHashMap; use futures::{prelude::*, channel::mpsc, compat::Compat01As03}; use log::error; -use primitives::offchain::{HttpRequestId, Timestamp, HttpRequestStatus, HttpError}; +use sp_core::offchain::{HttpRequestId, Timestamp, HttpRequestStatus, HttpError}; use std::{fmt, io::Read as _, mem, pin::Pin, task::Context, task::Poll}; /// Creates a pair of [`HttpApi`] and [`HttpWorker`]. @@ -696,7 +696,7 @@ mod tests { use super::http; use futures::prelude::*; use futures01::Future as _; - use primitives::offchain::{HttpError, HttpRequestId, HttpRequestStatus, Duration}; + use sp_core::offchain::{HttpError, HttpRequestId, HttpRequestStatus, Duration}; // Returns an `HttpApi` whose worker is ran in the background, and a `SocketAddr` to an HTTP // server that runs in the background as well. diff --git a/client/offchain/src/api/http_dummy.rs b/client/offchain/src/api/http_dummy.rs index e3cb272a0d07583ac669a04d6ba6b1afb425bda3..83c3b3c80cae2db1f7220e42caa039e339e6f185 100644 --- a/client/offchain/src/api/http_dummy.rs +++ b/client/offchain/src/api/http_dummy.rs @@ -16,7 +16,7 @@ //! Contains the same API as the `http` module, except that everything returns an error. -use primitives::offchain::{HttpRequestId, Timestamp, HttpRequestStatus, HttpError}; +use sp_core::offchain::{HttpRequestId, Timestamp, HttpRequestStatus, HttpError}; use std::{future::Future, pin::Pin, task::Context, task::Poll}; /// Creates a pair of [`HttpApi`] and [`HttpWorker`]. diff --git a/client/offchain/src/api/timestamp.rs b/client/offchain/src/api/timestamp.rs index 445c7f3878474aef80646351871ea417b959ae67..8c45fce0cd40546e5c976df41eb07d3d410afe2b 100644 --- a/client/offchain/src/api/timestamp.rs +++ b/client/offchain/src/api/timestamp.rs @@ -16,7 +16,7 @@ //! Helper methods dedicated to timestamps. -use primitives::offchain::Timestamp; +use sp_core::offchain::Timestamp; use std::convert::TryInto; use std::time::{SystemTime, Duration}; diff --git a/client/offchain/src/lib.rs b/client/offchain/src/lib.rs index a1db2456bd9e731f8e40dbf4f0cf2b39288fe750..208cfdfb0fa82fec376c8da3b45527b0a4dd4f9a 100644 --- a/client/offchain/src/lib.rs +++ b/client/offchain/src/lib.rs @@ -37,16 +37,16 @@ use std::{fmt, marker::PhantomData, sync::Arc}; use parking_lot::Mutex; use threadpool::ThreadPool; -use sr_api::ApiExt; +use sp_api::ApiExt; use futures::future::Future; use log::{debug, warn}; -use network::NetworkStateInfo; -use primitives::{offchain::{self, OffchainStorage}, ExecutionContext}; -use sr_primitives::{generic::BlockId, traits::{self, ProvideRuntimeApi}}; +use sc_network::NetworkStateInfo; +use sp_core::{offchain::{self, OffchainStorage}, ExecutionContext}; +use sp_runtime::{generic::BlockId, traits::{self, ProvideRuntimeApi}}; mod api; -pub use offchain_primitives::{OffchainWorkerApi, STORAGE_PREFIX}; +pub use sp_offchain::{OffchainWorkerApi, STORAGE_PREFIX}; /// An offchain workers manager. pub struct OffchainWorkers { @@ -145,9 +145,11 @@ impl OffchainWorkers< #[cfg(test)] mod tests { use super::*; - use network::{Multiaddr, PeerId}; use std::sync::Arc; - use transaction_pool::txpool::Pool; + use sc_network::{Multiaddr, PeerId}; + use substrate_test_runtime_client::runtime::Block; + use sc_transaction_pool::{BasicPool, FullChainApi}; + use sp_transaction_pool::{TransactionPool, InPoolTransaction}; struct MockNetworkStateInfo(); @@ -161,18 +163,29 @@ mod tests { } } + struct TestPool(BasicPool, Block>); + + impl sp_transaction_pool::OffchainSubmitTransaction for TestPool { + fn submit_at( + &self, + at: &BlockId, + extrinsic: ::Extrinsic, + ) -> Result<(), ()> { + futures::executor::block_on(self.0.submit_one(&at, extrinsic)) + .map(|_| ()) + .map_err(|_| ()) + } + } + #[test] fn should_call_into_runtime_and_produce_extrinsic() { // given let _ = env_logger::try_init(); - let client = Arc::new(test_client::new()); - let pool = Arc::new(Pool::new( - Default::default(), - transaction_pool::FullChainApi::new(client.clone()) - )); + let client = Arc::new(substrate_test_runtime_client::new()); + let pool = Arc::new(TestPool(BasicPool::new(Default::default(), FullChainApi::new(client.clone())))); client.execution_extensions() .register_transaction_pool(Arc::downgrade(&pool.clone()) as _); - let db = client_db::offchain::LocalStorage::new_test(); + let db = sc_client_db::offchain::LocalStorage::new_test(); let network_state = Arc::new(MockNetworkStateInfo()); // when @@ -180,7 +193,7 @@ mod tests { futures::executor::block_on(offchain.on_block_imported(&0u64, network_state, false)); // then - assert_eq!(pool.status().ready, 1); - assert_eq!(pool.ready().next().unwrap().is_propagateable(), false); + assert_eq!(pool.0.status().ready, 1); + assert_eq!(pool.0.ready().next().unwrap().is_propagateable(), false); } } diff --git a/primitives/peerset/Cargo.toml b/client/peerset/Cargo.toml similarity index 93% rename from primitives/peerset/Cargo.toml rename to client/peerset/Cargo.toml index 16a71b5f6d6b514b368d4653811d26daf09bde19..31de04c497437c429aa4f7bb50d7aea094dc8ab1 100644 --- a/primitives/peerset/Cargo.toml +++ b/client/peerset/Cargo.toml @@ -2,7 +2,7 @@ description = "Connectivity manager based on reputation" homepage = "http://parity.io" license = "GPL-3.0" -name = "substrate-peerset" +name = "sc-peerset" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" diff --git a/primitives/peerset/src/lib.rs b/client/peerset/src/lib.rs similarity index 90% rename from primitives/peerset/src/lib.rs rename to client/peerset/src/lib.rs index a243fd00bd2b77f845d61179d8a014788ab383f6..ab7942f60d96976fff25cccd1935b97f72f89009 100644 --- a/primitives/peerset/src/lib.rs +++ b/client/peerset/src/lib.rs @@ -38,12 +38,33 @@ enum Action { AddReservedPeer(PeerId), RemoveReservedPeer(PeerId), SetReservedOnly(bool), - ReportPeer(PeerId, i32), + ReportPeer(PeerId, ReputationChange), SetPriorityGroup(String, HashSet), AddToPriorityGroup(String, PeerId), RemoveFromPriorityGroup(String, PeerId), } +/// Shared handle to the peer set manager (PSM). Distributed around the code. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct ReputationChange { + /// Reputation delta. + pub value: i32, + /// Reason for reputation change. + pub reason: &'static str, +} + +impl ReputationChange { + /// New reputation change with given delta and reason. + pub const fn new(value: i32, reason: &'static str) -> ReputationChange { + ReputationChange { value, reason } + } + + /// New reputation change that forces minimum possible reputation. + pub const fn new_fatal(reason: &'static str) -> ReputationChange { + ReputationChange { value: i32::min_value(), reason } + } +} + /// Shared handle to the peer set manager (PSM). Distributed around the code. #[derive(Debug, Clone)] pub struct PeersetHandle { @@ -75,7 +96,7 @@ impl PeersetHandle { } /// Reports an adjustment to the reputation of the given peer. - pub fn report_peer(&self, peer_id: PeerId, score_diff: i32) { + pub fn report_peer(&self, peer_id: PeerId, score_diff: ReputationChange) { let _ = self.tx.unbounded_send(Action::ReportPeer(peer_id, score_diff)); } @@ -258,20 +279,27 @@ impl Peerset { self.alloc_slots(); } - fn on_report_peer(&mut self, peer_id: PeerId, score_diff: i32) { + fn on_report_peer(&mut self, peer_id: PeerId, change: ReputationChange) { // We want reputations to be up-to-date before adjusting them. self.update_time(); match self.data.peer(&peer_id) { peersstate::Peer::Connected(mut peer) => { - peer.add_reputation(score_diff); + peer.add_reputation(change.value); if peer.reputation() < BANNED_THRESHOLD { + debug!(target: "peerset", "Report {}: {:+} to {}. Reason: {}, Disconnecting", + peer_id, change.value, peer.reputation(), change.reason + ); peer.disconnect(); self.message_queue.push_back(Message::Drop(peer_id)); + } else { + trace!(target: "peerset", "Report {}: {:+} to {}. Reason: {}", + peer_id, change.value, peer.reputation(), change.reason + ); } }, - peersstate::Peer::NotConnected(mut peer) => peer.add_reputation(score_diff), - peersstate::Peer::Unknown(peer) => peer.discover().add_reputation(score_diff), + peersstate::Peer::NotConnected(mut peer) => peer.add_reputation(change.value), + peersstate::Peer::Unknown(peer) => peer.discover().add_reputation(change.value), } } @@ -293,7 +321,7 @@ impl Peerset { // takes `ln(0.5) / ln(k)` seconds to reduce the reputation by half. Use this formula to // empirically determine a value of `k` that looks correct. for _ in 0..secs_diff { - for peer in self.data.peers().cloned().collect::>() { + for peer_id in self.data.peers().cloned().collect::>() { // We use `k = 0.98`, so we divide by `50`. With that value, it takes 34.3 seconds // to reduce the reputation by half. fn reput_tick(reput: i32) -> i32 { @@ -305,13 +333,21 @@ impl Peerset { } reput.saturating_sub(diff) } - match self.data.peer(&peer) { - peersstate::Peer::Connected(mut peer) => - peer.set_reputation(reput_tick(peer.reputation())), - peersstate::Peer::NotConnected(mut peer) => - peer.set_reputation(reput_tick(peer.reputation())), + match self.data.peer(&peer_id) { + peersstate::Peer::Connected(mut peer) => { + let before = peer.reputation(); + let after = reput_tick(before); + trace!(target: "peerset", "Fleeting {}: {} -> {}", peer_id, before, after); + peer.set_reputation(after) + } + peersstate::Peer::NotConnected(mut peer) => { + let before = peer.reputation(); + let after = reput_tick(before); + trace!(target: "peerset", "Fleeting {}: {} -> {}", peer_id, before, after); + peer.set_reputation(after) + } peersstate::Peer::Unknown(_) => unreachable!("We iterate over known peers; qed") - } + }; } } } @@ -432,7 +468,7 @@ impl Peerset { } /// Reports an adjustment to the reputation of the given peer. - pub fn report_peer(&mut self, peer_id: PeerId, score_diff: i32) { + pub fn report_peer(&mut self, peer_id: PeerId, score_diff: ReputationChange) { // We don't immediately perform the adjustments in order to have state consistency. We // don't want the reporting here to take priority over messages sent using the // `PeersetHandle`. @@ -510,7 +546,7 @@ impl Stream for Peerset { mod tests { use libp2p::PeerId; use futures::prelude::*; - use super::{PeersetConfig, Peerset, Message, IncomingIndex, BANNED_THRESHOLD}; + use super::{PeersetConfig, Peerset, Message, IncomingIndex, ReputationChange, BANNED_THRESHOLD}; use std::{pin::Pin, task::Poll, thread, time::Duration}; fn assert_messages(mut peerset: Peerset, messages: Vec) -> Peerset { @@ -620,7 +656,7 @@ mod tests { // We ban a node by setting its reputation under the threshold. let peer_id = PeerId::random(); - handle.report_peer(peer_id.clone(), BANNED_THRESHOLD - 1); + handle.report_peer(peer_id.clone(), ReputationChange::new(BANNED_THRESHOLD - 1, "")); let fut = futures::future::poll_fn(move |cx| { // We need one polling for the message to be processed. diff --git a/primitives/peerset/src/peersstate.rs b/client/peerset/src/peersstate.rs similarity index 99% rename from primitives/peerset/src/peersstate.rs rename to client/peerset/src/peersstate.rs index 57dfc50d345b0814f92ab51b80dbc821c0db1059..a1a50750f32a43a4e521be16cd4f6f094cc0bd9a 100644 --- a/primitives/peerset/src/peersstate.rs +++ b/client/peerset/src/peersstate.rs @@ -249,8 +249,8 @@ impl PeersState { /// Tries to accept the peer as an incoming connection. /// - /// If there are enough slots available, switches the node to "connected" and returns `Ok`. If - /// the slots are full, the node stays "not connected" and we return `Err`. + /// If there are enough slots available, switches the node to "connected" and returns `true`. If + /// the slots are full, the node stays "not connected" and we return `false`. /// /// Note that reserved nodes don't count towards the number of slots. fn try_accept_incoming(&mut self, peer_id: &PeerId) -> bool { diff --git a/primitives/peerset/tests/fuzz.rs b/client/peerset/tests/fuzz.rs similarity index 96% rename from primitives/peerset/tests/fuzz.rs rename to client/peerset/tests/fuzz.rs index be29916c34f2057fe37edd2496b243998b65f38d..55d8fabbad5f3b1d12dc8280bf1a99ce641a9865 100644 --- a/primitives/peerset/tests/fuzz.rs +++ b/client/peerset/tests/fuzz.rs @@ -19,7 +19,7 @@ use libp2p::PeerId; use rand::distributions::{Distribution, Uniform, WeightedIndex}; use rand::seq::IteratorRandom; use std::{collections::HashMap, collections::HashSet, iter, pin::Pin, task::Poll}; -use substrate_peerset::{IncomingIndex, Message, PeersetConfig, Peerset}; +use sc_peerset::{IncomingIndex, Message, PeersetConfig, Peerset, ReputationChange}; #[test] fn run() { @@ -97,7 +97,7 @@ fn test_once() { // If we generate 2, adjust a random reputation. 2 => if let Some(id) = known_nodes.iter().choose(&mut rng) { let val = Uniform::new_inclusive(i32::min_value(), i32::max_value()).sample(&mut rng); - peerset_handle.report_peer(id.clone(), val); + peerset_handle.report_peer(id.clone(), ReputationChange::new(val, "")); } // If we generate 3, disconnect from a random node. diff --git a/client/rpc/api/Cargo.toml b/client/rpc-api/Cargo.toml similarity index 52% rename from client/rpc/api/Cargo.toml rename to client/rpc-api/Cargo.toml index 906efeaffb9acde9f13d3e40b771cc856ca858df..2c7a2ee071d7ffc9095c53802bb011e1e0b9916a 100644 --- a/client/rpc/api/Cargo.toml +++ b/client/rpc-api/Cargo.toml @@ -1,12 +1,12 @@ [package] -name = "substrate-rpc-api" +name = "sc-rpc-api" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" [dependencies] codec = { package = "parity-scale-codec", version = "1.0.0" } -derive_more = "0.15.0" +derive_more = "0.99.2" futures = { version = "0.3.1", features = ["compat"] } jsonrpc-core = "14.0.3" jsonrpc-core-client = "14.0.3" @@ -14,9 +14,9 @@ jsonrpc-derive = "14.0.3" jsonrpc-pubsub = "14.0.3" log = "0.4.8" parking_lot = "0.9.0" -primitives = { package = "substrate-primitives", path = "../../../primitives/core" } -runtime_version = { package = "sr-version", path = "../../../primitives/sr-version" } +sp-core = { version = "2.0.0", path = "../../primitives/core" } +sp-version = { version = "2.0.0", path = "../../primitives/version" } serde = { version = "1.0.101", features = ["derive"] } serde_json = "1.0.41" -txpool = { package = "substrate-transaction-graph", path = "../../transaction-pool/graph" } -rpc-primitives = { package = "substrate-rpc-primitives", path = "../../../primitives/rpc" } +sp-transaction-pool = { version = "2.0.0", path = "../../primitives/transaction-pool" } +sp-rpc = { version = "2.0.0", path = "../../primitives/rpc" } diff --git a/client/rpc/api/src/author/error.rs b/client/rpc-api/src/author/error.rs similarity index 97% rename from client/rpc/api/src/author/error.rs rename to client/rpc-api/src/author/error.rs index 8e4f8877682b37cc036c06b41a453ae6cb08960d..b1dfcc140a622ec409f999b3c4d6253a082e062a 100644 --- a/client/rpc/api/src/author/error.rs +++ b/client/rpc-api/src/author/error.rs @@ -30,12 +30,14 @@ pub type FutureResult = Box pub enum Error { /// Client error. #[display(fmt="Client error: {}", _0)] + #[from(ignore)] Client(Box), /// Transaction pool error, #[display(fmt="Transaction pool error: {}", _0)] - Pool(txpool::error::Error), + Pool(sp_transaction_pool::error::Error), /// Verification error #[display(fmt="Extrinsic verification error: {}", _0)] + #[from(ignore)] Verification(Box), /// Incorrect extrinsic format. #[display(fmt="Invalid extrinsic format: {}", _0)] @@ -91,7 +93,7 @@ const UNSUPPORTED_KEY_TYPE: i64 = POOL_INVALID_TX + 7; impl From for rpc::Error { fn from(e: Error) -> Self { - use txpool::error::{Error as PoolError}; + use sp_transaction_pool::error::{Error as PoolError}; match e { Error::BadFormat(e) => rpc::Error { diff --git a/client/rpc/api/src/author/hash.rs b/client/rpc-api/src/author/hash.rs similarity index 97% rename from client/rpc/api/src/author/hash.rs rename to client/rpc-api/src/author/hash.rs index a01e26de3c94b27c269c6dc6e65dbc780ac5cc05..9d2f658ae6957efefc11f5900f14dd634c450d74 100644 --- a/client/rpc/api/src/author/hash.rs +++ b/client/rpc-api/src/author/hash.rs @@ -16,7 +16,7 @@ //! Extrinsic helpers for author RPC module. -use primitives::Bytes; +use sp_core::Bytes; use serde::{Serialize, Deserialize}; /// RPC Extrinsic or hash diff --git a/client/rpc/api/src/author/mod.rs b/client/rpc-api/src/author/mod.rs similarity index 90% rename from client/rpc/api/src/author/mod.rs rename to client/rpc-api/src/author/mod.rs index 4ea96cb3c6122be47da5dea671b78249ebb40b36..8d2b51faf88e9197f8e28ace98b18958d495f795 100644 --- a/client/rpc/api/src/author/mod.rs +++ b/client/rpc-api/src/author/mod.rs @@ -21,11 +21,9 @@ pub mod hash; use jsonrpc_derive::rpc; use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; -use primitives::{ - Bytes -}; +use sp_core::Bytes; +use sp_transaction_pool::TransactionStatus; use self::error::{FutureResult, Result}; -use txpool::watcher::Status; pub use self::gen_client::Client as AuthorClient; @@ -62,6 +60,9 @@ pub trait AuthorApi { ) -> Result>; /// Submit an extrinsic to watch. + /// + /// See [`TransactionStatus`](sp_transaction_pool::TransactionStatus) for details on transaction + /// lifecycle. #[pubsub( subscription = "author_extrinsicUpdate", subscribe, @@ -69,7 +70,7 @@ pub trait AuthorApi { )] fn watch_extrinsic(&self, metadata: Self::Metadata, - subscriber: Subscriber>, + subscriber: Subscriber>, bytes: Bytes ); diff --git a/client/rpc/api/src/chain/error.rs b/client/rpc-api/src/chain/error.rs similarity index 100% rename from client/rpc/api/src/chain/error.rs rename to client/rpc-api/src/chain/error.rs diff --git a/client/rpc/api/src/chain/mod.rs b/client/rpc-api/src/chain/mod.rs similarity index 87% rename from client/rpc/api/src/chain/mod.rs rename to client/rpc-api/src/chain/mod.rs index 73f4388236cc8bec6e58c61173f864be1ceaa944..f3c51d38710402af6d2b65f882e46ed2fbc60c22 100644 --- a/client/rpc/api/src/chain/mod.rs +++ b/client/rpc-api/src/chain/mod.rs @@ -22,7 +22,7 @@ use jsonrpc_core::Result as RpcResult; use jsonrpc_core::futures::Future; use jsonrpc_derive::rpc; use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; -use rpc_primitives::number; +use sp_rpc::{number::NumberOrHex, list::ListOrValue}; use self::error::{FutureResult, Result}; pub use self::gen_client::Client as ChainClient; @@ -45,7 +45,10 @@ pub trait ChainApi { /// /// By default returns latest block hash. #[rpc(name = "chain_getBlockHash", alias("chain_getHead"))] - fn block_hash(&self, hash: Option>) -> Result>; + fn block_hash( + &self, + hash: Option>>, + ) -> Result>>; /// Get hash of the last finalized block in the canon chain. #[rpc(name = "chain_getFinalizedHead", alias("chain_getFinalisedHead"))] @@ -67,7 +70,11 @@ pub trait ChainApi { name = "chain_unsubscribeNewHeads", alias("unsubscribe_newHead", "chain_unsubscribeNewHead") )] - fn unsubscribe_new_heads(&self, metadata: Option, id: SubscriptionId) -> RpcResult; + fn unsubscribe_new_heads( + &self, + metadata: Option, + id: SubscriptionId, + ) -> RpcResult; /// New head subscription #[pubsub( @@ -85,5 +92,9 @@ pub trait ChainApi { name = "chain_unsubscribeFinalizedHeads", alias("chain_unsubscribeFinalisedHeads") )] - fn unsubscribe_finalized_heads(&self, metadata: Option, id: SubscriptionId) -> RpcResult; + fn unsubscribe_finalized_heads( + &self, + metadata: Option, + id: SubscriptionId, + ) -> RpcResult; } diff --git a/client/rpc/api/src/errors.rs b/client/rpc-api/src/errors.rs similarity index 100% rename from client/rpc/api/src/errors.rs rename to client/rpc-api/src/errors.rs diff --git a/client/rpc/api/src/helpers.rs b/client/rpc-api/src/helpers.rs similarity index 100% rename from client/rpc/api/src/helpers.rs rename to client/rpc-api/src/helpers.rs diff --git a/client/rpc/api/src/lib.rs b/client/rpc-api/src/lib.rs similarity index 100% rename from client/rpc/api/src/lib.rs rename to client/rpc-api/src/lib.rs diff --git a/client/rpc/api/src/state/error.rs b/client/rpc-api/src/state/error.rs similarity index 100% rename from client/rpc/api/src/state/error.rs rename to client/rpc-api/src/state/error.rs diff --git a/client/rpc/api/src/state/mod.rs b/client/rpc-api/src/state/mod.rs similarity index 94% rename from client/rpc/api/src/state/mod.rs rename to client/rpc-api/src/state/mod.rs index 0d06092ca1659b988584536cf5af56ae24ab09ee..ecc31581c609d0c99357e5daaf01012354187078 100644 --- a/client/rpc/api/src/state/mod.rs +++ b/client/rpc-api/src/state/mod.rs @@ -22,9 +22,9 @@ use jsonrpc_core::Result as RpcResult; use jsonrpc_core::futures::Future; use jsonrpc_derive::rpc; use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; -use primitives::Bytes; -use primitives::storage::{StorageKey, StorageData, StorageChangeSet}; -use runtime_version::RuntimeVersion; +use sp_core::Bytes; +use sp_core::storage::{StorageKey, StorageData, StorageChangeSet}; +use sp_version::RuntimeVersion; use self::error::FutureResult; pub use self::gen_client::Client as StateClient; @@ -60,6 +60,8 @@ pub trait StateApi { fn child_storage_keys( &self, child_storage_key: StorageKey, + child_info: StorageKey, + child_type: u32, prefix: StorageKey, hash: Option ) -> FutureResult>; @@ -69,6 +71,8 @@ pub trait StateApi { fn child_storage( &self, child_storage_key: StorageKey, + child_info: StorageKey, + child_type: u32, key: StorageKey, hash: Option ) -> FutureResult>; @@ -78,6 +82,8 @@ pub trait StateApi { fn child_storage_hash( &self, child_storage_key: StorageKey, + child_info: StorageKey, + child_type: u32, key: StorageKey, hash: Option ) -> FutureResult>; @@ -87,6 +93,8 @@ pub trait StateApi { fn child_storage_size( &self, child_storage_key: StorageKey, + child_info: StorageKey, + child_type: u32, key: StorageKey, hash: Option ) -> FutureResult>; diff --git a/client/rpc/api/src/subscriptions.rs b/client/rpc-api/src/subscriptions.rs similarity index 100% rename from client/rpc/api/src/subscriptions.rs rename to client/rpc-api/src/subscriptions.rs diff --git a/client/rpc/api/src/system/error.rs b/client/rpc-api/src/system/error.rs similarity index 87% rename from client/rpc/api/src/system/error.rs rename to client/rpc-api/src/system/error.rs index 32b694e3ac0088611bcd85edaae1e732cda650b9..9ea2a2de0d46757bdf03c44b3883c9594fef3193 100644 --- a/client/rpc/api/src/system/error.rs +++ b/client/rpc-api/src/system/error.rs @@ -28,6 +28,8 @@ pub enum Error { /// Provided block range couldn't be resolved to a list of blocks. #[display(fmt = "Node is not fully functional: {}", _0)] NotHealthy(Health), + /// Peer argument is malformatted. + MalformattedPeerArg(String), } impl std::error::Error for Error {} @@ -43,6 +45,11 @@ impl From for rpc::Error { message: format!("{}", e), data: serde_json::to_value(h).ok(), }, + Error::MalformattedPeerArg(ref e) => rpc::Error { + code :rpc::ErrorCode::ServerError(BASE_ERROR + 2), + message: e.clone(), + data: None, + } } } } diff --git a/client/rpc/api/src/system/helpers.rs b/client/rpc-api/src/system/helpers.rs similarity index 100% rename from client/rpc/api/src/system/helpers.rs rename to client/rpc-api/src/system/helpers.rs diff --git a/client/rpc/api/src/system/mod.rs b/client/rpc-api/src/system/mod.rs similarity index 68% rename from client/rpc/api/src/system/mod.rs rename to client/rpc-api/src/system/mod.rs index f59fd84c7c027bc891cd664e5be386c44dbe2885..22c1b3bb2a837792b1e9e8c171f27a763c444a94 100644 --- a/client/rpc/api/src/system/mod.rs +++ b/client/rpc-api/src/system/mod.rs @@ -21,8 +21,9 @@ pub mod helpers; use crate::helpers::Receiver; use jsonrpc_derive::rpc; +use futures::{future::BoxFuture, compat::Compat}; -use self::error::Result; +use self::error::Result as SystemResult; pub use self::helpers::{Properties, SystemInfo, Health, PeerInfo, NodeRole}; pub use self::gen_client::Client as SystemClient; @@ -32,19 +33,19 @@ pub use self::gen_client::Client as SystemClient; pub trait SystemApi { /// Get the node's implementation name. Plain old string. #[rpc(name = "system_name")] - fn system_name(&self) -> Result; + fn system_name(&self) -> SystemResult; /// Get the node implementation's version. Should be a semver string. #[rpc(name = "system_version")] - fn system_version(&self) -> Result; + fn system_version(&self) -> SystemResult; /// Get the chain's type. Given as a string identifier. #[rpc(name = "system_chain")] - fn system_chain(&self) -> Result; + fn system_chain(&self) -> SystemResult; /// Get a custom set of properties as a JSON object, defined in the chain spec. #[rpc(name = "system_properties")] - fn system_properties(&self) -> Result; + fn system_properties(&self) -> SystemResult; /// Return health status of the node. /// @@ -65,6 +66,21 @@ pub trait SystemApi { #[rpc(name = "system_networkState", returns = "jsonrpc_core::Value")] fn system_network_state(&self) -> Receiver; + /// Adds a reserved peer. Returns the empty string or an error. The string + /// parameter should encode a `p2p` multiaddr. + /// + /// `/ip4/198.51.100.19/tcp/30333/p2p/QmSk5HQbn6LhUwDiNMseVUjuRYhEtYj4aUZ6WfWoGURpdV` + /// is an example of a valid, passing multiaddr with PeerId attached. + #[rpc(name = "system_addReservedPeer", returns = "()")] + fn system_add_reserved_peer(&self, peer: String) + -> Compat>>; + + /// Remove a reserved peer. Returns the empty string or an error. The string + /// should encode only the PeerId e.g. `QmSk5HQbn6LhUwDiNMseVUjuRYhEtYj4aUZ6WfWoGURpdV`. + #[rpc(name = "system_removeReservedPeer", returns = "()")] + fn system_remove_reserved_peer(&self, peer_id: String) + -> Compat>>; + /// Returns the roles the node is running as. #[rpc(name = "system_nodeRoles", returns = "Vec")] fn system_node_roles(&self) -> Receiver>; diff --git a/client/rpc-servers/Cargo.toml b/client/rpc-servers/Cargo.toml index c3b9802f567cf7293a845ed57fba075481ff37e7..e540274e254144f747f1d6d5d17ad23767798c42 100644 --- a/client/rpc-servers/Cargo.toml +++ b/client/rpc-servers/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "substrate-rpc-servers" +name = "sc-rpc-server" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" @@ -10,7 +10,7 @@ pubsub = { package = "jsonrpc-pubsub", version = "14.0.3" } log = "0.4.8" serde = "1.0.101" serde_json = "1.0.41" -sr-primitives = { path = "../../primitives/sr-primitives" } +sp-runtime = { version = "2.0.0", path = "../../primitives/runtime" } [target.'cfg(not(target_os = "unknown"))'.dependencies] http = { package = "jsonrpc-http-server", version = "14.0.3" } diff --git a/client/rpc/Cargo.toml b/client/rpc/Cargo.toml index f8eaac0af0cdf8b27d4d98e4344ec10c2aacef80..f4a42d169a6dc068203b23b698f22866180dd6c3 100644 --- a/client/rpc/Cargo.toml +++ b/client/rpc/Cargo.toml @@ -1,37 +1,39 @@ [package] -name = "substrate-rpc" +name = "sc-rpc" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" [dependencies] -api = { package = "substrate-rpc-api", path = "./api" } -client-api = { package = "substrate-client-api", path = "../api" } -client = { package = "substrate-client", path = "../" } -sr-api = { path = "../../primitives/sr-api" } +sc-rpc-api = { version = "2.0.0", path = "../rpc-api" } +sc-client-api = { version = "2.0.0", path = "../api" } +sc-client = { version = "2.0.0", path = "../" } +sp-api = { version = "2.0.0", path = "../../primitives/api" } codec = { package = "parity-scale-codec", version = "1.0.0" } futures = { version = "0.3.1", features = ["compat"] } jsonrpc-pubsub = "14.0.3" log = "0.4.8" -primitives = { package = "substrate-primitives", path = "../../primitives/core" } +sp-core = { version = "2.0.0", path = "../../primitives/core" } rpc = { package = "jsonrpc-core", version = "14.0.3" } -runtime_version = { package = "sr-version", path = "../../primitives/sr-version" } +sp-version = { version = "2.0.0", path = "../../primitives/version" } serde_json = "1.0.41" -session = { package = "substrate-session", path = "../../primitives/session" } -sr-primitives = { path = "../../primitives/sr-primitives" } -rpc-primitives = { package = "substrate-rpc-primitives", path = "../../primitives/rpc" } -state_machine = { package = "substrate-state-machine", path = "../../primitives/state-machine" } -substrate-executor = { path = "../executor" } -substrate-keystore = { path = "../keystore" } -transaction_pool = { package = "substrate-transaction-pool", path = "../transaction-pool" } +sp-session = { version = "2.0.0", path = "../../primitives/session" } +sp-runtime = { version = "2.0.0", path = "../../primitives/runtime" } +sp-rpc = { version = "2.0.0", path = "../../primitives/rpc" } +sp-state-machine = { version = "2.0.0", path = "../../primitives/state-machine" } +sc-executor = { version = "2.0.0", path = "../executor" } +sc-keystore = { version = "2.0.0", path = "../keystore" } +sp-transaction-pool = { version = "2.0.0", path = "../../primitives/transaction-pool" } +sp-blockchain = { version = "2.0.0", path = "../../primitives/blockchain" } hash-db = { version = "0.15.2", default-features = false } parking_lot = { version = "0.9.0" } [dev-dependencies] assert_matches = "1.3.0" futures01 = { package = "futures", version = "0.1.29" } -network = { package = "substrate-network", path = "../network" } +sc-network = { version = "0.8", path = "../network" } rustc-hex = "2.0.1" -sr-io = { path = "../../primitives/sr-io" } -test-client = { package = "substrate-test-runtime-client", path = "../../test/utils/runtime/client" } +sp-io = { version = "2.0.0", path = "../../primitives/io" } +substrate-test-runtime-client = { version = "2.0.0", path = "../../test-utils/runtime/client" } tokio = "0.1.22" +sc-transaction-pool = { version = "2.0.0", path = "../transaction-pool" } diff --git a/client/rpc/src/author/mod.rs b/client/rpc/src/author/mod.rs index 29be7b8d88222e151d5fb23eee03b089c45dfb83..1cdbda5904c852cc00b4bd6a8a8379532fd3a304 100644 --- a/client/rpc/src/author/mod.rs +++ b/client/rpc/src/author/mod.rs @@ -20,55 +20,50 @@ mod tests; use std::{sync::Arc, convert::TryInto}; -use futures::future::{FutureExt, TryFutureExt}; use log::warn; -use client::Client; -use client_api::error::Error as ClientError; +use sc_client::Client; +use sp_blockchain::Error as ClientError; use rpc::futures::{ Sink, Future, future::result, }; -use futures::{StreamExt as _, compat::Compat, future::ready}; -use api::Subscriptions; +use futures::{StreamExt as _, compat::Compat}; +use futures::future::{ready, FutureExt, TryFutureExt}; +use sc_rpc_api::Subscriptions; use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; use codec::{Encode, Decode}; -use primitives::{Bytes, Blake2Hasher, H256, traits::BareCryptoStorePtr}; -use sr_primitives::{generic, traits::{self, ProvideRuntimeApi}}; -use transaction_pool::{ - txpool::{ - ChainApi as PoolChainApi, - BlockHash, - ExHash, - IntoPoolError, - Pool, - watcher::Status, - }, +use sp_core::{Bytes, Blake2Hasher, H256, traits::BareCryptoStorePtr}; +use sp_api::ConstructRuntimeApi; +use sp_runtime::{generic, traits::{self, ProvideRuntimeApi}}; +use sp_transaction_pool::{ + TransactionPool, InPoolTransaction, TransactionStatus, + BlockHash, TxHash, TransactionFor, error::IntoPoolError, }; -use session::SessionKeys; +use sp_session::SessionKeys; /// Re-export the API for backward compatibility. -pub use api::author::*; +pub use sc_rpc_api::author::*; use self::error::{Error, FutureResult, Result}; /// Authoring API -pub struct Author where P: PoolChainApi + Sync + Send + 'static { +pub struct Author { /// Substrate client - client: Arc::Block, RA>>, + client: Arc>, /// Transactions pool - pool: Arc>, + pool: Arc

, /// Subscriptions manager subscriptions: Subscriptions, /// The key store. keystore: BareCryptoStorePtr, } -impl Author where P: PoolChainApi + Sync + Send + 'static { +impl Author { /// Create new instance of Authoring API. pub fn new( - client: Arc::Block, RA>>, - pool: Arc>, + client: Arc>, + pool: Arc

, subscriptions: Subscriptions, keystore: BareCryptoStorePtr, ) -> Self { @@ -81,16 +76,15 @@ impl Author where P: PoolChainApi + Sync + Send + 'sta } } -impl AuthorApi, BlockHash

> for Author where - B: client_api::backend::Backend<

::Block, Blake2Hasher> + Send + Sync + 'static, - E: client_api::CallExecutor<

::Block, Blake2Hasher> + Send + Sync + 'static, - P: PoolChainApi + Sync + Send + 'static, - P::Block: traits::Block, - P::Error: 'static, - RA: Send + Sync + 'static, - Client: ProvideRuntimeApi, - as ProvideRuntimeApi>::Api: - SessionKeys, +impl AuthorApi for Author where + Block: traits::Block, + B: sc_client_api::backend::Backend + Send + Sync + 'static, + E: sc_client_api::CallExecutor + Clone + Send + Sync + 'static, + P: TransactionPool + Sync + Send + 'static, + RA: ConstructRuntimeApi> + Send + Sync + 'static, + Client: ProvideRuntimeApi, + as ProvideRuntimeApi>::Api: + SessionKeys, { type Metadata = crate::metadata::Metadata; @@ -115,7 +109,7 @@ impl AuthorApi, BlockHash

> for Author whe ).map(Into::into).map_err(|e| Error::Client(Box::new(e))) } - fn submit_extrinsic(&self, ext: Bytes) -> FutureResult> { + fn submit_extrinsic(&self, ext: Bytes) -> FutureResult> { let xt = match Decode::decode(&mut &ext[..]) { Ok(xt) => xt, Err(err) => return Box::new(result(Err(err.into()))), @@ -131,13 +125,13 @@ impl AuthorApi, BlockHash

> for Author whe } fn pending_extrinsics(&self) -> Result> { - Ok(self.pool.ready().map(|tx| tx.data.encode().into()).collect()) + Ok(self.pool.ready().map(|tx| tx.data().encode().into()).collect()) } fn remove_extrinsic( &self, - bytes_or_hash: Vec>>, - ) -> Result>> { + bytes_or_hash: Vec>>, + ) -> Result>> { let hashes = bytes_or_hash.into_iter() .map(|x| match x { hash::ExtrinsicOrHash::Hash(h) => Ok(h), @@ -149,21 +143,22 @@ impl AuthorApi, BlockHash

> for Author whe .collect::>>()?; Ok( - self.pool.remove_invalid(&hashes) + self.pool + .remove_invalid(&hashes) .into_iter() - .map(|tx| tx.hash.clone()) + .map(|tx| tx.hash().clone()) .collect() ) } fn watch_extrinsic(&self, _metadata: Self::Metadata, - subscriber: Subscriber, BlockHash

>>, + subscriber: Subscriber, BlockHash

>>, xt: Bytes, ) { let submit = || -> Result<_> { let best_block_hash = self.client.info().chain.best_hash; - let dxt = <

::Block as traits::Block>::Extrinsic::decode(&mut &xt[..]) + let dxt = TransactionFor::

::decode(&mut &xt[..]) .map_err(error::Error::from)?; Ok( self.pool @@ -179,7 +174,7 @@ impl AuthorApi, BlockHash

> for Author whe let future = ready(submit()) .and_then(|res| res) // convert the watcher into a `Stream` - .map(|res| res.map(|watcher| watcher.into_stream().map(|v| Ok::<_, ()>(Ok(v))))) + .map(|res| res.map(|stream| stream.map(|v| Ok::<_, ()>(Ok(v))))) // now handle the import result, // start a new subscrition .map(move |result| match result { diff --git a/client/rpc/src/author/tests.rs b/client/rpc/src/author/tests.rs index 5ae044ff49ede78ab20adca9d9c3da1b108fd489..f672e38fa599fd084a9a284e6594530b5a403e38 100644 --- a/client/rpc/src/author/tests.rs +++ b/client/rpc/src/author/tests.rs @@ -19,19 +19,16 @@ use super::*; use std::sync::Arc; use assert_matches::assert_matches; use codec::Encode; -use primitives::{ +use sp_core::{ H256, blake2_256, hexdisplay::HexDisplay, testing::{ED25519, SR25519, KeyStore}, traits::BareCryptoStorePtr, ed25519, crypto::Pair, }; use rpc::futures::Stream as _; -use test_client::{ - self, AccountKeyring, runtime::{Extrinsic, Transfer, SessionKeys, RuntimeApi, Block}, DefaultTestClientBuilderExt, - TestClientBuilderExt, Backend, Client, Executor -}; -use transaction_pool::{ - txpool::Pool, - FullChainApi, +use substrate_test_runtime_client::{ + self, AccountKeyring, runtime::{Extrinsic, Transfer, SessionKeys, RuntimeApi, Block}, + DefaultTestClientBuilderExt, TestClientBuilderExt, Backend, Client, Executor, }; +use sc_transaction_pool::{BasicPool, FullChainApi}; use tokio::runtime; fn uxt(sender: AccountKeyring, nonce: u64) -> Extrinsic { @@ -44,18 +41,23 @@ fn uxt(sender: AccountKeyring, nonce: u64) -> Extrinsic { tx.into_signed_tx() } +type FullTransactionPool = BasicPool< + FullChainApi, Block>, + Block, +>; + struct TestSetup { pub runtime: runtime::Runtime, pub client: Arc>, pub keystore: BareCryptoStorePtr, - pub pool: Arc, Block>>>, + pub pool: Arc, } impl Default for TestSetup { fn default() -> Self { let keystore = KeyStore::new(); - let client = Arc::new(test_client::TestClientBuilder::new().set_keystore(keystore.clone()).build()); - let pool = Arc::new(Pool::new(Default::default(), FullChainApi::new(client.clone()))); + let client = Arc::new(substrate_test_runtime_client::TestClientBuilder::new().set_keystore(keystore.clone()).build()); + let pool = Arc::new(BasicPool::new(Default::default(), FullChainApi::new(client.clone()))); TestSetup { runtime: runtime::Runtime::new().expect("Failed to create runtime in test setup"), client, @@ -66,7 +68,7 @@ impl Default for TestSetup { } impl TestSetup { - fn author(&self) -> Author, Block>, RuntimeApi> { + fn author(&self) -> Author { Author { client: self.client.clone(), pool: self.pool.clone(), diff --git a/client/rpc/src/chain/chain_full.rs b/client/rpc/src/chain/chain_full.rs index 945ed19838db2d1aa7aa04e1d9227b16cd076568..f0a0b180c38997831d61cb1e20d0350916a9954d 100644 --- a/client/rpc/src/chain/chain_full.rs +++ b/client/rpc/src/chain/chain_full.rs @@ -19,11 +19,11 @@ use std::sync::Arc; use rpc::futures::future::result; -use api::Subscriptions; -use client_api::{CallExecutor, backend::Backend}; -use client::Client; -use primitives::{H256, Blake2Hasher}; -use sr_primitives::{ +use sc_rpc_api::Subscriptions; +use sc_client_api::{CallExecutor, backend::Backend}; +use sc_client::Client; +use sp_core::{H256, Blake2Hasher}; +use sp_runtime::{ generic::{BlockId, SignedBlock}, traits::{Block as BlockT}, }; diff --git a/client/rpc/src/chain/chain_light.rs b/client/rpc/src/chain/chain_light.rs index 94afc7a9d347d79d1bd7187796a512d898fd20a5..0c850153f7563d14f2d7a6ce4b1cd366253dd661 100644 --- a/client/rpc/src/chain/chain_light.rs +++ b/client/rpc/src/chain/chain_light.rs @@ -20,16 +20,16 @@ use std::sync::Arc; use futures::{future::ready, FutureExt, TryFutureExt}; use rpc::futures::future::{result, Future, Either}; -use api::Subscriptions; -use client::{ +use sc_rpc_api::Subscriptions; +use sc_client::{ self, Client, light::{ fetcher::{Fetcher, RemoteBodyRequest}, blockchain::RemoteBlockchain, }, }; -use primitives::{H256, Blake2Hasher}; -use sr_primitives::{ +use sp_core::{H256, Blake2Hasher}; +use sp_runtime::{ generic::{BlockId, SignedBlock}, traits::{Block as BlockT}, }; @@ -68,8 +68,8 @@ impl> LightChain impl ChainBackend for LightChain where Block: BlockT + 'static, - B: client_api::backend::Backend + Send + Sync + 'static, - E: client::CallExecutor + Send + Sync + 'static, + B: sc_client_api::backend::Backend + Send + Sync + 'static, + E: sc_client::CallExecutor + Send + Sync + 'static, RA: Send + Sync + 'static, F: Fetcher + Send + Sync + 'static, { @@ -85,7 +85,7 @@ impl ChainBackend for LightChain: Send + Sync + 'static where Block: BlockT + 'static, - B: client_api::backend::Backend + Send + Sync + 'static, - E: client::CallExecutor + Send + Sync + 'static, + B: sc_client_api::backend::Backend + Send + Sync + 'static, + E: sc_client::CallExecutor + Send + Sync + 'static, { /// Get client reference. fn client(&self) -> &Arc>; @@ -79,7 +79,7 @@ trait ChainBackend: Send + Sync + 'static /// By default returns latest block hash. fn block_hash( &self, - number: Option>>, + number: Option>>, ) -> Result> { Ok(match number { None => Some(self.client().info().chain.best_hash), @@ -156,8 +156,8 @@ pub fn new_full( ) -> Chain where Block: BlockT + 'static, - B: client_api::backend::Backend + Send + Sync + 'static, - E: client::CallExecutor + Send + Sync + 'static + Clone, + B: sc_client_api::backend::Backend + Send + Sync + 'static, + E: sc_client::CallExecutor + Send + Sync + 'static + Clone, RA: Send + Sync + 'static, { Chain { @@ -174,8 +174,8 @@ pub fn new_light>( ) -> Chain where Block: BlockT + 'static, - B: client_api::backend::Backend + Send + Sync + 'static, - E: client::CallExecutor + Send + Sync + 'static + Clone, + B: sc_client_api::backend::Backend + Send + Sync + 'static, + E: sc_client::CallExecutor + Send + Sync + 'static + Clone, RA: Send + Sync + 'static, F: Send + Sync + 'static, { @@ -196,8 +196,8 @@ pub struct Chain { impl ChainApi, Block::Hash, Block::Header, SignedBlock> for Chain where Block: BlockT + 'static, - B: client_api::backend::Backend + Send + Sync + 'static, - E: client::CallExecutor + Send + Sync + 'static, + B: sc_client_api::backend::Backend + Send + Sync + 'static, + E: sc_client::CallExecutor + Send + Sync + 'static, RA: Send + Sync + 'static { type Metadata = crate::metadata::Metadata; @@ -211,8 +211,19 @@ impl ChainApi, Block::Hash, Block::Header, Sig self.backend.block(hash) } - fn block_hash(&self, number: Option>>) -> Result> { - self.backend.block_hash(number) + fn block_hash( + &self, + number: Option>>> + ) -> Result>> { + match number { + None => self.backend.block_hash(None).map(ListOrValue::Value), + Some(ListOrValue::Value(number)) => self.backend.block_hash(Some(number)).map(ListOrValue::Value), + Some(ListOrValue::List(list)) => Ok(ListOrValue::List(list + .into_iter() + .map(|number| self.backend.block_hash(Some(number))) + .collect::>()? + )) + } } fn finalized_head(&self) -> Result { @@ -245,8 +256,8 @@ fn subscribe_headers( stream: F, ) where Block: BlockT + 'static, - B: client_api::backend::Backend + Send + Sync + 'static, - E: client::CallExecutor + Send + Sync + 'static, + B: sc_client_api::backend::Backend + Send + Sync + 'static, + E: sc_client::CallExecutor + Send + Sync + 'static, F: FnOnce() -> S, G: FnOnce() -> Block::Hash, ERR: ::std::fmt::Debug, @@ -277,6 +288,6 @@ fn subscribe_headers( }); } -fn client_err(err: client::error::Error) -> Error { +fn client_err(err: sp_blockchain::Error) -> Error { Error::Client(Box::new(err)) } diff --git a/client/rpc/src/chain/tests.rs b/client/rpc/src/chain/tests.rs index 8b46befee65208b61da8ca10e350436d83ee8eec..c07ea2044c608122fb183496d57fd1aedcc69851 100644 --- a/client/rpc/src/chain/tests.rs +++ b/client/rpc/src/chain/tests.rs @@ -16,18 +16,19 @@ use super::*; use assert_matches::assert_matches; -use test_client::{ +use substrate_test_runtime_client::{ prelude::*, - consensus::BlockOrigin, + sp_consensus::BlockOrigin, runtime::{H256, Block, Header}, }; +use sp_rpc::list::ListOrValue; #[test] fn should_return_header() { let core = ::tokio::runtime::Runtime::new().unwrap(); let remote = core.executor(); - let client = Arc::new(test_client::new()); + let client = Arc::new(substrate_test_runtime_client::new()); let api = new_full(client.clone(), Subscriptions::new(Arc::new(remote))); assert_matches!( @@ -63,7 +64,7 @@ fn should_return_a_block() { let core = ::tokio::runtime::Runtime::new().unwrap(); let remote = core.executor(); - let client = Arc::new(test_client::new()); + let client = Arc::new(substrate_test_runtime_client::new()); let api = new_full(client.clone(), Subscriptions::new(Arc::new(remote))); let block = client.new_block(Default::default()).unwrap().bake().unwrap(); @@ -115,39 +116,44 @@ fn should_return_block_hash() { let core = ::tokio::runtime::Runtime::new().unwrap(); let remote = core.executor(); - let client = Arc::new(test_client::new()); + let client = Arc::new(substrate_test_runtime_client::new()); let api = new_full(client.clone(), Subscriptions::new(Arc::new(remote))); assert_matches!( api.block_hash(None.into()), - Ok(Some(ref x)) if x == &client.genesis_hash() + Ok(ListOrValue::Value(Some(ref x))) if x == &client.genesis_hash() ); assert_matches!( - api.block_hash(Some(0u64.into()).into()), - Ok(Some(ref x)) if x == &client.genesis_hash() + api.block_hash(Some(ListOrValue::Value(0u64.into())).into()), + Ok(ListOrValue::Value(Some(ref x))) if x == &client.genesis_hash() ); assert_matches!( - api.block_hash(Some(1u64.into()).into()), - Ok(None) + api.block_hash(Some(ListOrValue::Value(1u64.into())).into()), + Ok(ListOrValue::Value(None)) ); let block = client.new_block(Default::default()).unwrap().bake().unwrap(); client.import(BlockOrigin::Own, block.clone()).unwrap(); assert_matches!( - api.block_hash(Some(0u64.into()).into()), - Ok(Some(ref x)) if x == &client.genesis_hash() + api.block_hash(Some(ListOrValue::Value(0u64.into())).into()), + Ok(ListOrValue::Value(Some(ref x))) if x == &client.genesis_hash() + ); + assert_matches!( + api.block_hash(Some(ListOrValue::Value(1u64.into())).into()), + Ok(ListOrValue::Value(Some(ref x))) if x == &block.hash() ); assert_matches!( - api.block_hash(Some(1u64.into()).into()), - Ok(Some(ref x)) if x == &block.hash() + api.block_hash(Some(ListOrValue::Value(sp_core::U256::from(1u64).into())).into()), + Ok(ListOrValue::Value(Some(ref x))) if x == &block.hash() ); + assert_matches!( - api.block_hash(Some(::primitives::U256::from(1u64).into()).into()), - Ok(Some(ref x)) if x == &block.hash() + api.block_hash(Some(vec![0u64.into(), 1.into(), 2.into()].into())), + Ok(ListOrValue::List(list)) if list == &[client.genesis_hash().into(), block.hash().into(), None] ); } @@ -157,7 +163,7 @@ fn should_return_finalized_hash() { let core = ::tokio::runtime::Runtime::new().unwrap(); let remote = core.executor(); - let client = Arc::new(test_client::new()); + let client = Arc::new(substrate_test_runtime_client::new()); let api = new_full(client.clone(), Subscriptions::new(Arc::new(remote))); assert_matches!( @@ -189,7 +195,7 @@ fn should_notify_about_latest_block() { let (subscriber, id, transport) = Subscriber::new_test("test"); { - let client = Arc::new(test_client::new()); + let client = Arc::new(substrate_test_runtime_client::new()); let api = new_full(client.clone(), Subscriptions::new(Arc::new(remote))); api.subscribe_new_heads(Default::default(), subscriber); @@ -218,7 +224,7 @@ fn should_notify_about_finalized_block() { let (subscriber, id, transport) = Subscriber::new_test("test"); { - let client = Arc::new(test_client::new()); + let client = Arc::new(substrate_test_runtime_client::new()); let api = new_full(client.clone(), Subscriptions::new(Arc::new(remote))); api.subscribe_finalized_heads(Default::default(), subscriber); diff --git a/client/rpc/src/lib.rs b/client/rpc/src/lib.rs index 1341acb63d3537e49d48ace6b363172dc09da2f6..748a78f1310d520a9d488e308caf24ee07bd1121 100644 --- a/client/rpc/src/lib.rs +++ b/client/rpc/src/lib.rs @@ -22,7 +22,7 @@ mod metadata; -pub use api::Subscriptions; +pub use sc_rpc_api::Subscriptions; pub use self::metadata::Metadata; pub use rpc::IoHandlerExtension as RpcExtension; diff --git a/client/rpc/src/state/mod.rs b/client/rpc/src/state/mod.rs index 8e15c488070fd3aa8682b706eed062e23fea4302..f0dce859324d58cd0cb699c2c9757c039aa8b01a 100644 --- a/client/rpc/src/state/mod.rs +++ b/client/rpc/src/state/mod.rs @@ -26,29 +26,29 @@ use std::sync::Arc; use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; use rpc::{Result as RpcResult, futures::Future}; -use api::Subscriptions; -use client::{Client, CallExecutor, light::{blockchain::RemoteBlockchain, fetcher::Fetcher}}; -use primitives::{ +use sc_rpc_api::Subscriptions; +use sc_client::{Client, CallExecutor, light::{blockchain::RemoteBlockchain, fetcher::Fetcher}}; +use sp_core::{ Blake2Hasher, Bytes, H256, storage::{StorageKey, StorageData, StorageChangeSet}, }; -use runtime_version::RuntimeVersion; -use sr_primitives::{ +use sp_version::RuntimeVersion; +use sp_runtime::{ traits::{Block as BlockT, ProvideRuntimeApi}, }; -use sr_api::Metadata; +use sp_api::Metadata; use self::error::{Error, FutureResult}; -pub use api::state::*; +pub use sc_rpc_api::state::*; /// State backend API. pub trait StateBackend: Send + Sync + 'static where Block: BlockT + 'static, - B: client_api::backend::Backend + Send + Sync + 'static, - E: client::CallExecutor + Send + Sync + 'static, + B: sc_client_api::backend::Backend + Send + Sync + 'static, + E: sc_client::CallExecutor + Send + Sync + 'static, RA: Send + Sync + 'static, { /// Call runtime method at given block. @@ -95,6 +95,8 @@ pub trait StateBackend: Send + Sync + 'static &self, block: Option, child_storage_key: StorageKey, + child_info: StorageKey, + child_type: u32, prefix: StorageKey, ) -> FutureResult>; @@ -103,6 +105,8 @@ pub trait StateBackend: Send + Sync + 'static &self, block: Option, child_storage_key: StorageKey, + child_info: StorageKey, + child_type: u32, key: StorageKey, ) -> FutureResult>; @@ -111,6 +115,8 @@ pub trait StateBackend: Send + Sync + 'static &self, block: Option, child_storage_key: StorageKey, + child_info: StorageKey, + child_type: u32, key: StorageKey, ) -> FutureResult>; @@ -119,9 +125,11 @@ pub trait StateBackend: Send + Sync + 'static &self, block: Option, child_storage_key: StorageKey, + child_info: StorageKey, + child_type: u32, key: StorageKey, ) -> FutureResult> { - Box::new(self.child_storage(block, child_storage_key, key) + Box::new(self.child_storage(block, child_storage_key, child_info, child_type, key) .map(|x| x.map(|x| x.0.len() as u64))) } @@ -179,12 +187,12 @@ pub fn new_full( ) -> State where Block: BlockT + 'static, - B: client_api::backend::Backend + Send + Sync + 'static, + B: sc_client_api::backend::Backend + Send + Sync + 'static, E: CallExecutor + Send + Sync + 'static + Clone, RA: Send + Sync + 'static, Client: ProvideRuntimeApi, as ProvideRuntimeApi>::Api: - Metadata, + Metadata, { State { backend: Box::new(self::state_full::FullState::new(client, subscriptions)), @@ -200,7 +208,7 @@ pub fn new_light>( ) -> State where Block: BlockT + 'static, - B: client_api::backend::Backend + Send + Sync + 'static, + B: sc_client_api::backend::Backend + Send + Sync + 'static, E: CallExecutor + Send + Sync + 'static + Clone, RA: Send + Sync + 'static, F: Send + Sync + 'static, @@ -223,7 +231,7 @@ pub struct State { impl StateApi for State where Block: BlockT + 'static, - B: client_api::backend::Backend + Send + Sync + 'static, + B: sc_client_api::backend::Backend + Send + Sync + 'static, E: CallExecutor + Send + Sync + 'static + Clone, RA: Send + Sync + 'static, { @@ -256,37 +264,45 @@ impl StateApi for State fn child_storage( &self, child_storage_key: StorageKey, + child_info: StorageKey, + child_type: u32, key: StorageKey, block: Option ) -> FutureResult> { - self.backend.child_storage(block, child_storage_key, key) + self.backend.child_storage(block, child_storage_key, child_info, child_type, key) } fn child_storage_keys( &self, child_storage_key: StorageKey, + child_info: StorageKey, + child_type: u32, key_prefix: StorageKey, block: Option ) -> FutureResult> { - self.backend.child_storage_keys(block, child_storage_key, key_prefix) + self.backend.child_storage_keys(block, child_storage_key, child_info, child_type, key_prefix) } fn child_storage_hash( &self, child_storage_key: StorageKey, + child_info: StorageKey, + child_type: u32, key: StorageKey, block: Option ) -> FutureResult> { - self.backend.child_storage_hash(block, child_storage_key, key) + self.backend.child_storage_hash(block, child_storage_key, child_info, child_type, key) } fn child_storage_size( &self, child_storage_key: StorageKey, + child_info: StorageKey, + child_type: u32, key: StorageKey, block: Option ) -> FutureResult> { - self.backend.child_storage_size(block, child_storage_key, key) + self.backend.child_storage_size(block, child_storage_key, child_info, child_type, key) } fn metadata(&self, block: Option) -> FutureResult { @@ -332,6 +348,12 @@ impl StateApi for State } } -fn client_err(err: client::error::Error) -> Error { +fn client_err(err: sp_blockchain::Error) -> Error { Error::Client(Box::new(err)) } + +const CHILD_RESOLUTION_ERROR: &str = "Unexpected child info and type"; + +fn child_resolution_error() -> sp_blockchain::Error { + sp_blockchain::Error::Msg(CHILD_RESOLUTION_ERROR.to_string()) +} diff --git a/client/rpc/src/state/state_full.rs b/client/rpc/src/state/state_full.rs index dcb876c846d85d5fbc44495df1871a57e87530e9..05bb64c36fabb3195c4bdf891eaafbae78473c22 100644 --- a/client/rpc/src/state/state_full.rs +++ b/client/rpc/src/state/state_full.rs @@ -27,24 +27,28 @@ use rpc::{ futures::{stream, Future, Sink, Stream, future::result}, }; -use api::Subscriptions; -use client_api::{backend::Backend, error::Result as ClientResult}; -use client::{ - Client, CallExecutor, BlockchainEvents, +use sc_rpc_api::Subscriptions; +use sc_client_api::backend::Backend; +use sp_blockchain::{ + Result as ClientResult, Error as ClientError, HeaderMetadata, CachedHeaderMetadata }; -use primitives::{ - H256, Blake2Hasher, Bytes, storage::{well_known_keys, StorageKey, StorageData, StorageChangeSet}, +use sc_client::{ + Client, CallExecutor, BlockchainEvents, }; -use runtime_version::RuntimeVersion; -use state_machine::ExecutionStrategy; -use sr_primitives::{ +use sp_core::{ + H256, Blake2Hasher, Bytes, + storage::{well_known_keys, StorageKey, StorageData, StorageChangeSet, ChildInfo}, +}; +use sp_version::RuntimeVersion; +use sp_state_machine::ExecutionStrategy; +use sp_runtime::{ generic::BlockId, - traits::{Block as BlockT, Header, NumberFor, ProvideRuntimeApi, SaturatedConversion}, + traits::{Block as BlockT, NumberFor, ProvideRuntimeApi, SaturatedConversion}, }; -use sr_api::Metadata; +use sp_api::Metadata; -use super::{StateBackend, error::{FutureResult, Error, Result}, client_err}; +use super::{StateBackend, error::{FutureResult, Error, Result}, client_err, child_resolution_error}; /// Ranges to query in state_queryStorage. struct QueryStorageRange { @@ -90,59 +94,49 @@ impl FullState from: Block::Hash, to: Option ) -> Result> { - let to = self.block_or_best(to).map_err(client_err)?; - let from_hdr = self.client.header(&BlockId::hash(from)).map_err(client_err)?; - let to_hdr = self.client.header(&BlockId::hash(to)).map_err(client_err)?; - match (from_hdr, to_hdr) { - (Some(ref from), Some(ref to)) if from.number() <= to.number() => { - // check if we can get from `to` to `from` by going through parent_hashes. - let from_number = *from.number(); - let blocks = { - let mut blocks = vec![to.hash()]; - let mut last = to.clone(); - while *last.number() > from_number { - let hdr = self.client - .header(&BlockId::hash(*last.parent_hash())) - .map_err(client_err)?; - if let Some(hdr) = hdr { - blocks.push(hdr.hash()); - last = hdr; - } else { - return Err(invalid_block_range( - Some(from), - Some(to), - format!("Parent of {} ({}) not found", last.number(), last.hash()), - )) - } - } - if last.hash() != from.hash() { - return Err(invalid_block_range( - Some(from), - Some(to), - format!("Expected to reach `from`, got {} ({})", last.number(), last.hash()), - )) - } - blocks.reverse(); - blocks - }; - // check if we can filter blocks-with-changes from some (sub)range using changes tries - let changes_trie_range = self.client - .max_key_changes_range(from_number, BlockId::Hash(to.hash())) - .map_err(client_err)?; - let filtered_range_begin = changes_trie_range - .map(|(begin, _)| (begin - from_number).saturated_into::()); - let (unfiltered_range, filtered_range) = split_range(blocks.len(), filtered_range_begin); - Ok(QueryStorageRange { - hashes: blocks, - first_number: from_number, - unfiltered_range, - filtered_range, - }) - }, - (from, to) => Err( - invalid_block_range(from.as_ref(), to.as_ref(), "Invalid range or unknown block".into()) - ), + let to = self.block_or_best(to).map_err(|e| invalid_block::(from, to, e.to_string()))?; + + let invalid_block_err = |e: ClientError| invalid_block::(from, Some(to), e.to_string()); + let from_meta = self.client.header_metadata(from).map_err(invalid_block_err)?; + let to_meta = self.client.header_metadata(to).map_err(invalid_block_err)?; + + if from_meta.number >= to_meta.number { + return Err(invalid_block_range(&from_meta, &to_meta, "from number >= to number".to_owned())) } + + // check if we can get from `to` to `from` by going through parent_hashes. + let from_number = from_meta.number; + let hashes = { + let mut hashes = vec![to_meta.hash]; + let mut last = to_meta.clone(); + while last.number > from_number { + let header_metadata = self.client + .header_metadata(last.parent) + .map_err(|e| invalid_block_range::(&last, &to_meta, e.to_string()))?; + hashes.push(header_metadata.hash); + last = header_metadata; + } + if last.hash != from_meta.hash { + return Err(invalid_block_range(&from_meta, &to_meta, "from and to are on different forks".to_owned())) + } + hashes.reverse(); + hashes + }; + + // check if we can filter blocks-with-changes from some (sub)range using changes tries + let changes_trie_range = self.client + .max_key_changes_range(from_number, BlockId::Hash(to_meta.hash)) + .map_err(client_err)?; + let filtered_range_begin = changes_trie_range + .map(|(begin, _)| (begin - from_number).saturated_into::()); + let (unfiltered_range, filtered_range) = split_range(hashes.len(), filtered_range_begin); + + Ok(QueryStorageRange { + hashes, + first_number: from_number, + unfiltered_range, + filtered_range, + }) } /// Iterates through range.unfiltered_range and check each block for changes of keys' values. @@ -232,7 +226,7 @@ impl StateBackend for FullState: ProvideRuntimeApi, as ProvideRuntimeApi>::Api: - Metadata, + Metadata, { fn call( &self, @@ -294,11 +288,19 @@ impl StateBackend for FullState, child_storage_key: StorageKey, + child_info: StorageKey, + child_type: u32, prefix: StorageKey, ) -> FutureResult> { Box::new(result( self.block_or_best(block) - .and_then(|block| self.client.child_storage_keys(&BlockId::Hash(block), &child_storage_key, &prefix)) + .and_then(|block| self.client.child_storage_keys( + &BlockId::Hash(block), + &child_storage_key, + ChildInfo::resolve_child_info(child_type, &child_info.0[..]) + .ok_or_else(child_resolution_error)?, + &prefix, + )) .map_err(client_err))) } @@ -306,11 +308,19 @@ impl StateBackend for FullState, child_storage_key: StorageKey, + child_info: StorageKey, + child_type: u32, key: StorageKey, ) -> FutureResult> { Box::new(result( self.block_or_best(block) - .and_then(|block| self.client.child_storage(&BlockId::Hash(block), &child_storage_key, &key)) + .and_then(|block| self.client.child_storage( + &BlockId::Hash(block), + &child_storage_key, + ChildInfo::resolve_child_info(child_type, &child_info.0[..]) + .ok_or_else(child_resolution_error)?, + &key, + )) .map_err(client_err))) } @@ -318,11 +328,19 @@ impl StateBackend for FullState, child_storage_key: StorageKey, + child_info: StorageKey, + child_type: u32, key: StorageKey, ) -> FutureResult> { Box::new(result( self.block_or_best(block) - .and_then(|block| self.client.child_storage_hash(&BlockId::Hash(block), &child_storage_key, &key)) + .and_then(|block| self.client.child_storage_hash( + &BlockId::Hash(block), + &child_storage_key, + ChildInfo::resolve_child_info(child_type, &child_info.0[..]) + .ok_or_else(child_resolution_error)?, + &key, + )) .map_err(client_err))) } @@ -500,15 +518,28 @@ pub(crate) fn split_range(size: usize, middle: Option) -> (Range, (range1, range2) } -fn invalid_block_range(from: Option<&H>, to: Option<&H>, reason: String) -> Error { - let to_string = |x: Option<&H>| match x { - None => "unknown hash".into(), - Some(h) => format!("{} ({})", h.number(), h.hash()), - }; +fn invalid_block_range( + from: &CachedHeaderMetadata, + to: &CachedHeaderMetadata, + details: String, +) -> Error { + let to_string = |h: &CachedHeaderMetadata| format!("{} ({:?})", h.number, h.hash); Error::InvalidBlockRange { from: to_string(from), to: to_string(to), - details: reason, + details, + } +} + +fn invalid_block( + from: B::Hash, + to: Option, + details: String, +) -> Error { + Error::InvalidBlockRange { + from: format!("{:?}", from), + to: format!("{:?}", to), + details, } } diff --git a/client/rpc/src/state/state_light.rs b/client/rpc/src/state/state_light.rs index c3155ef4a93ba9b2aabd2f29b903fe19d211778c..a00ce729459a92d4f9a91e155d171d16c60491fd 100644 --- a/client/rpc/src/state/state_light.rs +++ b/client/rpc/src/state/state_light.rs @@ -38,22 +38,22 @@ use rpc::{ futures::stream::Stream, }; -use api::Subscriptions; -use client_api::backend::Backend; -use client::{ - BlockchainEvents, Client, CallExecutor, - error::Error as ClientError, +use sc_rpc_api::Subscriptions; +use sc_client_api::backend::Backend; +use sp_blockchain::Error as ClientError; +use sc_client::{ + BlockchainEvents, Client, CallExecutor, light::{ blockchain::{future_header, RemoteBlockchain}, fetcher::{Fetcher, RemoteCallRequest, RemoteReadRequest, RemoteReadChildRequest}, }, }; -use primitives::{ +use sp_core::{ H256, Blake2Hasher, Bytes, OpaqueMetadata, storage::{StorageKey, StorageData, StorageChangeSet}, }; -use runtime_version::RuntimeVersion; -use sr_primitives::{ +use sp_version::RuntimeVersion; +use sp_runtime::{ generic::BlockId, traits::Block as BlockT, }; @@ -236,6 +236,8 @@ impl StateBackend for LightState, _child_storage_key: StorageKey, + _child_info: StorageKey, + _child_type: u32, _prefix: StorageKey, ) -> FutureResult> { Box::new(result(Err(client_err(ClientError::NotAvailableOnLightClient)))) @@ -245,6 +247,8 @@ impl StateBackend for LightState, child_storage_key: StorageKey, + child_info: StorageKey, + child_type: u32, key: StorageKey, ) -> FutureResult> { let block = self.block_or_best(block); @@ -255,6 +259,8 @@ impl StateBackend for LightState StateBackend for LightState, child_storage_key: StorageKey, + child_info: StorageKey, + child_type: u32, key: StorageKey, ) -> FutureResult> { Box::new(self - .child_storage(block, child_storage_key, key) + .child_storage(block, child_storage_key, child_info, child_type, key) .and_then(|maybe_storage| result(Ok(maybe_storage.map(|storage| Blake2Hasher::hash(&storage.0)))) ) @@ -547,7 +555,8 @@ fn runtime_version>( Bytes(Vec::new()), ) .then(|version| ready(version.and_then(|version| - Decode::decode(&mut &version.0[..]).map_err(|_| client_err(ClientError::VersionInvalid)) + Decode::decode(&mut &version.0[..]) + .map_err(|e| client_err(ClientError::VersionInvalid(e.what().into()))) ))) } @@ -696,13 +705,13 @@ fn ignore_error(future: F) -> impl std::future::Future Ok(Some(result)), Err(()) => Ok(None), - })) + })) } #[cfg(test)] mod tests { use rpc::futures::stream::futures_ordered; - use test_client::runtime::Block; + use substrate_test_runtime_client::runtime::Block; use super::*; #[test] diff --git a/client/rpc/src/state/tests.rs b/client/rpc/src/state/tests.rs index f6658b272a4266fb3fac875fe646f45e68fb0265..78275840beecc8966d24db525f701d01db1bf10e 100644 --- a/client/rpc/src/state/tests.rs +++ b/client/rpc/src/state/tests.rs @@ -21,14 +21,17 @@ use self::error::Error; use std::sync::Arc; use assert_matches::assert_matches; use futures01::stream::Stream; -use primitives::storage::well_known_keys; -use sr_io::hashing::blake2_256; -use test_client::{ +use sp_core::storage::{well_known_keys, ChildInfo}; +use sp_core::hash::H256; +use sp_io::hashing::blake2_256; +use substrate_test_runtime_client::{ prelude::*, - consensus::BlockOrigin, + sp_consensus::BlockOrigin, runtime, }; +const CHILD_INFO: ChildInfo<'static> = ChildInfo::new_default(b"unique_id"); + #[test] fn should_return_storage() { const KEY: &[u8] = b":mock"; @@ -39,12 +42,14 @@ fn should_return_storage() { let mut core = tokio::runtime::Runtime::new().unwrap(); let client = TestClientBuilder::new() .add_extra_storage(KEY.to_vec(), VALUE.to_vec()) - .add_extra_child_storage(STORAGE_KEY.to_vec(), KEY.to_vec(), CHILD_VALUE.to_vec()) + .add_extra_child_storage(STORAGE_KEY.to_vec(), CHILD_INFO, KEY.to_vec(), CHILD_VALUE.to_vec()) .build(); let genesis_hash = client.genesis_hash(); let client = new_full(Arc::new(client), Subscriptions::new(Arc::new(core.executor()))); let key = StorageKey(KEY.to_vec()); let storage_key = StorageKey(STORAGE_KEY.to_vec()); + let (child_info, child_type) = CHILD_INFO.info(); + let child_info = StorageKey(child_info.to_vec()); assert_eq!( client.storage(key.clone(), Some(genesis_hash).into()).wait() @@ -62,7 +67,7 @@ fn should_return_storage() { ); assert_eq!( core.block_on( - client.child_storage(storage_key, key, Some(genesis_hash).into()) + client.child_storage(storage_key, child_info, child_type, key, Some(genesis_hash).into()) .map(|x| x.map(|x| x.0.len())) ).unwrap().unwrap() as usize, CHILD_VALUE.len(), @@ -72,27 +77,48 @@ fn should_return_storage() { #[test] fn should_return_child_storage() { + let (child_info, child_type) = CHILD_INFO.info(); + let child_info = StorageKey(child_info.to_vec()); let core = tokio::runtime::Runtime::new().unwrap(); - let client = Arc::new(test_client::TestClientBuilder::new() - .add_child_storage("test", "key", vec![42_u8]) + let client = Arc::new(substrate_test_runtime_client::TestClientBuilder::new() + .add_child_storage("test", "key", CHILD_INFO, vec![42_u8]) .build()); let genesis_hash = client.genesis_hash(); let client = new_full(client, Subscriptions::new(Arc::new(core.executor()))); - let child_key = StorageKey(well_known_keys::CHILD_STORAGE_KEY_PREFIX.iter().chain(b"test").cloned().collect()); + let child_key = StorageKey( + well_known_keys::CHILD_STORAGE_KEY_PREFIX.iter().chain(b"test").cloned().collect() + ); let key = StorageKey(b"key".to_vec()); assert_matches!( - client.child_storage(child_key.clone(), key.clone(), Some(genesis_hash).into()).wait(), + client.child_storage( + child_key.clone(), + child_info.clone(), + child_type, + key.clone(), + Some(genesis_hash).into(), + ).wait(), Ok(Some(StorageData(ref d))) if d[0] == 42 && d.len() == 1 ); assert_matches!( - client.child_storage_hash(child_key.clone(), key.clone(), Some(genesis_hash).into()) - .wait().map(|x| x.is_some()), + client.child_storage_hash( + child_key.clone(), + child_info.clone(), + child_type, + key.clone(), + Some(genesis_hash).into(), + ).wait().map(|x| x.is_some()), Ok(true) ); assert_matches!( - client.child_storage_size(child_key.clone(), key.clone(), None).wait(), + client.child_storage_size( + child_key.clone(), + child_info.clone(), + child_type, + key.clone(), + None, + ).wait(), Ok(Some(1)) ); } @@ -100,7 +126,7 @@ fn should_return_child_storage() { #[test] fn should_call_contract() { let core = tokio::runtime::Runtime::new().unwrap(); - let client = Arc::new(test_client::new()); + let client = Arc::new(substrate_test_runtime_client::new()); let genesis_hash = client.genesis_hash(); let client = new_full(client, Subscriptions::new(Arc::new(core.executor()))); @@ -117,7 +143,7 @@ fn should_notify_about_storage_changes() { let (subscriber, id, transport) = Subscriber::new_test("test"); { - let client = Arc::new(test_client::new()); + let client = Arc::new(substrate_test_runtime_client::new()); let api = new_full(client.clone(), Subscriptions::new(Arc::new(remote))); api.subscribe_storage(Default::default(), subscriber, None.into()); @@ -149,7 +175,7 @@ fn should_send_initial_storage_changes_and_notifications() { let (subscriber, id, transport) = Subscriber::new_test("test"); { - let client = Arc::new(test_client::new()); + let client = Arc::new(substrate_test_runtime_client::new()); let api = new_full(client.clone(), Subscriptions::new(Arc::new(remote))); let alice_balance_key = blake2_256(&runtime::system::balance_of_key(AccountKeyring::Alice.into())); @@ -255,9 +281,101 @@ fn should_query_storage() { ], }); assert_eq!(result.wait().unwrap(), expected); + + // Query changes up to block2. + let result = api.query_storage( + keys.clone(), + genesis_hash, + Some(block2_hash), + ); + + assert_eq!(result.wait().unwrap(), expected); + + // Inverted range. + let result = api.query_storage( + keys.clone(), + block1_hash, + Some(genesis_hash), + ); + + assert_eq!( + result.wait().map_err(|e| e.to_string()), + Err(Error::InvalidBlockRange { + from: format!("1 ({:?})", block1_hash), + to: format!("0 ({:?})", genesis_hash), + details: "from number >= to number".to_owned(), + }).map_err(|e| e.to_string()) + ); + + let random_hash1 = H256::random(); + let random_hash2 = H256::random(); + + // Invalid second hash. + let result = api.query_storage( + keys.clone(), + genesis_hash, + Some(random_hash1), + ); + + assert_eq!( + result.wait().map_err(|e| e.to_string()), + Err(Error::InvalidBlockRange { + from: format!("{:?}", genesis_hash), + to: format!("{:?}", Some(random_hash1)), + details: format!("UnknownBlock: header not found in db: {}", random_hash1), + }).map_err(|e| e.to_string()) + ); + + // Invalid first hash with Some other hash. + let result = api.query_storage( + keys.clone(), + random_hash1, + Some(genesis_hash), + ); + + assert_eq!( + result.wait().map_err(|e| e.to_string()), + Err(Error::InvalidBlockRange { + from: format!("{:?}", random_hash1), + to: format!("{:?}", Some(genesis_hash)), + details: format!("UnknownBlock: header not found in db: {}", random_hash1), + }).map_err(|e| e.to_string()), + ); + + // Invalid first hash with None. + let result = api.query_storage( + keys.clone(), + random_hash1, + None, + ); + + assert_eq!( + result.wait().map_err(|e| e.to_string()), + Err(Error::InvalidBlockRange { + from: format!("{:?}", random_hash1), + to: format!("{:?}", Some(block2_hash)), // Best block hash. + details: format!("UnknownBlock: header not found in db: {}", random_hash1), + }).map_err(|e| e.to_string()), + ); + + // Both hashes invalid. + let result = api.query_storage( + keys.clone(), + random_hash1, + Some(random_hash2), + ); + + assert_eq!( + result.wait().map_err(|e| e.to_string()), + Err(Error::InvalidBlockRange { + from: format!("{:?}", random_hash1), // First hash not found. + to: format!("{:?}", Some(random_hash2)), + details: format!("UnknownBlock: header not found in db: {}", random_hash1), + }).map_err(|e| e.to_string()), + ); } - run_tests(Arc::new(test_client::new())); + run_tests(Arc::new(substrate_test_runtime_client::new())); run_tests(Arc::new(TestClientBuilder::new().set_support_changes_trie(true).build())); } @@ -275,7 +393,7 @@ fn should_split_ranges() { fn should_return_runtime_version() { let core = tokio::runtime::Runtime::new().unwrap(); - let client = Arc::new(test_client::new()); + let client = Arc::new(substrate_test_runtime_client::new()); let api = new_full(client.clone(), Subscriptions::new(Arc::new(core.executor()))); let result = "{\"specName\":\"test\",\"implName\":\"parity-test\",\"authoringVersion\":1,\ @@ -298,7 +416,7 @@ fn should_notify_on_runtime_version_initially() { let (subscriber, id, transport) = Subscriber::new_test("test"); { - let client = Arc::new(test_client::new()); + let client = Arc::new(substrate_test_runtime_client::new()); let api = new_full(client.clone(), Subscriptions::new(Arc::new(core.executor()))); api.subscribe_runtime_version(Default::default(), subscriber); diff --git a/client/rpc/src/system/mod.rs b/client/rpc/src/system/mod.rs index 88d29386655286c7cb54bafc6c88739c9190bd5d..b6048291aa0f3e0812443ab0779c6425fc6406da 100644 --- a/client/rpc/src/system/mod.rs +++ b/client/rpc/src/system/mod.rs @@ -19,12 +19,14 @@ #[cfg(test)] mod tests; +use futures::{future::BoxFuture, FutureExt, TryFutureExt}; use futures::{channel::{mpsc, oneshot}, compat::Compat}; -use api::Receiver; -use sr_primitives::traits::{self, Header as HeaderT}; +use sc_rpc_api::Receiver; +use sp_runtime::traits::{self, Header as HeaderT}; + use self::error::Result; -pub use api::system::*; +pub use sc_rpc_api::system::*; pub use self::helpers::{Properties, SystemInfo, Health, PeerInfo, NodeRole}; pub use self::gen_client::Client as SystemClient; @@ -42,6 +44,10 @@ pub enum Request { Peers(oneshot::Sender::Number>>>), /// Must return the state of the network. NetworkState(oneshot::Sender), + /// Must return any potential parse error. + NetworkAddReservedPeer(String, oneshot::Sender>), + /// Must return any potential parse error. + NetworkRemoveReservedPeer(String, oneshot::Sender>), /// Must return the node role. NodeRoles(oneshot::Sender>) } @@ -53,7 +59,7 @@ impl System { /// reading from that channel and answering the requests. pub fn new( info: SystemInfo, - send_back: mpsc::UnboundedSender> + send_back: mpsc::UnboundedSender>, ) -> Self { System { info, @@ -97,6 +103,34 @@ impl SystemApi::Number> for Sy Receiver(Compat::new(rx)) } + fn system_add_reserved_peer(&self, peer: String) + -> Compat>> + { + let (tx, rx) = oneshot::channel(); + let _ = self.send_back.unbounded_send(Request::NetworkAddReservedPeer(peer, tx)); + async move { + match rx.await { + Ok(Ok(())) => Ok(()), + Ok(Err(e)) => Err(rpc::Error::from(e)), + Err(_) => Err(rpc::Error::internal_error()), + } + }.boxed().compat() + } + + fn system_remove_reserved_peer(&self, peer: String) + -> Compat>> + { + let (tx, rx) = oneshot::channel(); + let _ = self.send_back.unbounded_send(Request::NetworkRemoveReservedPeer(peer, tx)); + async move { + match rx.await { + Ok(Ok(())) => Ok(()), + Ok(Err(e)) => Err(rpc::Error::from(e)), + Err(_) => Err(rpc::Error::internal_error()), + } + }.boxed().compat() + } + fn system_node_roles(&self) -> Receiver> { let (tx, rx) = oneshot::channel(); let _ = self.send_back.unbounded_send(Request::NodeRoles(tx)); diff --git a/client/rpc/src/system/tests.rs b/client/rpc/src/system/tests.rs index b4b3e67cee878b23e16027bfe65f76d4df518a62..f69882cf3848932da48e99a1188329ff3f4a0892 100644 --- a/client/rpc/src/system/tests.rs +++ b/client/rpc/src/system/tests.rs @@ -16,9 +16,9 @@ use super::*; -use network::{self, PeerId}; -use network::config::Roles; -use test_client::runtime::Block; +use sc_network::{self, PeerId}; +use sc_network::config::Roles; +use substrate_test_runtime_client::runtime::Block; use assert_matches::assert_matches; use futures::{prelude::*, channel::mpsc}; use std::thread; @@ -69,7 +69,7 @@ fn api>>(sync: T) -> System { let _ = sender.send(peers); } Request::NetworkState(sender) => { - let _ = sender.send(serde_json::to_value(&network::NetworkState { + let _ = sender.send(serde_json::to_value(&sc_network::NetworkState { peer_id: String::new(), listened_addresses: Default::default(), external_addresses: Default::default(), @@ -80,6 +80,18 @@ fn api>>(sync: T) -> System { peerset: serde_json::Value::Null, }).unwrap()); }, + Request::NetworkAddReservedPeer(peer, sender) => { + let _ = match sc_network::config::parse_str_addr(&peer) { + Ok(_) => sender.send(Ok(())), + Err(s) => sender.send(Err(error::Error::MalformattedPeerArg(s.to_string()))), + }; + }, + Request::NetworkRemoveReservedPeer(peer, sender) => { + let _ = match peer.parse::() { + Ok(_) => sender.send(Ok(())), + Err(s) => sender.send(Err(error::Error::MalformattedPeerArg(s.to_string()))), + }; + } Request::NodeRoles(sender) => { let _ = sender.send(vec![NodeRole::Authority]); } @@ -211,8 +223,8 @@ fn system_peers() { fn system_network_state() { let res = wait_receiver(api(None).system_network_state()); assert_eq!( - serde_json::from_value::(res).unwrap(), - network::NetworkState { + serde_json::from_value::(res).unwrap(), + sc_network::NetworkState { peer_id: String::new(), listened_addresses: Default::default(), external_addresses: Default::default(), @@ -232,3 +244,27 @@ fn system_node_roles() { vec![NodeRole::Authority] ); } + +#[test] +fn system_network_add_reserved() { + let good_peer_id = "/ip4/198.51.100.19/tcp/30333/p2p/QmSk5HQbn6LhUwDiNMseVUjuRYhEtYj4aUZ6WfWoGURpdV"; + let bad_peer_id = "/ip4/198.51.100.19/tcp/30333"; + let mut runtime = tokio::runtime::current_thread::Runtime::new().unwrap(); + + let good_fut = api(None).system_add_reserved_peer(good_peer_id.into()); + let bad_fut = api(None).system_add_reserved_peer(bad_peer_id.into()); + assert_eq!(runtime.block_on(good_fut), Ok(())); + assert!(runtime.block_on(bad_fut).is_err()); +} + +#[test] +fn system_network_remove_reserved() { + let good_peer_id = "QmSk5HQbn6LhUwDiNMseVUjuRYhEtYj4aUZ6WfWoGURpdV"; + let bad_peer_id = "/ip4/198.51.100.19/tcp/30333/p2p/QmSk5HQbn6LhUwDiNMseVUjuRYhEtYj4aUZ6WfWoGURpdV"; + let mut runtime = tokio::runtime::current_thread::Runtime::new().unwrap(); + + let good_fut = api(None).system_remove_reserved_peer(good_peer_id.into()); + let bad_fut = api(None).system_remove_reserved_peer(bad_peer_id.into()); + assert_eq!(runtime.block_on(good_fut), Ok(())); + assert!(runtime.block_on(bad_fut).is_err()); +} diff --git a/client/service/Cargo.toml b/client/service/Cargo.toml index 81f6aabbe0bc753a28a38e8c00523b54b6e02716..ce27b0995c5efe78a11828fdaf28cb8d6f44e939 100644 --- a/client/service/Cargo.toml +++ b/client/service/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "substrate-service" +name = "sc-service" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" @@ -8,13 +8,13 @@ edition = "2018" default = ["rocksdb"] # The RocksDB feature activates the RocksDB database backend. If it is not activated, and you pass # a path to a database, an error will be produced at runtime. -rocksdb = ["client_db/kvdb-rocksdb"] +rocksdb = ["sc-client-db/kvdb-rocksdb"] wasmtime = [ - "substrate-executor/wasmtime", + "sc-executor/wasmtime", ] [dependencies] -derive_more = "0.15.0" +derive_more = "0.99.2" futures = "0.1.29" futures03 = { package = "futures", version = "0.3.1", features = ["compat"] } parking_lot = "0.9.0" @@ -23,43 +23,41 @@ log = "0.4.8" slog = { version = "2.5.2", features = ["nested-values"] } tokio-executor = "0.1.8" tokio-timer = "0.2.11" -exit-future = "0.1.4" +exit-future = "0.2.0" serde = "1.0.101" serde_json = "1.0.41" sysinfo = "0.9.5" target_info = "0.1.0" -keystore = { package = "substrate-keystore", path = "../keystore" } -sr-io = { path = "../../primitives/sr-io" } -sr-primitives = { path = "../../primitives/sr-primitives" } -primitives = { package = "substrate-primitives", path = "../../primitives/core" } -session = { package = "substrate-session", path = "../../primitives/session" } -app-crypto = { package = "substrate-application-crypto", path = "../../primitives/application-crypto" } -consensus_common = { package = "substrate-consensus-common", path = "../../primitives/consensus/common" } -network = { package = "substrate-network", path = "../network" } -chain-spec = { package = "substrate-chain-spec", path = "../chain-spec" } -client-api = { package = "substrate-client-api", path = "../api" } -client = { package = "substrate-client", path = "../" } -sr-api = { path = "../../primitives/sr-api" } -tx-pool-api = { package = "substrate-transaction-pool-runtime-api", path = "../../primitives/transaction-pool/runtime-api" } -client_db = { package = "substrate-client-db", path = "../db" } +sc-keystore = { version = "2.0.0", path = "../keystore" } +sp-io = { version = "2.0.0", path = "../../primitives/io" } +sp-runtime = { version = "2.0.0", path = "../../primitives/runtime" } +sp-blockchain = { version = "2.0.0", path = "../../primitives/blockchain" } +sp-core = { version = "2.0.0", path = "../../primitives/core" } +sp-session = { version = "2.0.0", path = "../../primitives/session" } +sp-application-crypto = { version = "2.0.0", path = "../../primitives/application-crypto" } +sp-consensus = { version = "0.8", path = "../../primitives/consensus/common" } +sc-network = { version = "0.8", path = "../network" } +sc-chain-spec = { version = "2.0.0", path = "../chain-spec" } +sc-client-api = { version = "2.0.0", path = "../api" } +sc-client = { version = "2.0.0", path = "../" } +sp-api = { version = "2.0.0", path = "../../primitives/api" } +sc-client-db = { version = "2.0.0", path = "../db" } codec = { package = "parity-scale-codec", version = "1.0.0" } -substrate-executor = { path = "../executor" } -transaction_pool = { package = "substrate-transaction-pool", path = "../transaction-pool" } -rpc-servers = { package = "substrate-rpc-servers", path = "../rpc-servers" } -rpc = { package = "substrate-rpc", path = "../rpc" } -tel = { package = "substrate-telemetry", path = "../telemetry" } -offchain = { package = "substrate-offchain", path = "../offchain" } +sc-executor = { version = "2.0.0", path = "../executor" } +sc-transaction-pool = { version = "2.0.0", path = "../transaction-pool" } +sp-transaction-pool = { version = "2.0.0", path = "../../primitives/transaction-pool" } +sc-rpc-server = { version = "2.0.0", path = "../rpc-servers" } +sc-rpc = { version = "2.0.0", path = "../rpc" } +sc-telemetry = { version = "2.0.0", path = "../telemetry" } +sc-offchain = { version = "2.0.0", path = "../offchain" } parity-multiaddr = { package = "parity-multiaddr", version = "0.5.0" } -grafana-data-source = { path = "../grafana-data-source" } -substrate-tracing = { package = "substrate-tracing", path = "../tracing" } +grafana-data-source = { version = "2.0.0", path = "../../utils/grafana-data-source" } +sc-tracing = { version = "2.0.0", path = "../tracing" } tracing = "0.1.10" [dev-dependencies] -substrate-test-runtime-client = { path = "../../test/utils/runtime/client" } -node-executor = { path = "../../bin/node/executor" } -node-primitives = { path = "../../bin/node/primitives" } -node-runtime = { path = "../../bin/node/runtime" } -babe-primitives = { package = "substrate-consensus-babe-primitives", path = "../../primitives/consensus/babe" } -grandpa = { package = "substrate-finality-grandpa", path = "../finality-grandpa" } -grandpa-primitives = { package = "substrate-finality-grandpa-primitives", path = "../../primitives/finality-grandpa" } +substrate-test-runtime-client = { version = "2.0.0", path = "../../test-utils/runtime/client" } +sp-consensus-babe = { version = "0.8", path = "../../primitives/consensus/babe" } +grandpa = { version = "2.0.0", package = "sc-finality-grandpa", path = "../finality-grandpa" } +grandpa-primitives = { version = "2.0.0", package = "sp-finality-grandpa", path = "../../primitives/finality-grandpa" } tokio = "0.1" diff --git a/client/service/src/builder.rs b/client/service/src/builder.rs index 049dc5d92e897236e992425acc745f7b58b81472..713b873ff94e34eb17152aee4507b7921ee8c068 100644 --- a/client/service/src/builder.rs +++ b/client/service/src/builder.rs @@ -14,46 +14,46 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use crate::{Service, NetworkStatus, NetworkState, error::{self, Error}, DEFAULT_PROTOCOL_ID}; +use crate::{Service, NetworkStatus, NetworkState, error::Error, DEFAULT_PROTOCOL_ID}; use crate::{SpawnTaskHandle, start_rpc_servers, build_network_future, TransactionPoolAdapter}; use crate::status_sinks; use crate::config::{Configuration, DatabaseConfig}; -use client_api::{ +use sc_client_api::{ self, BlockchainEvents, backend::RemoteBackend, light::RemoteBlockchain, }; -use client::Client; -use chain_spec::{RuntimeGenesis, Extension}; -use codec::{Decode, Encode, IoReader}; -use consensus_common::import_queue::ImportQueue; +use sc_client::Client; +use sc_chain_spec::{RuntimeGenesis, Extension}; +use sp_consensus::import_queue::ImportQueue; use futures::{prelude::*, sync::mpsc}; use futures03::{ - compat::{Compat, Future01CompatExt}, - future::ready, + compat::Compat, FutureExt as _, TryFutureExt as _, StreamExt as _, TryStreamExt as _, future::{select, Either} }; -use keystore::{Store as Keystore}; +use sc_keystore::{Store as Keystore}; use log::{info, warn, error}; -use network::{FinalityProofProvider, OnDemand, NetworkService, NetworkStateInfo, DhtEvent}; -use network::{config::BoxFinalityProofRequestBuilder, specialization::NetworkSpecialization}; +use sc_network::{FinalityProofProvider, OnDemand, NetworkService, NetworkStateInfo, DhtEvent}; +use sc_network::{config::BoxFinalityProofRequestBuilder, specialization::NetworkSpecialization}; use parking_lot::{Mutex, RwLock}; -use primitives::{Blake2Hasher, H256, Hasher}; -use rpc; -use sr_primitives::generic::BlockId; -use sr_primitives::traits::{ - Block as BlockT, Extrinsic, ProvideRuntimeApi, NumberFor, One, Zero, Header, SaturatedConversion +use sp_core::{Blake2Hasher, H256, Hasher}; +use sc_rpc; +use sp_api::ConstructRuntimeApi; +use sp_runtime::generic::BlockId; +use sp_runtime::traits::{ + Block as BlockT, ProvideRuntimeApi, NumberFor, Header, SaturatedConversion, }; -use substrate_executor::{NativeExecutor, NativeExecutionDispatch}; +use sc_executor::{NativeExecutor, NativeExecutionDispatch}; use std::{ io::{Read, Write, Seek}, - marker::PhantomData, sync::Arc, sync::atomic::AtomicBool, time::SystemTime + marker::PhantomData, sync::Arc, time::SystemTime }; use sysinfo::{get_current_pid, ProcessExt, System, SystemExt}; -use tel::{telemetry, SUBSTRATE_INFO}; -use transaction_pool::txpool::{self, ChainApi, Pool as TransactionPool}; +use sc_telemetry::{telemetry, SUBSTRATE_INFO}; +use sp_transaction_pool::{TransactionPool, TransactionPoolMaintainer}; +use sp_blockchain; use grafana_data_source::{self, record_metrics}; /// Aggregator for the components required to build a service. @@ -78,12 +78,12 @@ pub struct ServiceBuilder { config: Configuration, - client: Arc, + pub (crate) client: Arc, backend: Arc, keystore: Arc>, fetcher: Option, select_chain: Option, - import_queue: TImpQu, + pub (crate) import_queue: TImpQu, finality_proof_request_builder: Option, finality_proof_provider: Option, network_protocol: TNetP, @@ -103,11 +103,11 @@ type TFullClient = Client< >; /// Full client backend type. -type TFullBackend = client_db::Backend; +type TFullBackend = sc_client_db::Backend; /// Full client call executor type. -type TFullCallExecutor = client::LocalCallExecutor< - client_db::Backend, +type TFullCallExecutor = sc_client::LocalCallExecutor< + sc_client_db::Backend, NativeExecutor, >; @@ -120,20 +120,20 @@ type TLightClient = Client< >; /// Light client backend type. -type TLightBackend = client::light::backend::Backend< - client_db::light::LightStorage, +type TLightBackend = sc_client::light::backend::Backend< + sc_client_db::light::LightStorage, Blake2Hasher, >; /// Light call executor type. -type TLightCallExecutor = client::light::call_executor::GenesisCallExecutor< - client::light::backend::Backend< - client_db::light::LightStorage, +type TLightCallExecutor = sc_client::light::call_executor::GenesisCallExecutor< + sc_client::light::backend::Backend< + sc_client_db::light::LightStorage, Blake2Hasher >, - client::LocalCallExecutor< - client::light::backend::Backend< - client_db::light::LightStorage, + sc_client::LocalCallExecutor< + sc_client::light::backend::Backend< + sc_client_db::light::LightStorage, Blake2Hasher >, NativeExecutor @@ -174,33 +174,33 @@ where TGen: RuntimeGenesis, TCSExt: Extension { let fork_blocks = config.chain_spec .extensions() - .get::>() + .get::>() .cloned() .unwrap_or_default(); let (client, backend) = { - let db_config = client_db::DatabaseSettings { + let db_config = sc_client_db::DatabaseSettings { state_cache_size: config.state_cache_size, state_cache_child_ratio: config.state_cache_child_ratio.map(|v| (v, 100)), pruning: config.pruning.clone(), source: match &config.database { DatabaseConfig::Path { path, cache_size } => - client_db::DatabaseSettingsSrc::Path { + sc_client_db::DatabaseSettingsSrc::Path { path: path.clone(), cache_size: cache_size.clone().map(|u| u as usize), }, DatabaseConfig::Custom(db) => - client_db::DatabaseSettingsSrc::Custom(db.clone()), + sc_client_db::DatabaseSettingsSrc::Custom(db.clone()), }, }; - let extensions = client_api::execution_extensions::ExecutionExtensions::new( + let extensions = sc_client_api::execution_extensions::ExecutionExtensions::new( config.execution_strategies.clone(), Some(keystore.clone()), ); - client_db::new_client( + sc_client_db::new_client( db_config, executor, &config.chain_spec, @@ -261,29 +261,29 @@ where TGen: RuntimeGenesis, TCSExt: Extension { ); let db_storage = { - let db_settings = client_db::DatabaseSettings { + let db_settings = sc_client_db::DatabaseSettings { state_cache_size: config.state_cache_size, state_cache_child_ratio: config.state_cache_child_ratio.map(|v| (v, 100)), pruning: config.pruning.clone(), source: match &config.database { DatabaseConfig::Path { path, cache_size } => - client_db::DatabaseSettingsSrc::Path { + sc_client_db::DatabaseSettingsSrc::Path { path: path.clone(), cache_size: cache_size.clone().map(|u| u as usize), }, DatabaseConfig::Custom(db) => - client_db::DatabaseSettingsSrc::Custom(db.clone()), + sc_client_db::DatabaseSettingsSrc::Custom(db.clone()), }, }; - client_db::light::LightStorage::new(db_settings)? + sc_client_db::light::LightStorage::new(db_settings)? }; - let light_blockchain = client::light::new_light_blockchain(db_storage); - let fetch_checker = Arc::new(client::light::new_fetch_checker(light_blockchain.clone(), executor.clone())); - let fetcher = Arc::new(network::OnDemand::new(fetch_checker)); - let backend = client::light::new_light_backend(light_blockchain); + let light_blockchain = sc_client::light::new_light_blockchain(db_storage); + let fetch_checker = Arc::new(sc_client::light::new_fetch_checker(light_blockchain.clone(), executor.clone())); + let fetcher = Arc::new(sc_network::OnDemand::new(fetch_checker)); + let backend = sc_client::light::new_light_backend(light_blockchain); let remote_blockchain = backend.remote_blockchain(); - let client = Arc::new(client::light::new_light( + let client = Arc::new(sc_client::light::new_light( backend.clone(), &config.chain_spec, executor, @@ -294,7 +294,7 @@ where TGen: RuntimeGenesis, TCSExt: Extension { client, backend, keystore, - fetcher: Some(fetcher), + fetcher: Some(fetcher.clone()), select_chain: None, import_queue: (), finality_proof_request_builder: None, @@ -558,10 +558,19 @@ impl( self, - transaction_pool_builder: impl FnOnce(transaction_pool::txpool::Options, Arc) -> Result + transaction_pool_builder: impl FnOnce( + sc_transaction_pool::txpool::Options, + Arc, + Option, + ) -> Result ) -> Result, Error> { - let transaction_pool = transaction_pool_builder(self.config.transaction_pool.clone(), self.client.clone())?; + TNetP, UExPool, TRpc, Backend>, Error> + where TSc: Clone, TFchr: Clone { + let transaction_pool = transaction_pool_builder( + self.config.transaction_pool.clone(), + self.client.clone(), + self.fetcher.clone(), + )?; Ok(ServiceBuilder { config: self.config, @@ -585,10 +594,23 @@ impl( self, - rpc_ext_builder: impl FnOnce(Arc, Arc, Arc) -> URpc + rpc_ext_builder: impl FnOnce( + Arc, + Arc, + Arc, + Option, + Option>>, + ) -> Result, ) -> Result, Error> { - let rpc_extensions = rpc_ext_builder(self.client.clone(), self.transaction_pool.clone(), self.backend.clone()); + TNetP, TExPool, URpc, Backend>, Error> + where TSc: Clone, TFchr: Clone { + let rpc_extensions = rpc_ext_builder( + self.client.clone(), + self.transaction_pool.clone(), + self.backend.clone(), + self.fetcher.clone(), + self.remote_backend.clone(), + )?; Ok(ServiceBuilder { config: self.config, @@ -636,21 +658,17 @@ impl Box + Send>; -} - -/// Implemented on `ServiceBuilder`. Allows exporting blocks once you have given all the required -/// components to the builder. -pub trait ServiceBuilderExport { - /// Type of block of the builder. - type Block: BlockT; /// Performs the blocks export. fn export_blocks( @@ -660,88 +678,21 @@ pub trait ServiceBuilderExport { to: Option>, json: bool ) -> Box>; -} - -/// Implemented on `ServiceBuilder`. Allows reverting the chain once you have given all the -/// required components to the builder. -pub trait ServiceBuilderRevert { - /// Type of block of the builder. - type Block: BlockT; - /// Performs a revert of `blocks` bocks. + /// Performs a revert of `blocks` blocks. fn revert_chain( &self, blocks: NumberFor ) -> Result<(), Error>; -} - -impl< - TBl, TRtApi, TCfg, TGen, TCSExt, TBackend, - TExec, TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, - TExPool, TRpc, Backend -> ServiceBuilderImport for ServiceBuilder< - TBl, TRtApi, TCfg, TGen, TCSExt, Client, - TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPool, TRpc, Backend -> where - TBl: BlockT::Out>, - TBackend: 'static + client_api::backend::Backend + Send, - TExec: 'static + client::CallExecutor + Send + Sync + Clone, - TImpQu: 'static + ImportQueue, - TRtApi: 'static + Send + Sync, -{ - fn import_blocks( - self, - input: impl Read + Seek + Send + 'static, - ) -> Box + Send> { - let client = self.client; - let mut queue = self.import_queue; - Box::new(import_blocks!(TBl, client, queue, input).compat()) - } -} - -impl - ServiceBuilderExport for ServiceBuilder, - TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPool, TRpc, TBackend> -where - TBl: BlockT::Out>, - TBackend: 'static + client_api::backend::Backend + Send, - TExec: 'static + client::CallExecutor + Send + Sync + Clone, - TRtApi: 'static + Send + Sync, -{ - type Block = TBl; - fn export_blocks( + /// Re-validate known block. + fn check_block( self, - mut output: impl Write + 'static, - from: NumberFor, - to: Option>, - json: bool - ) -> Box> { - let client = self.client; - Box::new(export_blocks!(client, output, from, to, json).compat()) - } -} - -impl - ServiceBuilderRevert for ServiceBuilder, - TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPool, TRpc, TBackend> -where - TBl: BlockT::Out>, - TBackend: 'static + client_api::backend::Backend + Send, - TExec: 'static + client::CallExecutor + Send + Sync + Clone -{ - type Block = TBl; - - fn revert_chain( - &self, - blocks: NumberFor - ) -> Result<(), Error> { - let client = &self.client; - revert_chain!(client, blocks) - } + block: BlockId + ) -> Box + Send>; } -impl +impl ServiceBuilder< TBl, TRtApi, @@ -755,29 +706,31 @@ ServiceBuilder< BoxFinalityProofRequestBuilder, Arc>, TNetP, - TransactionPool, + TExPool, TRpc, TBackend, > where Client: ProvideRuntimeApi, as ProvideRuntimeApi>::Api: - sr_api::Metadata + - offchain::OffchainWorkerApi + - tx_pool_api::TaggedTransactionQueue + - session::SessionKeys + - sr_api::ApiExt, + sp_api::Metadata + + sc_offchain::OffchainWorkerApi + + sp_transaction_pool::runtime_api::TaggedTransactionQueue + + sp_session::SessionKeys + + sp_api::ApiExt, TBl: BlockT::Out>, - TRtApi: 'static + Send + Sync, + TRtApi: ConstructRuntimeApi> + 'static + Send + Sync, TCfg: Default, TGen: RuntimeGenesis, TCSExt: Extension, - TBackend: 'static + client_api::backend::Backend + Send, - TExec: 'static + client::CallExecutor + Send + Sync + Clone, + TBackend: 'static + sc_client_api::backend::Backend + Send, + TExec: 'static + sc_client::CallExecutor + Send + Sync + Clone, TSc: Clone, TImpQu: 'static + ImportQueue, TNetP: NetworkSpecialization, - TExPoolApi: 'static + ChainApi::Hash>, - TRpc: rpc::RpcExtension + Clone, + TExPool: 'static + + TransactionPool::Hash> + + TransactionPoolMaintainer::Hash>, + TRpc: sc_rpc::RpcExtension + Clone, { /// Builds the service. pub fn build(self) -> Result, NetworkService::Hash>, - TransactionPool, - offchain::OffchainWorkers< + TExPool, + sc_offchain::OffchainWorkers< Client, TBackend::OffchainStorage, TBl @@ -811,7 +764,7 @@ ServiceBuilder< dht_event_tx, } = self; - session::generate_initial_session_keys( + sp_session::generate_initial_session_keys( client.clone(), &BlockId::Hash(client.info().chain.best_hash), config.dev_key_seed.clone().map(|s| vec![s]).unwrap_or_default(), @@ -823,6 +776,9 @@ ServiceBuilder< let (to_spawn_tx, to_spawn_rx) = mpsc::unbounded:: + Send>>(); + // A side-channel for essential tasks to communicate shutdown. + let (essential_failed_tx, essential_failed_rx) = mpsc::unbounded(); + let import_queue = Box::new(import_queue); let chain_info = client.info().chain; @@ -856,13 +812,13 @@ ServiceBuilder< DEFAULT_PROTOCOL_ID } }.as_bytes(); - network::config::ProtocolId::from(protocol_id_full) + sc_network::config::ProtocolId::from(protocol_id_full) }; let block_announce_validator = - Box::new(consensus_common::block_validation::DefaultBlockAnnounceValidator::new(client.clone())); + Box::new(sp_consensus::block_validation::DefaultBlockAnnounceValidator::new(client.clone())); - let network_params = network::config::Params { + let network_params = sc_network::config::Params { roles: config.roles, network_config: config.network.clone(), chain: client.clone(), @@ -877,14 +833,14 @@ ServiceBuilder< }; let has_bootnodes = !network_params.network_config.boot_nodes.is_empty(); - let network_mut = network::NetworkWorker::new(network_params)?; + let network_mut = sc_network::NetworkWorker::new(network_params)?; let network = network_mut.service().clone(); let network_status_sinks = Arc::new(Mutex::new(status_sinks::StatusSinks::new())); let offchain_storage = backend.offchain_storage(); let offchain_workers = match (config.offchain_worker, offchain_storage) { (true, Some(db)) => { - Some(Arc::new(offchain::OffchainWorkers::new(client.clone(), db))) + Some(Arc::new(sc_offchain::OffchainWorkers::new(client.clone(), db))) }, (true, None) => { log::warn!("Offchain workers disabled, due to lack of offchain storage support in backend."); @@ -896,7 +852,6 @@ ServiceBuilder< { // block notifications let txpool = Arc::downgrade(&transaction_pool); - let wclient = Arc::downgrade(&client); let offchain = offchain_workers.as_ref().map(Arc::downgrade); let to_spawn_tx_ = to_spawn_tx.clone(); let network_state_info: Arc = network.clone(); @@ -908,14 +863,12 @@ ServiceBuilder< let number = *notification.header.number(); let txpool = txpool.upgrade(); - if let (Some(txpool), Some(client)) = (txpool.as_ref(), wclient.upgrade()) { - let future = maintain_transaction_pool( + if let Some(txpool) = txpool.as_ref() { + let future = txpool.maintain( &BlockId::hash(notification.hash), - &client, - &*txpool, ¬ification.retracted, - ).map_err(|e| warn!("Pool error processing new block: {:?}", e))?; - let _ = to_spawn_tx_.unbounded_send(future); + ).map(|_| Ok(())).compat(); + let _ = to_spawn_tx_.unbounded_send(Box::new(future)); } let offchain = offchain.as_ref().and_then(|o| o.upgrade()); @@ -927,7 +880,7 @@ ServiceBuilder< Ok(()) }) - .select(exit.clone()) + .select(exit.clone().map(Ok).compat()) .then(|_| Ok(())); let _ = to_spawn_tx.unbounded_send(Box::new(events)); } @@ -949,7 +902,7 @@ ServiceBuilder< ); Ok(()) }) - .select(exit.clone()) + .select(exit.clone().map(Ok).compat()) .then(|_| Ok(())); let _ = to_spawn_tx.unbounded_send(Box::new(events)); @@ -1001,7 +954,7 @@ ServiceBuilder< "bandwidth_upload" => bandwidth_upload, "used_state_cache_size" => used_state_cache_size, ); - record_metrics!( + let _ = record_metrics!( "peers" => num_peers, "height" => best_number, "txcount" => txpool_status.ready, @@ -1010,11 +963,11 @@ ServiceBuilder< "finalized_height" => finalized_number, "bandwidth_download" => bandwidth_download, "bandwidth_upload" => bandwidth_upload, - "used_state_cache_size" => used_state_cache_size + "used_state_cache_size" => used_state_cache_size, ); Ok(()) - }).select(exit.clone()).then(|_| Ok(())); + }).select(exit.clone().map(Ok).compat()).then(|_| Ok(())); let _ = to_spawn_tx.unbounded_send(Box::new(tel_task)); // Periodically send the network state to the telemetry. @@ -1027,22 +980,22 @@ ServiceBuilder< "state" => network_state, ); Ok(()) - }).select(exit.clone()).then(|_| Ok(())); + }).select(exit.clone().map(Ok).compat()).then(|_| Ok(())); let _ = to_spawn_tx.unbounded_send(Box::new(tel_task_2)); // RPC let (system_rpc_tx, system_rpc_rx) = futures03::channel::mpsc::unbounded(); let gen_handler = || { - use rpc::{chain, state, author, system}; + use sc_rpc::{chain, state, author, system}; - let system_info = rpc::system::SystemInfo { + let system_info = sc_rpc::system::SystemInfo { chain_name: config.chain_spec.name().into(), impl_name: config.impl_name.into(), impl_version: config.impl_version.into(), properties: config.chain_spec.properties().clone(), }; - let subscriptions = rpc::Subscriptions::new(Arc::new(SpawnTaskHandle { + let subscriptions = sc_rpc::Subscriptions::new(Arc::new(SpawnTaskHandle { sender: to_spawn_tx.clone(), on_exit: exit.clone() })); @@ -1050,13 +1003,13 @@ ServiceBuilder< let (chain, state) = if let (Some(remote_backend), Some(on_demand)) = (remote_backend.as_ref(), on_demand.as_ref()) { // Light clients - let chain = rpc::chain::new_light( + let chain = sc_rpc::chain::new_light( client.clone(), subscriptions.clone(), remote_backend.clone(), on_demand.clone() ); - let state = rpc::state::new_light( + let state = sc_rpc::state::new_light( client.clone(), subscriptions.clone(), remote_backend.clone(), @@ -1066,12 +1019,12 @@ ServiceBuilder< } else { // Full nodes - let chain = rpc::chain::new_full(client.clone(), subscriptions.clone()); - let state = rpc::state::new_full(client.clone(), subscriptions.clone()); + let chain = sc_rpc::chain::new_full(client.clone(), subscriptions.clone()); + let state = sc_rpc::state::new_full(client.clone(), subscriptions.clone()); (chain, state) }; - let author = rpc::author::Author::new( + let author = sc_rpc::author::Author::new( client.clone(), transaction_pool.clone(), subscriptions, @@ -1079,7 +1032,7 @@ ServiceBuilder< ); let system = system::System::new(system_info, system_rpc_tx.clone()); - rpc_servers::rpc_handler(( + sc_rpc_server::rpc_handler(( state::StateApi::to_delegate(state), chain::ChainApi::to_delegate(chain), author::AuthorApi::to_delegate(author), @@ -1101,7 +1054,7 @@ ServiceBuilder< dht_event_tx, ) .map_err(|_| ()) - .select(exit.clone()) + .select(exit.clone().map(Ok).compat()) .then(|_| Ok(())))); let telemetry_connection_sinks: Arc>>> = Default::default(); @@ -1115,7 +1068,7 @@ ServiceBuilder< let version = version.clone(); let chain_name = config.chain_spec.name().to_owned(); let telemetry_connection_sinks_ = telemetry_connection_sinks.clone(); - let telemetry = tel::init_telemetry(tel::TelemetryConfig { + let telemetry = sc_telemetry::init_telemetry(sc_telemetry::TelemetryConfig { endpoints, wasm_external_transport: config.telemetry_external_transport.take(), }); @@ -1127,7 +1080,7 @@ ServiceBuilder< .compat() .for_each(move |event| { // Safe-guard in case we add more events in the future. - let tel::TelemetryEvent::Connected = event; + let sc_telemetry::TelemetryEvent::Connected = event; telemetry!(SUBSTRATE_INFO; "system.connected"; "name" => name.clone(), @@ -1146,7 +1099,7 @@ ServiceBuilder< Ok(()) }); let _ = to_spawn_tx.unbounded_send(Box::new(future - .select(exit.clone()) + .select(exit.clone().map(Ok).compat()) .then(|_| Ok(())))); telemetry }); @@ -1155,7 +1108,7 @@ ServiceBuilder< if let Some(port) = config.grafana_port { let future = select( grafana_data_source::run_server(port).boxed(), - exit.clone().compat() + exit.clone() ).map(|either| match either { Either::Left((result, _)) => result.map_err(|_| ()), Either::Right(_) => Ok(()) @@ -1163,10 +1116,10 @@ ServiceBuilder< let _ = to_spawn_tx.unbounded_send(Box::new(future)); } - + // Instrumentation if let Some(tracing_targets) = config.tracing_targets.as_ref() { - let subscriber = substrate_tracing::ProfilingSubscriber::new( + let subscriber = sc_tracing::ProfilingSubscriber::new( config.tracing_receiver, tracing_targets ); match tracing::subscriber::set_global_default(subscriber) { @@ -1183,7 +1136,8 @@ ServiceBuilder< transaction_pool, exit, signal: Some(signal), - essential_failed: Arc::new(AtomicBool::new(false)), + essential_failed_tx, + essential_failed_rx, to_spawn_tx, to_spawn_rx, to_poll: Vec::new(), @@ -1197,157 +1151,3 @@ ServiceBuilder< }) } } - -pub(crate) fn maintain_transaction_pool( - id: &BlockId, - client: &Arc>, - transaction_pool: &TransactionPool, - retracted: &[Block::Hash], -) -> error::Result + Send>> where - Block: BlockT::Out>, - Backend: 'static + client_api::backend::Backend, - Client: ProvideRuntimeApi, - as ProvideRuntimeApi>::Api: - tx_pool_api::TaggedTransactionQueue, - Executor: 'static + client::CallExecutor, - PoolApi: 'static + txpool::ChainApi, - Api: 'static, -{ - // Put transactions from retracted blocks back into the pool. - let client_copy = client.clone(); - let retracted_transactions = retracted.to_vec().into_iter() - .filter_map(move |hash| client_copy.block(&BlockId::hash(hash)).ok().unwrap_or(None)) - .flat_map(|block| block.block.deconstruct().1.into_iter()) - .filter(|tx| tx.is_signed().unwrap_or(false)); - let resubmit_future = transaction_pool - .submit_at(id, retracted_transactions, true) - .then(|resubmit_result| ready(match resubmit_result { - Ok(_) => Ok(()), - Err(e) => { - warn!("Error re-submitting transactions: {:?}", e); - Ok(()) - } - })) - .compat(); - - // Avoid calling into runtime if there is nothing to prune from the pool anyway. - if transaction_pool.status().is_empty() { - return Ok(Box::new(resubmit_future)) - } - - let block = client.block(id)?; - Ok(match block { - Some(block) => { - let parent_id = BlockId::hash(*block.block.header().parent_hash()); - let prune_future = transaction_pool - .prune(id, &parent_id, block.block.extrinsics()) - .boxed() - .compat() - .map_err(|e| { format!("{:?}", e); }); - - Box::new(resubmit_future.and_then(|_| prune_future)) - }, - None => Box::new(resubmit_future), - }) -} - -#[cfg(test)] -mod tests { - use super::*; - use futures03::executor::block_on; - use consensus_common::{BlockOrigin, SelectChain}; - use substrate_test_runtime_client::{prelude::*, runtime::Transfer}; - - #[test] - fn should_remove_transactions_from_the_pool() { - let (client, longest_chain) = TestClientBuilder::new().build_with_longest_chain(); - let client = Arc::new(client); - let pool = TransactionPool::new(Default::default(), ::transaction_pool::FullChainApi::new(client.clone())); - let transaction = Transfer { - amount: 5, - nonce: 0, - from: AccountKeyring::Alice.into(), - to: Default::default(), - }.into_signed_tx(); - let best = longest_chain.best_chain().unwrap(); - - // store the transaction in the pool - block_on(pool.submit_one(&BlockId::hash(best.hash()), transaction.clone())).unwrap(); - - // import the block - let mut builder = client.new_block(Default::default()).unwrap(); - builder.push(transaction.clone()).unwrap(); - let block = builder.bake().unwrap(); - let id = BlockId::hash(block.header().hash()); - client.import(BlockOrigin::Own, block).unwrap(); - - // fire notification - this should clean up the queue - assert_eq!(pool.status().ready, 1); - maintain_transaction_pool( - &id, - &client, - &pool, - &[] - ).unwrap().wait().unwrap(); - - // then - assert_eq!(pool.status().ready, 0); - assert_eq!(pool.status().future, 0); - } - - #[test] - fn should_add_reverted_transactions_to_the_pool() { - let (client, longest_chain) = TestClientBuilder::new().build_with_longest_chain(); - let client = Arc::new(client); - let pool = TransactionPool::new(Default::default(), ::transaction_pool::FullChainApi::new(client.clone())); - let transaction = Transfer { - amount: 5, - nonce: 0, - from: AccountKeyring::Alice.into(), - to: Default::default(), - }.into_signed_tx(); - let best = longest_chain.best_chain().unwrap(); - - // store the transaction in the pool - block_on(pool.submit_one(&BlockId::hash(best.hash()), transaction.clone())).unwrap(); - - // import the block - let mut builder = client.new_block(Default::default()).unwrap(); - builder.push(transaction.clone()).unwrap(); - let block = builder.bake().unwrap(); - let block1_hash = block.header().hash(); - let id = BlockId::hash(block1_hash.clone()); - client.import(BlockOrigin::Own, block).unwrap(); - - // fire notification - this should clean up the queue - assert_eq!(pool.status().ready, 1); - maintain_transaction_pool( - &id, - &client, - &pool, - &[] - ).unwrap().wait().unwrap(); - - // then - assert_eq!(pool.status().ready, 0); - assert_eq!(pool.status().future, 0); - - // import second block - let builder = client.new_block_at(&BlockId::hash(best.hash()), Default::default()).unwrap(); - let block = builder.bake().unwrap(); - let id = BlockId::hash(block.header().hash()); - client.import(BlockOrigin::Own, block).unwrap(); - - // fire notification - this should add the transaction back to the pool. - maintain_transaction_pool( - &id, - &client, - &pool, - &[block1_hash] - ).unwrap().wait().unwrap(); - - // then - assert_eq!(pool.status().ready, 1); - assert_eq!(pool.status().future, 0); - } -} diff --git a/client/service/src/chain_ops.rs b/client/service/src/chain_ops.rs index 2ccd1200069253fea6e1a4542c95172565f2e8d4..fb62cd3399b41b5598a3a401a7f14aeb26ed18da 100644 --- a/client/service/src/chain_ops.rs +++ b/client/service/src/chain_ops.rs @@ -17,239 +17,297 @@ //! Chain utilities. use crate::error; -use chain_spec::{ChainSpec, RuntimeGenesis, Extension}; - -/// Defines the logic for an operation exporting blocks within a range. -#[macro_export] -/// Export blocks -macro_rules! export_blocks { -($client:ident, $output:ident, $from:ident, $to:ident, $json:ident) => {{ - let mut block = $from; - - let last = match $to { - Some(v) if v.is_zero() => One::one(), - Some(v) => v, - None => $client.info().chain.best_number, - }; - - let mut wrote_header = false; - - // Exporting blocks is implemented as a future, because we want the operation to be - // interruptible. - // - // Every time we write a block to the output, the `Future` re-schedules itself and returns - // `Poll::Pending`. - // This makes it possible either to interleave other operations in-between the block exports, - // or to stop the operation completely. - futures03::future::poll_fn(move |cx| { - if last < block { - return std::task::Poll::Ready(Err("Invalid block range specified".into())); - } +use crate::builder::{ServiceBuilderCommand, ServiceBuilder}; +use crate::error::Error; +use sc_chain_spec::{ChainSpec, RuntimeGenesis, Extension}; +use log::{warn, info}; +use futures::{future, prelude::*}; +use futures03::{ + TryFutureExt as _, +}; +use sp_core::{Blake2Hasher, Hasher}; +use sp_runtime::traits::{ + Block as BlockT, NumberFor, One, Zero, Header, SaturatedConversion +}; +use sp_runtime::generic::{BlockId, SignedBlock}; +use codec::{Decode, Encode, IoReader}; +use sc_client::Client; +use sp_consensus::import_queue::{IncomingBlock, Link, BlockImportError, BlockImportResult, ImportQueue}; +use sp_consensus::BlockOrigin; - if !wrote_header { - info!("Exporting blocks from #{} to #{}", block, last); - if !$json { - let last_: u64 = last.saturated_into::(); - let block_: u64 = block.saturated_into::(); - let len: u64 = last_ - block_ + 1; - $output.write_all(&len.encode())?; - } - wrote_header = true; - } +use std::{ + io::{Read, Write, Seek}, +}; - match $client.block(&BlockId::number(block))? { - Some(block) => { - if $json { - serde_json::to_writer(&mut $output, &block) - .map_err(|e| format!("Error writing JSON: {}", e))?; - } else { - $output.write_all(&block.encode())?; - } - }, - // Reached end of the chain. - None => return std::task::Poll::Ready(Ok(())), - } - if (block % 10000.into()).is_zero() { - info!("#{}", block); - } - if block == last { - return std::task::Poll::Ready(Ok(())); - } - block += One::one(); +use sc_network::message; - // Re-schedule the task in order to continue the operation. - cx.waker().wake_by_ref(); - std::task::Poll::Pending - }) -}} +/// Build a chain spec json +pub fn build_spec(spec: ChainSpec, raw: bool) -> error::Result where + G: RuntimeGenesis, + E: Extension, +{ + Ok(spec.to_json(raw)?) } -/// Defines the logic for an operation importing blocks from some known import. -#[macro_export] -/// Import blocks -macro_rules! import_blocks { -($block:ty, $client:ident, $queue:ident, $input:ident) => {{ - use consensus_common::import_queue::{IncomingBlock, Link, BlockImportError, BlockImportResult}; - use consensus_common::BlockOrigin; - use network::message; - use sr_primitives::generic::SignedBlock; - use sr_primitives::traits::Block; - - struct WaitLink { - imported_blocks: u64, - has_error: bool, - } +impl< + TBl, TRtApi, TCfg, TGen, TCSExt, TBackend, + TExec, TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, + TExPool, TRpc, Backend +> ServiceBuilderCommand for ServiceBuilder< + TBl, TRtApi, TCfg, TGen, TCSExt, Client, + TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPool, TRpc, Backend +> where + TBl: BlockT::Out>, + TBackend: 'static + sc_client_api::backend::Backend + Send, + TExec: 'static + sc_client::CallExecutor + Send + Sync + Clone, + TImpQu: 'static + ImportQueue, + TRtApi: 'static + Send + Sync, +{ + type Block = TBl; - impl WaitLink { - fn new() -> WaitLink { - WaitLink { - imported_blocks: 0, - has_error: false, - } + fn import_blocks( + self, + input: impl Read + Seek + Send + 'static, + force: bool, + ) -> Box + Send> { + struct WaitLink { + imported_blocks: u64, + has_error: bool, } - } - impl Link for WaitLink { - fn blocks_processed( - &mut self, - imported: usize, - _count: usize, - results: Vec<(Result>, BlockImportError>, B::Hash)> - ) { - self.imported_blocks += imported as u64; - - for result in results { - if let (Err(err), hash) = result { - warn!("There was an error importing block with hash {:?}: {:?}", hash, err); - self.has_error = true; - break; + impl WaitLink { + fn new() -> WaitLink { + WaitLink { + imported_blocks: 0, + has_error: false, } } } - } - let mut io_reader_input = IoReader($input); - let mut count = None::; - let mut read_block_count = 0; - let mut link = WaitLink::new(); - - // Importing blocks is implemented as a future, because we want the operation to be - // interruptible. - // - // Every time we read a block from the input or import a bunch of blocks from the import - // queue, the `Future` re-schedules itself and returns `Poll::Pending`. - // This makes it possible either to interleave other operations in-between the block imports, - // or to stop the operation completely. - futures03::future::poll_fn(move |cx| { - // Start by reading the number of blocks if not done so already. - let count = match count { - Some(c) => c, - None => { - let c: u64 = match Decode::decode(&mut io_reader_input) { - Ok(c) => c, - Err(err) => { - let err = format!("Error reading file: {}", err); - return std::task::Poll::Ready(Err(From::from(err))); - }, - }; - info!("Importing {} blocks", c); - count = Some(c); - c + impl Link for WaitLink { + fn blocks_processed( + &mut self, + imported: usize, + _count: usize, + results: Vec<(Result>, BlockImportError>, B::Hash)> + ) { + self.imported_blocks += imported as u64; + + for result in results { + if let (Err(err), hash) = result { + warn!("There was an error importing block with hash {:?}: {:?}", hash, err); + self.has_error = true; + break; + } + } } - }; + } + + let client = self.client; + let mut queue = self.import_queue; + + let mut io_reader_input = IoReader(input); + let mut count = None::; + let mut read_block_count = 0; + let mut link = WaitLink::new(); - // Read blocks from the input. - if read_block_count < count { - match SignedBlock::<$block>::decode(&mut io_reader_input) { - Ok(signed) => { - let (header, extrinsics) = signed.block.deconstruct(); - let hash = header.hash(); - let block = message::BlockData::<$block> { - hash, - justification: signed.justification, - header: Some(header), - body: Some(extrinsics), - receipt: None, - message_queue: None + // Importing blocks is implemented as a future, because we want the operation to be + // interruptible. + // + // Every time we read a block from the input or import a bunch of blocks from the import + // queue, the `Future` re-schedules itself and returns `Poll::Pending`. + // This makes it possible either to interleave other operations in-between the block imports, + // or to stop the operation completely. + let import = futures03::future::poll_fn(move |cx| { + // Start by reading the number of blocks if not done so already. + let count = match count { + Some(c) => c, + None => { + let c: u64 = match Decode::decode(&mut io_reader_input) { + Ok(c) => c, + Err(err) => { + let err = format!("Error reading file: {}", err); + return std::task::Poll::Ready(Err(From::from(err))); + }, }; - // import queue handles verification and importing it into the client - $queue.import_blocks(BlockOrigin::File, vec![ - IncomingBlock::<$block> { - hash: block.hash, - header: block.header, - body: block.body, - justification: block.justification, - origin: None, - allow_missing_state: false, - } - ]); + info!("Importing {} blocks", c); + count = Some(c); + c } - Err(e) => { - warn!("Error reading block data at {}: {}", read_block_count, e); - return std::task::Poll::Ready(Ok(())); + }; + + // Read blocks from the input. + if read_block_count < count { + match SignedBlock::::decode(&mut io_reader_input) { + Ok(signed) => { + let (header, extrinsics) = signed.block.deconstruct(); + let hash = header.hash(); + let block = message::BlockData:: { + hash, + justification: signed.justification, + header: Some(header), + body: Some(extrinsics), + receipt: None, + message_queue: None + }; + // import queue handles verification and importing it into the client + queue.import_blocks(BlockOrigin::File, vec![ + IncomingBlock:: { + hash: block.hash, + header: block.header, + body: block.body, + justification: block.justification, + origin: None, + allow_missing_state: false, + import_existing: force, + } + ]); + } + Err(e) => { + warn!("Error reading block data at {}: {}", read_block_count, e); + return std::task::Poll::Ready(Ok(())); + } + } + + read_block_count += 1; + if read_block_count % 1000 == 0 { + info!("#{} blocks were added to the queue", read_block_count); } + + cx.waker().wake_by_ref(); + return std::task::Poll::Pending; } - read_block_count += 1; - if read_block_count % 1000 == 0 { - info!("#{} blocks were added to the queue", read_block_count); + let blocks_before = link.imported_blocks; + queue.poll_actions(cx, &mut link); + + if link.has_error { + info!( + "Stopping after #{} blocks because of an error", + link.imported_blocks, + ); + return std::task::Poll::Ready(Ok(())); } - cx.waker().wake_by_ref(); - return std::task::Poll::Pending; - } + if link.imported_blocks / 1000 != blocks_before / 1000 { + info!( + "#{} blocks were imported (#{} left)", + link.imported_blocks, + count - link.imported_blocks + ); + } - let blocks_before = link.imported_blocks; - $queue.poll_actions(cx, &mut link); + if link.imported_blocks >= count { + info!("Imported {} blocks. Best: #{}", read_block_count, client.info().chain.best_number); + return std::task::Poll::Ready(Ok(())); - if link.has_error { - info!( - "Stopping after #{} blocks because of an error", - link.imported_blocks, - ); - return std::task::Poll::Ready(Ok(())); - } + } else { + // Polling the import queue will re-schedule the task when ready. + return std::task::Poll::Pending; + } + }); + Box::new(import.compat()) + } - if link.imported_blocks / 1000 != blocks_before / 1000 { - info!( - "#{} blocks were imported (#{} left)", - link.imported_blocks, - count - link.imported_blocks - ); - } + fn export_blocks( + self, + mut output: impl Write + 'static, + from: NumberFor, + to: Option>, + json: bool + ) -> Box> { + let client = self.client; + let mut block = from; + + let last = match to { + Some(v) if v.is_zero() => One::one(), + Some(v) => v, + None => client.info().chain.best_number, + }; + + let mut wrote_header = false; + + // Exporting blocks is implemented as a future, because we want the operation to be + // interruptible. + // + // Every time we write a block to the output, the `Future` re-schedules itself and returns + // `Poll::Pending`. + // This makes it possible either to interleave other operations in-between the block exports, + // or to stop the operation completely. + let export = futures03::future::poll_fn(move |cx| { + if last < block { + return std::task::Poll::Ready(Err("Invalid block range specified".into())); + } + + if !wrote_header { + info!("Exporting blocks from #{} to #{}", block, last); + if !json { + let last_: u64 = last.saturated_into::(); + let block_: u64 = block.saturated_into::(); + let len: u64 = last_ - block_ + 1; + output.write_all(&len.encode())?; + } + wrote_header = true; + } - if link.imported_blocks >= count { - info!("Imported {} blocks. Best: #{}", read_block_count, $client.info().chain.best_number); - return std::task::Poll::Ready(Ok(())); + match client.block(&BlockId::number(block))? { + Some(block) => { + if json { + serde_json::to_writer(&mut output, &block) + .map_err(|e| format!("Error writing JSON: {}", e))?; + } else { + output.write_all(&block.encode())?; + } + }, + // Reached end of the chain. + None => return std::task::Poll::Ready(Ok(())), + } + if (block % 10000.into()).is_zero() { + info!("#{}", block); + } + if block == last { + return std::task::Poll::Ready(Ok(())); + } + block += One::one(); + // Re-schedule the task in order to continue the operation. + cx.waker().wake_by_ref(); + std::task::Poll::Pending + }); + + Box::new(export.compat()) + } + + fn revert_chain( + &self, + blocks: NumberFor + ) -> Result<(), Error> { + let reverted = self.client.revert(blocks)?; + let info = self.client.info().chain; + + if reverted.is_zero() { + info!("There aren't any non-finalized blocks to revert."); } else { - // Polling the import queue will re-schedule the task when ready. - return std::task::Poll::Pending; + info!("Reverted {} blocks. Best: #{} ({})", reverted, info.best_number, info.best_hash); } - }) -}} -} + Ok(()) + } -/// Revert the chain some number of blocks. -#[macro_export] -macro_rules! revert_chain { -($client:ident, $blocks:ident) => {{ - let reverted = $client.revert($blocks)?; - let info = $client.info().chain; - - if reverted.is_zero() { - info!("There aren't any non-finalized blocks to revert."); - } else { - info!("Reverted {} blocks. Best: #{} ({})", reverted, info.best_number, info.best_hash); + fn check_block( + self, + block_id: BlockId + ) -> Box + Send> { + match self.client.block(&block_id) { + Ok(Some(block)) => { + let mut buf = Vec::new(); + 1u64.encode_to(&mut buf); + block.encode_to(&mut buf); + let reader = std::io::Cursor::new(buf); + self.import_blocks(reader, true) + } + Ok(None) => Box::new(future::err("Unknown block".into())), + Err(e) => Box::new(future::err(format!("Error reading block: {:?}", e).into())), + } } - Ok(()) -}} } -/// Build a chain spec json -pub fn build_spec(spec: ChainSpec, raw: bool) -> error::Result where - G: RuntimeGenesis, - E: Extension, -{ - Ok(spec.to_json(raw)?) -} diff --git a/client/service/src/config.rs b/client/service/src/config.rs index a17c0ee877de2fac436f2f225d4d58830f92694e..0b5152e24828d14d37876a695142f40730c51f18 100644 --- a/client/service/src/config.rs +++ b/client/service/src/config.rs @@ -16,17 +16,17 @@ //! Service configuration. -pub use client::ExecutionStrategies; -pub use client_db::{kvdb::KeyValueDB, PruningMode}; -pub use network::config::{ExtTransport, NetworkConfiguration, Roles}; -pub use substrate_executor::WasmExecutionMethod; +pub use sc_client::ExecutionStrategies; +pub use sc_client_db::{kvdb::KeyValueDB, PruningMode}; +pub use sc_network::config::{ExtTransport, NetworkConfiguration, Roles}; +pub use sc_executor::WasmExecutionMethod; use std::{path::PathBuf, net::SocketAddr, sync::Arc}; -use transaction_pool; -use chain_spec::{ChainSpec, RuntimeGenesis, Extension, NoExtension}; -use primitives::crypto::Protected; +pub use sc_transaction_pool::txpool::Options as TransactionPoolOptions; +use sc_chain_spec::{ChainSpec, RuntimeGenesis, Extension, NoExtension}; +use sp_core::crypto::Protected; use target_info::Target; -use tel::TelemetryEndpoints; +use sc_telemetry::TelemetryEndpoints; /// Service configuration. #[derive(Clone)] @@ -40,7 +40,7 @@ pub struct Configuration { /// Node roles. pub roles: Roles, /// Extrinsic pool configuration. - pub transaction_pool: transaction_pool::txpool::Options, + pub transaction_pool: TransactionPoolOptions, /// Network configuration. pub network: NetworkConfiguration, /// Path to the base configuration directory. @@ -103,7 +103,7 @@ pub struct Configuration { /// Tracing targets pub tracing_targets: Option, /// Tracing receiver - pub tracing_receiver: substrate_tracing::TracingReceiver, + pub tracing_receiver: sc_tracing::TracingReceiver, } /// Configuration of the database of the client. diff --git a/client/service/src/error.rs b/client/service/src/error.rs index 85a6892b264e1241a1190cbd21a4b50b935ae77a..d1dc827a3836bfa9267782fc162f2972bc1703bb 100644 --- a/client/service/src/error.rs +++ b/client/service/src/error.rs @@ -16,10 +16,10 @@ //! Errors that can occur during the service operation. -use client; -use network; -use keystore; -use consensus_common; +use sc_network; +use sc_keystore; +use sp_consensus; +use sp_blockchain; /// Service Result typedef. pub type Result = std::result::Result; @@ -28,15 +28,15 @@ pub type Result = std::result::Result; #[derive(Debug, derive_more::Display, derive_more::From)] pub enum Error { /// Client error. - Client(client::error::Error), + Client(sp_blockchain::Error), /// IO error. Io(std::io::Error), /// Consensus error. - Consensus(consensus_common::Error), + Consensus(sp_consensus::Error), /// Network error. - Network(network::error::Error), + Network(sc_network::error::Error), /// Keystore error. - Keystore(keystore::Error), + Keystore(sc_keystore::Error), /// Best chain selection strategy is missing. #[display(fmt="Best chain selection strategy (SelectChain) is not provided.")] SelectChainRequired, diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index 2bc56647a609286c9f9525b5465a147db09c15f5..757d3b0bf6465b9ae8516151fe9b62287d9db00c 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -31,41 +31,39 @@ use std::io; use std::marker::PhantomData; use std::net::SocketAddr; use std::collections::HashMap; -use std::sync::atomic::{AtomicBool, Ordering}; use std::time::{Duration, Instant}; use futures::sync::mpsc; use parking_lot::Mutex; -use client::Client; +use sc_client::Client; use exit_future::Signal; use futures::prelude::*; use futures03::{ future::{ready, FutureExt as _, TryFutureExt as _}, stream::{StreamExt as _, TryStreamExt as _}, }; -use network::{ +use sc_network::{ NetworkService, NetworkState, specialization::NetworkSpecialization, Event, DhtEvent, PeerId, ReportHandle, }; use log::{log, warn, debug, error, Level}; use codec::{Encode, Decode}; -use primitives::{Blake2Hasher, H256}; -use sr_primitives::generic::BlockId; -use sr_primitives::traits::{NumberFor, Block as BlockT}; +use sp_core::{Blake2Hasher, H256}; +use sp_runtime::generic::BlockId; +use sp_runtime::traits::{NumberFor, Block as BlockT}; pub use self::error::Error; -pub use self::builder::{ServiceBuilder, ServiceBuilderExport, ServiceBuilderImport, ServiceBuilderRevert}; +pub use self::builder::{ServiceBuilder, ServiceBuilderCommand}; pub use config::{Configuration, Roles, PruningMode}; -pub use chain_spec::{ChainSpec, Properties, RuntimeGenesis, Extension as ChainSpecExtension}; -pub use transaction_pool::txpool::{ - self, Pool as TransactionPool, Options as TransactionPoolOptions, ChainApi, IntoPoolError -}; -pub use client::FinalityNotifications; -pub use rpc::Metadata as RpcMetadata; +pub use sc_chain_spec::{ChainSpec, Properties, RuntimeGenesis, Extension as ChainSpecExtension}; +pub use sp_transaction_pool::{TransactionPool, TransactionPoolMaintainer, InPoolTransaction, error::IntoPoolError}; +pub use sc_transaction_pool::txpool::Options as TransactionPoolOptions; +pub use sc_client::FinalityNotifications; +pub use sc_rpc::Metadata as RpcMetadata; #[doc(hidden)] pub use std::{ops::Deref, result::Result, sync::Arc}; #[doc(hidden)] -pub use network::{FinalityProofProvider, OnDemand, config::BoxFinalityProofRequestBuilder}; +pub use sc_network::{FinalityProofProvider, OnDemand, config::BoxFinalityProofRequestBuilder}; #[doc(hidden)] pub use futures::future::Executor; @@ -85,9 +83,11 @@ pub struct Service { exit: exit_future::Exit, /// A signal that makes the exit future above resolve, fired on service drop. signal: Option, - /// Set to `true` when a spawned essential task has failed. The next time + /// Send a signal when a spawned essential task has concluded. The next time /// the service future is polled it should complete with an error. - essential_failed: Arc, + essential_failed_tx: mpsc::UnboundedSender<()>, + /// A receiver for spawned essential-tasks concluding. + essential_failed_rx: mpsc::UnboundedReceiver<()>, /// Sender for futures that must be spawned as background tasks. to_spawn_tx: mpsc::UnboundedSender + Send>>, /// Receiver for futures that must be spawned as background tasks. @@ -96,12 +96,12 @@ pub struct Service { /// If spawning a background task is not possible, we instead push the task into this `Vec`. /// The elements must then be polled manually. to_poll: Vec + Send>>, - rpc_handlers: rpc_servers::RpcHandler, + rpc_handlers: sc_rpc_server::RpcHandler, _rpc: Box, - _telemetry: Option, + _telemetry: Option, _telemetry_on_connect_sinks: Arc>>>, _offchain_workers: Option>, - keystore: keystore::KeyStorePtr, + keystore: sc_keystore::KeyStorePtr, marker: PhantomData, } @@ -120,7 +120,8 @@ impl Executor + Send>> for SpawnTaskHandle &self, future: Box + Send>, ) -> Result<(), futures::future::ExecuteError + Send>>> { - let future = Box::new(future.select(self.on_exit.clone()).then(|_| Ok(()))); + let exit = self.on_exit.clone().map(Ok).compat(); + let future = Box::new(future.select(exit).then(|_| Ok(()))); if let Err(err) = self.sender.unbounded_send(future) { let kind = futures::future::ExecuteErrorKind::Shutdown; Err(futures::future::ExecuteError::new(kind, err.into_inner())) @@ -130,21 +131,30 @@ impl Executor + Send>> for SpawnTaskHandle } } +impl futures03::task::Spawn for SpawnTaskHandle { + fn spawn_obj(&self, future: futures03::task::FutureObj<'static, ()>) + -> Result<(), futures03::task::SpawnError> { + self.execute(Box::new(futures03::compat::Compat::new(future.unit_error()))) + .map_err(|_| futures03::task::SpawnError::shutdown()) + } +} + /// Abstraction over a Substrate service. pub trait AbstractService: 'static + Future + Executor + Send>> + Send { /// Type of block of this chain. type Block: BlockT; /// Backend storage for the client. - type Backend: 'static + client_api::backend::Backend; + type Backend: 'static + sc_client_api::backend::Backend; /// How to execute calls towards the runtime. - type CallExecutor: 'static + client::CallExecutor + Send + Sync + Clone; + type CallExecutor: 'static + sc_client::CallExecutor + Send + Sync + Clone; /// API that the runtime provides. type RuntimeApi: Send + Sync; /// Chain selection algorithm. - type SelectChain: consensus_common::SelectChain; - /// API of the transaction pool. - type TransactionPoolApi: ChainApi; + type SelectChain: sp_consensus::SelectChain; + /// Transaction pool. + type TransactionPool: TransactionPool + + TransactionPoolMaintainer; /// Network specialization. type NetworkSpecialization: NetworkSpecialization; @@ -152,7 +162,7 @@ pub trait AbstractService: 'static + Future + fn telemetry_on_connect_stream(&self) -> mpsc::UnboundedReceiver<()>; /// return a shared instance of Telemetry (if enabled) - fn telemetry(&self) -> Option; + fn telemetry(&self) -> Option; /// Spawns a task in the background that runs the future passed as parameter. fn spawn_task(&self, task: impl Future + Send + 'static); @@ -166,7 +176,7 @@ pub trait AbstractService: 'static + Future + fn spawn_task_handle(&self) -> SpawnTaskHandle; /// Returns the keystore that stores keys. - fn keystore(&self) -> keystore::KeyStorePtr; + fn keystore(&self) -> sc_keystore::KeyStorePtr; /// Starts an RPC query. /// @@ -180,7 +190,7 @@ pub trait AbstractService: 'static + Future + fn rpc_query(&self, mem: &RpcSession, request: &str) -> Box, Error = ()> + Send>; /// Get shared client instance. - fn client(&self) -> Arc>; + fn client(&self) -> Arc>; /// Get clone of select chain. fn select_chain(&self) -> Option; @@ -192,22 +202,23 @@ pub trait AbstractService: 'static + Future + fn network_status(&self, interval: Duration) -> mpsc::UnboundedReceiver<(NetworkStatus, NetworkState)>; /// Get shared transaction pool instance. - fn transaction_pool(&self) -> Arc>; + fn transaction_pool(&self) -> Arc; /// Get a handle to a future that will resolve on exit. fn on_exit(&self) -> ::exit_future::Exit; } -impl AbstractService for +impl AbstractService for Service, TSc, NetworkStatus, - NetworkService, TransactionPool, TOc> + NetworkService, TExPool, TOc> where TBl: BlockT, - TBackend: 'static + client_api::backend::Backend, - TExec: 'static + client::CallExecutor + Send + Sync + Clone, + TBackend: 'static + sc_client_api::backend::Backend, + TExec: 'static + sc_client::CallExecutor + Send + Sync + Clone, TRtApi: 'static + Send + Sync, - TSc: consensus_common::SelectChain + 'static + Clone + Send, - TExPoolApi: 'static + ChainApi, + TSc: sp_consensus::SelectChain + 'static + Clone + Send, + TExPool: 'static + TransactionPool + + TransactionPoolMaintainer, TOc: 'static + Send + Sync, TNetSpec: NetworkSpecialization, { @@ -216,7 +227,7 @@ where type CallExecutor = TExec; type RuntimeApi = TRtApi; type SelectChain = TSc; - type TransactionPoolApi = TExPoolApi; + type TransactionPool = TExPool; type NetworkSpecialization = TNetSpec; fn telemetry_on_connect_stream(&self) -> mpsc::UnboundedReceiver<()> { @@ -225,26 +236,31 @@ where stream } - fn telemetry(&self) -> Option { + fn telemetry(&self) -> Option { self._telemetry.as_ref().map(|t| t.clone()) } - fn keystore(&self) -> keystore::KeyStorePtr { + fn keystore(&self) -> sc_keystore::KeyStorePtr { self.keystore.clone() } fn spawn_task(&self, task: impl Future + Send + 'static) { - let task = task.select(self.on_exit()).then(|_| Ok(())); + let exit = self.on_exit().map(Ok).compat(); + let task = task.select(exit).then(|_| Ok(())); let _ = self.to_spawn_tx.unbounded_send(Box::new(task)); } fn spawn_essential_task(&self, task: impl Future + Send + 'static) { - let essential_failed = self.essential_failed.clone(); - let essential_task = task.map_err(move |_| { - error!("Essential task failed. Shutting down service."); - essential_failed.store(true, Ordering::Relaxed); - }); - let task = essential_task.select(self.on_exit()).then(|_| Ok(())); + let essential_failed = self.essential_failed_tx.clone(); + let essential_task = std::panic::AssertUnwindSafe(task) + .catch_unwind() + .then(move |_| { + error!("Essential task failed. Shutting down service."); + let _ = essential_failed.send(()); + Ok(()) + }); + let exit = self.on_exit().map(Ok::<_, ()>).compat(); + let task = essential_task.select(exit).then(|_| Ok(())); let _ = self.to_spawn_tx.unbounded_send(Box::new(task)); } @@ -260,7 +276,7 @@ where Box::new(self.rpc_handlers.handle_request(request, mem.metadata.clone())) } - fn client(&self) -> Arc> { + fn client(&self) -> Arc> { self.client.clone() } @@ -278,7 +294,7 @@ where stream } - fn transaction_pool(&self) -> Arc> { + fn transaction_pool(&self) -> Arc { self.transaction_pool.clone() } @@ -294,8 +310,13 @@ impl Future for type Error = Error; fn poll(&mut self) -> Poll { - if self.essential_failed.load(Ordering::Relaxed) { - return Err(Error::Other("Essential task failed.".into())); + match self.essential_failed_rx.poll() { + Ok(Async::NotReady) => {}, + Ok(Async::Ready(_)) | Err(_) => { + // Ready(None) should not be possible since we hold a live + // sender. + return Err(Error::Other("Essential task failed.".into())); + } } while let Ok(Async::Ready(Some(task_to_spawn))) = self.to_spawn_rx.poll() { @@ -341,15 +362,15 @@ impl Executor, - S: network::specialization::NetworkSpecialization, - H: network::ExHashT + C: sc_client::BlockchainEvents, + S: sc_network::specialization::NetworkSpecialization, + H: sc_network::ExHashT > ( roles: Roles, - mut network: network::NetworkWorker, + mut network: sc_network::NetworkWorker, client: Arc, status_sinks: Arc, NetworkState)>>>, - rpc_rx: futures03::channel::mpsc::UnboundedReceiver>, + rpc_rx: futures03::channel::mpsc::UnboundedReceiver>, should_have_peers: bool, dht_event_tx: Option>, ) -> impl Future { @@ -362,6 +383,9 @@ fn build_network_future< let mut finality_notification_stream = client.finality_notification_stream().fuse() .map(|v| Ok::<_, ()>(v)).compat(); + // Initializing a stream in order to obtain DHT events from the network. + let mut event_stream = network.service().event_stream(); + futures::future::poll_fn(move || { let before_polling = Instant::now(); @@ -382,16 +406,16 @@ fn build_network_future< // Poll the RPC requests and answer them. while let Ok(Async::Ready(Some(request))) = rpc_rx.poll() { match request { - rpc::system::Request::Health(sender) => { - let _ = sender.send(rpc::system::Health { + sc_rpc::system::Request::Health(sender) => { + let _ = sender.send(sc_rpc::system::Health { peers: network.peers_debug_info().len(), is_syncing: network.service().is_major_syncing(), should_have_peers, }); }, - rpc::system::Request::Peers(sender) => { + sc_rpc::system::Request::Peers(sender) => { let _ = sender.send(network.peers_debug_info().into_iter().map(|(peer_id, p)| - rpc::system::PeerInfo { + sc_rpc::system::PeerInfo { peer_id: peer_id.to_base58(), roles: format!("{:?}", p.roles), protocol_version: p.protocol_version, @@ -400,13 +424,29 @@ fn build_network_future< } ).collect()); } - rpc::system::Request::NetworkState(sender) => { + sc_rpc::system::Request::NetworkState(sender) => { if let Some(network_state) = serde_json::to_value(&network.network_state()).ok() { let _ = sender.send(network_state); } } - rpc::system::Request::NodeRoles(sender) => { - use rpc::system::NodeRole; + sc_rpc::system::Request::NetworkAddReservedPeer(peer_addr, sender) => { + let x = network.add_reserved_peer(peer_addr) + .map_err(sc_rpc::system::error::Error::MalformattedPeerArg); + let _ = sender.send(x); + } + sc_rpc::system::Request::NetworkRemoveReservedPeer(peer_id, sender) => { + let _ = match peer_id.parse::() { + Ok(peer_id) => { + network.remove_reserved_peer(peer_id); + sender.send(Ok(())) + } + Err(e) => sender.send(Err(sc_rpc::system::error::Error::MalformattedPeerArg( + e.to_string(), + ))), + }; + } + sc_rpc::system::Request::NodeRoles(sender) => { + use sc_rpc::system::NodeRole; let node_roles = (0 .. 8) .filter(|&bit_number| (roles.bits() >> bit_number) & 1 == 1) @@ -438,22 +478,32 @@ fn build_network_future< (status, state) }); + // Processing DHT events. + while let Ok(Async::Ready(Some(event))) = event_stream.poll() { + match event { + Event::Dht(event) => { + // Given that client/authority-discovery is the only upper stack consumer of Dht events at the moment, all Dht + // events are being passed on to the authority-discovery module. In the future there might be multiple + // consumers of these events. In that case this would need to be refactored to properly dispatch the events, + // e.g. via a subscriber model. + if let Some(Err(e)) = dht_event_tx.as_ref().map(|c| c.clone().try_send(event)) { + if e.is_full() { + warn!(target: "service", "Dht event channel to authority discovery is full, dropping event."); + } else if e.is_disconnected() { + warn!(target: "service", "Dht event channel to authority discovery is disconnected, dropping event."); + } + } + } + _ => {} + } + } + // Main network polling. - while let Ok(Async::Ready(Some(Event::Dht(event)))) = network.poll().map_err(|err| { + if let Ok(Async::Ready(())) = network.poll().map_err(|err| { warn!(target: "service", "Error in network: {:?}", err); }) { - // Given that client/authority-discovery is the only upper stack consumer of Dht events at the moment, all Dht - // events are being passed on to the authority-discovery module. In the future there might be multiple - // consumers of these events. In that case this would need to be refactored to properly dispatch the events, - // e.g. via a subscriber model. - if let Some(Err(e)) = dht_event_tx.as_ref().map(|c| c.clone().try_send(event)) { - if e.is_full() { - warn!(target: "service", "Dht event channel to authority discovery is full, dropping event."); - } else if e.is_disconnected() { - warn!(target: "service", "Dht event channel to authority discovery is disconnected, dropping event."); - } - } - }; + return Ok(Async::Ready(())); + } // Now some diagnostic for performances. let polling_dur = before_polling.elapsed(); @@ -472,7 +522,7 @@ fn build_network_future< #[derive(Clone)] pub struct NetworkStatus { /// Current global sync state. - pub sync_state: network::SyncState, + pub sync_state: sc_network::SyncState, /// Target sync block number. pub best_seen_block: Option>, /// Number of peers participating in syncing. @@ -493,14 +543,14 @@ impl Drop for fn drop(&mut self) { debug!(target: "service", "Substrate service shutdown"); if let Some(signal) = self.signal.take() { - signal.fire(); + let _ = signal.fire(); } } } /// Starts RPC servers that run in their own thread, and returns an opaque object that keeps them alive. #[cfg(not(target_os = "unknown"))] -fn start_rpc_servers rpc_servers::RpcHandler>( +fn start_rpc_servers sc_rpc_server::RpcHandler>( config: &Configuration, mut gen_handler: H ) -> Result, error::Error> { @@ -512,7 +562,7 @@ fn start_rpc_servers rpc_servers::RpcHandler { - warn!("Unable to bind server to {}. Trying random port.", address); + warn!("Unable to bind RPC server to {}. Trying random port.", address); address.set_port(0); start(&address) }, @@ -525,11 +575,11 @@ fn start_rpc_servers rpc_servers::RpcHandler rpc_servers::RpcHandler rpc_servers::RpcHandler>( +fn start_rpc_servers sc_rpc_server::RpcHandler>( _: &Configuration, _: H ) -> Result, error::Error> { @@ -552,7 +602,7 @@ fn start_rpc_servers rpc_servers::RpcHandler { /// Get transactions for propagation. /// /// Function extracted to simplify the test and prevent creating `ServiceFactory`. -fn transactions_to_propagate(pool: &TransactionPool) +fn transactions_to_propagate(pool: &Pool) -> Vec<(H, B::Extrinsic)> where - PoolApi: ChainApi, + Pool: TransactionPool, B: BlockT, - H: std::hash::Hash + Eq + sr_primitives::traits::Member + sr_primitives::traits::MaybeSerialize, - E: txpool::error::IntoPoolError + From, + H: std::hash::Hash + Eq + sp_runtime::traits::Member + sp_runtime::traits::MaybeSerialize, + E: IntoPoolError + From, { pool.ready() .filter(|t| t.is_propagateable()) .map(|t| { - let hash = t.hash.clone(); - let ex: B::Extrinsic = t.data.clone(); + let hash = t.hash().clone(); + let ex: B::Extrinsic = t.data().clone(); (hash, ex) }) .collect() } -impl network::TransactionPool for - TransactionPoolAdapter> +impl sc_network::TransactionPool for + TransactionPoolAdapter where - C: network::ClientHandle + Send + Sync, - PoolApi: 'static + ChainApi, + C: sc_network::ClientHandle + Send + Sync, + Pool: 'static + TransactionPool, B: BlockT, - H: std::hash::Hash + Eq + sr_primitives::traits::Member + sr_primitives::traits::MaybeSerialize, - E: txpool::error::IntoPoolError + From, + H: std::hash::Hash + Eq + sp_runtime::traits::Member + sp_runtime::traits::MaybeSerialize, + E: 'static + IntoPoolError + From, { fn transactions(&self) -> Vec<(H, ::Extrinsic)> { - transactions_to_propagate(&self.pool) + transactions_to_propagate(&*self.pool) } fn hash_of(&self, transaction: &B::Extrinsic) -> H { @@ -619,8 +669,8 @@ where &self, report_handle: ReportHandle, who: PeerId, - reputation_change_good: i32, - reputation_change_bad: i32, + reputation_change_good: sc_network::ReputationChange, + reputation_change_bad: sc_network::ReputationChange, transaction: B::Extrinsic ) { if !self.imports_external_transactions { @@ -638,7 +688,7 @@ where match import_result { Ok(_) => report_handle.report_peer(who, reputation_change_good), Err(e) => match e.into_pool_error() { - Ok(txpool::error::Error::AlreadyImported(_)) => (), + Ok(sp_transaction_pool::error::Error::AlreadyImported(_)) => (), Ok(e) => { report_handle.report_peer(who, reputation_change_bad); debug!("Error adding transaction to the pool: {:?}", e) @@ -667,19 +717,17 @@ where mod tests { use super::*; use futures03::executor::block_on; - use consensus_common::SelectChain; - use sr_primitives::traits::BlindCheckable; + use sp_consensus::SelectChain; + use sp_runtime::traits::BlindCheckable; use substrate_test_runtime_client::{prelude::*, runtime::{Extrinsic, Transfer}}; + use sc_transaction_pool::{BasicPool, FullChainApi}; #[test] fn should_not_propagate_transactions_that_are_marked_as_such() { // given let (client, longest_chain) = TestClientBuilder::new().build_with_longest_chain(); let client = Arc::new(client); - let pool = Arc::new(TransactionPool::new( - Default::default(), - transaction_pool::FullChainApi::new(client.clone()) - )); + let pool = Arc::new(BasicPool::new(Default::default(), FullChainApi::new(client.clone()))); let best = longest_chain.best_chain().unwrap(); let transaction = Transfer { amount: 5, @@ -692,7 +740,7 @@ mod tests { assert_eq!(pool.status().ready, 2); // when - let transactions = transactions_to_propagate(&pool); + let transactions = transactions_to_propagate(&*pool); // then assert_eq!(transactions.len(), 1); diff --git a/client/service/test/Cargo.toml b/client/service/test/Cargo.toml index 365fd87bfec86989508d8cd3db0e96c1a4e457db..2789bfda0fe1937c476a4af54067da8fc942b308 100644 --- a/client/service/test/Cargo.toml +++ b/client/service/test/Cargo.toml @@ -1,20 +1,21 @@ [package] -name = "substrate-service-test" +name = "sc-service-test" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" [dependencies] -tempdir = "0.3.7" +tempfile = "3.1.0" tokio = "0.1.22" futures = "0.1.29" log = "0.4.8" env_logger = "0.7.0" fdlimit = "0.1.1" futures03 = { package = "futures", version = "0.3.1", features = ["compat"] } -service = { package = "substrate-service", path = "../../service", default-features = false } -network = { package = "substrate-network", path = "../../network" } -consensus = { package = "substrate-consensus-common", path = "../../../primitives/consensus/common" } -client = { package = "substrate-client", path = "../../" } -sr-primitives = { path = "../../../primitives/sr-primitives" } -primitives = { package = "substrate-primitives", path = "../../../primitives/core" } +sc-service = { version = "2.0.0", default-features = false, path = "../../service" } +sc-network = { version = "0.8", path = "../../network" } +sp-consensus = { version = "0.8", path = "../../../primitives/consensus/common" } +sc-client = { version = "2.0.0", path = "../../" } +sp-runtime = { version = "2.0.0", path = "../../../primitives/runtime" } +sp-core = { version = "2.0.0", path = "../../../primitives/core" } +sp-transaction-pool = { version = "2.0.0", path = "../../../primitives/transaction-pool" } diff --git a/client/service/test/src/lib.rs b/client/service/test/src/lib.rs index 594e5bf7ed4004c3d55696e633a74bddc7fb6785..dae0f5604fcc8aa92d8d87c25237af7012e0e897 100644 --- a/client/service/test/src/lib.rs +++ b/client/service/test/src/lib.rs @@ -22,10 +22,10 @@ use std::net::Ipv4Addr; use std::time::Duration; use log::info; use futures::{Future, Stream, Poll}; -use tempdir::TempDir; +use tempfile::TempDir; use tokio::{runtime::Runtime, prelude::FutureExt}; use tokio::timer::Interval; -use service::{ +use sc_service::{ AbstractService, ChainSpec, Configuration, @@ -33,9 +33,10 @@ use service::{ Roles, Error, }; -use network::{multiaddr, Multiaddr}; -use network::config::{NetworkConfiguration, TransportConfig, NodeKeyConfig, Secret, NonReservedPeerMode}; -use sr_primitives::{generic::BlockId, traits::Block as BlockT}; +use sc_network::{multiaddr, Multiaddr}; +use sc_network::config::{NetworkConfiguration, TransportConfig, NodeKeyConfig, Secret, NonReservedPeerMode}; +use sp_runtime::{generic::BlockId, traits::Block as BlockT}; +use sp_transaction_pool::TransactionPool; /// Maximum duration of single wait call. const MAX_WAIT_TIME: Duration = Duration::from_secs(60 * 3); @@ -71,9 +72,9 @@ impl From for SyncService { } } -impl> Future for SyncService { +impl> Future for SyncService { type Item = (); - type Error = service::Error; + type Error = sc_service::Error; fn poll(&mut self) -> Poll { self.0.lock().unwrap().poll() @@ -154,6 +155,7 @@ fn node_config ( out_peers: 450, reserved_nodes: vec![], non_reserved_mode: NonReservedPeerMode::Accept, + sentry_nodes: vec![], client_version: "network/test/0.1".to_owned(), node_name: "unknown".to_owned(), transport: TransportConfig::Normal { @@ -184,7 +186,7 @@ fn node_config ( chain_spec: (*spec).clone(), custom: Default::default(), name: format!("Node {}", index), - wasm_method: service::config::WasmExecutionMethod::Interpreted, + wasm_method: sc_service::config::WasmExecutionMethod::Interpreted, execution_strategies: Default::default(), rpc_http: None, rpc_ws: None, @@ -289,12 +291,14 @@ impl TestNet where } } +fn tempdir_with_prefix(prefix: &str) -> TempDir { + tempfile::Builder::new().prefix(prefix).tempdir().expect("Error creating test dir") +} + pub fn connectivity( spec: ChainSpec, full_builder: Fb, light_builder: Lb, - light_node_interconnectivity: bool, // should normally be false, unless the light nodes - // aren't actually light. ) where E: Clone, Fb: Fn(Configuration<(), G, E>) -> Result, @@ -306,14 +310,10 @@ pub fn connectivity( const NUM_LIGHT_NODES: usize = 5; let expected_full_connections = NUM_FULL_NODES - 1 + NUM_LIGHT_NODES; - let expected_light_connections = if light_node_interconnectivity { - expected_full_connections - } else { - NUM_FULL_NODES - }; + let expected_light_connections = NUM_FULL_NODES; { - let temp = TempDir::new("substrate-connectivity-test").expect("Error creating test dir"); + let temp = tempdir_with_prefix("substrate-connectivity-test"); let runtime = { let mut network = TestNet::new( &temp, @@ -351,7 +351,7 @@ pub fn connectivity( temp.close().expect("Error removing temp dir"); } { - let temp = TempDir::new("substrate-connectivity-test").expect("Error creating test dir"); + let temp = tempdir_with_prefix("substrate-connectivity-test"); { let mut network = TestNet::new( &temp, @@ -413,7 +413,7 @@ pub fn sync( // FIXME: BABE light client support is currently not working. const NUM_LIGHT_NODES: usize = 10; const NUM_BLOCKS: usize = 512; - let temp = TempDir::new("substrate-sync-test").expect("Error creating test dir"); + let temp = tempdir_with_prefix("substrate-sync-test"); let mut network = TestNet::new( &temp, spec.clone(), @@ -478,7 +478,7 @@ pub fn consensus( const NUM_FULL_NODES: usize = 10; const NUM_LIGHT_NODES: usize = 10; const NUM_BLOCKS: usize = 10; // 10 * 2 sec block production time = ~20 seconds - let temp = TempDir::new("substrate-conensus-test").expect("Error creating test dir"); + let temp = tempdir_with_prefix("substrate-conensus-test"); let mut network = TestNet::new( &temp, spec.clone(), diff --git a/client/src/call_executor.rs b/client/src/call_executor.rs index e03293f2a722b9f3dce28f76d73fa881d2284719..3115c78103558f7274649effe7f983e6aa6f06b7 100644 --- a/client/src/call_executor.rs +++ b/client/src/call_executor.rs @@ -16,24 +16,22 @@ use std::{sync::Arc, panic::UnwindSafe, result, cell::RefCell}; use codec::{Encode, Decode}; -use sr_primitives::{ +use sp_runtime::{ generic::BlockId, traits::Block as BlockT, traits::NumberFor, }; -use state_machine::{ +use sp_state_machine::{ self, OverlayedChanges, Ext, ExecutionManager, StateMachine, ExecutionStrategy, backend::Backend as _, ChangesTrieTransaction, StorageProof, }; -use executor::{RuntimeVersion, RuntimeInfo, NativeVersion}; -use externalities::Extensions; +use sc_executor::{RuntimeVersion, RuntimeInfo, NativeVersion}; +use sp_externalities::Extensions; use hash_db::Hasher; -use primitives::{ +use sp_core::{ H256, Blake2Hasher, NativeOrEncoded, NeverNativeValue, traits::CodeExecutor, }; -use sr_api::{ProofRecorder, InitializeBlock}; -use client_api::{ - error, backend, call_executor::CallExecutor, -}; +use sp_api::{ProofRecorder, InitializeBlock}; +use sc_client_api::{backend, call_executor::CallExecutor}; /// Call executor that executes methods locally, querying all required /// data from local backend. @@ -65,10 +63,10 @@ impl Clone for LocalCallExecutor where E: Clone { } impl CallExecutor for LocalCallExecutor -where - B: backend::Backend, - E: CodeExecutor + RuntimeInfo, - Block: BlockT, + where + B: backend::Backend, + E: CodeExecutor + RuntimeInfo, + Block: BlockT, { type Error = E::Error; @@ -79,7 +77,7 @@ where call_data: &[u8], strategy: ExecutionStrategy, extensions: Option, - ) -> error::Result> { + ) -> sp_blockchain::Result> { let mut changes = OverlayedChanges::default(); let state = self.backend.state_at(*id)?; let return_data = StateMachine::new( @@ -96,13 +94,16 @@ where None, ) .map(|(result, _, _)| result)?; - self.backend.destroy_state(state)?; + { + let _lock = self.backend.get_import_lock().read(); + self.backend.destroy_state(state)?; + } Ok(return_data.into_encoded()) } fn contextual_call< 'a, - IB: Fn() -> error::Result<()>, + IB: Fn() -> sp_blockchain::Result<()>, EM: Fn( Result, Self::Error>, Result, Self::Error> @@ -121,7 +122,7 @@ where native_call: Option, recorder: &Option>, extensions: Option, - ) -> Result, error::Error> where ExecutionManager: Clone { + ) -> Result, sp_blockchain::Error> where ExecutionManager: Clone { match initialize_block { InitializeBlock::Do(ref init_block) if init_block.borrow().as_ref().map(|id| id != at).unwrap_or(true) => { @@ -137,11 +138,11 @@ where Some(recorder) => { let trie_state = state.as_trie_backend() .ok_or_else(|| - Box::new(state_machine::ExecutionError::UnableToGenerateProof) - as Box + Box::new(sp_state_machine::ExecutionError::UnableToGenerateProof) + as Box )?; - let backend = state_machine::ProvingBackend::new_with_recorder( + let backend = sp_state_machine::ProvingBackend::new_with_recorder( trie_state, recorder.clone() ); @@ -179,11 +180,14 @@ where ) .map(|(result, _, _)| result) }?; - self.backend.destroy_state(state)?; + { + let _lock = self.backend.get_import_lock().read(); + self.backend.destroy_state(state)?; + } Ok(result) } - fn runtime_version(&self, id: &BlockId) -> error::Result { + fn runtime_version(&self, id: &BlockId) -> sp_blockchain::Result { let mut overlay = OverlayedChanges::default(); let state = self.backend.state_at(*id)?; @@ -194,12 +198,15 @@ where None, ); let version = self.executor.runtime_version(&mut ext); - self.backend.destroy_state(state)?; - version.ok_or(error::Error::VersionInvalid.into()) + { + let _lock = self.backend.get_import_lock().read(); + self.backend.destroy_state(state)?; + } + version.map_err(|e| sp_blockchain::Error::VersionInvalid(format!("{:?}", e)).into()) } fn call_at_state< - S: state_machine::Backend, + S: sp_state_machine::Backend, F: FnOnce( Result, Self::Error>, Result, Self::Error>, @@ -214,7 +221,7 @@ where manager: ExecutionManager, native_call: Option, extensions: Option, - ) -> error::Result<( + ) -> sp_blockchain::Result<( NativeOrEncoded, (S::Transaction, ::Out), Option>>, @@ -240,22 +247,19 @@ where .map_err(Into::into) } - fn prove_at_trie_state>( + fn prove_at_trie_state>( &self, - trie_state: &state_machine::TrieBackend, + trie_state: &sp_state_machine::TrieBackend, overlay: &mut OverlayedChanges, method: &str, call_data: &[u8] - ) -> Result<(Vec, StorageProof), error::Error> { - state_machine::prove_execution_on_trie_backend( + ) -> Result<(Vec, StorageProof), sp_blockchain::Error> { + sp_state_machine::prove_execution_on_trie_backend( trie_state, overlay, &self.executor, method, call_data, - // Passing `None` here, since we don't really want to prove anything - // about our local keys. - None, ) .map_err(Into::into) } @@ -264,3 +268,21 @@ where Some(self.executor.native_version()) } } + +impl sp_version::GetRuntimeVersion for LocalCallExecutor + where + B: backend::Backend, + E: CodeExecutor + RuntimeInfo, + Block: BlockT, +{ + fn native_version(&self) -> &sp_version::NativeVersion { + self.executor.native_version() + } + + fn runtime_version( + &self, + at: &BlockId, + ) -> Result { + CallExecutor::runtime_version(self, at).map_err(|e| format!("{:?}", e)) + } +} diff --git a/client/src/cht.rs b/client/src/cht.rs index 874ea02c2a1a35b7bf2d31f1b74ae449d05c4e49..7eeea10bb3d9d76dcf9c10589da9f84d4215167e 100644 --- a/client/src/cht.rs +++ b/client/src/cht.rs @@ -25,15 +25,15 @@ use hash_db; use codec::Encode; -use trie; +use sp_trie; -use primitives::{H256, convert_hash}; -use sr_primitives::traits::{Header as HeaderT, SimpleArithmetic, Zero, One}; -use state_machine::backend::InMemory as InMemoryState; -use state_machine::{MemoryDB, TrieBackend, Backend as StateBackend, StorageProof, +use sp_core::{H256, convert_hash}; +use sp_runtime::traits::{Header as HeaderT, SimpleArithmetic, Zero, One}; +use sp_state_machine::backend::InMemory as InMemoryState; +use sp_state_machine::{MemoryDB, TrieBackend, Backend as StateBackend, StorageProof, prove_read_on_trie_backend, read_proof_check, read_proof_check_on_proving_backend}; -use client_api::error::{Error as ClientError, Result as ClientResult}; +use sp_blockchain::{Error as ClientError, Result as ClientResult}; /// The size of each CHT. This value is passed to every CHT-related function from /// production code. Other values are passed from tests. @@ -76,8 +76,8 @@ pub fn compute_root( Hasher::Out: Ord, I: IntoIterator>>, { - use trie::TrieConfiguration; - Ok(trie::trie_types::Layout::::trie_root( + use sp_trie::TrieConfiguration; + Ok(sp_trie::trie_types::Layout::::trie_root( build_pairs::(cht_size, cht_num, hashes)? )) } @@ -92,15 +92,15 @@ pub fn build_proof( where Header: HeaderT, Hasher: hash_db::Hasher, - Hasher::Out: Ord, + Hasher::Out: Ord + codec::Codec, BlocksI: IntoIterator, HashesI: IntoIterator>>, { let transaction = build_pairs::(cht_size, cht_num, hashes)? .into_iter() - .map(|(k, v)| (None, k, Some(v))) + .map(|(k, v)| (k, Some(v))) .collect::>(); - let mut storage = InMemoryState::::default().update(transaction); + let mut storage = InMemoryState::::default().update(vec![(None, transaction)]); let trie_storage = storage.as_trie_backend() .expect("InMemoryState::as_trie_backend always returns Some; qed"); prove_read_on_trie_backend( @@ -119,7 +119,7 @@ pub fn check_proof( where Header: HeaderT, Hasher: hash_db::Hasher, - Hasher::Out: Ord, + Hasher::Out: Ord + codec::Codec, { do_check_proof::( local_root, @@ -148,7 +148,7 @@ pub fn check_proof_on_proving_backend( where Header: HeaderT, Hasher: hash_db::Hasher, - Hasher::Out: Ord, + Hasher::Out: Ord + codec::Codec, { do_check_proof::( local_root, @@ -317,8 +317,8 @@ pub fn decode_cht_value(value: &[u8]) -> Option { #[cfg(test)] mod tests { - use primitives::{Blake2Hasher}; - use test_client::runtime::Header; + use sp_core::{Blake2Hasher}; + use substrate_test_runtime_client::runtime::Header; use super::*; #[test] diff --git a/client/src/client.rs b/client/src/client.rs index 578845a20930b27721a84d0a02230c86c6a58e8e..a0fc940d24da7f0399723294e2bbbc29d23dbf94 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -25,14 +25,14 @@ use futures::channel::mpsc; use parking_lot::{Mutex, RwLock}; use codec::{Encode, Decode}; use hash_db::{Hasher, Prefix}; -use primitives::{ +use sp_core::{ Blake2Hasher, H256, ChangesTrieConfiguration, convert_hash, NeverNativeValue, ExecutionContext, NativeOrEncoded, - storage::{StorageKey, StorageData, well_known_keys}, + storage::{StorageKey, StorageData, well_known_keys, ChildInfo}, traits::CodeExecutor, }; -use substrate_telemetry::{telemetry, SUBSTRATE_INFO}; -use sr_primitives::{ +use sc_telemetry::{telemetry, SUBSTRATE_INFO}; +use sp_runtime::{ Justification, BuildStorage, generic::{BlockId, SignedBlock, DigestItem}, traits::{ @@ -40,33 +40,33 @@ use sr_primitives::{ ApiRef, ProvideRuntimeApi, SaturatedConversion, One, DigestFor, }, }; -use state_machine::{ +use sp_state_machine::{ DBValue, Backend as StateBackend, ChangesTrieAnchorBlockId, ExecutionStrategy, ExecutionManager, prove_read, prove_child_read, ChangesTrieRootsStorage, ChangesTrieStorage, ChangesTrieTransaction, ChangesTrieConfigurationRange, key_changes, key_changes_proof, OverlayedChanges, BackendTrustLevel, StorageProof, merge_storage_proofs, }; -use executor::{RuntimeVersion, RuntimeInfo}; -use consensus::{ +use sc_executor::{RuntimeVersion, RuntimeInfo}; +use sp_consensus::{ Error as ConsensusError, BlockStatus, BlockImportParams, BlockCheckParams, ImportResult, BlockOrigin, ForkChoiceStrategy, SelectChain, self, }; -use header_metadata::{HeaderMetadata, CachedHeaderMetadata}; +use sp_blockchain::{self as blockchain, + Backend as ChainBackend, + HeaderBackend as ChainHeaderBackend, ProvideCache, Cache, + well_known_cache_keys::Id as CacheKeyId, + HeaderMetadata, CachedHeaderMetadata, +}; -use sr_api::{CallRuntimeAt, ConstructRuntimeApi, Core as CoreApi, ProofRecorder, InitializeBlock}; -use block_builder::BlockBuilderApi; +use sp_api::{CallRuntimeAt, ConstructRuntimeApi, Core as CoreApi, ProofRecorder, InitializeBlock}; +use sc_block_builder::BlockBuilderApi; -pub use client_api::{ +pub use sc_client_api::{ backend::{ self, BlockImportOperation, PrunableStateChangesTrieStorage, ClientImportOperation, Finalizer, ImportSummary, NewBlockState, }, - blockchain::{ - self, Backend as ChainBackend, - HeaderBackend as ChainHeaderBackend, ProvideCache, Cache, - well_known_cache_keys::Id as CacheKeyId, - }, client::{ ImportNotifications, FinalityNotification, FinalityNotifications, BlockImportNotification, ClientInfo, BlockchainEvents, BlockBody, ProvideUncles, ForkBlocks, @@ -74,10 +74,9 @@ pub use client_api::{ }, execution_extensions::{ExecutionExtensions, ExecutionStrategies}, notifications::{StorageNotifications, StorageEventStream}, - error::Error, - error, CallExecutor, }; +use sp_blockchain::Error; use crate::{ call_executor::LocalCallExecutor, @@ -89,7 +88,7 @@ type StorageUpdate = < < >::BlockImportOperation as BlockImportOperation - >::State as state_machine::Backend>::Transaction; + >::State as sp_state_machine::Backend>::Transaction; type ChangesUpdate = ChangesTrieTransaction>; /// Substrate Client @@ -145,8 +144,8 @@ impl PrePostHeader { pub fn new_in_mem( executor: E, genesis_storage: S, - keystore: Option, -) -> error::Result, +) -> sp_blockchain::Result, LocalCallExecutor, E>, Block, @@ -165,8 +164,8 @@ pub fn new_with_backend( backend: Arc, executor: E, build_genesis_storage: S, - keystore: Option, -) -> error::Result, Block, RA>> + keystore: Option, +) -> sp_blockchain::Result, Block, RA>> where E: CodeExecutor + RuntimeInfo, S: BuildStorage, @@ -198,12 +197,12 @@ impl Client where build_genesis_storage: S, fork_blocks: ForkBlocks, execution_extensions: ExecutionExtensions, - ) -> error::Result { + ) -> sp_blockchain::Result { if backend.blockchain().header(BlockId::Number(Zero::zero()))?.is_none() { - let (genesis_storage, children_genesis_storage) = build_genesis_storage.build_storage()?; + let genesis_storage = build_genesis_storage.build_storage()?; let mut op = backend.begin_operation()?; backend.begin_state_operation(&mut op, BlockId::Hash(Default::default()))?; - let state_root = op.reset_storage(genesis_storage, children_genesis_storage)?; + let state_root = op.reset_storage(genesis_storage)?; let genesis_block = genesis::construct_genesis_block::(state_root.into()); info!("Initializing Genesis block/state (state: {}, header-hash: {})", genesis_block.header().state_root(), @@ -237,29 +236,29 @@ impl Client where } /// Get a reference to the state at a given block. - pub fn state_at(&self, block: &BlockId) -> error::Result { + pub fn state_at(&self, block: &BlockId) -> sp_blockchain::Result { self.backend.state_at(*block) } /// Given a `BlockId` and a key prefix, return the matching child storage keys in that block. - pub fn storage_keys(&self, id: &BlockId, key_prefix: &StorageKey) -> error::Result> { + pub fn storage_keys(&self, id: &BlockId, key_prefix: &StorageKey) -> sp_blockchain::Result> { let keys = self.state_at(id)?.keys(&key_prefix.0).into_iter().map(StorageKey).collect(); Ok(keys) } /// Given a `BlockId` and a key, return the value under the key in that block. - pub fn storage(&self, id: &BlockId, key: &StorageKey) -> error::Result> { + pub fn storage(&self, id: &BlockId, key: &StorageKey) -> sp_blockchain::Result> { Ok(self.state_at(id)? - .storage(&key.0).map_err(|e| error::Error::from_state(Box::new(e)))? + .storage(&key.0).map_err(|e| sp_blockchain::Error::from_state(Box::new(e)))? .map(StorageData) ) } /// Given a `BlockId` and a key, return the value under the hash in that block. pub fn storage_hash(&self, id: &BlockId, key: &StorageKey) - -> error::Result> { + -> sp_blockchain::Result> { Ok(self.state_at(id)? - .storage_hash(&key.0).map_err(|e| error::Error::from_state(Box::new(e)))? + .storage_hash(&key.0).map_err(|e| sp_blockchain::Error::from_state(Box::new(e)))? ) } @@ -268,10 +267,11 @@ impl Client where &self, id: &BlockId, child_storage_key: &StorageKey, + child_info: ChildInfo, key_prefix: &StorageKey - ) -> error::Result> { + ) -> sp_blockchain::Result> { let keys = self.state_at(id)? - .child_keys(&child_storage_key.0, &key_prefix.0) + .child_keys(&child_storage_key.0, child_info, &key_prefix.0) .into_iter() .map(StorageKey) .collect(); @@ -282,11 +282,13 @@ impl Client where pub fn child_storage( &self, id: &BlockId, - child_storage_key: &StorageKey, + storage_key: &StorageKey, + child_info: ChildInfo, key: &StorageKey - ) -> error::Result> { + ) -> sp_blockchain::Result> { Ok(self.state_at(id)? - .child_storage(&child_storage_key.0, &key.0).map_err(|e| error::Error::from_state(Box::new(e)))? + .child_storage(&storage_key.0, child_info, &key.0) + .map_err(|e| sp_blockchain::Error::from_state(Box::new(e)))? .map(StorageData)) } @@ -294,23 +296,25 @@ impl Client where pub fn child_storage_hash( &self, id: &BlockId, - child_storage_key: &StorageKey, + storage_key: &StorageKey, + child_info: ChildInfo, key: &StorageKey - ) -> error::Result> { + ) -> sp_blockchain::Result> { Ok(self.state_at(id)? - .child_storage_hash(&child_storage_key.0, &key.0).map_err(|e| error::Error::from_state(Box::new(e)))? + .child_storage_hash(&storage_key.0, child_info, &key.0) + .map_err(|e| sp_blockchain::Error::from_state(Box::new(e)))? ) } /// Get the code at a given block. - pub fn code_at(&self, id: &BlockId) -> error::Result> { + pub fn code_at(&self, id: &BlockId) -> sp_blockchain::Result> { Ok(self.storage(id, &StorageKey(well_known_keys::CODE.to_vec()))? .expect("None is returned if there's no value stored for the given key;\ ':code' key is always defined; qed").0) } /// Get the RuntimeVersion at a given block. - pub fn runtime_version_at(&self, id: &BlockId) -> error::Result { + pub fn runtime_version_at(&self, id: &BlockId) -> sp_blockchain::Result { self.executor.runtime_version(id) } @@ -320,7 +324,7 @@ impl Client where } /// Reads storage value at a given block + key, returning read proof. - pub fn read_proof(&self, id: &BlockId, keys: I) -> error::Result where + pub fn read_proof(&self, id: &BlockId, keys: I) -> sp_blockchain::Result where I: IntoIterator, I::Item: AsRef<[u8]>, { @@ -335,13 +339,14 @@ impl Client where &self, id: &BlockId, storage_key: &[u8], + child_info: ChildInfo, keys: I, - ) -> error::Result where + ) -> sp_blockchain::Result where I: IntoIterator, I::Item: AsRef<[u8]>, { self.state_at(id) - .and_then(|state| prove_child_read(state, storage_key, keys) + .and_then(|state| prove_child_read(state, storage_key, child_info, keys) .map_err(Into::into)) } @@ -353,21 +358,21 @@ impl Client where id: &BlockId, method: &str, call_data: &[u8] - ) -> error::Result<(Vec, StorageProof)> { + ) -> sp_blockchain::Result<(Vec, StorageProof)> { let state = self.state_at(id)?; let header = self.prepare_environment_block(id)?; prove_execution(state, header, &self.executor, method, call_data) } /// Reads given header and generates CHT-based header proof. - pub fn header_proof(&self, id: &BlockId) -> error::Result<(Block::Header, StorageProof)> { + pub fn header_proof(&self, id: &BlockId) -> sp_blockchain::Result<(Block::Header, StorageProof)> { self.header_proof_with_cht_size(id, cht::size()) } /// Get block hash by number. pub fn block_hash(&self, block_number: <::Header as HeaderT>::Number - ) -> error::Result> { + ) -> sp_blockchain::Result> { self.backend.blockchain().hash(block_number) } @@ -376,8 +381,8 @@ impl Client where &self, id: &BlockId, cht_size: NumberFor, - ) -> error::Result<(Block::Header, StorageProof)> { - let proof_error = || error::Error::Backend(format!("Failed to generate header proof for {:?}", id)); + ) -> sp_blockchain::Result<(Block::Header, StorageProof)> { + let proof_error = || sp_blockchain::Error::Backend(format!("Failed to generate header proof for {:?}", id)); let header = self.backend.blockchain().expect_header(*id)?; let block_num = *header.number(); let cht_num = cht::block_to_cht_number(cht_size, block_num).ok_or_else(proof_error)?; @@ -401,14 +406,14 @@ impl Client where &self, first: NumberFor, last: BlockId, - ) -> error::Result, BlockId)>> { + ) -> sp_blockchain::Result, BlockId)>> { let (config, storage) = match self.require_changes_trie().ok() { Some((config, storage)) => (config, storage), None => return Ok(None), }; let last_num = self.backend.blockchain().expect_block_number_from_id(&last)?; if first > last_num { - return Err(error::Error::ChangesTrieAccessFailed("Invalid changes trie range".into())); + return Err(sp_blockchain::Error::ChangesTrieAccessFailed("Invalid changes trie range".into())); } let finalized_number = self.backend.blockchain().info().finalized_number; let oldest = storage.oldest_changes_trie_block(&config, finalized_number); @@ -426,7 +431,7 @@ impl Client where last: BlockId, storage_key: Option<&StorageKey>, key: &StorageKey - ) -> error::Result, u32)>> { + ) -> sp_blockchain::Result, u32)>> { let (config, storage) = self.require_changes_trie()?; let last_number = self.backend.blockchain().expect_block_number_from_id(&last)?; let last_hash = self.backend.blockchain().expect_block_hash_from_id(&last)?; @@ -450,7 +455,7 @@ impl Client where storage_key.as_ref().map(|sk| sk.0.as_slice()), &key.0) .and_then(|r| r.map(|r| r.map(|(block, tx)| (block, tx))).collect::>()) - .map_err(|err| error::Error::ChangesTrieAccessFailed(err)) + .map_err(|err| sp_blockchain::Error::ChangesTrieAccessFailed(err)) } /// Get proof for computation of (block, extrinsic) pairs where key has been changed at given blocks range. @@ -467,7 +472,7 @@ impl Client where max: Block::Hash, storage_key: Option<&StorageKey>, key: &StorageKey, - ) -> error::Result> { + ) -> sp_blockchain::Result> { self.key_changes_proof_with_cht_size( first, last, @@ -489,7 +494,7 @@ impl Client where storage_key: Option<&StorageKey>, key: &StorageKey, cht_size: NumberFor, - ) -> error::Result> { + ) -> sp_blockchain::Result> { struct AccessedRootsRecorder<'a, Block: BlockT> { storage: &'a dyn ChangesTrieStorage>, min: NumberFor, @@ -520,7 +525,7 @@ impl Client where } impl<'a, Block: BlockT> ChangesTrieStorage> for AccessedRootsRecorder<'a, Block> { - fn as_roots_storage(&self) -> &dyn state_machine::ChangesTrieRootsStorage> { + fn as_roots_storage(&self) -> &dyn sp_state_machine::ChangesTrieRootsStorage> { self } @@ -575,7 +580,7 @@ impl Client where storage_key.as_ref().map(|sk| sk.0.as_slice()), &key.0, ) - .map_err(|err| error::Error::from(error::Error::ChangesTrieAccessFailed(err)))?; + .map_err(|err| sp_blockchain::Error::from(sp_blockchain::Error::ChangesTrieAccessFailed(err)))?; // now gather proofs for all changes tries roots that were touched during key_changes_proof // execution AND are unknown (i.e. replaced with CHT) to the requester @@ -595,7 +600,7 @@ impl Client where &self, cht_size: NumberFor, blocks: I - ) -> error::Result { + ) -> sp_blockchain::Result { // most probably we have touched several changes tries that are parts of the single CHT // => GroupBy changes tries by CHT number and then gather proof for the whole group at once let mut proofs = Vec::new(); @@ -615,7 +620,7 @@ impl Client where cht_size: NumberFor, cht_num: NumberFor, blocks: Vec> - ) -> error::Result { + ) -> sp_blockchain::Result { let cht_start = cht::start_number(cht_size, cht_num); let mut current_num = cht_start; let cht_range = ::std::iter::from_fn(|| { @@ -631,12 +636,12 @@ impl Client where } /// Returns changes trie configuration and storage or an error if it is not supported. - fn require_changes_trie(&self) -> error::Result<(ChangesTrieConfiguration, &B::ChangesTrieStorage)> { + fn require_changes_trie(&self) -> sp_blockchain::Result<(ChangesTrieConfiguration, &B::ChangesTrieStorage)> { let config = self.changes_trie_config()?; let storage = self.backend.changes_trie_storage(); match (config, storage) { (Some(config), Some(storage)) => Ok((config, storage)), - _ => Err(error::Error::ChangesTriesNotSupported.into()), + _ => Err(sp_blockchain::Error::ChangesTriesNotSupported.into()), } } @@ -644,14 +649,14 @@ impl Client where pub fn new_block( &self, inherent_digests: DigestFor, - ) -> error::Result> where + ) -> sp_blockchain::Result> where E: Clone + Send + Sync, RA: Send + Sync, Self: ProvideRuntimeApi, ::Api: BlockBuilderApi { let info = self.info(); - block_builder::BlockBuilder::new( + sc_block_builder::BlockBuilder::new( self, info.chain.best_hash, info.chain.best_number, @@ -665,13 +670,13 @@ impl Client where &self, parent: &BlockId, inherent_digests: DigestFor, - ) -> error::Result> where + ) -> sp_blockchain::Result> where E: Clone + Send + Sync, RA: Send + Sync, Self: ProvideRuntimeApi, ::Api: BlockBuilderApi { - block_builder::BlockBuilder::new( + sc_block_builder::BlockBuilder::new( self, self.expect_block_hash_from_id(parent)?, self.expect_block_number_from_id(parent)?, @@ -689,13 +694,13 @@ impl Client where &self, parent: &BlockId, inherent_digests: DigestFor, - ) -> error::Result> where + ) -> sp_blockchain::Result> where E: Clone + Send + Sync, RA: Send + Sync, Self: ProvideRuntimeApi, ::Api: BlockBuilderApi { - block_builder::BlockBuilder::new( + sc_block_builder::BlockBuilder::new( self, self.expect_block_hash_from_id(parent)?, self.expect_block_number_from_id(parent)?, @@ -707,10 +712,10 @@ impl Client where /// Lock the import lock, and run operations inside. pub fn lock_import_and_run(&self, f: F) -> Result where F: FnOnce(&mut ClientImportOperation) -> Result, - Err: From, + Err: From, { let inner = || { - let _import_lock = self.backend.get_import_lock().lock(); + let _import_lock = self.backend.get_import_lock().write(); let mut op = ClientImportOperation { op: self.backend.begin_operation()?, @@ -744,7 +749,7 @@ impl Client where operation: &mut ClientImportOperation, import_block: BlockImportParams, new_cache: HashMap>, - ) -> error::Result where + ) -> sp_blockchain::Result where E: CallExecutor + Send + Sync + Clone, { let BlockImportParams { @@ -757,6 +762,7 @@ impl Client where auxiliary, fork_choice, allow_missing_state, + import_existing, } = import_block; assert!(justification.is_some() && finalized || justification.is_none()); @@ -801,6 +807,7 @@ impl Client where auxiliary, fork_choice, enact_state, + import_existing, ); if let Ok(ImportResult::Imported(ref aux)) = result { @@ -829,13 +836,17 @@ impl Client where aux: Vec<(Vec, Option>)>, fork_choice: ForkChoiceStrategy, enact_state: bool, - ) -> error::Result where + import_existing: bool, + ) -> sp_blockchain::Result where E: CallExecutor + Send + Sync + Clone, { let parent_hash = import_headers.post().parent_hash().clone(); - match self.backend.blockchain().status(BlockId::Hash(hash))? { - blockchain::BlockStatus::InChain => return Ok(ImportResult::AlreadyInChain), - blockchain::BlockStatus::Unknown => {}, + let status = self.backend.blockchain().status(BlockId::Hash(hash))?; + match (import_existing, status) { + (false, blockchain::BlockStatus::InChain) => return Ok(ImportResult::AlreadyInChain), + (false, blockchain::BlockStatus::Unknown) => {}, + (true, blockchain::BlockStatus::InChain) => {}, + (true, blockchain::BlockStatus::Unknown) => return Err(Error::UnknownBlock(format!("{:?}", hash))), } let info = self.backend.blockchain().info(); @@ -843,7 +854,7 @@ impl Client where // the block is lower than our last finalized block so it must revert // finality, refusing import. if *import_headers.post().number() <= info.finalized_number { - return Err(error::Error::NotInFinalizedChain); + return Err(sp_blockchain::Error::NotInFinalizedChain); } // this is a fairly arbitrary choice of where to draw the line on making notifications, @@ -902,7 +913,7 @@ impl Client where }; let retracted = if is_new_best { - let route_from_best = header_metadata::tree_route( + let route_from_best = sp_blockchain::tree_route( self.backend.blockchain(), info.best_hash, parent_hash, @@ -948,7 +959,7 @@ impl Client where origin: BlockOrigin, hash: Block::Hash, body: &[Block::Extrinsic], - ) -> error::Result<( + ) -> sp_blockchain::Result<( Option>, Option>>, Option<( @@ -1007,9 +1018,9 @@ impl Client where overlay.commit_prospective(); let (top, children) = overlay.into_committed(); - let children = children.map(|(sk, it)| (sk, it.collect())).collect(); + let children = children.map(|(sk, it)| (sk, it.0.collect())).collect(); if import_headers.post().state_root() != &storage_update.1 { - return Err(error::Error::InvalidStateRoot); + return Err(sp_blockchain::Error::InvalidStateRoot); } Ok((Some(storage_update.0), Some(changes_update), Some((top.collect(), children)))) @@ -1025,7 +1036,7 @@ impl Client where justification: Option, best_block: Block::Hash, notify: bool, - ) -> error::Result<()> { + ) -> sp_blockchain::Result<()> { // find tree route from last finalized to given block. let last_finalized = self.backend.blockchain().last_finalized()?; @@ -1034,16 +1045,16 @@ impl Client where return Ok(()); } - let route_from_finalized = header_metadata::tree_route(self.backend.blockchain(), last_finalized, block)?; + let route_from_finalized = sp_blockchain::tree_route(self.backend.blockchain(), last_finalized, block)?; if let Some(retracted) = route_from_finalized.retracted().get(0) { warn!("Safety violation: attempted to revert finalized block {:?} which is not in the \ same chain as last finalized {:?}", retracted, last_finalized); - return Err(error::Error::NotInFinalizedChain); + return Err(sp_blockchain::Error::NotInFinalizedChain); } - let route_from_best = header_metadata::tree_route(self.backend.blockchain(), best_block, block)?; + let route_from_best = sp_blockchain::tree_route(self.backend.blockchain(), best_block, block)?; // if the block is not a direct ancestor of the current best chain, // then some other block is the common ancestor. @@ -1083,7 +1094,7 @@ impl Client where fn notify_finalized( &self, notify_finalized: Vec, - ) -> error::Result<()> { + ) -> sp_blockchain::Result<()> { let mut sinks = self.finality_notification_sinks.lock(); for finalized_hash in notify_finalized { @@ -1106,7 +1117,7 @@ impl Client where Ok(()) } - fn notify_imported(&self, notify_import: ImportSummary) -> error::Result<()> { + fn notify_imported(&self, notify_import: ImportSummary) -> sp_blockchain::Result<()> { if let Some(storage_changes) = notify_import.storage_changes { // TODO [ToDr] How to handle re-orgs? Should we re-emit all storage changes? self.storage_notifications.lock() @@ -1133,7 +1144,7 @@ impl Client where /// Attempts to revert the chain by `n` blocks. Returns the number of blocks that were /// successfully reverted. - pub fn revert(&self, n: NumberFor) -> error::Result> { + pub fn revert(&self, n: NumberFor) -> sp_blockchain::Result> { Ok(self.backend.revert(n)?) } @@ -1147,7 +1158,7 @@ impl Client where } /// Get block status. - pub fn block_status(&self, id: &BlockId) -> error::Result { + pub fn block_status(&self, id: &BlockId) -> sp_blockchain::Result { // this can probably be implemented more efficiently if let BlockId::Hash(ref h) = id { if self.importing_block.read().as_ref().map_or(false, |importing| h == importing) { @@ -1171,23 +1182,23 @@ impl Client where } /// Get block header by id. - pub fn header(&self, id: &BlockId) -> error::Result::Header>> { + pub fn header(&self, id: &BlockId) -> sp_blockchain::Result::Header>> { self.backend.blockchain().header(*id) } /// Get block body by id. - pub fn body(&self, id: &BlockId) -> error::Result::Extrinsic>>> { + pub fn body(&self, id: &BlockId) -> sp_blockchain::Result::Extrinsic>>> { self.backend.blockchain().body(*id) } /// Get block justification set by id. - pub fn justification(&self, id: &BlockId) -> error::Result> { + pub fn justification(&self, id: &BlockId) -> sp_blockchain::Result> { self.backend.blockchain().justification(*id) } /// Get full block by id. pub fn block(&self, id: &BlockId) - -> error::Result>> + -> sp_blockchain::Result>> { Ok(match (self.header(id)?, self.body(id)?, self.justification(id)?) { (Some(header), Some(extrinsics), justification) => @@ -1197,8 +1208,8 @@ impl Client where } /// Gets the uncles of the block with `target_hash` going back `max_generation` ancestors. - pub fn uncles(&self, target_hash: Block::Hash, max_generation: NumberFor) -> error::Result> { - let load_header = |id: Block::Hash| -> error::Result { + pub fn uncles(&self, target_hash: Block::Hash, max_generation: NumberFor) -> sp_blockchain::Result> { + let load_header = |id: Block::Hash| -> sp_blockchain::Result { match self.backend.blockchain().header(BlockId::Hash(id))? { Some(hdr) => Ok(hdr), None => Err(Error::UnknownBlock(format!("{:?}", id))), @@ -1230,12 +1241,12 @@ impl Client where fn changes_trie_config(&self) -> Result, Error> { Ok(self.backend.state_at(BlockId::Number(self.backend.blockchain().info().best_number))? .storage(well_known_keys::CHANGES_TRIE_CONFIG) - .map_err(|e| error::Error::from_state(Box::new(e)))? + .map_err(|e| sp_blockchain::Error::from_state(Box::new(e)))? .and_then(|c| Decode::decode(&mut &*c).ok())) } /// Prepare in-memory header that is used in execution environment. - fn prepare_environment_block(&self, parent: &BlockId) -> error::Result { + fn prepare_environment_block(&self, parent: &BlockId) -> sp_blockchain::Result { let parent_header = self.backend.blockchain().expect_header(*parent)?; Ok(<::Header as HeaderT>::new( self.backend.blockchain().expect_block_number_from_id(parent)? + One::one(), @@ -1252,7 +1263,7 @@ impl HeaderMetadata for Client where E: CallExecutor, Block: BlockT, { - type Error = error::Error; + type Error = sp_blockchain::Error; fn header_metadata(&self, hash: Block::Hash) -> Result, Self::Error> { self.backend.blockchain().header_metadata(hash) @@ -1272,7 +1283,7 @@ impl ProvideUncles for Client where E: CallExecutor, Block: BlockT, { - fn uncles(&self, target_hash: Block::Hash, max_generation: NumberFor) -> error::Result> { + fn uncles(&self, target_hash: Block::Hash, max_generation: NumberFor) -> sp_blockchain::Result> { Ok(Client::uncles(self, target_hash, max_generation)? .into_iter() .filter_map(|hash| Client::header(self, &BlockId::Hash(hash)).unwrap_or(None)) @@ -1287,7 +1298,7 @@ impl ChainHeaderBackend for Client wher Block: BlockT, RA: Send + Sync, { - fn header(&self, id: BlockId) -> error::Result> { + fn header(&self, id: BlockId) -> sp_blockchain::Result> { self.backend.blockchain().header(id) } @@ -1295,20 +1306,20 @@ impl ChainHeaderBackend for Client wher self.backend.blockchain().info() } - fn status(&self, id: BlockId) -> error::Result { + fn status(&self, id: BlockId) -> sp_blockchain::Result { self.backend.blockchain().status(id) } - fn number(&self, hash: Block::Hash) -> error::Result::Header as HeaderT>::Number>> { + fn number(&self, hash: Block::Hash) -> sp_blockchain::Result::Header as HeaderT>::Number>> { self.backend.blockchain().number(hash) } - fn hash(&self, number: NumberFor) -> error::Result> { + fn hash(&self, number: NumberFor) -> sp_blockchain::Result> { self.backend.blockchain().hash(number) } } -impl sr_primitives::traits::BlockIdTo for Client where +impl sp_runtime::traits::BlockIdTo for Client where B: backend::Backend, E: CallExecutor + Send + Sync, Block: BlockT, @@ -1316,11 +1327,11 @@ impl sr_primitives::traits::BlockIdTo for Client) -> error::Result> { + fn to_hash(&self, block_id: &BlockId) -> sp_blockchain::Result> { self.block_hash_from_id(block_id) } - fn to_number(&self, block_id: &BlockId) -> error::Result>> { + fn to_number(&self, block_id: &BlockId) -> sp_blockchain::Result>> { self.block_number_from_id(block_id) } } @@ -1331,7 +1342,7 @@ impl ChainHeaderBackend for &Client whe Block: BlockT, RA: Send + Sync, { - fn header(&self, id: BlockId) -> error::Result> { + fn header(&self, id: BlockId) -> sp_blockchain::Result> { (**self).backend.blockchain().header(id) } @@ -1339,15 +1350,15 @@ impl ChainHeaderBackend for &Client whe (**self).backend.blockchain().info() } - fn status(&self, id: BlockId) -> error::Result { + fn status(&self, id: BlockId) -> sp_blockchain::Result { (**self).status(id) } - fn number(&self, hash: Block::Hash) -> error::Result::Header as HeaderT>::Number>> { + fn number(&self, hash: Block::Hash) -> sp_blockchain::Result::Header as HeaderT>::Number>> { (**self).number(hash) } - fn hash(&self, number: NumberFor) -> error::Result> { + fn hash(&self, number: NumberFor) -> sp_blockchain::Result> { (**self).hash(number) } } @@ -1397,7 +1408,7 @@ impl CallRuntimeAt for Client where native_call: Option, context: ExecutionContext, recorder: &Option>, - ) -> error::Result> { + ) -> sp_blockchain::Result> { let (manager, extensions) = self.execution_extensions.manager_and_extensions(at, context); self.executor.contextual_call::<_, fn(_,_) -> _,_,_>( || core_api.initialize_block(at, &self.prepare_environment_block(at)?), @@ -1413,7 +1424,7 @@ impl CallRuntimeAt for Client where ) } - fn runtime_version_at(&self, at: &BlockId) -> error::Result { + fn runtime_version_at(&self, at: &BlockId) -> sp_blockchain::Result { self.runtime_version_at(at) } } @@ -1421,7 +1432,7 @@ impl CallRuntimeAt for Client where /// NOTE: only use this implementation when you are sure there are NO consensus-level BlockImport /// objects. Otherwise, importing blocks directly into the client would be bypassing /// important verification work. -impl<'a, B, E, Block, RA> consensus::BlockImport for &'a Client where +impl<'a, B, E, Block, RA> sp_consensus::BlockImport for &'a Client where B: backend::Backend, E: CallExecutor + Clone + Send + Sync, Block: BlockT, @@ -1455,7 +1466,7 @@ impl<'a, B, E, Block, RA> consensus::BlockImport for &'a Client, ) -> Result { - let BlockCheckParams { hash, number, parent_hash, allow_missing_state } = block; + let BlockCheckParams { hash, number, parent_hash, allow_missing_state, import_existing } = block; if let Some(h) = self.fork_blocks.as_ref().and_then(|x| x.get(&number)) { if &hash != h { @@ -1474,7 +1485,8 @@ impl<'a, B, E, Block, RA> consensus::BlockImport for &'a Client return Ok(ImportResult::AlreadyInChain), + BlockStatus::InChainWithState | BlockStatus::Queued if !import_existing => return Ok(ImportResult::AlreadyInChain), + BlockStatus::InChainWithState | BlockStatus::Queued => {}, BlockStatus::InChainPruned => return Ok(ImportResult::AlreadyInChain), BlockStatus::Unknown => {}, BlockStatus::KnownBad => return Ok(ImportResult::KnownBad), @@ -1495,7 +1507,7 @@ impl<'a, B, E, Block, RA> consensus::BlockImport for &'a Client consensus::BlockImport for Client where +impl sp_consensus::BlockImport for Client where B: backend::Backend, E: CallExecutor + Clone + Send + Sync, Block: BlockT, @@ -1529,13 +1541,13 @@ impl Finalizer for Client, justification: Option, notify: bool, - ) -> error::Result<()> { + ) -> sp_blockchain::Result<()> { let last_best = self.backend.blockchain().info().best_hash; let to_finalize_hash = self.backend.blockchain().expect_block_hash_from_id(&id)?; self.apply_finality_with_block_hash(operation, to_finalize_hash, justification, last_best, notify) } - fn finalize_block(&self, id: BlockId, justification: Option, notify: bool) -> error::Result<()> { + fn finalize_block(&self, id: BlockId, justification: Option, notify: bool) -> sp_blockchain::Result<()> { self.lock_import_and_run(|operation| { self.apply_finality(operation, id, justification, notify) }) @@ -1553,11 +1565,11 @@ impl Finalizer for &Client, justification: Option, notify: bool, - ) -> error::Result<()> { + ) -> sp_blockchain::Result<()> { (**self).apply_finality(operation, id, justification, notify) } - fn finalize_block(&self, id: BlockId, justification: Option, notify: bool) -> error::Result<()> { + fn finalize_block(&self, id: BlockId, justification: Option, notify: bool) -> sp_blockchain::Result<()> { (**self).finalize_block(id, justification, notify) } } @@ -1585,7 +1597,7 @@ where &self, filter_keys: Option<&[StorageKey]>, child_filter_keys: Option<&[(StorageKey, Option>)]>, - ) -> error::Result> { + ) -> sp_blockchain::Result> { Ok(self.storage_notifications.lock().listen(filter_keys, child_filter_keys)) } } @@ -1620,7 +1632,7 @@ where } } - fn best_block_header(&self) -> error::Result<::Header> { + fn best_block_header(&self) -> sp_blockchain::Result<::Header> { let info = self.backend.blockchain().info(); let import_lock = self.backend.get_import_lock(); let best_hash = self.backend.blockchain().best_containing(info.best_hash, None, import_lock)? @@ -1630,7 +1642,7 @@ where .expect("given block hash was fetched from block in db; qed")) } - fn leaves(&self) -> Result::Hash>, error::Error> { + fn leaves(&self) -> Result::Hash>, sp_blockchain::Error> { self.backend.blockchain().leaves() } } @@ -1670,7 +1682,7 @@ impl BlockBody for Client E: CallExecutor, Block: BlockT, { - fn block_body(&self, id: &BlockId) -> error::Result::Extrinsic>>> { + fn block_body(&self, id: &BlockId) -> sp_blockchain::Result::Extrinsic>>> { self.body(id) } } @@ -1688,7 +1700,7 @@ impl backend::AuxStore for Client 'c: 'a, I: IntoIterator, D: IntoIterator, - >(&self, insert: I, delete: D) -> error::Result<()> { + >(&self, insert: I, delete: D) -> sp_blockchain::Result<()> { // Import is locked here because we may have other block import // operations that tries to set aux data. Note that for consensus // layer, one can always use atomic operations to make sure @@ -1698,7 +1710,7 @@ impl backend::AuxStore for Client }) } /// Query auxiliary data from key-value store. - fn get_aux(&self, key: &[u8]) -> error::Result>> { + fn get_aux(&self, key: &[u8]) -> sp_blockchain::Result>> { backend::AuxStore::get_aux(&*self.backend, key) } } @@ -1717,11 +1729,11 @@ impl backend::AuxStore for &Client 'c: 'a, I: IntoIterator, D: IntoIterator, - >(&self, insert: I, delete: D) -> error::Result<()> { + >(&self, insert: I, delete: D) -> sp_blockchain::Result<()> { (**self).insert_aux(insert, delete) } - fn get_aux(&self, key: &[u8]) -> error::Result>> { + fn get_aux(&self, key: &[u8]) -> sp_blockchain::Result>> { (**self).get_aux(key) } } @@ -1731,7 +1743,7 @@ pub fn apply_aux<'a, 'b: 'a, 'c: 'a, B, Block, H, D, I>( operation: &mut ClientImportOperation, insert: I, delete: D -) -> error::Result<()> +) -> sp_blockchain::Result<()> where Block: BlockT, H: Hasher, @@ -1746,10 +1758,11 @@ where ) } -impl consensus::block_validation::Chain for Client - where BE: backend::Backend, - E: CallExecutor, - B: BlockT +impl sp_consensus::block_validation::Chain for Client + where + BE: backend::Backend, + E: CallExecutor, + B: BlockT { fn block_status(&self, id: &BlockId) -> Result> { Client::block_status(self, id).map_err(|e| Box::new(e) as Box<_>) @@ -1760,13 +1773,13 @@ impl consensus::block_validation::Chain for Client ( - test_client::client::Client, + substrate_test_runtime_client::sc_client::Client, Vec, Vec<(u64, u64, Vec, Vec<(u64, u32)>)>, ) { @@ -1845,7 +1858,7 @@ pub(crate) mod tests { #[test] fn client_initializes_from_genesis_ok() { - let client = test_client::new(); + let client = substrate_test_runtime_client::new(); assert_eq!( client.runtime_api().balance_of( @@ -1865,7 +1878,7 @@ pub(crate) mod tests { #[test] fn block_builder_works_with_no_transactions() { - let client = test_client::new(); + let client = substrate_test_runtime_client::new(); let builder = client.new_block(Default::default()).unwrap(); @@ -1876,7 +1889,7 @@ pub(crate) mod tests { #[test] fn block_builder_works_with_transactions() { - let client = test_client::new(); + let client = substrate_test_runtime_client::new(); let mut builder = client.new_block(Default::default()).unwrap(); @@ -1912,7 +1925,7 @@ pub(crate) mod tests { #[test] fn block_builder_does_not_include_invalid() { - let client = test_client::new(); + let client = substrate_test_runtime_client::new(); let mut builder = client.new_block(Default::default()).unwrap(); @@ -1974,7 +1987,7 @@ pub(crate) mod tests { fn uncles_with_only_ancestors() { // block tree: // G -> A1 -> A2 - let client = test_client::new(); + let client = substrate_test_runtime_client::new(); // G -> A1 let a1 = client.new_block(Default::default()).unwrap().bake().unwrap(); @@ -1994,7 +2007,7 @@ pub(crate) mod tests { // A1 -> B2 -> B3 -> B4 // B2 -> C3 // A1 -> D2 - let client = test_client::new(); + let client = substrate_test_runtime_client::new(); // G -> A1 let a1 = client.new_block(Default::default()).unwrap().bake().unwrap(); @@ -2431,7 +2444,7 @@ pub(crate) mod tests { #[test] fn import_with_justification() { - let client = test_client::new(); + let client = substrate_test_runtime_client::new(); // G -> A1 let a1 = client.new_block(Default::default()).unwrap().bake().unwrap(); @@ -2470,7 +2483,7 @@ pub(crate) mod tests { #[test] fn importing_diverged_finalized_block_should_trigger_reorg() { - let client = test_client::new(); + let client = substrate_test_runtime_client::new(); // G -> A1 -> A2 // \ @@ -2586,7 +2599,7 @@ pub(crate) mod tests { #[test] fn get_header_by_block_number_doesnt_panic() { - let client = test_client::new(); + let client = substrate_test_runtime_client::new(); // backend uses u32 for block numbers, make sure we don't panic when // trying to convert @@ -2597,7 +2610,7 @@ pub(crate) mod tests { #[test] fn state_reverted_on_reorg() { let _ = env_logger::try_init(); - let client = test_client::new(); + let client = substrate_test_runtime_client::new(); let current_balance = || client.runtime_api().balance_of( @@ -2702,7 +2715,7 @@ pub(crate) mod tests { let import_err = client.import(BlockOrigin::Own, b3).err().unwrap(); let expected_err = ConsensusError::ClientImport( - error::Error::NotInFinalizedChain.to_string() + sp_blockchain::Error::NotInFinalizedChain.to_string() ); assert_eq!( @@ -2725,7 +2738,7 @@ pub(crate) mod tests { let import_err = client.import(BlockOrigin::Own, c1).err().unwrap(); let expected_err = ConsensusError::ClientImport( - error::Error::NotInFinalizedChain.to_string() + sp_blockchain::Error::NotInFinalizedChain.to_string() ); assert_eq!( @@ -2774,7 +2787,8 @@ pub(crate) mod tests { hash: a1.hash().clone(), number: 0, parent_hash: a1.header().parent_hash().clone(), - allow_missing_state: false + allow_missing_state: false, + import_existing: false, }; assert_eq!(client.check_block(check_block_a1.clone()).unwrap(), ImportResult::imported(false)); @@ -2793,7 +2807,8 @@ pub(crate) mod tests { hash: a2.hash().clone(), number: 1, parent_hash: a1.header().parent_hash().clone(), - allow_missing_state: false + allow_missing_state: false, + import_existing: false, }; assert_eq!(client.check_block(check_block_a1.clone()).unwrap(), ImportResult::AlreadyInChain); @@ -2809,7 +2824,8 @@ pub(crate) mod tests { hash: a3.hash().clone(), number: 2, parent_hash: a2.header().parent_hash().clone(), - allow_missing_state: false + allow_missing_state: false, + import_existing: false, }; // a1 and a2 are both pruned at this point @@ -2824,7 +2840,8 @@ pub(crate) mod tests { hash: b1.hash().clone(), number: 0, parent_hash: b1.header().parent_hash().clone(), - allow_missing_state: false + allow_missing_state: false, + import_existing: false, }; assert_eq!(client.check_block(check_block_b1.clone()).unwrap(), ImportResult::MissingState); check_block_b1.allow_missing_state = true; diff --git a/client/src/genesis.rs b/client/src/genesis.rs index 94822466bbff5e22ca90f461a4667545e872f93b..506771217d79fe348993993f547b7b8a4a5287ac 100644 --- a/client/src/genesis.rs +++ b/client/src/genesis.rs @@ -16,7 +16,7 @@ //! Tool for creating the genesis block. -use sr_primitives::traits::{Block as BlockT, Header as HeaderT, Hash as HashT, Zero}; +use sp_runtime::traits::{Block as BlockT, Header as HeaderT, Hash as HashT, Zero}; /// Create a genesis block, given the initial storage. pub fn construct_genesis_block< @@ -43,27 +43,27 @@ pub fn construct_genesis_block< #[cfg(test)] mod tests { use codec::{Encode, Decode, Joiner}; - use executor::native_executor_instance; - use state_machine::{ + use sc_executor::native_executor_instance; + use sp_state_machine::{ StateMachine, OverlayedChanges, ExecutionStrategy, InMemoryChangesTrieStorage, }; - use state_machine::backend::InMemory; - use test_client::{ + use sp_state_machine::backend::InMemory; + use substrate_test_runtime_client::{ runtime::genesismap::{GenesisConfig, insert_genesis_block}, runtime::{Hash, Transfer, Block, BlockNumber, Header, Digest}, AccountKeyring, Sr25519Keyring, }; - use primitives::{Blake2Hasher, map}; + use sp_core::Blake2Hasher; use hex_literal::*; native_executor_instance!( Executor, - test_client::runtime::api::dispatch, - test_client::runtime::native_version + substrate_test_runtime_client::runtime::api::dispatch, + substrate_test_runtime_client::runtime::native_version ); - fn executor() -> executor::NativeExecutor { - executor::NativeExecutor::new(executor::WasmExecutionMethod::Interpreted, None) + fn executor() -> sc_executor::NativeExecutor { + sc_executor::NativeExecutor::new(sc_executor::WasmExecutionMethod::Interpreted, None) } fn construct_block( @@ -73,7 +73,7 @@ mod tests { state_root: Hash, txs: Vec ) -> (Vec, Hash) { - use trie::{TrieConfiguration, trie_types::Layout}; + use sp_trie::{TrieConfiguration, trie_types::Layout}; let transactions = txs.into_iter().map(|tx| tx.into_signed_tx()).collect::>(); @@ -154,8 +154,7 @@ mod tests { vec![AccountKeyring::One.into(), AccountKeyring::Two.into()], 1000, None, - map![], - map![], + Default::default(), ).genesis_map(); let genesis_hash = insert_genesis_block(&mut storage); @@ -183,8 +182,7 @@ mod tests { vec![AccountKeyring::One.into(), AccountKeyring::Two.into()], 1000, None, - map![], - map![], + Default::default(), ).genesis_map(); let genesis_hash = insert_genesis_block(&mut storage); @@ -212,8 +210,7 @@ mod tests { vec![AccountKeyring::One.into(), AccountKeyring::Two.into()], 68, None, - map![], - map![], + Default::default(), ).genesis_map(); let genesis_hash = insert_genesis_block(&mut storage); diff --git a/client/src/in_mem.rs b/client/src/in_mem.rs index efab895794eeacc8b5fba59ded0610f23f7bbe70..58e88934f3ea57cdaae87c81b3a2441c30db3a66 100644 --- a/client/src/in_mem.rs +++ b/client/src/in_mem.rs @@ -18,22 +18,21 @@ use std::collections::{HashMap, HashSet}; use std::sync::Arc; -use parking_lot::{RwLock, Mutex}; -use primitives::{ChangesTrieConfiguration, storage::well_known_keys}; -use primitives::offchain::storage::{ +use parking_lot::RwLock; +use sp_core::{ChangesTrieConfiguration, storage::well_known_keys}; +use sp_core::offchain::storage::{ InMemOffchainStorage as OffchainStorage }; -use sr_primitives::generic::{BlockId, DigestItem}; -use sr_primitives::traits::{Block as BlockT, Header as HeaderT, Zero, NumberFor}; -use sr_primitives::{Justification, StorageOverlay, ChildrenStorageOverlay}; -use state_machine::backend::{Backend as StateBackend, InMemory}; -use state_machine::{self, InMemoryChangesTrieStorage, ChangesTrieAnchorBlockId, ChangesTrieTransaction}; +use sp_runtime::generic::{BlockId, DigestItem}; +use sp_runtime::traits::{Block as BlockT, Header as HeaderT, Zero, NumberFor}; +use sp_runtime::{Justification, Storage}; +use sp_state_machine::backend::{Backend as StateBackend, InMemory}; +use sp_state_machine::{self, InMemoryChangesTrieStorage, ChangesTrieAnchorBlockId, ChangesTrieTransaction}; use hash_db::{Hasher, Prefix}; -use trie::MemoryDB; -use header_metadata::{CachedHeaderMetadata, HeaderMetadata}; +use sp_trie::MemoryDB; +use sp_blockchain::{CachedHeaderMetadata, HeaderMetadata}; -use client_api::{ - error, +use sc_client_api::{ backend::{self, NewBlockState, StorageCollection, ChildStorageCollection}, blockchain::{ self, BlockStatus, HeaderBackend, well_known_cache_keys::Id as CacheKeyId @@ -158,7 +157,7 @@ impl Blockchain { justification: Option, body: Option::Extrinsic>>, new_state: NewBlockState, - ) -> client_api::error::Result<()> { + ) -> sp_blockchain::Result<()> { let number = header.number().clone(); if new_state.is_best() { self.apply_head(&header)?; @@ -208,16 +207,16 @@ impl Blockchain { } /// Set an existing block as head. - pub fn set_head(&self, id: BlockId) -> error::Result<()> { + pub fn set_head(&self, id: BlockId) -> sp_blockchain::Result<()> { let header = match self.header(id)? { Some(h) => h, - None => return Err(error::Error::UnknownBlock(format!("{}", id))), + None => return Err(sp_blockchain::Error::UnknownBlock(format!("{}", id))), }; self.apply_head(&header) } - fn apply_head(&self, header: &::Header) -> error::Result<()> { + fn apply_head(&self, header: &::Header) -> sp_blockchain::Result<()> { let hash = header.hash(); let number = header.number(); @@ -228,7 +227,7 @@ impl Blockchain { if &best_hash == header.parent_hash() { None } else { - let route = header_metadata::tree_route(self, best_hash, *header.parent_hash())?; + let route = sp_blockchain::tree_route(self, best_hash, *header.parent_hash())?; Some(route) } }; @@ -255,10 +254,10 @@ impl Blockchain { Ok(()) } - fn finalize_header(&self, id: BlockId, justification: Option) -> error::Result<()> { + fn finalize_header(&self, id: BlockId, justification: Option) -> sp_blockchain::Result<()> { let hash = match self.header(id)? { Some(h) => h.hash(), - None => return Err(error::Error::UnknownBlock(format!("{}", id))), + None => return Err(sp_blockchain::Error::UnknownBlock(format!("{}", id))), }; let mut storage = self.storage.write(); @@ -290,7 +289,7 @@ impl Blockchain { } impl HeaderBackend for Blockchain { - fn header(&self, id: BlockId) -> error::Result::Header>> { + fn header(&self, id: BlockId) -> sp_blockchain::Result::Header>> { Ok(self.id(id).and_then(|hash| { self.storage.read().blocks.get(&hash).map(|b| b.header().clone()) })) @@ -307,28 +306,28 @@ impl HeaderBackend for Blockchain { } } - fn status(&self, id: BlockId) -> error::Result { + fn status(&self, id: BlockId) -> sp_blockchain::Result { match self.id(id).map_or(false, |hash| self.storage.read().blocks.contains_key(&hash)) { true => Ok(BlockStatus::InChain), false => Ok(BlockStatus::Unknown), } } - fn number(&self, hash: Block::Hash) -> error::Result>> { + fn number(&self, hash: Block::Hash) -> sp_blockchain::Result>> { Ok(self.storage.read().blocks.get(&hash).map(|b| *b.header().number())) } - fn hash(&self, number: <::Header as HeaderT>::Number) -> error::Result> { + fn hash(&self, number: <::Header as HeaderT>::Number) -> sp_blockchain::Result> { Ok(self.id(BlockId::Number(number))) } } impl HeaderMetadata for Blockchain { - type Error = error::Error; + type Error = sp_blockchain::Error; fn header_metadata(&self, hash: Block::Hash) -> Result, Self::Error> { self.header(BlockId::hash(hash))?.map(|header| CachedHeaderMetadata::from(&header)) - .ok_or(error::Error::UnknownBlock(format!("header not found: {}", hash))) + .ok_or(sp_blockchain::Error::UnknownBlock(format!("header not found: {}", hash))) } fn insert_header_metadata(&self, _hash: Block::Hash, _metadata: CachedHeaderMetadata) { @@ -340,20 +339,20 @@ impl HeaderMetadata for Blockchain { } impl blockchain::Backend for Blockchain { - fn body(&self, id: BlockId) -> error::Result::Extrinsic>>> { + fn body(&self, id: BlockId) -> sp_blockchain::Result::Extrinsic>>> { Ok(self.id(id).and_then(|hash| { self.storage.read().blocks.get(&hash) .and_then(|b| b.extrinsics().map(|x| x.to_vec())) })) } - fn justification(&self, id: BlockId) -> error::Result> { + fn justification(&self, id: BlockId) -> sp_blockchain::Result> { Ok(self.id(id).and_then(|hash| self.storage.read().blocks.get(&hash).and_then(|b| b.justification().map(|x| x.clone())) )) } - fn last_finalized(&self) -> error::Result { + fn last_finalized(&self) -> sp_blockchain::Result { Ok(self.storage.read().finalized_hash.clone()) } @@ -361,11 +360,11 @@ impl blockchain::Backend for Blockchain { None } - fn leaves(&self) -> error::Result> { + fn leaves(&self) -> sp_blockchain::Result> { Ok(self.storage.read().leaves.hashes()) } - fn children(&self, _parent_hash: Block::Hash) -> error::Result> { + fn children(&self, _parent_hash: Block::Hash) -> sp_blockchain::Result> { unimplemented!() } } @@ -383,7 +382,7 @@ impl backend::AuxStore for Blockchain { 'c: 'a, I: IntoIterator, D: IntoIterator, - >(&self, insert: I, delete: D) -> error::Result<()> { + >(&self, insert: I, delete: D) -> sp_blockchain::Result<()> { let mut storage = self.storage.write(); for (k, v) in insert { storage.aux.insert(k.to_vec(), v.to_vec()); @@ -394,12 +393,12 @@ impl backend::AuxStore for Blockchain { Ok(()) } - fn get_aux(&self, key: &[u8]) -> error::Result>> { + fn get_aux(&self, key: &[u8]) -> sp_blockchain::Result>> { Ok(self.storage.read().aux.get(key).cloned()) } } -impl client_api::light::Storage for Blockchain +impl sc_client_api::light::Storage for Blockchain where Block::Hash: From<[u8; 32]>, { @@ -409,7 +408,7 @@ impl client_api::light::Storage for Blockchain _cache: HashMap>, state: NewBlockState, aux_ops: Vec<(Vec, Option>)>, - ) -> error::Result<()> { + ) -> sp_blockchain::Result<()> { let hash = header.hash(); self.insert(hash, header, None, None, state)?; @@ -417,15 +416,15 @@ impl client_api::light::Storage for Blockchain Ok(()) } - fn set_head(&self, id: BlockId) -> error::Result<()> { + fn set_head(&self, id: BlockId) -> sp_blockchain::Result<()> { Blockchain::set_head(self, id) } - fn last_finalized(&self) -> error::Result { + fn last_finalized(&self) -> sp_blockchain::Result { Ok(self.storage.read().finalized_hash.clone()) } - fn finalize_header(&self, id: BlockId) -> error::Result<()> { + fn finalize_header(&self, id: BlockId) -> sp_blockchain::Result<()> { Blockchain::finalize_header(self, id, None) } @@ -433,18 +432,18 @@ impl client_api::light::Storage for Blockchain &self, _cht_size: NumberFor, block: NumberFor, - ) -> error::Result { + ) -> sp_blockchain::Result { self.storage.read().header_cht_roots.get(&block).cloned() - .ok_or_else(|| error::Error::Backend(format!("Header CHT for block {} not exists", block))) + .ok_or_else(|| sp_blockchain::Error::Backend(format!("Header CHT for block {} not exists", block))) } fn changes_trie_cht_root( &self, _cht_size: NumberFor, block: NumberFor, - ) -> error::Result { + ) -> sp_blockchain::Result { self.storage.read().changes_trie_cht_roots.get(&block).cloned() - .ok_or_else(|| error::Error::Backend(format!("Changes trie CHT for block {} not exists", block))) + .ok_or_else(|| sp_blockchain::Error::Backend(format!("Changes trie CHT for block {} not exists", block))) } fn cache(&self) -> Option>> { @@ -473,7 +472,7 @@ where { type State = InMemory; - fn state(&self) -> error::Result> { + fn state(&self) -> sp_blockchain::Result> { Ok(Some(&self.old_state)) } @@ -483,7 +482,7 @@ where body: Option::Extrinsic>>, justification: Option, state: NewBlockState, - ) -> error::Result<()> { + ) -> sp_blockchain::Result<()> { assert!(self.pending_block.is_none(), "Only one block per operation is allowed"); self.pending_block = Some(PendingBlock { block: StoredBlock::new(header, body, justification), @@ -496,25 +495,25 @@ where self.pending_cache = cache; } - fn update_db_storage(&mut self, update: as StateBackend>::Transaction) -> error::Result<()> { + fn update_db_storage(&mut self, update: as StateBackend>::Transaction) -> sp_blockchain::Result<()> { self.new_state = Some(self.old_state.update(update)); Ok(()) } - fn update_changes_trie(&mut self, update: ChangesTrieTransaction>) -> error::Result<()> { + fn update_changes_trie(&mut self, update: ChangesTrieTransaction>) -> sp_blockchain::Result<()> { self.changes_trie_update = Some(update.0); Ok(()) } - fn reset_storage(&mut self, top: StorageOverlay, children: ChildrenStorageOverlay) -> error::Result { - check_genesis_storage(&top, &children)?; + fn reset_storage(&mut self, storage: Storage) -> sp_blockchain::Result { + check_genesis_storage(&storage)?; - let child_delta = children.into_iter() - .map(|(storage_key, child_overlay)| - (storage_key, child_overlay.into_iter().map(|(k, v)| (k, Some(v))))); + let child_delta = storage.children.into_iter() + .map(|(storage_key, child_content)| + (storage_key, child_content.data.into_iter().map(|(k, v)| (k, Some(v))), child_content.child_info)); let (root, transaction) = self.old_state.full_storage_root( - top.into_iter().map(|(k, v)| (k, Some(v))), + storage.top.into_iter().map(|(k, v)| (k, Some(v))), child_delta ); @@ -522,7 +521,7 @@ where Ok(root) } - fn insert_aux(&mut self, ops: I) -> error::Result<()> + fn insert_aux(&mut self, ops: I) -> sp_blockchain::Result<()> where I: IntoIterator, Option>)> { self.aux.append(&mut ops.into_iter().collect()); @@ -533,16 +532,16 @@ where &mut self, _update: StorageCollection, _child_update: ChildStorageCollection, - ) -> error::Result<()> { + ) -> sp_blockchain::Result<()> { Ok(()) } - fn mark_finalized(&mut self, block: BlockId, justification: Option) -> error::Result<()> { + fn mark_finalized(&mut self, block: BlockId, justification: Option) -> sp_blockchain::Result<()> { self.finalized_blocks.push((block, justification)); Ok(()) } - fn mark_head(&mut self, block: BlockId) -> error::Result<()> { + fn mark_head(&mut self, block: BlockId) -> sp_blockchain::Result<()> { assert!(self.pending_block.is_none(), "Only one set block per operation is allowed"); self.set_head = Some(block); Ok(()) @@ -562,7 +561,7 @@ where states: RwLock>>, changes_trie_storage: ChangesTrieStorage, blockchain: Blockchain, - import_lock: Mutex<()>, + import_lock: RwLock<()>, } impl Backend @@ -594,11 +593,11 @@ where 'c: 'a, I: IntoIterator, D: IntoIterator, - >(&self, insert: I, delete: D) -> error::Result<()> { + >(&self, insert: I, delete: D) -> sp_blockchain::Result<()> { self.blockchain.insert_aux(insert, delete) } - fn get_aux(&self, key: &[u8]) -> error::Result>> { + fn get_aux(&self, key: &[u8]) -> sp_blockchain::Result>> { self.blockchain.get_aux(key) } } @@ -615,7 +614,7 @@ where type ChangesTrieStorage = ChangesTrieStorage; type OffchainStorage = OffchainStorage; - fn begin_operation(&self) -> error::Result { + fn begin_operation(&self) -> sp_blockchain::Result { let old_state = self.state_at(BlockId::Hash(Default::default()))?; Ok(BlockImportOperation { pending_block: None, @@ -629,12 +628,12 @@ where }) } - fn begin_state_operation(&self, operation: &mut Self::BlockImportOperation, block: BlockId) -> error::Result<()> { + fn begin_state_operation(&self, operation: &mut Self::BlockImportOperation, block: BlockId) -> sp_blockchain::Result<()> { operation.old_state = self.state_at(block)?; Ok(()) } - fn commit_operation(&self, operation: Self::BlockImportOperation) -> error::Result<()> { + fn commit_operation(&self, operation: Self::BlockImportOperation) -> sp_blockchain::Result<()> { if !operation.finalized_blocks.is_empty() { for (block, justification) in operation.finalized_blocks { self.blockchain.finalize_header(block, justification)?; @@ -674,7 +673,7 @@ where Ok(()) } - fn finalize_block(&self, block: BlockId, justification: Option) -> error::Result<()> { + fn finalize_block(&self, block: BlockId, justification: Option) -> sp_blockchain::Result<()> { self.blockchain.finalize_header(block, justification) } @@ -694,7 +693,7 @@ where None } - fn state_at(&self, block: BlockId) -> error::Result { + fn state_at(&self, block: BlockId) -> sp_blockchain::Result { match block { BlockId::Hash(h) if h == Default::default() => { return Ok(Self::State::default()); @@ -704,15 +703,15 @@ where match self.blockchain.id(block).and_then(|id| self.states.read().get(&id).cloned()) { Some(state) => Ok(state), - None => Err(error::Error::UnknownBlock(format!("{}", block))), + None => Err(sp_blockchain::Error::UnknownBlock(format!("{}", block))), } } - fn revert(&self, _n: NumberFor) -> error::Result> { + fn revert(&self, _n: NumberFor) -> sp_blockchain::Result> { Ok(Zero::zero()) } - fn get_import_lock(&self) -> &Mutex<()> { + fn get_import_lock(&self) -> &RwLock<()> { &self.import_lock } } @@ -753,7 +752,7 @@ impl backend::PrunableStateChangesTrieStorage state_machine::ChangesTrieRootsStorage> for ChangesTrieStorage +impl sp_state_machine::ChangesTrieRootsStorage> for ChangesTrieStorage where Block: BlockT, H: Hasher, @@ -761,7 +760,7 @@ impl state_machine::ChangesTrieRootsStorage> for C fn build_anchor( &self, _hash: H::Out, - ) -> Result>, String> { + ) -> Result>, String> { Err("Dummy implementation".into()) } @@ -774,12 +773,12 @@ impl state_machine::ChangesTrieRootsStorage> for C } } -impl state_machine::ChangesTrieStorage> for ChangesTrieStorage +impl sp_state_machine::ChangesTrieStorage> for ChangesTrieStorage where Block: BlockT, H: Hasher, { - fn as_roots_storage(&self) -> &dyn state_machine::ChangesTrieRootsStorage> { + fn as_roots_storage(&self) -> &dyn sp_state_machine::ChangesTrieRootsStorage> { self } @@ -791,19 +790,19 @@ impl state_machine::ChangesTrieStorage> for Change false } - fn get(&self, key: &H::Out, prefix: Prefix) -> Result, String> { + fn get(&self, key: &H::Out, prefix: Prefix) -> Result, String> { self.0.get(key, prefix) } } /// Check that genesis storage is valid. -pub fn check_genesis_storage(top: &StorageOverlay, children: &ChildrenStorageOverlay) -> error::Result<()> { - if top.iter().any(|(k, _)| well_known_keys::is_child_storage_key(k)) { - return Err(error::Error::GenesisInvalid.into()); +pub fn check_genesis_storage(storage: &Storage) -> sp_blockchain::Result<()> { + if storage.top.iter().any(|(k, _)| well_known_keys::is_child_storage_key(k)) { + return Err(sp_blockchain::Error::GenesisInvalid.into()); } - if children.keys().any(|child_key| !well_known_keys::is_child_storage_key(&child_key)) { - return Err(error::Error::GenesisInvalid.into()); + if storage.children.keys().any(|child_key| !well_known_keys::is_child_storage_key(&child_key)) { + return Err(sp_blockchain::Error::GenesisInvalid.into()); } Ok(()) @@ -811,25 +810,25 @@ pub fn check_genesis_storage(top: &StorageOverlay, children: &ChildrenStorageOve #[cfg(test)] mod tests { - use primitives::offchain::{OffchainStorage, storage::InMemOffchainStorage}; + use sp_core::offchain::{OffchainStorage, storage::InMemOffchainStorage}; use std::sync::Arc; - use test_client; - use primitives::Blake2Hasher; + use substrate_test_runtime_client; + use sp_core::Blake2Hasher; - type TestBackend = test_client::client::in_mem::Backend; + type TestBackend = substrate_test_runtime_client::sc_client::in_mem::Backend; #[test] fn test_leaves_with_complex_block_tree() { let backend = Arc::new(TestBackend::new()); - test_client::trait_tests::test_leaves_for_backend(backend); + substrate_test_runtime_client::trait_tests::test_leaves_for_backend(backend); } #[test] fn test_blockchain_query_by_number_gets_canonical() { let backend = Arc::new(TestBackend::new()); - test_client::trait_tests::test_blockchain_query_by_number_gets_canonical(backend); + substrate_test_runtime_client::trait_tests::test_blockchain_query_by_number_gets_canonical(backend); } #[test] diff --git a/client/src/leaves.rs b/client/src/leaves.rs index bc42e83a66f570661189209c59eef06ae6819ed8..91ea00a2f37b5d89437eeb80e2b4877c7b6fa380 100644 --- a/client/src/leaves.rs +++ b/client/src/leaves.rs @@ -19,9 +19,9 @@ use std::collections::BTreeMap; use std::cmp::Reverse; use kvdb::{KeyValueDB, DBTransaction}; -use sr_primitives::traits::SimpleArithmetic; +use sp_runtime::traits::SimpleArithmetic; use codec::{Encode, Decode}; -use client_api::error; +use sp_blockchain::{Error, Result}; #[derive(Debug, Clone, PartialEq, Eq)] struct LeafSetItem { @@ -77,7 +77,7 @@ impl LeafSet where } /// Read the leaf list from the DB, using given prefix for keys. - pub fn read_from_db(db: &dyn KeyValueDB, column: Option, prefix: &[u8]) -> error::Result { + pub fn read_from_db(db: &dyn KeyValueDB, column: Option, prefix: &[u8]) -> Result { let mut storage = BTreeMap::new(); for (key, value) in db.iter_from_prefix(column, prefix) { @@ -85,11 +85,11 @@ impl LeafSet where let raw_hash = &mut &key[prefix.len()..]; let hash = match Decode::decode(raw_hash) { Ok(hash) => hash, - Err(_) => return Err(error::Error::Backend("Error decoding hash".into())), + Err(_) => return Err(Error::Backend("Error decoding hash".into())), }; let number = match Decode::decode(&mut &value[..]) { Ok(number) => number, - Err(_) => return Err(error::Error::Backend("Error decoding number".into())), + Err(_) => return Err(Error::Backend("Error decoding number".into())), }; storage.entry(Reverse(number)).or_insert_with(Vec::new).push(hash); } diff --git a/client/src/lib.rs b/client/src/lib.rs index 71127d3cb061e9e67119328bb3c3742b431cbaa8..70d1f2865995a435faf4bf69ad89c8d265e4c794 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -28,7 +28,7 @@ //! Creating a [`Client`] is done by calling the `new` method and passing to it a //! [`Backend`](backend::Backend) and an [`Executor`](CallExecutor). //! -//! The former is typically provided by the `substrate-client-db` crate. +//! The former is typically provided by the `sc-client-db` crate. //! //! The latter typically requires passing one of: //! @@ -46,16 +46,16 @@ //! //! ``` //! use std::sync::Arc; -//! use substrate_client::{Client, in_mem::Backend, LocalCallExecutor}; -//! use primitives::Blake2Hasher; -//! use sr_primitives::{StorageOverlay, ChildrenStorageOverlay}; -//! use executor::{NativeExecutor, WasmExecutionMethod}; +//! use sc_client::{Client, in_mem::Backend, LocalCallExecutor}; +//! use sp_core::Blake2Hasher; +//! use sp_runtime::Storage; +//! use sc_executor::{NativeExecutor, WasmExecutionMethod}; //! //! // In this example, we're using the `Block` and `RuntimeApi` types from the //! // `substrate-test-runtime-client` crate. These types are automatically generated when //! // compiling a runtime. In a typical use-case, these types would have been to be generated //! // from your runtime. -//! use test_client::{LocalExecutor, runtime::Block, runtime::RuntimeApi}; +//! use substrate_test_runtime_client::{LocalExecutor, runtime::Block, runtime::RuntimeApi}; //! //! let backend = Arc::new(Backend::::new()); //! let client = Client::<_, _, _, RuntimeApi>::new( @@ -65,7 +65,7 @@ //! NativeExecutor::::new(WasmExecutionMethod::Interpreted, None), //! ), //! // This parameter provides the storage for the chain genesis. -//! <(StorageOverlay, ChildrenStorageOverlay)>::default(), +//! ::default(), //! Default::default(), //! Default::default(), //! ); @@ -83,8 +83,7 @@ pub mod leaves; mod call_executor; mod client; -pub use client_api::{ - error, +pub use sc_client_api::{ blockchain, blockchain::well_known_cache_keys, blockchain::Info as ChainInfo, @@ -103,4 +102,4 @@ pub use crate::{ }, leaves::LeafSet, }; -pub use state_machine::{ExecutionStrategy, StorageProof}; +pub use sp_state_machine::{ExecutionStrategy, StorageProof}; diff --git a/client/src/light/backend.rs b/client/src/light/backend.rs index 5db0c55d5e9792455bcd617dc7d45bf7b6568d11..f946d91b3c8c3daaf1187145bb11836f93564195 100644 --- a/client/src/light/backend.rs +++ b/client/src/light/backend.rs @@ -19,14 +19,18 @@ use std::collections::HashMap; use std::sync::Arc; -use parking_lot::{RwLock, Mutex}; +use parking_lot::RwLock; -use state_machine::{Backend as StateBackend, TrieBackend, backend::InMemory as InMemoryState, ChangesTrieTransaction}; -use primitives::offchain::storage::InMemOffchainStorage; -use sr_primitives::{generic::BlockId, Justification, StorageOverlay, ChildrenStorageOverlay}; -use sr_primitives::traits::{Block as BlockT, NumberFor, Zero, Header}; +use sp_core::storage::{ChildInfo, OwnedChildInfo}; +use sp_core::offchain::storage::InMemOffchainStorage; +use sp_state_machine::{ + Backend as StateBackend, TrieBackend, backend::InMemory as InMemoryState, ChangesTrieTransaction +}; +use sp_runtime::{generic::BlockId, Justification, Storage}; +use sp_runtime::traits::{Block as BlockT, NumberFor, Zero, Header}; use crate::in_mem::{self, check_genesis_storage}; -use client_api::{ +use sp_blockchain::{ Error as ClientError, Result as ClientResult }; +use sc_client_api::{ backend::{ AuxStore, Backend as ClientBackend, BlockImportOperation, RemoteBackend, NewBlockState, StorageCollection, ChildStorageCollection, @@ -34,14 +38,11 @@ use client_api::{ blockchain::{ HeaderBackend as BlockchainHeaderBackend, well_known_cache_keys, }, - error::{ - Error as ClientError, Result as ClientResult - }, light::Storage as BlockchainStorage, }; use crate::light::blockchain::Blockchain; use hash_db::Hasher; -use trie::MemoryDB; +use sp_trie::MemoryDB; const IN_MEMORY_EXPECT_PROOF: &str = "InMemory state backend has Void error type and always succeeds; qed"; @@ -49,7 +50,7 @@ const IN_MEMORY_EXPECT_PROOF: &str = "InMemory state backend has Void error type pub struct Backend { blockchain: Arc>, genesis_state: RwLock>>, - import_lock: Mutex<()>, + import_lock: RwLock<()>, } /// Light block (header and justification) import operation. @@ -216,7 +217,7 @@ impl ClientBackend for Backend where Err(ClientError::NotAvailableOnLightClient) } - fn get_import_lock(&self) -> &Mutex<()> { + fn get_import_lock(&self) -> &RwLock<()> { &self.import_lock } } @@ -280,22 +281,21 @@ where Ok(()) } - fn reset_storage(&mut self, top: StorageOverlay, children: ChildrenStorageOverlay) -> ClientResult { - check_genesis_storage(&top, &children)?; + fn reset_storage(&mut self, input: Storage) -> ClientResult { + check_genesis_storage(&input)?; // this is only called when genesis block is imported => shouldn't be performance bottleneck - let mut storage: HashMap>, StorageOverlay> = HashMap::new(); - storage.insert(None, top); + let mut storage: HashMap, OwnedChildInfo)>, _> = HashMap::new(); + storage.insert(None, input.top); // create a list of children keys to re-compute roots for - let child_delta = children.keys() - .cloned() - .map(|storage_key| (storage_key, None)) + let child_delta = input.children.iter() + .map(|(storage_key, storage_child)| (storage_key.clone(), None, storage_child.child_info.clone())) .collect::>(); // make sure to persist the child storage - for (child_key, child_storage) in children { - storage.insert(Some(child_key), child_storage); + for (child_key, storage_child) in input.children { + storage.insert(Some((child_key, storage_child.child_info)), storage_child.data); } let storage_update: InMemoryState = storage.into(); @@ -343,7 +343,7 @@ impl std::fmt::Debug for GenesisOrUnavailableState { impl StateBackend for GenesisOrUnavailableState where - H::Out: Ord, + H::Out: Ord + codec::Codec, { type Error = ClientError; type Transaction = (); @@ -357,10 +357,38 @@ impl StateBackend for GenesisOrUnavailableState } } - fn child_storage(&self, storage_key: &[u8], key: &[u8]) -> ClientResult>> { + fn child_storage( + &self, + storage_key: &[u8], + child_info: ChildInfo, + key: &[u8], + ) -> ClientResult>> { match *self { GenesisOrUnavailableState::Genesis(ref state) => - Ok(state.child_storage(storage_key, key).expect(IN_MEMORY_EXPECT_PROOF)), + Ok(state.child_storage(storage_key, child_info, key).expect(IN_MEMORY_EXPECT_PROOF)), + GenesisOrUnavailableState::Unavailable => Err(ClientError::NotAvailableOnLightClient), + } + } + + fn next_storage_key(&self, key: &[u8]) -> Result>, Self::Error> { + match *self { + GenesisOrUnavailableState::Genesis(ref state) => + Ok(state.next_storage_key(key).expect(IN_MEMORY_EXPECT_PROOF)), + GenesisOrUnavailableState::Unavailable => Err(ClientError::NotAvailableOnLightClient), + } + } + + fn next_child_storage_key( + &self, + storage_key: &[u8], + child_info: ChildInfo, + key: &[u8], + ) -> Result>, Self::Error> { + match *self { + GenesisOrUnavailableState::Genesis(ref state) => Ok( + state.next_child_storage_key(storage_key, child_info, key) + .expect(IN_MEMORY_EXPECT_PROOF) + ), GenesisOrUnavailableState::Unavailable => Err(ClientError::NotAvailableOnLightClient), } } @@ -379,10 +407,15 @@ impl StateBackend for GenesisOrUnavailableState } } - - fn for_keys_in_child_storage(&self, storage_key: &[u8], action: A) { + fn for_keys_in_child_storage( + &self, + storage_key: &[u8], + child_info: ChildInfo, + action: A, + ) { match *self { - GenesisOrUnavailableState::Genesis(ref state) => state.for_keys_in_child_storage(storage_key, action), + GenesisOrUnavailableState::Genesis(ref state) => + state.for_keys_in_child_storage(storage_key, child_info, action), GenesisOrUnavailableState::Unavailable => (), } } @@ -390,12 +423,13 @@ impl StateBackend for GenesisOrUnavailableState fn for_child_keys_with_prefix( &self, storage_key: &[u8], + child_info: ChildInfo, prefix: &[u8], action: A, ) { match *self { GenesisOrUnavailableState::Genesis(ref state) => - state.for_child_keys_with_prefix(storage_key, prefix, action), + state.for_child_keys_with_prefix(storage_key, child_info, prefix, action), GenesisOrUnavailableState::Unavailable => (), } } @@ -411,16 +445,21 @@ impl StateBackend for GenesisOrUnavailableState } } - fn child_storage_root(&self, key: &[u8], delta: I) -> (Vec, bool, Self::Transaction) + fn child_storage_root( + &self, + storage_key: &[u8], + child_info: ChildInfo, + delta: I, + ) -> (H::Out, bool, Self::Transaction) where I: IntoIterator, Option>)> { match *self { GenesisOrUnavailableState::Genesis(ref state) => { - let (root, is_equal, _) = state.child_storage_root(key, delta); + let (root, is_equal, _) = state.child_storage_root(storage_key, child_info, delta); (root, is_equal, ()) }, - GenesisOrUnavailableState::Unavailable => (H::Out::default().as_ref().to_vec(), true, ()), + GenesisOrUnavailableState::Unavailable => (H::Out::default(), true, ()), } } @@ -448,21 +487,21 @@ impl StateBackend for GenesisOrUnavailableState #[cfg(test)] mod tests { - use primitives::Blake2Hasher; - use test_client::{self, runtime::Block}; - use client_api::backend::NewBlockState; + use sp_core::Blake2Hasher; + use substrate_test_runtime_client::{self, runtime::Block}; + use sc_client_api::backend::NewBlockState; use crate::light::blockchain::tests::{DummyBlockchain, DummyStorage}; use super::*; #[test] fn local_state_is_created_when_genesis_state_is_available() { let def = Default::default(); - let header0 = test_client::runtime::Header::new(0, def, def, def, Default::default()); + let header0 = substrate_test_runtime_client::runtime::Header::new(0, def, def, def, Default::default()); let backend: Backend<_, Blake2Hasher> = Backend::new(Arc::new(DummyBlockchain::new(DummyStorage::new()))); let mut op = backend.begin_operation().unwrap(); op.set_block_data(header0, None, None, NewBlockState::Final).unwrap(); - op.reset_storage(Default::default(), Default::default()).unwrap(); + op.reset_storage(Default::default()).unwrap(); backend.commit_operation(op).unwrap(); match backend.state_at(BlockId::Number(0)).unwrap() { diff --git a/client/src/light/blockchain.rs b/client/src/light/blockchain.rs index b9003c6a292bed8bfeb8cbf1fb7c74dca32be254..54cb8d9b090dca59b92e40f4cf1d1eb502b64cfa 100644 --- a/client/src/light/blockchain.rs +++ b/client/src/light/blockchain.rs @@ -20,11 +20,14 @@ use std::future::Future; use std::sync::Arc; -use sr_primitives::{Justification, generic::BlockId}; -use sr_primitives::traits::{Block as BlockT, Header as HeaderT, NumberFor, Zero}; +use sp_runtime::{Justification, generic::BlockId}; +use sp_runtime::traits::{Block as BlockT, Header as HeaderT, NumberFor, Zero}; -use header_metadata::{HeaderMetadata, CachedHeaderMetadata}; -pub use client_api::{ +use sp_blockchain::{ + HeaderMetadata, CachedHeaderMetadata, + Error as ClientError, Result as ClientResult, +}; +pub use sc_client_api::{ backend::{ AuxStore, NewBlockState }, @@ -33,9 +36,6 @@ pub use client_api::{ HeaderBackend as BlockchainHeaderBackend, Info as BlockchainInfo, ProvideCache, well_known_cache_keys, }, - error::{ - Error as ClientError, Result as ClientResult - }, light::{ RemoteBlockchain, LocalOrRemote, Storage } @@ -195,8 +195,8 @@ pub fn future_header>( pub mod tests { use std::collections::HashMap; use parking_lot::Mutex; - use test_client::runtime::{Hash, Block, Header}; - use client_api::blockchain::Info; + use substrate_test_runtime_client::runtime::{Hash, Block, Header}; + use sc_client_api::blockchain::Info; use super::*; pub type DummyBlockchain = Blockchain; diff --git a/client/src/light/call_executor.rs b/client/src/light/call_executor.rs index a4a8a549de93c852494c3c66ed5a4dcf895d67b5..656271b9324a026d45628255cec712c93639e27d 100644 --- a/client/src/light/call_executor.rs +++ b/client/src/light/call_executor.rs @@ -21,30 +21,31 @@ use std::{ }; use codec::{Encode, Decode}; -use primitives::{ +use sp_core::{ H256, Blake2Hasher, convert_hash, NativeOrEncoded, traits::CodeExecutor, }; -use sr_primitives::{ +use sp_runtime::{ generic::BlockId, traits::{One, Block as BlockT, Header as HeaderT, NumberFor}, }; -use externalities::Extensions; -use state_machine::{ +use sp_externalities::Extensions; +use sp_state_machine::{ self, Backend as StateBackend, OverlayedChanges, ExecutionStrategy, create_proof_check_backend, execution_proof_check_on_trie_backend, ExecutionManager, ChangesTrieTransaction, StorageProof, merge_storage_proofs, }; use hash_db::Hasher; -use sr_api::{ProofRecorder, InitializeBlock}; +use sp_api::{ProofRecorder, InitializeBlock}; -use client_api::{ +use sp_blockchain::{Error as ClientError, Result as ClientResult}; + +use sc_client_api::{ backend::RemoteBackend, - error::{Error as ClientError, Result as ClientResult}, light::RemoteCallRequest, call_executor::CallExecutor }; -use executor::{RuntimeVersion, NativeVersion}; +use sc_executor::{RuntimeVersion, NativeVersion}; /// Call executor that is able to execute calls only on genesis state. /// @@ -113,7 +114,7 @@ impl CallExecutor for _manager: ExecutionManager, native_call: Option, recorder: &Option>, - extensions: Option, + extensions: Option, ) -> ClientResult> where ExecutionManager: Clone { // there's no actual way/need to specify native/wasm execution strategy on light node // => we can safely ignore passed values @@ -175,9 +176,9 @@ impl CallExecutor for Err(ClientError::NotAvailableOnLightClient) } - fn prove_at_trie_state>( + fn prove_at_trie_state>( &self, - _state: &state_machine::TrieBackend, + _state: &sp_state_machine::TrieBackend, _changes: &mut OverlayedChanges, _method: &str, _call_data: &[u8] @@ -207,7 +208,7 @@ pub fn prove_execution( E: CallExecutor, { let trie_state = state.as_trie_backend() - .ok_or_else(|| Box::new(state_machine::ExecutionError::UnableToGenerateProof) as Box)?; + .ok_or_else(|| Box::new(sp_state_machine::ExecutionError::UnableToGenerateProof) as Box)?; // prepare execution environment + record preparation proof let mut changes = Default::default(); @@ -277,7 +278,6 @@ fn check_execution_proof_with_make_header, + S: sp_state_machine::Backend, F: FnOnce( Result, Self::Error>, Result, Self::Error> @@ -373,9 +372,9 @@ mod tests { unreachable!() } - fn prove_at_trie_state>( + fn prove_at_trie_state>( &self, - _trie_state: &state_machine::TrieBackend, + _trie_state: &sp_state_machine::TrieBackend, _overlay: &mut OverlayedChanges, _method: &str, _call_data: &[u8] @@ -388,7 +387,7 @@ mod tests { } } - fn local_executor() -> NativeExecutor { + fn local_executor() -> NativeExecutor { NativeExecutor::new(WasmExecutionMethod::Interpreted, None) } @@ -409,7 +408,7 @@ mod tests { let local_result = check_execution_proof::<_, _, Blake2Hasher>( &local_executor(), &RemoteCallRequest { - block: test_client::runtime::Hash::default(), + block: substrate_test_runtime_client::runtime::Hash::default(), header: remote_header, method: method.into(), call_data: vec![], @@ -436,7 +435,7 @@ mod tests { let execution_result = check_execution_proof_with_make_header::<_, _, Blake2Hasher, _>( &local_executor(), &RemoteCallRequest { - block: test_client::runtime::Hash::default(), + block: substrate_test_runtime_client::runtime::Hash::default(), header: remote_header, method: method.into(), call_data: vec![], @@ -452,16 +451,16 @@ mod tests { ), ); match execution_result { - Err(client_api::error::Error::Execution(_)) => (), + Err(sp_blockchain::Error::Execution(_)) => (), _ => panic!("Unexpected execution result: {:?}", execution_result), } } // prepare remote client - let remote_client = test_client::new(); + let remote_client = substrate_test_runtime_client::new(); for i in 1u32..3u32 { let mut digest = Digest::default(); - digest.push(sr_primitives::generic::DigestItem::Other::(i.to_le_bytes().to_vec())); + digest.push(sp_runtime::generic::DigestItem::Other::(i.to_le_bytes().to_vec())); remote_client.import_justified( BlockOrigin::Own, remote_client.new_block(digest).unwrap().bake().unwrap(), @@ -489,7 +488,7 @@ mod tests { execute_with_proof_failure(&remote_client, 2, "Core_version"); // check that proof check doesn't panic even if proof is incorrect AND panic handler is set - panic_handler::set("TEST", "1.2.3"); + sp_panic_handler::set("TEST", "1.2.3"); execute_with_proof_failure(&remote_client, 2, "Core_version"); } @@ -497,9 +496,9 @@ mod tests { fn code_is_executed_at_genesis_only() { let backend = Arc::new(InMemBackend::::new()); let def = H256::default(); - let header0 = test_client::runtime::Header::new(0, def, def, def, Default::default()); + let header0 = substrate_test_runtime_client::runtime::Header::new(0, def, def, def, Default::default()); let hash0 = header0.hash(); - let header1 = test_client::runtime::Header::new(1, def, def, hash0, Default::default()); + let header1 = substrate_test_runtime_client::runtime::Header::new(1, def, def, hash0, Default::default()); let hash1 = header1.hash(); backend.blockchain().insert(hash0, header0, None, None, NewBlockState::Final).unwrap(); backend.blockchain().insert(hash1, header1, None, None, NewBlockState::Final).unwrap(); diff --git a/client/src/light/fetcher.rs b/client/src/light/fetcher.rs index e8b88e93b9bab86b8bf7226fe130b9506fc80437..c081f6bb9eed57a7b50fc7da62f508b1c442dd08 100644 --- a/client/src/light/fetcher.rs +++ b/client/src/light/fetcher.rs @@ -22,23 +22,21 @@ use std::marker::PhantomData; use hash_db::{HashDB, Hasher, EMPTY_PREFIX}; use codec::{Decode, Encode}; -use primitives::{convert_hash, traits::CodeExecutor, H256}; -use sr_primitives::traits::{ +use sp_core::{convert_hash, traits::CodeExecutor, H256}; +use sp_runtime::traits::{ Block as BlockT, Header as HeaderT, Hash, HashFor, NumberFor, SimpleArithmetic, CheckedConversion, Zero, }; -use state_machine::{ +use sp_state_machine::{ ChangesTrieRootsStorage, ChangesTrieAnchorBlockId, ChangesTrieConfigurationRange, TrieBackend, read_proof_check, key_changes_proof_check, create_proof_check_backend_storage, read_child_proof_check, }; -pub use state_machine::StorageProof; +pub use sp_state_machine::StorageProof; +use sp_blockchain::{Error as ClientError, Result as ClientResult}; use crate::cht; -pub use client_api::{ - error::{ - Error as ClientError, Result as ClientResult - }, +pub use sc_client_api::{ light::{ RemoteCallRequest, RemoteHeaderRequest, RemoteReadRequest, RemoteReadChildRequest, RemoteChangesRequest, ChangesProof, RemoteBodyRequest, Fetcher, FetchChecker, @@ -72,7 +70,7 @@ impl> LightDataChecker { ) -> ClientResult, u32)>> where H: Hasher, - H::Out: Ord, + H::Out: Ord + codec::Codec, { // since we need roots of all changes tries for the range begin..max // => remote node can't use max block greater that one that we have passed @@ -150,7 +148,7 @@ impl> LightDataChecker { ) -> ClientResult<()> where H: Hasher, - H::Out: Ord, + H::Out: Ord + codec::Codec, { // all the checks are sharing the same storage let storage = create_proof_check_backend_storage(remote_roots_proof); @@ -296,7 +294,7 @@ impl<'a, H, Number, Hash> ChangesTrieRootsStorage for RootsStorage<'a fn build_anchor( &self, _hash: H::Out, - ) -> Result, String> { + ) -> Result, String> { Err("build_anchor is only called when building block".into()) } @@ -328,40 +326,40 @@ impl<'a, H, Number, Hash> ChangesTrieRootsStorage for RootsStorage<'a pub mod tests { use codec::Decode; use crate::client::tests::prepare_client_with_key_changes; - use executor::{NativeExecutor, WasmExecutionMethod}; - use client_api::{ - backend::NewBlockState, - error::Error as ClientError, - }; - use test_client::{ + use sc_executor::{NativeExecutor, WasmExecutionMethod}; + use sp_blockchain::Error as ClientError; + use sc_client_api::backend::NewBlockState; + use substrate_test_runtime_client::{ self, ClientExt, blockchain::HeaderBackend, AccountKeyring, runtime::{self, Hash, Block, Header, Extrinsic} }; - use consensus::BlockOrigin; + use sp_consensus::BlockOrigin; use crate::in_mem::{Blockchain as InMemoryBlockchain}; use crate::light::fetcher::{FetchChecker, LightDataChecker, RemoteHeaderRequest}; use crate::light::blockchain::tests::{DummyStorage, DummyBlockchain}; - use primitives::{blake2_256, Blake2Hasher, H256}; - use primitives::storage::{well_known_keys, StorageKey}; - use sr_primitives::generic::BlockId; - use state_machine::Backend; + use sp_core::{blake2_256, Blake2Hasher, H256}; + use sp_core::storage::{well_known_keys, StorageKey, ChildInfo}; + use sp_runtime::generic::BlockId; + use sp_state_machine::Backend; use super::*; + const CHILD_INFO_1: ChildInfo<'static> = ChildInfo::new_default(b"unique_id_1"); + type TestChecker = LightDataChecker< - NativeExecutor, + NativeExecutor, Blake2Hasher, Block, DummyStorage, >; - fn local_executor() -> NativeExecutor { + fn local_executor() -> NativeExecutor { NativeExecutor::new(WasmExecutionMethod::Interpreted, None) } fn prepare_for_read_proof_check() -> (TestChecker, Header, StorageProof, u32) { // prepare remote client - let remote_client = test_client::new(); + let remote_client = substrate_test_runtime_client::new(); let remote_block_id = BlockId::Number(0); let remote_block_hash = remote_client.block_hash(0).unwrap().unwrap(); let mut remote_block_header = remote_client.header(&remote_block_id).unwrap().unwrap(); @@ -394,12 +392,16 @@ pub mod tests { } fn prepare_for_read_child_proof_check() -> (TestChecker, Header, StorageProof, Vec) { - use test_client::DefaultTestClientBuilderExt; - use test_client::TestClientBuilderExt; + use substrate_test_runtime_client::DefaultTestClientBuilderExt; + use substrate_test_runtime_client::TestClientBuilderExt; // prepare remote client - let remote_client = test_client::TestClientBuilder::new() - .add_extra_child_storage(b":child_storage:default:child1".to_vec(), b"key1".to_vec(), b"value1".to_vec()) - .build(); + let remote_client = substrate_test_runtime_client::TestClientBuilder::new() + .add_extra_child_storage( + b":child_storage:default:child1".to_vec(), + CHILD_INFO_1, + b"key1".to_vec(), + b"value1".to_vec(), + ).build(); let remote_block_id = BlockId::Number(0); let remote_block_hash = remote_client.block_hash(0).unwrap().unwrap(); let mut remote_block_header = remote_client.header(&remote_block_id).unwrap().unwrap(); @@ -410,12 +412,14 @@ pub mod tests { let child_value = remote_client.child_storage( &remote_block_id, &StorageKey(b":child_storage:default:child1".to_vec()), + CHILD_INFO_1, &StorageKey(b"key1".to_vec()), ).unwrap().unwrap().0; assert_eq!(b"value1"[..], child_value[..]); let remote_read_proof = remote_client.read_child_proof( &remote_block_id, b":child_storage:default:child1", + CHILD_INFO_1, &[b"key1"], ).unwrap(); @@ -437,7 +441,7 @@ pub mod tests { fn prepare_for_header_proof_check(insert_cht: bool) -> (TestChecker, Hash, Header, StorageProof) { // prepare remote client - let remote_client = test_client::new(); + let remote_client = substrate_test_runtime_client::new(); let mut local_headers_hashes = Vec::new(); for i in 0..4 { let builder = remote_client.new_block(Default::default()).unwrap(); @@ -464,7 +468,7 @@ pub mod tests { } fn header_with_computed_extrinsics_root(extrinsics: Vec) -> Header { - use trie::{TrieConfiguration, trie_types::Layout}; + use sp_trie::{TrieConfiguration, trie_types::Layout}; let iter = extrinsics.iter().map(Encode::encode); let extrinsics_root = Layout::::ordered_trie_root(iter); @@ -491,11 +495,14 @@ pub mod tests { remote_read_proof, result, ) = prepare_for_read_child_proof_check(); + let child_infos = CHILD_INFO_1.info(); assert_eq!((&local_checker as &dyn FetchChecker).check_read_child_proof( &RemoteReadChildRequest::

{ block: remote_block_header.hash(), header: remote_block_header, storage_key: b":child_storage:default:child1".to_vec(), + child_info: child_infos.0.to_vec(), + child_type: child_infos.1, keys: vec![b"key1".to_vec()], retry_count: None, }, diff --git a/client/src/light/mod.rs b/client/src/light/mod.rs index 787e48e449a1efdd04fc2fa84bf6b264d1c6ac74..cc27bc698b77fb1d35cf8477037fed7b526ab337 100644 --- a/client/src/light/mod.rs +++ b/client/src/light/mod.rs @@ -23,15 +23,15 @@ pub mod fetcher; use std::sync::Arc; -use executor::RuntimeInfo; -use primitives::{H256, Blake2Hasher, traits::CodeExecutor}; -use sr_primitives::BuildStorage; -use sr_primitives::traits::Block as BlockT; +use sc_executor::RuntimeInfo; +use sp_core::{H256, Blake2Hasher, traits::CodeExecutor}; +use sp_runtime::BuildStorage; +use sp_runtime::traits::Block as BlockT; +use sp_blockchain::Result as ClientResult; use crate::call_executor::LocalCallExecutor; use crate::client::Client; -use client_api::{ - error::Result as ClientResult, +use sc_client_api::{ light::Storage as BlockchainStorage, }; use crate::light::backend::Backend; diff --git a/client/state-db/Cargo.toml b/client/state-db/Cargo.toml index d2752c14dd9c868c08e2d17a4675b8a15c545da5..31335d752ea672f8ac88f6400218ce5487f708c6 100644 --- a/client/state-db/Cargo.toml +++ b/client/state-db/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "substrate-state-db" +name = "sc-state-db" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" @@ -7,7 +7,7 @@ edition = "2018" [dependencies] parking_lot = "0.9.0" log = "0.4.8" -primitives = { package = "substrate-primitives", path = "../../primitives/core" } +sp-core = { version = "2.0.0", path = "../../primitives/core" } codec = { package = "parity-scale-codec", version = "1.0.0", features = ["derive"] } [dev-dependencies] diff --git a/client/state-db/src/lib.rs b/client/state-db/src/lib.rs index e561d9ce9617cb4c4edf92270160805bd151e1b8..331da7d5758f20d9f76c47f074b4a8808bc3907e 100644 --- a/client/state-db/src/lib.rs +++ b/client/state-db/src/lib.rs @@ -471,7 +471,7 @@ impl StateDb { #[cfg(test)] mod tests { use std::io; - use primitives::H256; + use sp_core::H256; use crate::{StateDb, PruningMode, Constraints}; use crate::test::{make_db, make_changeset, TestDb}; diff --git a/client/state-db/src/noncanonical.rs b/client/state-db/src/noncanonical.rs index 58715715ccdd230c7acb8c315896a25b55159046..6e4cd079aee390e68c60cd6e9e341d6f43c60906 100644 --- a/client/state-db/src/noncanonical.rs +++ b/client/state-db/src/noncanonical.rs @@ -436,7 +436,7 @@ impl NonCanonicalOverlay { #[cfg(test)] mod tests { use std::io; - use primitives::H256; + use sp_core::H256; use super::{NonCanonicalOverlay, to_journal_key}; use crate::{ChangeSet, CommitSet}; use crate::test::{make_db, make_changeset}; diff --git a/client/state-db/src/pruning.rs b/client/state-db/src/pruning.rs index 21f472fe69da9e18561d22b090019fa6fee1b9b1..4cb130eff8af5c76b87f6cdc636e63b71c75b4fd 100644 --- a/client/state-db/src/pruning.rs +++ b/client/state-db/src/pruning.rs @@ -201,7 +201,7 @@ impl RefWindow { #[cfg(test)] mod tests { use super::RefWindow; - use primitives::H256; + use sp_core::H256; use crate::CommitSet; use crate::test::{make_db, make_commit, TestDb}; diff --git a/client/state-db/src/test.rs b/client/state-db/src/test.rs index d90c36990612ed8ec059fafc4e5475510784f901..dfbb08998b659ae9c61089d2c0b3aceecad5be50 100644 --- a/client/state-db/src/test.rs +++ b/client/state-db/src/test.rs @@ -17,7 +17,7 @@ //! Test utils use std::collections::HashMap; -use primitives::H256; +use sp_core::H256; use crate::{DBValue, ChangeSet, CommitSet, MetaDb, NodeDb}; #[derive(Default, Debug, Clone, PartialEq, Eq)] diff --git a/client/telemetry/Cargo.toml b/client/telemetry/Cargo.toml index 07a296b02f8e0f51fbe672572dc5c0beae4180c4..0fdacc5d79e138a9faf0dcb36d02178c0a5fa5dc 100644 --- a/client/telemetry/Cargo.toml +++ b/client/telemetry/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "substrate-telemetry" +name = "sc-telemetry" version = "2.0.0" authors = ["Parity Technologies "] description = "Telemetry utils" @@ -16,10 +16,8 @@ log = "0.4.8" rand = "0.7.2" serde = { version = "1.0.101", features = ["derive"] } slog = { version = "2.5.2", features = ["nested-values"] } -# TODO: we're using slog-async just to be able to clone records; See https://github.com/slog-rs/slog/issues/221, -# https://github.com/paritytech/substrate/issues/2823 and https://github.com/paritytech/substrate/issues/3260 -slog-async = { git = "https://github.com/paritytech/slog-async", features = ["nested-values"] } slog-json = { version = "2.3.0", features = ["nested-values"] } slog-scope = "4.1.2" tokio-io = "0.1.12" +take_mut = "0.2.2" void = "1.0.2" diff --git a/client/telemetry/src/async_record.rs b/client/telemetry/src/async_record.rs new file mode 100644 index 0000000000000000000000000000000000000000..34b7c1435afa1a66991f912bb1b2bbb4244b8936 --- /dev/null +++ b/client/telemetry/src/async_record.rs @@ -0,0 +1,155 @@ +//! # Internal types to ssync drain slog +//! FIXME: REMOVE THIS ONCE THE PR WAS MERGE +//! https://github.com/slog-rs/async/pull/14 + +use slog::{Record, RecordStatic, Level, SingleKV, KV, BorrowedKV}; +use slog::{Serializer, OwnedKVList, Key}; + +use std::fmt; +use take_mut::take; + +struct ToSendSerializer { + kv: Box, +} + +impl ToSendSerializer { + fn new() -> Self { + ToSendSerializer { kv: Box::new(()) } + } + + fn finish(self) -> Box { + self.kv + } +} + +impl Serializer for ToSendSerializer { + fn emit_bool(&mut self, key: Key, val: bool) -> slog::Result { + take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val)))); + Ok(()) + } + fn emit_unit(&mut self, key: Key) -> slog::Result { + take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, ())))); + Ok(()) + } + fn emit_none(&mut self, key: Key) -> slog::Result { + let val: Option<()> = None; + take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val)))); + Ok(()) + } + fn emit_char(&mut self, key: Key, val: char) -> slog::Result { + take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val)))); + Ok(()) + } + fn emit_u8(&mut self, key: Key, val: u8) -> slog::Result { + take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val)))); + Ok(()) + } + fn emit_i8(&mut self, key: Key, val: i8) -> slog::Result { + take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val)))); + Ok(()) + } + fn emit_u16(&mut self, key: Key, val: u16) -> slog::Result { + take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val)))); + Ok(()) + } + fn emit_i16(&mut self, key: Key, val: i16) -> slog::Result { + take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val)))); + Ok(()) + } + fn emit_u32(&mut self, key: Key, val: u32) -> slog::Result { + take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val)))); + Ok(()) + } + fn emit_i32(&mut self, key: Key, val: i32) -> slog::Result { + take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val)))); + Ok(()) + } + fn emit_f32(&mut self, key: Key, val: f32) -> slog::Result { + take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val)))); + Ok(()) + } + fn emit_u64(&mut self, key: Key, val: u64) -> slog::Result { + take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val)))); + Ok(()) + } + fn emit_i64(&mut self, key: Key, val: i64) -> slog::Result { + take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val)))); + Ok(()) + } + fn emit_f64(&mut self, key: Key, val: f64) -> slog::Result { + take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val)))); + Ok(()) + } + fn emit_usize(&mut self, key: Key, val: usize) -> slog::Result { + take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val)))); + Ok(()) + } + fn emit_isize(&mut self, key: Key, val: isize) -> slog::Result { + take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val)))); + Ok(()) + } + fn emit_str(&mut self, key: Key, val: &str) -> slog::Result { + let val = val.to_owned(); + take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val)))); + Ok(()) + } + fn emit_arguments( + &mut self, + key: Key, + val: &fmt::Arguments, + ) -> slog::Result { + let val = fmt::format(*val); + take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val)))); + Ok(()) + } + + fn emit_serde(&mut self, key: Key, value: &dyn slog::SerdeValue) -> slog::Result { + let val = value.to_sendable(); + take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val)))); + Ok(()) + } +} + +pub(crate) struct AsyncRecord { + msg: String, + level: Level, + location: Box, + tag: String, + logger_values: OwnedKVList, + kv: Box, +} + +impl AsyncRecord { + /// Serializes a `Record` and an `OwnedKVList`. + pub fn from(record: &Record, logger_values: &OwnedKVList) -> Self { + let mut ser = ToSendSerializer::new(); + record + .kv() + .serialize(record, &mut ser) + .expect("`ToSendSerializer` can't fail"); + + AsyncRecord { + msg: fmt::format(*record.msg()), + level: record.level(), + location: Box::new(*record.location()), + tag: String::from(record.tag()), + logger_values: logger_values.clone(), + kv: ser.finish(), + } + } + + /// Deconstruct this `AsyncRecord` into a record and `OwnedKVList`. + pub fn as_record_values(&self, mut f: impl FnMut(&Record, &OwnedKVList)) { + let rs = RecordStatic { + location: &*self.location, + level: self.level, + tag: &self.tag, + }; + + f(&Record::new( + &rs, + &format_args!("{}", self.msg), + BorrowedKV(&self.kv), + ), &self.logger_values) + } +} diff --git a/client/telemetry/src/lib.rs b/client/telemetry/src/lib.rs index 768fc2df84e6a6c0ae2bb7d4ebd341b3a546321c..bc2e9aa691ef1ef9e4d9be49cfb09202d9d1aa47 100644 --- a/client/telemetry/src/lib.rs +++ b/client/telemetry/src/lib.rs @@ -37,8 +37,8 @@ //! ```no_run //! use futures::prelude::*; //! -//! let telemetry = substrate_telemetry::init_telemetry(substrate_telemetry::TelemetryConfig { -//! endpoints: substrate_telemetry::TelemetryEndpoints::new(vec![ +//! let telemetry = sc_telemetry::init_telemetry(sc_telemetry::TelemetryConfig { +//! endpoints: sc_telemetry::TelemetryEndpoints::new(vec![ //! // The `0` is the maximum verbosity level of messages to send to this endpoint. //! ("wss://example.com".into(), 0) //! ]), @@ -52,7 +52,7 @@ //! }); //! //! // Sends a message on the telemetry. -//! substrate_telemetry::telemetry!(substrate_telemetry::SUBSTRATE_INFO; "test"; +//! sc_telemetry::telemetry!(sc_telemetry::SUBSTRATE_INFO; "test"; //! "foo" => "bar", //! ) //! ``` @@ -68,6 +68,7 @@ use std::{pin::Pin, sync::Arc, task::{Context, Poll}, time::{Duration, Instant}} pub use slog_scope::with_logger; pub use slog; +mod async_record; mod worker; /// Configuration for telemetry. @@ -124,20 +125,20 @@ pub struct Telemetry { /// Behind the `Mutex` in `Telemetry`. /// /// Note that ideally we wouldn't have to make the `Telemetry` clonable, as that would remove the -/// need for a `Mutex`. However there is currently a weird hack in place in `substrate-service` +/// need for a `Mutex`. However there is currently a weird hack in place in `sc-service` /// where we extract the telemetry registration so that it continues running during the shutdown /// process. struct TelemetryInner { /// Worker for the telemetry. worker: worker::TelemetryWorker, /// Receives log entries for them to be dispatched to the worker. - receiver: mpsc::Receiver, + receiver: mpsc::Receiver, } /// Implements `slog::Drain`. struct TelemetryDrain { /// Sends log entries. - sender: std::panic::AssertUnwindSafe>, + sender: std::panic::AssertUnwindSafe>, } /// Initializes the telemetry. See the crate root documentation for more information. @@ -241,7 +242,7 @@ impl slog::Drain for TelemetryDrain { fn log(&self, record: &slog::Record, values: &slog::OwnedKVList) -> Result { let before = Instant::now(); - let serialized = slog_async::AsyncRecord::from(record, values); + let serialized = async_record::AsyncRecord::from(record, values); // Note: interestingly, `try_send` requires a `&mut` because it modifies some internal value, while `clone()` // is lock-free. if let Err(err) = self.sender.clone().try_send(serialized) { diff --git a/client/tracing/Cargo.toml b/client/tracing/Cargo.toml index 25a1a7331be5a316ba5a0706cbe548337eb315be..2ceee93f6a62a11c29f6547130f49001b82999da 100644 --- a/client/tracing/Cargo.toml +++ b/client/tracing/Cargo.toml @@ -1,16 +1,21 @@ [package] -name = "substrate-tracing" +name = "sc-tracing" version = "2.0.0" license = "GPL-3.0" authors = ["Parity Technologies "] edition = "2018" [dependencies] +erased-serde = "0.3.9" log = { version = "0.4.8" } parking_lot = "0.9.0" +serde = "1.0.101" +serde_json = "1.0.41" +slog = { version = "2.5.2", features = ["nested-values"] } tracing-core = "0.1.7" -substrate-telemetry = { path = "../telemetry" } +sc-telemetry = { version = "2.0.0", path = "../telemetry" } +grafana-data-source = { version = "2.0.0", path = "../../utils/grafana-data-source" } [dev-dependencies] tracing = "0.1.10" diff --git a/client/tracing/src/lib.rs b/client/tracing/src/lib.rs index d6fc4a6418dfb2b96867d48db45c2c1b657e14d6..288d5e70192debff69464ee27628853332be6731 100644 --- a/client/tracing/src/lib.rs +++ b/client/tracing/src/lib.rs @@ -24,21 +24,37 @@ //! A span is set in the following way: //! ``` //! let span = tracing::span!(tracing::Level::INFO, "my_span_name"); -//! let _enter = span.enter(); +//! let _guard = span.enter(); //! ``` //! To begin timing, a span must be entered. When the span is dropped, the execution time //! is recorded and details sent to the `Receiver` which defines how to process it. //! -//! Currently we provide `Log` (default) and `Telemetry` variants for `Receiver` +//! It's possible to record values with each span in the following way: +//! ``` +//! let span = tracing::span!(tracing::Level::INFO, "my_span_name", my_number = 10, a_key = "a value"); +//! let _guard = span.enter(); +//! ``` +//! Currently we provide `Log` (default), `Telemetry` and `Grafana` variants for `Receiver` use std::collections::HashMap; +use std::fmt; use std::sync::atomic::{AtomicU64, Ordering}; use std::time::{Duration, Instant}; use parking_lot::Mutex; -use tracing_core::{event::Event, Level, metadata::Metadata, span::{Attributes, Id, Record}, subscriber::Subscriber}; +use serde::ser::{Serialize, Serializer, SerializeMap}; +use slog::{SerdeValue, Value}; +use tracing_core::{ + event::Event, + field::{Visit, Field}, + Level, + metadata::Metadata, + span::{Attributes, Id, Record}, + subscriber::Subscriber +}; -use substrate_telemetry::{telemetry, SUBSTRATE_INFO}; +use grafana_data_source::{self, record_metrics}; +use sc_telemetry::{telemetry, SUBSTRATE_INFO}; /// Used to configure how to receive the metrics #[derive(Debug, Clone)] @@ -47,6 +63,8 @@ pub enum TracingReceiver { Log, /// Output to telemetry Telemetry, + /// Output to Grafana + Grafana, } impl Default for TracingReceiver { @@ -59,11 +77,73 @@ impl Default for TracingReceiver { struct SpanDatum { id: u64, name: &'static str, - target: String, + target: &'static str, level: Level, line: u32, start_time: Instant, overall_time: Duration, + values: Visitor, +} + +#[derive(Clone, Debug)] +struct Visitor(Vec<(String, String)>); + +impl Visit for Visitor { + fn record_i64(&mut self, field: &Field, value: i64) { + self.record_debug(field, &value) + } + + fn record_u64(&mut self, field: &Field, value: u64) { + self.record_debug(field, &value) + } + + fn record_bool(&mut self, field: &Field, value: bool) { + self.record_debug(field, &value) + } + + fn record_debug(&mut self, field: &Field, value: &dyn std::fmt::Debug) { + self.0.push((field.name().to_string(), format!("{:?}",value))); + } +} + +impl Serialize for Visitor { + fn serialize(&self, serializer: S) -> Result + where S: Serializer, + { + let mut map = serializer.serialize_map(Some(self.0.len()))?; + for (k, v) in &self.0 { + map.serialize_entry(k, v)?; + } + map.end() + } +} + +impl fmt::Display for Visitor { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let values = self.0.iter().map(|(k,v)| format!("{}={}",k,v)).collect::>().join(", "); + write!(f, "{}", values) + } +} + +impl SerdeValue for Visitor { + fn as_serde(&self) -> &dyn erased_serde::Serialize { + self + } + + fn to_sendable(&self) -> Box { + Box::new(self.clone()) + } +} + +impl Value for Visitor { + fn serialize( + &self, + _record: &slog::Record, + key: slog::Key, + ser: &mut dyn slog::Serializer, + ) -> slog::Result { + ser.emit_serde(key, self) + } } /// Responsible for assigning ids to new spans, which are not re-used. @@ -76,9 +156,9 @@ pub struct ProfilingSubscriber { impl ProfilingSubscriber { /// Takes a `Receiver` and a comma separated list of targets, - /// either with a level "paint=trace" - /// or without "paint". - pub fn new(receiver: TracingReceiver, targets: &String) -> Self { + /// either with a level: "pallet=trace" + /// or without: "pallet". + pub fn new(receiver: TracingReceiver, targets: &str) -> Self { let targets: Vec<_> = targets.split(',').map(|s| parse_target(s)).collect(); ProfilingSubscriber { next_id: AtomicU64::new(1), @@ -92,7 +172,7 @@ impl ProfilingSubscriber { // Default to TRACE if no level given or unable to parse Level // We do not support a global `Level` currently fn parse_target(s: &str) -> (String, Level) { - match s.find("=") { + match s.find('=') { Some(i) => { let target = s[0..i].to_string(); if s.len() > i { @@ -121,14 +201,17 @@ impl Subscriber for ProfilingSubscriber { fn new_span(&self, attrs: &Attributes<'_>) -> Id { let id = self.next_id.fetch_add(1, Ordering::Relaxed); + let mut values = Visitor(Vec::new()); + attrs.record(&mut values); let span_datum = SpanDatum { - id: id, + id, name: attrs.metadata().name(), - target: attrs.metadata().target().to_string(), + target: attrs.metadata().target(), level: attrs.metadata().level().clone(), line: attrs.metadata().line().unwrap_or(0), start_time: Instant::now(), overall_time: Duration::from_nanos(0), + values, }; self.span_data.lock().insert(id, span_datum); Id::from_u64(id) @@ -172,20 +255,30 @@ impl ProfilingSubscriber { match self.receiver { TracingReceiver::Log => print_log(span_datum), TracingReceiver::Telemetry => send_telemetry(span_datum), + TracingReceiver::Grafana => send_grafana(span_datum), } } } fn print_log(span_datum: SpanDatum) { - let message = format!( - "Tracing: {} {}: {}, line: {}, time: {} ns", - span_datum.level, - span_datum.target, - span_datum.name, - span_datum.line, - span_datum.overall_time.as_nanos() - ); - log::info!(target: "substrate_tracing", "{}", message); + if span_datum.values.0.is_empty() { + log::info!("TRACING: {} {}: {}, line: {}, time: {}", + span_datum.level, + span_datum.target, + span_datum.name, + span_datum.line, + span_datum.overall_time.as_nanos(), + ); + } else { + log::info!("TRACING: {} {}: {}, line: {}, time: {}, {}", + span_datum.level, + span_datum.target, + span_datum.name, + span_datum.line, + span_datum.overall_time.as_nanos(), + span_datum.values + ); + } } fn send_telemetry(span_datum: SpanDatum) { @@ -194,5 +287,13 @@ fn send_telemetry(span_datum: SpanDatum) { "target" => span_datum.target, "line" => span_datum.line, "time" => span_datum.overall_time.as_nanos(), + "values" => span_datum.values ); } + +fn send_grafana(span_datum: SpanDatum) { + let name = format!("{}::{}", span_datum.target, span_datum.name); + if let Err(e) = record_metrics!(&name => span_datum.overall_time.as_nanos(),) { + log::warn!("Unable to send metrics to grafana: {:?}", e); + } +} diff --git a/client/transaction-pool/Cargo.toml b/client/transaction-pool/Cargo.toml index 60bf0c005c7d9dbd5d0a0ab49b79777b3f5cff5a..701826307129d44c1c40e2643744892ef2712558 100644 --- a/client/transaction-pool/Cargo.toml +++ b/client/transaction-pool/Cargo.toml @@ -1,21 +1,23 @@ [package] -name = "substrate-transaction-pool" +name = "sc-transaction-pool" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" [dependencies] codec = { package = "parity-scale-codec", version = "1.0.0" } -derive_more = "0.15.0" -futures = { version = "0.3.1", features = ["thread-pool"] } +derive_more = "0.99.2" +futures = { version = "0.3.1", features = ["compat"] } log = "0.4.8" parking_lot = "0.9.0" -primitives = { package = "substrate-primitives", path = "../../primitives/core" } -sr-api = { path = "../../primitives/sr-api" } -sr-primitives = { path = "../../primitives/sr-primitives" } -tx-runtime-api = { package = "substrate-transaction-pool-runtime-api", path = "../../primitives/transaction-pool/runtime-api" } -txpool = { package = "substrate-transaction-graph", path = "./graph" } +sp-core = { version = "2.0.0", path = "../../primitives/core" } +sp-api = { version = "2.0.0", path = "../../primitives/api" } +sp-runtime = { version = "2.0.0", path = "../../primitives/runtime" } +sc-transaction-graph = { version = "2.0.0", path = "./graph" } +sp-transaction-pool = { version = "2.0.0", path = "../../primitives/transaction-pool" } +sc-client-api = { version = "2.0.0", path = "../api" } +sp-blockchain = { version = "2.0.0", path = "../../primitives/blockchain" } [dev-dependencies] -keyring = { package = "substrate-keyring", path = "../../primitives/keyring" } -test-client = { package = "substrate-test-runtime-client", path = "../../test/utils/runtime/client" } +sp-keyring = { version = "2.0.0", path = "../../primitives/keyring" } +substrate-test-runtime-client = { version = "2.0.0", path = "../../test-utils/runtime/client" } diff --git a/client/transaction-pool/graph/Cargo.toml b/client/transaction-pool/graph/Cargo.toml index c81e59e17fe4cd2ef1b784713394472dc95a76d2..c5897e84fe50deb44d36f0d9328a4048374116ef 100644 --- a/client/transaction-pool/graph/Cargo.toml +++ b/client/transaction-pool/graph/Cargo.toml @@ -1,23 +1,23 @@ [package] -name = "substrate-transaction-graph" +name = "sc-transaction-graph" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" [dependencies] -derive_more = "0.15.0" +derive_more = "0.99.2" futures = "0.3.1" log = "0.4.8" parking_lot = "0.9.0" serde = { version = "1.0.101", features = ["derive"] } -primitives = { package = "substrate-primitives", path = "../../../primitives/core" } -sr-primitives = { path = "../../../primitives/sr-primitives" } +sp-core = { version = "2.0.0", path = "../../../primitives/core" } +sp-runtime = { version = "2.0.0", path = "../../../primitives/runtime" } +sp-transaction-pool = { version = "2.0.0", path = "../../../primitives/transaction-pool" } [dev-dependencies] assert_matches = "1.3.0" -env_logger = "0.7.0" codec = { package = "parity-scale-codec", version = "1.0.0" } -test_runtime = { package = "substrate-test-runtime", path = "../../../test/utils/runtime" } +substrate-test-runtime = { version = "2.0.0", path = "../../../test-utils/runtime" } criterion = "0.3" [[bench]] diff --git a/client/transaction-pool/graph/benches/basics.rs b/client/transaction-pool/graph/benches/basics.rs index dcd725ce465f42c6e90f1c70315642ab9d9c326d..bd65efe4487c52e1e5884ce62aa5c374a43212c6 100644 --- a/client/transaction-pool/graph/benches/basics.rs +++ b/client/transaction-pool/graph/benches/basics.rs @@ -17,15 +17,15 @@ use criterion::{criterion_group, criterion_main, Criterion}; use futures::executor::block_on; -use substrate_transaction_graph::*; -use sr_primitives::transaction_validity::{ValidTransaction, InvalidTransaction}; +use sc_transaction_graph::*; +use sp_runtime::transaction_validity::{ValidTransaction, InvalidTransaction}; use codec::Encode; -use test_runtime::{Block, Extrinsic, Transfer, H256, AccountId}; -use sr_primitives::{ +use substrate_test_runtime::{Block, Extrinsic, Transfer, H256, AccountId}; +use sp_runtime::{ generic::BlockId, transaction_validity::{TransactionValidity, TransactionTag as Tag}, }; -use primitives::blake2_256; +use sp_core::blake2_256; #[derive(Clone, Debug, Default)] struct TestApi { @@ -48,8 +48,8 @@ fn to_tag(nonce: u64, from: AccountId) -> Tag { impl ChainApi for TestApi { type Block = Block; type Hash = H256; - type Error = error::Error; - type ValidationFuture = futures::future::Ready>; + type Error = sp_transaction_pool::error::Error; + type ValidationFuture = futures::future::Ready>; fn validate_transaction( &self, diff --git a/client/transaction-pool/graph/src/base_pool.rs b/client/transaction-pool/graph/src/base_pool.rs index cb37aee07f4b8116fe2b0cb7cfcf36e746676474..8878e9e6dd0a7d5b85e777855f834a7ce7184e59 100644 --- a/client/transaction-pool/graph/src/base_pool.rs +++ b/client/transaction-pool/graph/src/base_pool.rs @@ -27,15 +27,15 @@ use std::{ use log::{trace, debug, warn}; use serde::Serialize; -use primitives::hexdisplay::HexDisplay; -use sr_primitives::traits::Member; -use sr_primitives::transaction_validity::{ +use sp_core::hexdisplay::HexDisplay; +use sp_runtime::traits::Member; +use sp_runtime::transaction_validity::{ TransactionTag as Tag, TransactionLongevity as Longevity, TransactionPriority as Priority, }; +use sp_transaction_pool::{error, PoolStatus, InPoolTransaction}; -use crate::error; use crate::future::{FutureTransactions, WaitingTransaction}; use crate::ready::ReadyTransactions; @@ -104,13 +104,65 @@ pub struct Transaction { pub propagate: bool, } -impl Transaction { - /// Returns `true` if the transaction should be propagated to other peers. - pub fn is_propagateable(&self) -> bool { +impl AsRef for Transaction { + fn as_ref(&self) -> &Extrinsic { + &self.data + } +} + +impl InPoolTransaction for Transaction { + type Transaction = Extrinsic; + type Hash = Hash; + + fn data(&self) -> &Extrinsic { + &self.data + } + + fn hash(&self) -> &Hash { + &self.hash + } + + fn priority(&self) -> &Priority { + &self.priority + } + + fn longevity(&self) ->&Longevity { + &self.valid_till + } + + fn requires(&self) -> &[Tag] { + &self.requires + } + + fn provides(&self) -> &[Tag] { + &self.provides + } + + fn is_propagateable(&self) -> bool { self.propagate } } +impl Transaction { + /// Explicit transaction clone. + /// + /// Transaction should be cloned only if absolutely necessary && we want + /// every reason to be commented. That's why we `Transaction` is not `Clone`, + /// but there's explicit `duplicate` method. + pub fn duplicate(&self) -> Self { + Transaction { + data: self.data.clone(), + bytes: self.bytes.clone(), + hash: self.hash.clone(), + priority: self.priority.clone(), + valid_till: self.valid_till.clone(), + requires: self.requires.clone(), + provides: self.provides.clone(), + propagate: self.propagate, + } + } +} + impl fmt::Debug for Transaction where Hash: fmt::Debug, Extrinsic: fmt::Debug, @@ -159,6 +211,7 @@ const RECENTLY_PRUNED_TAGS: usize = 2; /// required tags. #[derive(Debug)] pub struct BasePool { + reject_future_transactions: bool, future: FutureTransactions, ready: ReadyTransactions, /// Store recently pruned tags (for last two invocations). @@ -169,18 +222,37 @@ pub struct BasePool { recently_pruned_index: usize, } -impl Default for BasePool { +impl Default for BasePool { fn default() -> Self { + Self::new(false) + } +} + +impl BasePool { + /// Create new pool given reject_future_transactions flag. + pub fn new(reject_future_transactions: bool) -> Self { BasePool { + reject_future_transactions, future: Default::default(), ready: Default::default(), recently_pruned: Default::default(), recently_pruned_index: 0, } } -} -impl BasePool { + /// Temporary enables future transactions, runs closure and then restores + /// `reject_future_transactions` flag back to previous value. + /// + /// The closure accepts the mutable reference to the pool and original value + /// of the `reject_future_transactions` flag. + pub(crate) fn with_futures_enabled(&mut self, closure: impl FnOnce(&mut Self, bool) -> T) -> T { + let previous = self.reject_future_transactions; + self.reject_future_transactions = false; + let return_value = closure(self, previous); + self.reject_future_transactions = previous; + return_value + } + /// Imports transaction to the pool. /// /// The pool consists of two parts: Future and Ready. @@ -206,6 +278,10 @@ impl BasePool BasePool BasePool BasePool BasePool Vec>> { - let mut removed = self.ready.remove_invalid(hashes); + pub fn remove_subtree(&mut self, hashes: &[Hash]) -> Vec>> { + let mut removed = self.ready.remove_subtree(hashes); removed.extend(self.future.remove(hashes)); removed } + /// Removes and returns all transactions from the future queue. + pub fn clear_future(&mut self) -> Vec>> { + self.future.clear() + } + /// Prunes transactions that provide given list of tags. /// /// This will cause all transactions that provide these tags to be removed from the pool, - /// but unlike `remove_invalid`, dependent transactions are not touched. + /// but unlike `remove_subtree`, dependent transactions are not touched. /// Additional transactions from future queue might be promoted to ready if you satisfy tags /// that the pool didn't previously know about. pub fn prune_tags(&mut self, tags: impl IntoIterator) -> PruneStatus { @@ -385,7 +466,7 @@ impl BasePool BasePool Status { - Status { + pub fn status(&self) -> PoolStatus { + PoolStatus { ready: self.ready.len(), ready_bytes: self.ready.bytes(), future: self.future.len(), @@ -423,26 +504,6 @@ impl BasePool bool { - self.ready == 0 && self.future == 0 - } -} - /// Queue limits #[derive(Debug, Clone)] pub struct Limit { @@ -844,7 +905,7 @@ mod tests { assert_eq!(pool.future.len(), 1); // when - pool.remove_invalid(&[6, 1]); + pool.remove_subtree(&[6, 1]); // then assert_eq!(pool.ready().count(), 1); @@ -972,4 +1033,85 @@ requires: [03,02], provides: [04], data: [4]}".to_owned() propagate: false, }.is_propagateable(), false); } + + #[test] + fn should_reject_future_transactions() { + // given + let mut pool = pool(); + + // when + pool.reject_future_transactions = true; + + // then + let err = pool.import(Transaction { + data: vec![5u8], + bytes: 1, + hash: 5, + priority: 5u64, + valid_till: 64u64, + requires: vec![vec![0]], + provides: vec![], + propagate: true, + }); + + if let Err(error::Error::RejectedFutureTransaction) = err { + } else { + assert!(false, "Invalid error kind: {:?}", err); + } + } + + #[test] + fn should_clear_future_queue() { + // given + let mut pool = pool(); + + // when + pool.import(Transaction { + data: vec![5u8], + bytes: 1, + hash: 5, + priority: 5u64, + valid_till: 64u64, + requires: vec![vec![0]], + provides: vec![], + propagate: true, + }).unwrap(); + + // then + assert_eq!(pool.future.len(), 1); + + // and then when + assert_eq!(pool.clear_future().len(), 1); + + // then + assert_eq!(pool.future.len(), 0); + } + + #[test] + fn should_accept_future_transactions_when_explcitly_asked_to() { + // given + let mut pool = pool(); + pool.reject_future_transactions = true; + + // when + let flag_value = pool.with_futures_enabled(|pool, flag| { + pool.import(Transaction { + data: vec![5u8], + bytes: 1, + hash: 5, + priority: 5u64, + valid_till: 64u64, + requires: vec![vec![0]], + provides: vec![], + propagate: true, + }).unwrap(); + + flag + }); + + // then + assert_eq!(flag_value, true); + assert_eq!(pool.reject_future_transactions, true); + assert_eq!(pool.future.len(), 1); + } } diff --git a/client/transaction-pool/graph/src/error.rs b/client/transaction-pool/graph/src/error.rs index 79006461c6e37f0ef0e1ae793fa13f12a459a87b..4da1a58624997d04105645520e51b2aaf6e86da6 100644 --- a/client/transaction-pool/graph/src/error.rs +++ b/client/transaction-pool/graph/src/error.rs @@ -16,7 +16,7 @@ //! Transaction pool errors. -use sr_primitives::transaction_validity::{ +use sp_runtime::transaction_validity::{ TransactionPriority as Priority, InvalidTransaction, UnknownTransaction, }; @@ -52,7 +52,7 @@ pub enum Error { /// Transaction entering the pool. new: Priority }, - /// Deps cycle etected and we couldn't import transaction. + /// Deps cycle detected and we couldn't import transaction. #[display(fmt="Cycle Detected")] CycleDetected, /// Transaction was dropped immediately after it got inserted. diff --git a/client/transaction-pool/graph/src/future.rs b/client/transaction-pool/graph/src/future.rs index c7b13c912df183c054d7c717ce6cc056a0353e64..2902f03b26eb369c60c0b726d8946c574a97541d 100644 --- a/client/transaction-pool/graph/src/future.rs +++ b/client/transaction-pool/graph/src/future.rs @@ -22,8 +22,8 @@ use std::{ time, }; -use primitives::hexdisplay::HexDisplay; -use sr_primitives::transaction_validity::{ +use sp_core::hexdisplay::HexDisplay; +use sp_runtime::transaction_validity::{ TransactionTag as Tag, }; @@ -227,6 +227,12 @@ impl FutureTransactions { self.waiting.values().map(|waiting| &*waiting.transaction) } + /// Removes and returns all future transactions. + pub fn clear(&mut self) -> Vec>> { + self.wanted_tags.clear(); + self.waiting.drain().map(|(_, tx)| tx.transaction).collect() + } + /// Returns number of transactions in the Future queue. pub fn len(&self) -> usize { self.waiting.len() diff --git a/client/transaction-pool/graph/src/lib.rs b/client/transaction-pool/graph/src/lib.rs index 715e60874be951fdabfdb05e04c141f5cfa49c8c..db92bef2728ec187e8b8535b51d031379dd42363 100644 --- a/client/transaction-pool/graph/src/lib.rs +++ b/client/transaction-pool/graph/src/lib.rs @@ -32,11 +32,9 @@ mod rotator; mod validated_pool; pub mod base_pool; -pub mod error; pub mod watcher; -pub use self::error::IntoPoolError; -pub use self::base_pool::{Transaction, Status}; +pub use self::base_pool::Transaction; pub use self::pool::{ Pool, Options, ChainApi, EventStream, ExtrinsicFor, diff --git a/client/transaction-pool/graph/src/listener.rs b/client/transaction-pool/graph/src/listener.rs index a96c31544fc75c107efa05059307227890436e1e..a6d65a93ce239635de33606076686084f65e0ffa 100644 --- a/client/transaction-pool/graph/src/listener.rs +++ b/client/transaction-pool/graph/src/listener.rs @@ -22,7 +22,7 @@ use std::{ }; use serde::Serialize; use crate::watcher; -use sr_primitives::traits; +use sp_runtime::traits; use log::{debug, trace, warn}; /// Extrinsic pool default listener. @@ -91,14 +91,18 @@ impl Listene } /// Transaction was removed as invalid. - pub fn invalid(&mut self, tx: &H) { - warn!(target: "transaction-pool", "Extrinsic invalid: {:?}", tx); + pub fn invalid(&mut self, tx: &H, warn: bool) { + if warn { + warn!(target: "txpool", "Extrinsic invalid: {:?}", tx); + } else { + debug!(target: "txpool", "Extrinsic invalid: {:?}", tx); + } self.fire(tx, |watcher| watcher.invalid()); } /// Transaction was pruned from the pool. pub fn pruned(&mut self, header_hash: H2, tx: &H) { debug!(target: "txpool", "[{:?}] Pruned at {:?}", tx, header_hash); - self.fire(tx, |watcher| watcher.finalized(header_hash)) + self.fire(tx, |watcher| watcher.in_block(header_hash)) } } diff --git a/client/transaction-pool/graph/src/pool.rs b/client/transaction-pool/graph/src/pool.rs index d6ef61d17efd541f4df2b398bee2293ee9997032..4e4224695eeb45562f48f9edd15bd13d1438b780 100644 --- a/client/transaction-pool/graph/src/pool.rs +++ b/client/transaction-pool/graph/src/pool.rs @@ -21,7 +21,6 @@ use std::{ }; use crate::base_pool as base; -use crate::error; use crate::watcher::Watcher; use serde::Serialize; @@ -30,11 +29,13 @@ use futures::{ channel::mpsc, future::{Either, ready, join_all}, }; -use sr_primitives::{ +use sp_runtime::{ generic::BlockId, traits::{self, SaturatedConversion}, transaction_validity::{TransactionValidity, TransactionTag as Tag, TransactionValidityError}, }; +use sp_transaction_pool::{error, PoolStatus}; + use crate::validated_pool::{ValidatedPool, ValidatedTransaction}; /// Modification notification event stream type; @@ -92,6 +93,8 @@ pub struct Options { pub ready: base::Limit, /// Future queue limits. pub future: base::Limit, + /// Reject future transactions. + pub reject_future_transactions: bool, } impl Default for Options { @@ -105,6 +108,7 @@ impl Default for Options { count: 128, total_bytes: 1 * 1024 * 1024, }, + reject_future_transactions: false, } } } @@ -131,7 +135,9 @@ impl Pool { let validated_pool = self.validated_pool.clone(); self.verify(at, xts, force) .map(move |validated_transactions| validated_transactions - .map(|validated_transactions| validated_pool.submit(validated_transactions))) + .map(|validated_transactions| validated_pool.submit(validated_transactions + .into_iter() + .map(|(_, tx)| tx)))) } /// Imports one unverified extrinsic to the pool @@ -161,10 +167,66 @@ impl Pool { let validated_pool = self.validated_pool.clone(); Either::Right( self.verify_one(at, block_number, xt, false) - .map(move |validated_transactions| validated_pool.submit_and_watch(validated_transactions)) + .map(move |validated_transactions| validated_pool.submit_and_watch(validated_transactions.1)) ) } + /// Revalidate all ready transactions. + /// + /// Returns future that performs validation of all ready transactions and + /// then resubmits all transactions back to the pool. + pub fn revalidate_ready( + &self, + at: &BlockId, + max: Option, + ) -> impl Future> { + use std::time::Instant; + log::debug!(target: "txpool", + "Fetching ready transactions (up to: {})", + max.map(|x| format!("{}", x)).unwrap_or_else(|| "all".into()) + ); + let validated_pool = self.validated_pool.clone(); + let ready = self.validated_pool.ready() + .map(|tx| tx.data.clone()) + .take(max.unwrap_or_else(usize::max_value)); + + let now = Instant::now(); + self.verify(at, ready, false) + .map(move |revalidated_transactions| { + log::debug!(target: "txpool", + "Re-verified transactions, took {} ms. Resubmitting.", + now.elapsed().as_millis() + ); + let now = Instant::now(); + let res = revalidated_transactions.map( + |revalidated_transactions| validated_pool.resubmit(revalidated_transactions) + ); + log::debug!(target: "txpool", + "Resubmitted. Took {} ms. Status: {:?}", + now.elapsed().as_millis(), + validated_pool.status() + ); + res + }) + } + + /// Prunes known ready transactions. + /// + /// Used to clear the pool from transactions that were part of recently imported block. + /// The main difference from the `prune` is that we do not revalidate any transactions + /// and ignore unknown passed hashes. + pub fn prune_known(&self, at: &BlockId, hashes: &[ExHash]) -> Result<(), B::Error> { + // Get details of all extrinsics that are already in the pool + let in_pool_tags = self.validated_pool.extrinsics_tags(hashes) + .into_iter().filter_map(|x| x).flat_map(|x| x); + + // Prune all transactions that provide given tags + let prune_status = self.validated_pool.prune_tags(in_pool_tags)?; + let pruned_transactions = hashes.into_iter().cloned() + .chain(prune_status.pruned.iter().map(|tx| tx.hash.clone())); + self.validated_pool.fire_pruned(at, pruned_transactions) + } + /// Prunes ready transactions. /// /// Used to clear the pool from transactions that were part of recently imported block. @@ -184,7 +246,8 @@ impl Pool { extrinsics.len() ); // Get details of all extrinsics that are already in the pool - let (in_pool_hashes, in_pool_tags) = self.validated_pool.extrinsics_tags(extrinsics); + let in_pool_hashes = extrinsics.iter().map(|extrinsic| self.hash_of(extrinsic)).collect::>(); + let in_pool_tags = self.validated_pool.extrinsics_tags(&in_pool_hashes); // Zip the ones from the pool with the full list (we get pairs `(Extrinsic, Option>)`) let all = extrinsics.iter().zip(in_pool_tags.into_iter()); @@ -246,7 +309,7 @@ impl Pool { tags: impl IntoIterator, known_imported_hashes: impl IntoIterator> + Clone, ) -> impl Future> { - log::trace!(target: "txpool", "Pruning at {:?}", at); + log::debug!(target: "txpool", "Pruning at {:?}", at); // Prune all transactions that provide given tags let prune_status = match self.validated_pool.prune_tags(tags) { Ok(prune_status) => prune_status, @@ -274,13 +337,13 @@ impl Pool { &at, known_imported_hashes, pruned_hashes, - reverified_transactions, + reverified_transactions.into_iter().map(|(_, xt)| xt).collect(), )) ))) } /// Return an event stream of notifications for when transactions are imported to the pool. - /// + /// /// Consumers of this stream should use the `ready` method to actually get the /// pending transactions in the right order. pub fn import_notification_stream(&self) -> EventStream { @@ -292,7 +355,7 @@ impl Pool { self.validated_pool.on_broadcasted(propagated) } - /// Remove from the pool. + /// Remove invalid transactions from the pool. pub fn remove_invalid(&self, hashes: &[ExHash]) -> Vec> { self.validated_pool.remove_invalid(hashes) } @@ -303,7 +366,7 @@ impl Pool { } /// Returns pool status. - pub fn status(&self) -> base::Status { + pub fn status(&self) -> PoolStatus { self.validated_pool.status() } @@ -325,7 +388,7 @@ impl Pool { at: &BlockId, xts: impl IntoIterator>, force: bool, - ) -> impl Future>, B::Error>> { + ) -> impl Future, ValidatedTransactionFor>, B::Error>> { // we need a block number to compute tx validity let block_number = match self.resolve_block_number(at) { Ok(block_number) => block_number, @@ -338,7 +401,7 @@ impl Pool { ); // make single validation future that waits all until all extrinsics are validated - Either::Right(join_all(validation_futures).then(|x| ready(Ok(x)))) + Either::Right(join_all(validation_futures).then(|x| ready(Ok(x.into_iter().collect())))) } /// Returns future that validates single transaction at given block. @@ -348,14 +411,17 @@ impl Pool { block_number: NumberFor, xt: ExtrinsicFor, force: bool, - ) -> impl Future> { + ) -> impl Future, ValidatedTransactionFor)> { let (hash, bytes) = self.validated_pool.api().hash_and_length(&xt); if !force && self.validated_pool.is_banned(&hash) { - return Either::Left(ready(ValidatedTransaction::Invalid(hash, error::Error::TemporarilyBanned.into()))) + return Either::Left(ready(( + hash.clone(), + ValidatedTransaction::Invalid(hash, error::Error::TemporarilyBanned.into()), + ))) } Either::Right(self.validated_pool.api().validate_transaction(block_id, xt.clone()) - .then(move |validation_result| ready(match validation_result { + .then(move |validation_result| ready((hash.clone(), match validation_result { Ok(validity) => match validity { Ok(validity) => if validity.provides.is_empty() { ValidatedTransaction::Invalid(hash, error::Error::NoTagsProvided.into()) @@ -379,7 +445,7 @@ impl Pool { ValidatedTransaction::Unknown(hash, error::Error::UnknownTransaction(e).into()), }, Err(e) => ValidatedTransaction::Invalid(hash, e), - }))) + })))) } } @@ -391,50 +457,30 @@ impl Clone for Pool { } } -impl sr_primitives::offchain::TransactionPool for Pool { - fn submit_at( - &self, - at: &BlockId, - extrinsic: ::Extrinsic, - ) -> Result<(), ()> { - log::debug!( - target: "txpool", - "(offchain call) Submitting a transaction to the pool: {:?}", - extrinsic - ); - - let result = futures::executor::block_on(self.submit_one(&at, extrinsic)); - - result.map(|_| ()) - .map_err(|e| log::warn!( - target: "txpool", - "(offchain call) Error submitting a transaction to the pool: {:?}", - e - )) - } -} - #[cfg(test)] mod tests { use std::{ - collections::HashMap, + collections::{HashMap, HashSet}, time::Instant, }; use parking_lot::Mutex; use futures::executor::block_on; use super::*; - use sr_primitives::transaction_validity::{ValidTransaction, InvalidTransaction}; + use sp_transaction_pool::TransactionStatus; + use sp_runtime::transaction_validity::{ValidTransaction, InvalidTransaction}; use codec::Encode; - use test_runtime::{Block, Extrinsic, Transfer, H256, AccountId}; + use substrate_test_runtime::{Block, Extrinsic, Transfer, H256, AccountId}; use assert_matches::assert_matches; use crate::base_pool::Limit; - use crate::watcher; const INVALID_NONCE: u64 = 254; #[derive(Clone, Debug, Default)] struct TestApi { delay: Arc>>>, + invalidate: Arc>>, + clear_requirements: Arc>>, + add_requirements: Arc>>, } impl ChainApi for TestApi { @@ -449,6 +495,7 @@ mod tests { at: &BlockId, uxt: ExtrinsicFor, ) -> Self::ValidationFuture { + let hash = self.hash_and_length(&uxt).0; let block_number = self.block_id_to_number(at).unwrap().unwrap(); let nonce = uxt.transfer().nonce; @@ -462,16 +509,30 @@ mod tests { } } + if self.invalidate.lock().contains(&hash) { + return futures::future::ready(Ok(InvalidTransaction::Custom(0).into())); + } + futures::future::ready(if nonce < block_number { Ok(InvalidTransaction::Stale.into()) } else { - Ok(Ok(ValidTransaction { + let mut transaction = ValidTransaction { priority: 4, requires: if nonce > block_number { vec![vec![nonce as u8 - 1]] } else { vec![] }, provides: if nonce == INVALID_NONCE { vec![] } else { vec![vec![nonce as u8]] }, longevity: 3, propagate: true, - })) + }; + + if self.clear_requirements.lock().contains(&hash) { + transaction.requires.clear(); + } + + if self.add_requirements.lock().contains(&hash) { + transaction.requires.push(vec![128]); + } + + Ok(Ok(transaction)) }) } @@ -651,6 +712,7 @@ mod tests { let pool = Pool::new(Options { ready: limit.clone(), future: limit.clone(), + ..Default::default() }, TestApi::default()); let hash1 = block_on(pool.submit_one(&BlockId::Number(0), uxt(Transfer { @@ -685,6 +747,7 @@ mod tests { let pool = Pool::new(Options { ready: limit.clone(), future: limit.clone(), + ..Default::default() }, TestApi::default()); // when @@ -742,8 +805,8 @@ mod tests { // then let mut stream = futures::executor::block_on_stream(watcher.into_stream()); - assert_eq!(stream.next(), Some(watcher::Status::Ready)); - assert_eq!(stream.next(), Some(watcher::Status::Finalized(H256::from_low_u64_be(2).into()))); + assert_eq!(stream.next(), Some(TransactionStatus::Ready)); + assert_eq!(stream.next(), Some(TransactionStatus::InBlock(H256::from_low_u64_be(2).into()))); assert_eq!(stream.next(), None); } @@ -767,8 +830,8 @@ mod tests { // then let mut stream = futures::executor::block_on_stream(watcher.into_stream()); - assert_eq!(stream.next(), Some(watcher::Status::Ready)); - assert_eq!(stream.next(), Some(watcher::Status::Finalized(H256::from_low_u64_be(2).into()))); + assert_eq!(stream.next(), Some(TransactionStatus::Ready)); + assert_eq!(stream.next(), Some(TransactionStatus::InBlock(H256::from_low_u64_be(2).into()))); assert_eq!(stream.next(), None); } @@ -796,8 +859,8 @@ mod tests { // then let mut stream = futures::executor::block_on_stream(watcher.into_stream()); - assert_eq!(stream.next(), Some(watcher::Status::Future)); - assert_eq!(stream.next(), Some(watcher::Status::Ready)); + assert_eq!(stream.next(), Some(TransactionStatus::Future)); + assert_eq!(stream.next(), Some(TransactionStatus::Ready)); } #[test] @@ -819,8 +882,8 @@ mod tests { // then let mut stream = futures::executor::block_on_stream(watcher.into_stream()); - assert_eq!(stream.next(), Some(watcher::Status::Ready)); - assert_eq!(stream.next(), Some(watcher::Status::Invalid)); + assert_eq!(stream.next(), Some(TransactionStatus::Ready)); + assert_eq!(stream.next(), Some(TransactionStatus::Invalid)); assert_eq!(stream.next(), None); } @@ -846,8 +909,8 @@ mod tests { // then let mut stream = futures::executor::block_on_stream(watcher.into_stream()); - assert_eq!(stream.next(), Some(watcher::Status::Ready)); - assert_eq!(stream.next(), Some(watcher::Status::Broadcast(peers))); + assert_eq!(stream.next(), Some(TransactionStatus::Ready)); + assert_eq!(stream.next(), Some(TransactionStatus::Broadcast(peers))); } #[test] @@ -860,6 +923,7 @@ mod tests { let pool = Pool::new(Options { ready: limit.clone(), future: limit.clone(), + ..Default::default() }, TestApi::default()); let xt = uxt(Transfer { @@ -883,13 +947,12 @@ mod tests { // then let mut stream = futures::executor::block_on_stream(watcher.into_stream()); - assert_eq!(stream.next(), Some(watcher::Status::Ready)); - assert_eq!(stream.next(), Some(watcher::Status::Dropped)); + assert_eq!(stream.next(), Some(TransactionStatus::Ready)); + assert_eq!(stream.next(), Some(TransactionStatus::Dropped)); } #[test] fn should_handle_pruning_in_the_middle_of_import() { - let _ = env_logger::try_init(); // given let (ready, is_ready) = std::sync::mpsc::sync_channel(0); let (tx, rx) = std::sync::mpsc::sync_channel(1); @@ -941,5 +1004,81 @@ mod tests { assert_eq!(pool.status().future, 0); } } + + #[test] + fn should_revalidate_ready_transactions() { + fn transfer(nonce: u64) -> Extrinsic { + uxt(Transfer { + from: AccountId::from_h256(H256::from_low_u64_be(1)), + to: AccountId::from_h256(H256::from_low_u64_be(2)), + amount: 5, + nonce, + }) + } + + // given + let pool = pool(); + let tx0 = transfer(0); + let hash0 = pool.validated_pool.api().hash_and_length(&tx0).0; + let watcher0 = block_on(pool.submit_and_watch(&BlockId::Number(0), tx0)).unwrap(); + let tx1 = transfer(1); + let hash1 = pool.validated_pool.api().hash_and_length(&tx1).0; + let watcher1 = block_on(pool.submit_and_watch(&BlockId::Number(0), tx1)).unwrap(); + let tx2 = transfer(2); + let hash2 = pool.validated_pool.api().hash_and_length(&tx2).0; + let watcher2 = block_on(pool.submit_and_watch(&BlockId::Number(0), tx2)).unwrap(); + let tx3 = transfer(3); + let hash3 = pool.validated_pool.api().hash_and_length(&tx3).0; + let watcher3 = block_on(pool.submit_and_watch(&BlockId::Number(0), tx3)).unwrap(); + let tx4 = transfer(4); + let hash4 = pool.validated_pool.api().hash_and_length(&tx4).0; + let watcher4 = block_on(pool.submit_and_watch(&BlockId::Number(0), tx4)).unwrap(); + assert_eq!(pool.status().ready, 5); + + // when + pool.validated_pool.api().invalidate.lock().insert(hash3); + pool.validated_pool.api().clear_requirements.lock().insert(hash1); + pool.validated_pool.api().add_requirements.lock().insert(hash0); + block_on(pool.revalidate_ready(&BlockId::Number(0), None)).unwrap(); + + // then + // hash0 now has unsatisfied requirements => it is moved to the future queue + // hash1 is now independent of hash0 => it is in ready queue + // hash2 still depends on hash1 => it is in ready queue + // hash3 is now invalid => it is removed from the pool + // hash4 now depends on invalidated hash3 => it is moved to the future queue + // + // events for hash3 are: Ready, Invalid + // events for hash4 are: Ready, Invalid + assert_eq!(pool.status().ready, 2); + assert_eq!( + futures::executor::block_on_stream(watcher3.into_stream()).collect::>(), + vec![TransactionStatus::Ready, TransactionStatus::Invalid], + ); + + // when + pool.validated_pool.remove_invalid(&[hash0, hash1, hash2, hash4]); + + // then + // events for hash0 are: Ready, Future, Invalid + // events for hash1 are: Ready, Invalid + // events for hash2 are: Ready, Invalid + assert_eq!( + futures::executor::block_on_stream(watcher0.into_stream()).collect::>(), + vec![TransactionStatus::Ready, TransactionStatus::Future, TransactionStatus::Invalid], + ); + assert_eq!( + futures::executor::block_on_stream(watcher1.into_stream()).collect::>(), + vec![TransactionStatus::Ready, TransactionStatus::Invalid], + ); + assert_eq!( + futures::executor::block_on_stream(watcher2.into_stream()).collect::>(), + vec![TransactionStatus::Ready, TransactionStatus::Invalid], + ); + assert_eq!( + futures::executor::block_on_stream(watcher4.into_stream()).collect::>(), + vec![TransactionStatus::Ready, TransactionStatus::Future, TransactionStatus::Invalid], + ); + } } diff --git a/client/transaction-pool/graph/src/ready.rs b/client/transaction-pool/graph/src/ready.rs index 3698bf447eeaaecf0a6c2ad3212b9f7091b3e871..9fd11ab95962079ccaee64eb7b405cb9f4136835 100644 --- a/client/transaction-pool/graph/src/ready.rs +++ b/client/transaction-pool/graph/src/ready.rs @@ -22,14 +22,14 @@ use std::{ }; use serde::Serialize; -use log::debug; +use log::trace; use parking_lot::RwLock; -use sr_primitives::traits::Member; -use sr_primitives::transaction_validity::{ +use sp_runtime::traits::Member; +use sp_runtime::transaction_validity::{ TransactionTag as Tag, }; +use sp_transaction_pool::error; -use crate::error; use crate::future::WaitingTransaction; use crate::base_pool::Transaction; @@ -230,12 +230,12 @@ impl ReadyTransactions { }).collect() } - /// Removes invalid transactions from the ready pool. + /// Removes a subtree of transactions from the ready pool. /// /// NOTE removing a transaction will also cause a removal of all transactions that depend on that one /// (i.e. the entire subgraph that this transaction is a start of will be removed). /// All removed transactions are returned. - pub fn remove_invalid(&mut self, hashes: &[Hash]) -> Vec>> { + pub fn remove_subtree(&mut self, hashes: &[Hash]) -> Vec>> { let mut removed = vec![]; let mut to_remove = hashes.iter().cloned().collect::>(); @@ -267,7 +267,7 @@ impl ReadyTransactions { to_remove.append(&mut tx.unlocks); // add to removed - debug!(target: "txpool", "[{:?}] Removed as invalid: ", hash); + trace!(target: "txpool", "[{:?}] Removed as part of the subtree.", hash); removed.push(tx.transaction.transaction); } } @@ -433,6 +433,7 @@ impl ReadyTransactions { } } +/// Iterator of ready transactions ordered by priority. pub struct BestIterator { all: Arc>>>, awaiting: HashMap)>, diff --git a/client/transaction-pool/graph/src/validated_pool.rs b/client/transaction-pool/graph/src/validated_pool.rs index 7317d41f42e974b3b7ca89faf3913c2d3c19f750..49b86bbca03c31f1dcc989d54efef02ba8c723aa 100644 --- a/client/transaction-pool/graph/src/validated_pool.rs +++ b/client/transaction-pool/graph/src/validated_pool.rs @@ -18,24 +18,25 @@ use std::{ collections::{HashSet, HashMap}, fmt, hash, + sync::Arc, time, }; use crate::base_pool as base; -use crate::error; use crate::listener::Listener; use crate::rotator::PoolRotator; use crate::watcher::Watcher; use serde::Serialize; -use log::debug; +use log::{debug, warn}; use futures::channel::mpsc; use parking_lot::{Mutex, RwLock}; -use sr_primitives::{ +use sp_runtime::{ generic::BlockId, traits::{self, SaturatedConversion}, transaction_validity::TransactionTag as Tag, }; +use sp_transaction_pool::{error, PoolStatus}; use crate::base_pool::PruneStatus; use crate::pool::{EventStream, Options, ChainApi, BlockHash, ExHash, ExtrinsicFor, TransactionFor}; @@ -76,11 +77,12 @@ pub(crate) struct ValidatedPool { impl ValidatedPool { /// Create a new transaction pool. pub fn new(options: Options, api: B) -> Self { + let base_pool = base::BasePool::new(options.reject_future_transactions); ValidatedPool { api, options, listener: Default::default(), - pool: Default::default(), + pool: RwLock::new(base_pool), import_notification_sinks: Default::default(), rotator: Default::default(), } @@ -104,7 +106,12 @@ impl ValidatedPool { .map(|validated_tx| self.submit_one(validated_tx)) .collect::>(); - let removed = self.enforce_limits(); + // only enforce limits if there is at least one imported transaction + let removed = if results.iter().any(|res| res.is_ok()) { + self.enforce_limits() + } else { + Default::default() + }; results.into_iter().map(|res| match res { Ok(ref hash) if removed.contains(hash) => Err(error::Error::ImmediatelyDropped.into()), @@ -131,7 +138,7 @@ impl ValidatedPool { Err(err.into()) }, ValidatedTransaction::Unknown(hash, err) => { - self.listener.write().invalid(&hash); + self.listener.write().invalid(&hash, false); Err(err.into()) } } @@ -189,18 +196,136 @@ impl ValidatedPool { } } + /// Resubmits revalidated transactions back to the pool. + /// + /// Removes and then submits passed transactions and all dependent transactions. + /// Transactions that are missing from the pool are not submitted. + pub fn resubmit(&self, mut updated_transactions: HashMap, ValidatedTransactionFor>) { + #[derive(Debug, Clone, Copy, PartialEq)] + enum Status { Future, Ready, Failed, Dropped }; + + let (mut initial_statuses, final_statuses) = { + let mut pool = self.pool.write(); + + // remove all passed transactions from the ready/future queues + // (this may remove additional transactions as well) + // + // for every transaction that has an entry in the `updated_transactions`, + // we store updated validation result in txs_to_resubmit + // for every transaction that has no entry in the `updated_transactions`, + // we store last validation result (i.e. the pool entry) in txs_to_resubmit + let mut initial_statuses = HashMap::new(); + let mut txs_to_resubmit = Vec::with_capacity(updated_transactions.len()); + while !updated_transactions.is_empty() { + let hash = updated_transactions.keys().next().cloned().expect("transactions is not empty; qed"); + + // note we are not considering tx with hash invalid here - we just want + // to remove it along with dependent transactions and `remove_subtree()` + // does exactly what we need + let removed = pool.remove_subtree(&[hash.clone()]); + for removed_tx in removed { + let removed_hash = removed_tx.hash.clone(); + let updated_transaction = updated_transactions.remove(&removed_hash); + let tx_to_resubmit = if let Some(updated_tx) = updated_transaction { + updated_tx + } else { + // in most cases we'll end up in successful `try_unwrap`, but if not + // we still need to reinsert transaction back to the pool => duplicate call + let transaction = match Arc::try_unwrap(removed_tx) { + Ok(transaction) => transaction, + Err(transaction) => transaction.duplicate(), + }; + ValidatedTransaction::Valid(transaction) + }; + + initial_statuses.insert(removed_hash.clone(), Status::Ready); + txs_to_resubmit.push((removed_hash, tx_to_resubmit)); + } + // make sure to remove the hash even if it's not present in the pool any more. + updated_transactions.remove(&hash); + } + + // if we're rejecting future transactions, then insertion order matters here: + // if tx1 depends on tx2, then if tx1 is inserted before tx2, then it goes + // to the future queue and gets rejected immediately + // => let's temporary stop rejection and clear future queue before return + pool.with_futures_enabled(|pool, reject_future_transactions| { + // now resubmit all removed transactions back to the pool + let mut final_statuses = HashMap::new(); + for (hash, tx_to_resubmit) in txs_to_resubmit { + match tx_to_resubmit { + ValidatedTransaction::Valid(tx) => match pool.import(tx) { + Ok(imported) => match imported { + base::Imported::Ready { promoted, failed, removed, .. } => { + final_statuses.insert(hash, Status::Ready); + for hash in promoted { + final_statuses.insert(hash, Status::Ready); + } + for hash in failed { + final_statuses.insert(hash, Status::Failed); + } + for tx in removed { + final_statuses.insert(tx.hash.clone(), Status::Dropped); + } + }, + base::Imported::Future { .. } => { + final_statuses.insert(hash, Status::Future); + }, + }, + Err(err) => { + // we do not want to fail if single transaction import has failed + // nor we do want to propagate this error, because it could tx unknown to caller + // => let's just notify listeners (and issue debug message) + warn!( + target: "txpool", + "[{:?}] Removing invalid transaction from update: {}", + hash, + err, + ); + final_statuses.insert(hash, Status::Failed); + }, + }, + ValidatedTransaction::Invalid(_, _) | ValidatedTransaction::Unknown(_, _) => { + final_statuses.insert(hash, Status::Failed); + }, + } + } + + // if the pool is configured to reject future transactions, let's clear the future + // queue, updating final statuses as required + if reject_future_transactions { + for future_tx in pool.clear_future() { + final_statuses.insert(future_tx.hash.clone(), Status::Dropped); + } + } + + (initial_statuses, final_statuses) + }) + }; + + // and now let's notify listeners about status changes + let mut listener = self.listener.write(); + for (hash, final_status) in final_statuses { + let initial_status = initial_statuses.remove(&hash); + if initial_status.is_none() || Some(final_status) != initial_status { + match final_status { + Status::Future => listener.future(&hash), + Status::Ready => listener.ready(&hash, None), + Status::Dropped => listener.dropped(&hash, None), + Status::Failed => listener.invalid(&hash, initial_status.is_some()), + } + } + } + } + /// For each extrinsic, returns tags that it provides (if known), or None (if it is unknown). - pub fn extrinsics_tags(&self, extrinsics: &[ExtrinsicFor]) -> (Vec>, Vec>>) { - let hashes = extrinsics.iter().map(|extrinsic| self.api.hash_and_length(extrinsic).0).collect::>(); - let in_pool = self.pool.read().by_hash(&hashes); - ( - hashes, - in_pool.into_iter() - .map(|existing_in_pool| existing_in_pool - .map(|transaction| transaction.provides.iter().cloned() - .collect())) - .collect(), - ) + pub fn extrinsics_tags(&self, hashes: &[ExHash]) -> Vec>> { + self.pool.read().by_hash(&hashes) + .into_iter() + .map(|existing_in_pool| existing_in_pool + .map(|transaction| transaction.provides.iter().cloned() + .collect())) + .collect() } /// Prunes ready transactions that provide given list of tags. @@ -249,20 +374,29 @@ impl ValidatedPool { // Fire `pruned` notifications for collected hashes and make sure to include // `known_imported_hashes` since they were just imported as part of the block. let hashes = hashes.chain(known_imported_hashes.into_iter()); - { - let header_hash = self.api.block_id_to_hash(at)? - .ok_or_else(|| error::Error::InvalidBlockId(format!("{:?}", at)).into())?; - let mut listener = self.listener.write(); - for h in hashes { - listener.pruned(header_hash, &h); - } - } + self.fire_pruned(at, hashes)?; + // perform regular cleanup of old transactions in the pool // and update temporary bans. self.clear_stale(at)?; Ok(()) } + /// Fire notifications for pruned transactions. + pub fn fire_pruned( + &self, + at: &BlockId, + hashes: impl Iterator>, + ) -> Result<(), B::Error> { + let header_hash = self.api.block_id_to_hash(at)? + .ok_or_else(|| error::Error::InvalidBlockId(format!("{:?}", at)).into())?; + let mut listener = self.listener.write(); + for h in hashes { + listener.pruned(header_hash, &h); + } + Ok(()) + } + /// Removes stale transactions from the pool. /// /// Stale transactions are transaction beyond their longevity period. @@ -270,8 +404,8 @@ impl ValidatedPool { /// See `prune_tags` if you want this. pub fn clear_stale(&self, at: &BlockId) -> Result<(), B::Error> { let block_number = self.api.block_id_to_number(at)? - .ok_or_else(|| error::Error::InvalidBlockId(format!("{:?}", at)).into())? - .saturated_into::(); + .ok_or_else(|| error::Error::InvalidBlockId(format!("{:?}", at)).into())? + .saturated_into::(); let now = time::Instant::now(); let to_remove = { self.ready() @@ -324,17 +458,27 @@ impl ValidatedPool { } } - /// Remove from the pool. + /// Remove a subtree of transactions from the pool and mark them invalid. + /// + /// The transactions passed as an argument will be additionally banned + /// to prevent them from entering the pool right away. + /// Note this is not the case for the dependent transactions - those may + /// still be valid so we want to be able to re-import them. pub fn remove_invalid(&self, hashes: &[ExHash]) -> Vec> { + // early exit in case there is no invalid transactions. + if hashes.is_empty() { + return vec![] + } + // temporarily ban invalid transactions debug!(target: "txpool", "Banning invalid transactions: {:?}", hashes); self.rotator.ban(&time::Instant::now(), hashes.iter().cloned()); - let invalid = self.pool.write().remove_invalid(hashes); + let invalid = self.pool.write().remove_subtree(hashes); let mut listener = self.listener.write(); for tx in &invalid { - listener.invalid(&tx.hash); + listener.invalid(&tx.hash, true); } invalid @@ -346,7 +490,7 @@ impl ValidatedPool { } /// Returns pool status. - pub fn status(&self) -> base::Status { + pub fn status(&self) -> PoolStatus { self.pool.read().status() } } @@ -362,7 +506,7 @@ fn fire_events( base::Imported::Ready { ref promoted, ref failed, ref removed, ref hash } => { listener.ready(hash, None); for f in failed { - listener.invalid(f); + listener.invalid(f, true); } for r in removed { listener.dropped(&r.hash, Some(hash)); diff --git a/client/transaction-pool/graph/src/watcher.rs b/client/transaction-pool/graph/src/watcher.rs index 11d6b9f40742a3837ea66a3a926c90005fa51b0a..ded849e3806ba61eea767a955c276263c09a0e65 100644 --- a/client/transaction-pool/graph/src/watcher.rs +++ b/client/transaction-pool/graph/src/watcher.rs @@ -20,34 +20,14 @@ use futures::{ Stream, channel::mpsc, }; -use serde::{Serialize, Deserialize}; - -/// Possible extrinsic status events -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub enum Status { - /// Extrinsic is part of the future queue. - Future, - /// Extrinsic is part of the ready queue. - Ready, - /// Extrinsic has been finalized in block with given hash. - Finalized(H2), - /// Some state change (perhaps another extrinsic was included) rendered this extrinsic invalid. - Usurped(H), - /// The extrinsic has been broadcast to the given peers. - Broadcast(Vec), - /// Extrinsic has been dropped from the pool because of the limit. - Dropped, - /// Extrinsic was detected as invalid. - Invalid, -} +use sp_transaction_pool::TransactionStatus; /// Extrinsic watcher. /// /// Represents a stream of status updates for particular extrinsic. #[derive(Debug)] pub struct Watcher { - receiver: mpsc::UnboundedReceiver>, + receiver: mpsc::UnboundedReceiver>, hash: H, } @@ -60,7 +40,7 @@ impl Watcher { /// Pipe the notifications to given sink. /// /// Make sure to drive the future to completion. - pub fn into_stream(self) -> impl Stream> { + pub fn into_stream(self) -> impl Stream> { self.receiver } } @@ -68,7 +48,7 @@ impl Watcher { /// Sender part of the watcher. Exposed only for testing purposes. #[derive(Debug)] pub struct Sender { - receivers: Vec>>, + receivers: Vec>>, finalized: bool, } @@ -94,49 +74,50 @@ impl Sender { /// Transaction became ready. pub fn ready(&mut self) { - self.send(Status::Ready) + self.send(TransactionStatus::Ready) } /// Transaction was moved to future. pub fn future(&mut self) { - self.send(Status::Future) + self.send(TransactionStatus::Future) } /// Some state change (perhaps another extrinsic was included) rendered this extrinsic invalid. pub fn usurped(&mut self, hash: H) { - self.send(Status::Usurped(hash)) + self.send(TransactionStatus::Usurped(hash)); + self.finalized = true; } - /// Extrinsic has been finalized in block with given hash. - pub fn finalized(&mut self, hash: H2) { - self.send(Status::Finalized(hash)); + /// Extrinsic has been included in block with given hash. + pub fn in_block(&mut self, hash: H2) { + self.send(TransactionStatus::InBlock(hash)); self.finalized = true; } /// Extrinsic has been marked as invalid by the block builder. pub fn invalid(&mut self) { - self.send(Status::Invalid); + self.send(TransactionStatus::Invalid); // we mark as finalized as there are no more notifications self.finalized = true; } /// Transaction has been dropped from the pool because of the limit. pub fn dropped(&mut self) { - self.send(Status::Dropped); + self.send(TransactionStatus::Dropped); + self.finalized = true; } /// The extrinsic has been broadcast to the given peers. pub fn broadcast(&mut self, peers: Vec) { - self.send(Status::Broadcast(peers)) + self.send(TransactionStatus::Broadcast(peers)) } - /// Returns true if the are no more listeners for this extrinsic or it was finalized. pub fn is_done(&self) -> bool { self.finalized || self.receivers.is_empty() } - fn send(&mut self, status: Status) { + fn send(&mut self, status: TransactionStatus) { self.receivers.retain(|sender| sender.unbounded_send(status.clone()).is_ok()) } } diff --git a/client/transaction-pool/src/api.rs b/client/transaction-pool/src/api.rs index 28681fb11ba8a38ef53b93c98e6d8a0484dbd2d6..6f4899995ff33e4ede11c61807d0c8f2715f9aac 100644 --- a/client/transaction-pool/src/api.rs +++ b/client/transaction-pool/src/api.rs @@ -17,20 +17,20 @@ //! Chain api required for the transaction pool. use std::{marker::PhantomData, pin::Pin, sync::Arc}; +use codec::{Decode, Encode}; +use futures::{channel::oneshot, executor::{ThreadPool, ThreadPoolBuilder}, future::{Future, FutureExt, ready}}; -use codec::Encode; - -use futures::{channel::oneshot, executor::{ThreadPool, ThreadPoolBuilder}, future::Future}; - -use primitives::{H256, Blake2Hasher, Hasher}; - -use sr_primitives::{generic::BlockId, traits, transaction_validity::TransactionValidity}; - -use tx_runtime_api::TaggedTransactionQueue; +use sc_client_api::{ + blockchain::HeaderBackend, + light::{Fetcher, RemoteCallRequest} +}; +use sp_core::{H256, Blake2Hasher, Hasher}; +use sp_runtime::{generic::BlockId, traits::{self, Block as BlockT}, transaction_validity::TransactionValidity}; +use sp_transaction_pool::runtime_api::TaggedTransactionQueue; use crate::error::{self, Error}; -/// The transaction pool logic +/// The transaction pool logic for full client. pub struct FullChainApi { client: Arc, pool: ThreadPool, @@ -38,7 +38,7 @@ pub struct FullChainApi { } impl FullChainApi where - Block: traits::Block, + Block: BlockT, T: traits::ProvideRuntimeApi + traits::BlockIdTo { /// Create new transaction pool logic. pub fn new(client: Arc) -> Self { @@ -54,11 +54,11 @@ impl FullChainApi where } } -impl txpool::ChainApi for FullChainApi where - Block: traits::Block, +impl sc_transaction_graph::ChainApi for FullChainApi where + Block: BlockT, T: traits::ProvideRuntimeApi + traits::BlockIdTo + 'static + Send + Sync, T::Api: TaggedTransactionQueue, - sr_api::ApiErrorFor: Send, + sp_api::ApiErrorFor: Send, { type Block = Block; type Hash = H256; @@ -68,7 +68,7 @@ impl txpool::ChainApi for FullChainApi where fn validate_transaction( &self, at: &BlockId, - uxt: txpool::ExtrinsicFor, + uxt: sc_transaction_graph::ExtrinsicFor, ) -> Self::ValidationFuture { let (tx, rx) = oneshot::channel(); let client = self.client.clone(); @@ -93,18 +93,99 @@ impl txpool::ChainApi for FullChainApi where fn block_id_to_number( &self, at: &BlockId, - ) -> error::Result>> { + ) -> error::Result>> { self.client.to_number(at).map_err(|e| Error::BlockIdConversion(format!("{:?}", e))) } fn block_id_to_hash( &self, at: &BlockId, - ) -> error::Result>> { + ) -> error::Result>> { self.client.to_hash(at).map_err(|e| Error::BlockIdConversion(format!("{:?}", e))) } - fn hash_and_length(&self, ex: &txpool::ExtrinsicFor) -> (Self::Hash, usize) { + fn hash_and_length(&self, ex: &sc_transaction_graph::ExtrinsicFor) -> (Self::Hash, usize) { + ex.using_encoded(|x| { + (Blake2Hasher::hash(x), x.len()) + }) + } +} + +/// The transaction pool logic for light client. +pub struct LightChainApi { + client: Arc, + fetcher: Arc, + _phantom: PhantomData, +} + +impl LightChainApi where + Block: BlockT, + T: HeaderBackend, + F: Fetcher, +{ + /// Create new transaction pool logic. + pub fn new(client: Arc, fetcher: Arc) -> Self { + LightChainApi { + client, + fetcher, + _phantom: Default::default(), + } + } +} + +impl sc_transaction_graph::ChainApi for LightChainApi where + Block: BlockT, + T: HeaderBackend + 'static, + F: Fetcher + 'static, +{ + type Block = Block; + type Hash = H256; + type Error = error::Error; + type ValidationFuture = Box> + Send + Unpin>; + + fn validate_transaction( + &self, + at: &BlockId, + uxt: sc_transaction_graph::ExtrinsicFor, + ) -> Self::ValidationFuture { + let header_hash = self.client.expect_block_hash_from_id(at); + let header_and_hash = header_hash + .and_then(|header_hash| self.client.expect_header(BlockId::Hash(header_hash)) + .map(|header| (header_hash, header))); + let (block, header) = match header_and_hash { + Ok((header_hash, header)) => (header_hash, header), + Err(err) => return Box::new(ready(Err(err.into()))), + }; + let remote_validation_request = self.fetcher.remote_call(RemoteCallRequest { + block, + header, + method: "TaggedTransactionQueue_validate_transaction".into(), + call_data: uxt.encode(), + retry_count: None, + }); + let remote_validation_request = remote_validation_request.then(move |result| { + let result: error::Result = result + .map_err(Into::into) + .and_then(|result| Decode::decode(&mut &result[..]) + .map_err(|e| Error::RuntimeApi( + format!("Error decoding tx validation result: {:?}", e) + )) + ); + ready(result) + }); + + Box::new(remote_validation_request) + } + + fn block_id_to_number(&self, at: &BlockId) -> error::Result>> { + Ok(self.client.block_number_from_id(at)?) + } + + fn block_id_to_hash(&self, at: &BlockId) -> error::Result>> { + Ok(self.client.block_hash_from_id(at)?) + } + + fn hash_and_length(&self, ex: &sc_transaction_graph::ExtrinsicFor) -> (Self::Hash, usize) { ex.using_encoded(|x| { (Blake2Hasher::hash(x), x.len()) }) diff --git a/client/transaction-pool/src/error.rs b/client/transaction-pool/src/error.rs index ae0a058e5cc376218acac2568e9f9a070a7b0a0e..5394393c4657f904c772affe61b2b23883937705 100644 --- a/client/transaction-pool/src/error.rs +++ b/client/transaction-pool/src/error.rs @@ -16,6 +16,8 @@ //! Transaction pool error. +use sp_transaction_pool::error::Error as TxPoolError; + /// Transaction pool result. pub type Result = std::result::Result; @@ -23,10 +25,14 @@ pub type Result = std::result::Result; #[derive(Debug, derive_more::Display, derive_more::From)] pub enum Error { /// Pool error. - Pool(txpool::error::Error), + Pool(TxPoolError), + /// Blockchain error. + Blockchain(sp_blockchain::Error), /// Error while converting a `BlockId`. + #[from(ignore)] BlockIdConversion(String), /// Error while calling the runtime api. + #[from(ignore)] RuntimeApi(String), } @@ -34,14 +40,15 @@ impl std::error::Error for Error { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { match self { Error::Pool(ref err) => Some(err), + Error::Blockchain(ref err) => Some(err), Error::BlockIdConversion(_) => None, Error::RuntimeApi(_) => None, } } } -impl txpool::IntoPoolError for Error { - fn into_pool_error(self) -> std::result::Result { +impl sp_transaction_pool::error::IntoPoolError for Error { + fn into_pool_error(self) -> std::result::Result { match self { Error::Pool(e) => Ok(e), e => Err(e), diff --git a/client/transaction-pool/src/lib.rs b/client/transaction-pool/src/lib.rs index d7703de65285d2b8c5730dd6bc26dc232ffb6d6b..9ca4cc0a1eac1b3207a7b3c74792290eaefe9700 100644 --- a/client/transaction-pool/src/lib.rs +++ b/client/transaction-pool/src/lib.rs @@ -14,15 +14,119 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! Substrate transaction pool. +//! Substrate transaction pool implementation. #![warn(missing_docs)] #![warn(unused_extern_crates)] mod api; +mod maintainer; + pub mod error; #[cfg(test)] mod tests; -pub use api::FullChainApi; -pub use txpool; +pub use sc_transaction_graph as txpool; +pub use crate::api::{FullChainApi, LightChainApi}; +pub use crate::maintainer::{FullBasicPoolMaintainer, LightBasicPoolMaintainer}; + +use std::{collections::HashMap, sync::Arc}; +use futures::{Future, FutureExt}; + +use sp_runtime::{ + generic::BlockId, + traits::Block as BlockT, +}; +use sp_transaction_pool::{ + TransactionPool, PoolStatus, ImportNotificationStream, + TxHash, TransactionFor, TransactionStatusStreamFor, +}; + +/// Basic implementation of transaction pool that can be customized by providing PoolApi. +pub struct BasicPool + where + Block: BlockT, + PoolApi: sc_transaction_graph::ChainApi, +{ + pool: Arc>, +} + +impl BasicPool + where + Block: BlockT, + PoolApi: sc_transaction_graph::ChainApi, +{ + /// Create new basic transaction pool with provided api. + pub fn new(options: sc_transaction_graph::Options, pool_api: PoolApi) -> Self { + BasicPool { + pool: Arc::new(sc_transaction_graph::Pool::new(options, pool_api)), + } + } + + /// Gets shared reference to the underlying pool. + pub fn pool(&self) -> &Arc> { + &self.pool + } +} + +impl TransactionPool for BasicPool + where + Block: BlockT, + PoolApi: 'static + sc_transaction_graph::ChainApi, +{ + type Block = PoolApi::Block; + type Hash = sc_transaction_graph::ExHash; + type InPoolTransaction = sc_transaction_graph::base_pool::Transaction, TransactionFor>; + type Error = error::Error; + + fn submit_at( + &self, + at: &BlockId, + xts: impl IntoIterator> + 'static, + ) -> Box, Self::Error>>, Self::Error>> + Send + Unpin> { + Box::new(self.pool.submit_at(at, xts, false)) + } + + fn submit_one( + &self, + at: &BlockId, + xt: TransactionFor, + ) -> Box, Self::Error>> + Send + Unpin> { + Box::new(self.pool.submit_one(at, xt)) + } + + fn submit_and_watch( + &self, + at: &BlockId, + xt: TransactionFor, + ) -> Box>, Self::Error>> + Send + Unpin> { + Box::new( + self.pool.submit_and_watch(at, xt) + .map(|result| result.map(|watcher| Box::new(watcher.into_stream()) as _)) + ) + } + + fn remove_invalid(&self, hashes: &[TxHash]) -> Vec> { + self.pool.remove_invalid(hashes) + } + + fn status(&self) -> PoolStatus { + self.pool.status() + } + + fn ready(&self) -> Box>> { + Box::new(self.pool.ready()) + } + + fn import_notification_stream(&self) -> ImportNotificationStream { + self.pool.import_notification_stream() + } + + fn hash_of(&self, xt: &TransactionFor) -> TxHash { + self.pool.hash_of(xt) + } + + fn on_broadcasted(&self, propagations: HashMap, Vec>) { + self.pool.on_broadcasted(propagations) + } +} diff --git a/client/transaction-pool/src/maintainer.rs b/client/transaction-pool/src/maintainer.rs new file mode 100644 index 0000000000000000000000000000000000000000..799aa8bd126369035ea4ce9af62cd8549242d3d9 --- /dev/null +++ b/client/transaction-pool/src/maintainer.rs @@ -0,0 +1,608 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +use std::{ + marker::{PhantomData, Unpin}, + sync::Arc, + time::Instant, +}; +use futures::{ + Future, FutureExt, + future::{Either, join, ready}, +}; +use log::{warn, debug, trace}; +use parking_lot::Mutex; + +use sc_client_api::{ + client::BlockBody, + light::{Fetcher, RemoteBodyRequest}, +}; +use sp_core::{Blake2Hasher, H256}; +use sp_runtime::{ + generic::BlockId, + traits::{Block as BlockT, Extrinsic, Header, NumberFor, ProvideRuntimeApi, SimpleArithmetic}, +}; +use sp_blockchain::HeaderBackend; +use sp_transaction_pool::TransactionPoolMaintainer; +use sp_transaction_pool::runtime_api::TaggedTransactionQueue; + +use sc_transaction_graph::{self, ChainApi}; + +/// Basic transaction pool maintainer for full clients. +pub struct FullBasicPoolMaintainer { + pool: Arc>, + client: Arc, +} + +impl FullBasicPoolMaintainer { + /// Create new basic full pool maintainer. + pub fn new( + pool: Arc>, + client: Arc, + ) -> Self { + FullBasicPoolMaintainer { pool, client } + } +} + +impl TransactionPoolMaintainer +for + FullBasicPoolMaintainer +where + Block: BlockT::Out>, + Client: ProvideRuntimeApi + HeaderBackend + BlockBody + 'static, + Client::Api: TaggedTransactionQueue, + PoolApi: ChainApi + 'static, +{ + type Block = Block; + type Hash = Block::Hash; + + fn maintain( + &self, + id: &BlockId, + retracted: &[Block::Hash], + ) -> Box + Send + Unpin> { + let now = std::time::Instant::now(); + let took = move || format!("Took {} ms", now.elapsed().as_millis()); + + let id = *id; + trace!(target: "txpool", "[{:?}] Starting pool maintainance", id); + // Put transactions from retracted blocks back into the pool. + let client_copy = self.client.clone(); + let retracted_transactions = retracted.to_vec().into_iter() + .filter_map(move |hash| client_copy.block_body(&BlockId::hash(hash)).ok().unwrap_or(None)) + .flat_map(|block| block.into_iter()) + // if signed information is not present, attempt to resubmit anyway. + .filter(|tx| tx.is_signed().unwrap_or(true)); + let resubmit_future = self.pool + .submit_at(&id, retracted_transactions, true) + .then(move |resubmit_result| ready(match resubmit_result { + Ok(_) => trace!(target: "txpool", + "[{:?}] Re-submitting retracted done. {}", id, took() + ), + Err(e) => debug!(target: "txpool", + "[{:?}] Error re-submitting transactions: {:?}", id, e + ), + })); + + // Avoid calling into runtime if there is nothing to prune from the pool anyway. + if self.pool.status().is_empty() { + return Box::new(resubmit_future) + } + + let block = (self.client.header(id), self.client.block_body(&id)); + let prune_future = match block { + (Ok(Some(header)), Ok(Some(extrinsics))) => { + let parent_id = BlockId::hash(*header.parent_hash()); + let prune_future = self.pool + .prune(&id, &parent_id, &extrinsics) + .then(move |prune_result| ready(match prune_result { + Ok(_) => trace!(target: "txpool", + "[{:?}] Pruning done. {}", id, took() + ), + Err(e) => warn!(target: "txpool", + "[{:?}] Error pruning transactions: {:?}", id, e + ), + })); + + Either::Left(resubmit_future.then(|_| prune_future)) + }, + (Ok(_), Ok(_)) => Either::Right(resubmit_future), + err => { + warn!(target: "txpool", "[{:?}] Error reading block: {:?}", id, err); + Either::Right(resubmit_future) + }, + }; + + let revalidate_future = self.pool + .revalidate_ready(&id, Some(16)) + .then(move |result| ready(match result { + Ok(_) => debug!(target: "txpool", + "[{:?}] Revalidation done: {}", id, took() + ), + Err(e) => warn!(target: "txpool", + "[{:?}] Encountered errors while revalidating transactions: {:?}", id, e + ), + })); + + Box::new(prune_future.then(|_| revalidate_future)) + } +} + +/// Basic transaction pool maintainer for light clients. +pub struct LightBasicPoolMaintainer { + pool: Arc>, + client: Arc, + fetcher: Arc, + revalidate_time_period: Option, + revalidate_block_period: Option>, + revalidation_status: Arc>>>, + _phantom: PhantomData, +} + +impl LightBasicPoolMaintainer + where + Block: BlockT::Out>, + Client: ProvideRuntimeApi + HeaderBackend + BlockBody + 'static, + Client::Api: TaggedTransactionQueue, + PoolApi: ChainApi + 'static, + F: Fetcher + 'static, +{ + /// Create light pool maintainer with default constants. + /// + /// Default constants are: revalidate every 60 seconds or every 20 blocks + /// (whatever happens first). + pub fn with_defaults( + pool: Arc>, + client: Arc, + fetcher: Arc, + ) -> Self { + Self::new( + pool, + client, + fetcher, + Some(std::time::Duration::from_secs(60)), + Some(20.into()), + ) + } + + /// Create light pool maintainer with passed constants. + pub fn new( + pool: Arc>, + client: Arc, + fetcher: Arc, + revalidate_time_period: Option, + revalidate_block_period: Option>, + ) -> Self { + Self { + pool, + client, + fetcher, + revalidate_time_period, + revalidate_block_period, + revalidation_status: Arc::new(Mutex::new(TxPoolRevalidationStatus::NotScheduled)), + _phantom: Default::default(), + } + } + + /// Returns future that prunes block transactions from the pool. + fn prune( + &self, + id: &BlockId, + header: &Block::Header, + ) -> impl std::future::Future { + // fetch transactions (possible future optimization: proofs of inclusion) that + // have been included into new block and prune these from the pool + let id = id.clone(); + let pool = self.pool.clone(); + self.fetcher.remote_body(RemoteBodyRequest { + header: header.clone(), + retry_count: None, + }) + .then(move |transactions| ready( + transactions + .map_err(|e| format!("{}", e)) + .and_then(|transactions| { + let hashes = transactions + .into_iter() + .map(|tx| pool.hash_of(&tx)) + .collect::>(); + pool.prune_known(&id, &hashes) + .map_err(|e| format!("{}", e)) + }) + )) + .then(|r| { + if let Err(e) = r { + warn!("Error pruning known transactions: {}", e) + } + ready(()) + }) + } + + /// Returns future that performs in-pool transations revalidation, if required. + fn revalidate( + &self, + id: &BlockId, + header: &Block::Header, + ) -> impl std::future::Future { + // to determine whether ready transaction is still valid, we perform periodic revalidaton + // of ready transactions + let is_revalidation_required = self.revalidation_status.lock().is_required( + *header.number(), + self.revalidate_time_period, + self.revalidate_block_period, + ); + match is_revalidation_required { + true => { + let revalidation_status = self.revalidation_status.clone(); + Either::Left(self.pool + .revalidate_ready(id, None) + .map(|r| r.map_err(|e| warn!("Error revalidating known transactions: {}", e))) + .map(move |_| revalidation_status.lock().clear())) + }, + false => Either::Right(ready(())), + } + } +} + +impl TransactionPoolMaintainer +for + LightBasicPoolMaintainer +where + Block: BlockT::Out>, + Client: ProvideRuntimeApi + HeaderBackend + BlockBody + 'static, + Client::Api: TaggedTransactionQueue, + PoolApi: ChainApi + 'static, + F: Fetcher + 'static, +{ + type Block = Block; + type Hash = Block::Hash; + + fn maintain( + &self, + id: &BlockId, + _retracted: &[Block::Hash], + ) -> Box + Send + Unpin> { + // Do nothing if transaction pool is empty. + if self.pool.status().is_empty() { + self.revalidation_status.lock().clear(); + return Box::new(ready(())); + } + let header = self.client.header(*id) + .and_then(|h| h.ok_or(sp_blockchain::Error::UnknownBlock(format!("{}", id)))); + let header = match header { + Ok(header) => header, + Err(err) => { + println!("Failed to maintain light tx pool: {:?}", err); + return Box::new(ready(())); + } + }; + + // else prune block transactions from the pool + let prune_future = self.prune(id, &header); + + // and then (optionally) revalidate in-pool transactions + let revalidate_future = self.revalidate(id, &header); + + let maintain_future = join( + prune_future, + revalidate_future, + ).map(|_| ()); + + Box::new(maintain_future) + } +} + +/// The status of transactions revalidation at light tx pool. +#[cfg_attr(test, derive(Debug))] +enum TxPoolRevalidationStatus { + /// The revalidation has never been completed. + NotScheduled, + /// The revalidation is scheduled. + Scheduled(Option, Option), + /// The revalidation is in progress. + InProgress, +} + +impl TxPoolRevalidationStatus { + /// Called when revalidation is completed. + pub fn clear(&mut self) { + *self = TxPoolRevalidationStatus::NotScheduled; + } + + /// Returns true if revalidation is required. + pub fn is_required( + &mut self, + block: N, + revalidate_time_period: Option, + revalidate_block_period: Option, + ) -> bool { + match *self { + TxPoolRevalidationStatus::NotScheduled => { + *self = TxPoolRevalidationStatus::Scheduled( + revalidate_time_period.map(|period| Instant::now() + period), + revalidate_block_period.map(|period| block + period), + ); + false + }, + TxPoolRevalidationStatus::Scheduled(revalidate_at_time, revalidate_at_block) => { + let is_required = revalidate_at_time.map(|at| Instant::now() >= at).unwrap_or(false) + || revalidate_at_block.map(|at| block >= at).unwrap_or(false); + if is_required { + *self = TxPoolRevalidationStatus::InProgress; + } + is_required + }, + TxPoolRevalidationStatus::InProgress => false, + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use futures::executor::block_on; + use codec::Encode; + use substrate_test_runtime_client::{prelude::*, runtime::{Block, Transfer}, sp_consensus::{BlockOrigin, SelectChain}}; + use sp_transaction_pool::PoolStatus; + use crate::api::{FullChainApi, LightChainApi}; + + #[test] + fn should_remove_transactions_from_the_full_pool() { + let (client, longest_chain) = TestClientBuilder::new().build_with_longest_chain(); + let client = Arc::new(client); + let pool = sc_transaction_graph::Pool::new(Default::default(), FullChainApi::new(client.clone())); + let pool = Arc::new(pool); + let transaction = Transfer { + amount: 5, + nonce: 0, + from: AccountKeyring::Alice.into(), + to: Default::default(), + }.into_signed_tx(); + let best = longest_chain.best_chain().unwrap(); + + // store the transaction in the pool + block_on(pool.submit_one(&BlockId::hash(best.hash()), transaction.clone())).unwrap(); + + // import the block + let mut builder = client.new_block(Default::default()).unwrap(); + builder.push(transaction.clone()).unwrap(); + let block = builder.bake().unwrap(); + let id = BlockId::hash(block.header().hash()); + client.import(BlockOrigin::Own, block).unwrap(); + + // fire notification - this should clean up the queue + assert_eq!(pool.status().ready, 1); + block_on(FullBasicPoolMaintainer::new(pool.clone(), client).maintain(&id, &[])); + + // then + assert_eq!(pool.status().ready, 0); + assert_eq!(pool.status().future, 0); + } + + #[test] + fn should_remove_transactions_from_the_light_pool() { + let transaction = Transfer { + amount: 5, + nonce: 0, + from: AccountKeyring::Alice.into(), + to: Default::default(), + }.into_signed_tx(); + let fetcher_transaction = transaction.clone(); + let fetcher = Arc::new(substrate_test_runtime_client::new_light_fetcher() + .with_remote_body(Some(Box::new(move |_| Ok(vec![fetcher_transaction.clone()])))) + .with_remote_call(Some(Box::new(move |_| { + let validity: sp_runtime::transaction_validity::TransactionValidity = + Ok(sp_runtime::transaction_validity::ValidTransaction { + priority: 0, + requires: Vec::new(), + provides: vec![vec![42]], + longevity: 0, + propagate: true, + }); + Ok(validity.encode()) + })))); + + let (client, longest_chain) = TestClientBuilder::new().build_with_longest_chain(); + let client = Arc::new(client); + let pool = sc_transaction_graph::Pool::new(Default::default(), LightChainApi::new( + client.clone(), + fetcher.clone(), + )); + let pool = Arc::new(pool); + let best = longest_chain.best_chain().unwrap(); + + // store the transaction in the pool + block_on(pool.submit_one(&BlockId::hash(best.hash()), transaction.clone())).unwrap(); + + // fire notification - this should clean up the queue + assert_eq!(pool.status().ready, 1); + block_on(LightBasicPoolMaintainer::with_defaults(pool.clone(), client.clone(), fetcher).maintain( + &BlockId::Number(0), + &[], + )); + + // then + assert_eq!(pool.status().ready, 0); + assert_eq!(pool.status().future, 0); + } + + #[test] + fn should_schedule_transactions_revalidation_at_light_pool() { + // when revalidation is not scheduled, it became scheduled + let mut status = TxPoolRevalidationStatus::NotScheduled; + assert!(!status.is_required(10u32, None, None)); + match status { + TxPoolRevalidationStatus::Scheduled(_, _) => (), + _ => panic!("Unexpected status: {:?}", status), + } + + // revalidation required at time + let mut status = TxPoolRevalidationStatus::Scheduled(Some(Instant::now()), None); + assert!(status.is_required(10u32, None, None)); + match status { + TxPoolRevalidationStatus::InProgress => (), + _ => panic!("Unexpected status: {:?}", status), + } + + // revalidation required at block + let mut status = TxPoolRevalidationStatus::Scheduled(None, Some(10)); + assert!(status.is_required(10u32, None, None)); + match status { + TxPoolRevalidationStatus::InProgress => (), + _ => panic!("Unexpected status: {:?}", status), + } + } + + #[test] + fn should_revalidate_transactions_at_light_pool() { + use std::sync::atomic; + use sp_runtime::transaction_validity::*; + + let build_fetcher = || { + let validated = Arc::new(atomic::AtomicBool::new(false)); + Arc::new(substrate_test_runtime_client::new_light_fetcher() + .with_remote_body(Some(Box::new(move |_| Ok(vec![])))) + .with_remote_call(Some(Box::new(move |_| { + let is_inserted = validated.swap(true, atomic::Ordering::SeqCst); + let validity: TransactionValidity = if is_inserted { + Err(TransactionValidityError::Invalid( + InvalidTransaction::Custom(0) + )) + } else { + Ok(ValidTransaction { + priority: 0, + requires: Vec::new(), + provides: vec![vec![42]], + longevity: 0, + propagate: true, + }) + }; + Ok(validity.encode()) + })))) + }; + + fn with_fetcher_maintain + 'static>( + fetcher: Arc, + revalidate_time_period: Option, + revalidate_block_period: Option, + prepare_maintainer: impl Fn(&Mutex>), + ) -> PoolStatus { + let (client, longest_chain) = TestClientBuilder::new().build_with_longest_chain(); + let client = Arc::new(client); + + // now let's prepare pool + let pool = sc_transaction_graph::Pool::new(Default::default(), LightChainApi::new( + client.clone(), + fetcher.clone(), + )); + let pool = Arc::new(pool); + let best = longest_chain.best_chain().unwrap(); + + // let's prepare maintainer + let maintainer = LightBasicPoolMaintainer::new( + pool.clone(), + client, + fetcher, + revalidate_time_period, + revalidate_block_period, + ); + prepare_maintainer(&*maintainer.revalidation_status); + + // store the transaction in the pool + block_on(pool.submit_one( + &BlockId::hash(best.hash()), + Transfer { + amount: 5, + nonce: 0, + from: AccountKeyring::Alice.into(), + to: Default::default(), + }.into_signed_tx(), + )).unwrap(); + + // and run maintain procedures + block_on(maintainer.maintain(&BlockId::Number(0), &[])); + + pool.status() + } + + // when revalidation is never required - nothing happens + let fetcher = build_fetcher(); + //let maintainer = DefaultLightTransactionPoolMaintainer::new(client.clone(), fetcher.clone(), None, None); + let status = with_fetcher_maintain(fetcher, None, None, |_revalidation_status| {}); + assert_eq!(status.ready, 1); + + // when revalidation is scheduled by time - it is performed + let fetcher = build_fetcher(); + let status = with_fetcher_maintain(fetcher, None, None, |revalidation_status| + *revalidation_status.lock() = TxPoolRevalidationStatus::Scheduled(Some(Instant::now()), None) + ); + assert_eq!(status.ready, 0); + + // when revalidation is scheduled by block number - it is performed + let fetcher = build_fetcher(); + let status = with_fetcher_maintain(fetcher, None, None, |revalidation_status| + *revalidation_status.lock() = TxPoolRevalidationStatus::Scheduled(None, Some(0)) + ); + assert_eq!(status.ready, 0); + } + + #[test] + fn should_add_reverted_transactions_to_the_pool() { + let (client, longest_chain) = TestClientBuilder::new().build_with_longest_chain(); + let client = Arc::new(client); + let pool = sc_transaction_graph::Pool::new(Default::default(), FullChainApi::new(client.clone())); + let pool = Arc::new(pool); + let transaction = Transfer { + amount: 5, + nonce: 0, + from: AccountKeyring::Alice.into(), + to: Default::default(), + }.into_signed_tx(); + let best = longest_chain.best_chain().unwrap(); + + // store the transaction in the pool + block_on(pool.submit_one(&BlockId::hash(best.hash()), transaction.clone())).unwrap(); + + // import the block + let mut builder = client.new_block(Default::default()).unwrap(); + builder.push(transaction.clone()).unwrap(); + let block = builder.bake().unwrap(); + let block1_hash = block.header().hash(); + let id = BlockId::hash(block1_hash.clone()); + client.import(BlockOrigin::Own, block).unwrap(); + + // fire notification - this should clean up the queue + assert_eq!(pool.status().ready, 1); + block_on(FullBasicPoolMaintainer::new(pool.clone(), client.clone()).maintain(&id, &[])); + + // then + assert_eq!(pool.status().ready, 0); + assert_eq!(pool.status().future, 0); + + // import second block + let builder = client.new_block_at(&BlockId::hash(best.hash()), Default::default()).unwrap(); + let block = builder.bake().unwrap(); + let id = BlockId::hash(block.header().hash()); + client.import(BlockOrigin::Own, block).unwrap(); + + // fire notification - this should add the transaction back to the pool. + block_on(FullBasicPoolMaintainer::new(pool.clone(), client).maintain(&id, &[block1_hash])); + + // then + assert_eq!(pool.status().ready, 1); + assert_eq!(pool.status().future, 0); + } +} diff --git a/client/transaction-pool/src/tests.rs b/client/transaction-pool/src/tests.rs index 60a9e0562fce30ce678ee0cf52ee685608482484..e6bdffa945894352ab15db7d9df7aa5a99a3d3d1 100644 --- a/client/transaction-pool/src/tests.rs +++ b/client/transaction-pool/src/tests.rs @@ -19,9 +19,9 @@ use super::*; use codec::Encode; use futures::executor::block_on; -use txpool::{self, Pool}; -use test_client::{runtime::{AccountId, Block, Hash, Index, Extrinsic, Transfer}, AccountKeyring::{self, *}}; -use sr_primitives::{ +use sc_transaction_graph::{self, Pool}; +use substrate_test_runtime_client::{runtime::{AccountId, Block, Hash, Index, Extrinsic, Transfer}, AccountKeyring::{self, *}}; +use sp_runtime::{ generic::{self, BlockId}, traits::{Hash as HashT, BlakeTwo256}, transaction_validity::{TransactionValidity, ValidTransaction}, @@ -39,7 +39,7 @@ impl TestApi { } } -impl txpool::ChainApi for TestApi { +impl sc_transaction_graph::ChainApi for TestApi { type Block = Block; type Hash = Hash; type Error = error::Error; @@ -48,7 +48,7 @@ impl txpool::ChainApi for TestApi { fn validate_transaction( &self, at: &BlockId, - uxt: txpool::ExtrinsicFor, + uxt: sc_transaction_graph::ExtrinsicFor, ) -> Self::ValidationFuture { let expected = index(at); let requires = if expected == uxt.transfer().nonce { @@ -73,18 +73,18 @@ impl txpool::ChainApi for TestApi { )) } - fn block_id_to_number(&self, at: &BlockId) -> error::Result>> { + fn block_id_to_number(&self, at: &BlockId) -> error::Result>> { Ok(Some(number_of(at))) } - fn block_id_to_hash(&self, at: &BlockId) -> error::Result>> { + fn block_id_to_hash(&self, at: &BlockId) -> error::Result>> { Ok(match at { generic::BlockId::Hash(x) => Some(x.clone()), _ => Some(Default::default()), }) } - fn hash_and_length(&self, ex: &txpool::ExtrinsicFor) -> (Self::Hash, usize) { + fn hash_and_length(&self, ex: &sc_transaction_graph::ExtrinsicFor) -> (Self::Hash, usize) { let encoded = ex.encode(); (BlakeTwo256::hash(&encoded), encoded.len()) } diff --git a/docs/CODEOWNERS b/docs/CODEOWNERS index 5ad126c3f6503af45fe1e2c21d3577d6d90b9ed4..edb10617f4bc2f5b679df44a6f8f0bd9a8671c69 100644 --- a/docs/CODEOWNERS +++ b/docs/CODEOWNERS @@ -20,7 +20,7 @@ # Wasm execution and the wasm side of Substrate Runtime Interface /client/executor/ @pepyakin -/primitives/sr-io/ @pepyakin +/primitives/io/ @pepyakin # Sandboxing capability of Substrate Runtime /primitives/sr-sandbox/ @pepyakin @@ -28,6 +28,7 @@ # Transaction pool /client/transaction-pool/ @tomusdrw +/primitives/transaction-pool/ @tomusdrw # Offchain /client/offchain/ @tomusdrw @@ -61,7 +62,11 @@ /bin/node/executor/ @kianenigma # Transaction weight stuff -/primitives/sr-primitives/src/weights.rs @kianenigma +/primitives/runtime/src/weights.rs @kianenigma # Support crates /frame/support/ @thiolliere @kianenigma + +# Authority discovery +/client/authority-discovery/ @mxinden +/frame/authority-discovery/ @mxinden diff --git a/docs/README.adoc b/docs/README.adoc index 76e640db9b439b4529a05cac89707648fe5d18a1..d8c582296cabbfa396a7e1761a07f0555d3f1fd1 100644 --- a/docs/README.adoc +++ b/docs/README.adoc @@ -439,7 +439,7 @@ substrate-executor, substrate-finality-grandpa, substrate-keyring, substrate-key substrate-network-libp2p, substrate-primitives, substrate-rpc, substrate-rpc-servers, substrate-serializer, substrate-service, substrate-service-test, substrate-state-db, substrate-state-machine, substrate-telemetry, substrate-test-client, -substrate-test-runtime, substrate-transaction-graph, substrate-transaction-pool, +substrate-test-runtime, substrate-transaction-graph, sp-transaction-pool, substrate-trie * Substrate Runtime [source, shell] diff --git a/docs/Structure.adoc b/docs/Structure.adoc index cff2b480191358447b3b82c76981e2c2bf39c707..cb0e4b28cb001fb77e62e41a98775b893c447a8e 100644 --- a/docs/Structure.adoc +++ b/docs/Structure.adoc @@ -87,11 +87,14 @@ The default (testing) application pulling together our recommended setup of subs We also provide a template to get you started building your own node. -==== Subkey +==== Utils -* _found in_: `/bin/subkey` +* _found in_: `/bin/utils` -Subkey is a client library to generate keys and sign transactions to send to a substrate node. +- **subkey** + Subkey is a client library to generate keys and sign transactions to send to a substrate node. +- **chain-spec-builder** + The chain spec builder builds a chain specification that includes a Substrate runtime compiled as WASM. To ensure proper functioning of the included runtime compile (or run) the chain spec builder binary in `--release` mode. == Internal Dependency Tree diff --git a/docs/Upgrade.md b/docs/Upgrade.md new file mode 100644 index 0000000000000000000000000000000000000000..4908d53f579e4028bff5615947a86b285f8f8039 --- /dev/null +++ b/docs/Upgrade.md @@ -0,0 +1,5 @@ +# Upgrade path for you building on substrate + +## master + - crate rename has been fixed `sp-application-crypto` (was `sc-application-crypto`); `.maintain/rename-crates-for-2.0.sh` has been updated accordingly, you can use it to upgrade to latest naming convention + - crates have been renamed, run `bash .maintain/rename-crates-for-2.0.sh` \ No newline at end of file diff --git a/frame/assets/Cargo.toml b/frame/assets/Cargo.toml index e24a3b187a2d21c4393e9a091ef7406daf32cb98..f371f21e1ab7e90df582ece618093d9aca5153f3 100644 --- a/frame/assets/Cargo.toml +++ b/frame/assets/Cargo.toml @@ -8,23 +8,23 @@ edition = "2018" serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false } # Needed for various traits. In our case, `OnFinalize`. -sr-primitives = { path = "../../primitives/sr-primitives", default-features = false } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" } # Needed for type-safe access to storage DB. -support = { package = "frame-support", path = "../support", default-features = false } +frame-support = { version = "2.0.0", default-features = false, path = "../support" } # `system` module provides us with all sorts of useful stuff and macros depend on it being around. -system = { package = "frame-system", path = "../system", default-features = false } +frame-system = { version = "2.0.0", default-features = false, path = "../system" } [dev-dependencies] -primitives = { package = "substrate-primitives", path = "../../primitives/core" } -rstd = { package = "sr-std", path = "../../primitives/sr-std" } -runtime-io = { package = "sr-io", path = "../../primitives/sr-io" } +sp-core = { version = "2.0.0", path = "../../primitives/core" } +sp-std = { version = "2.0.0", path = "../../primitives/std" } +sp-io = { version = "2.0.0", path = "../../primitives/io" } [features] default = ["std"] std = [ "serde", "codec/std", - "sr-primitives/std", - "support/std", - "system/std", + "sp-runtime/std", + "frame-support/std", + "frame-system/std", ] diff --git a/frame/assets/src/lib.rs b/frame/assets/src/lib.rs index 6f4647ac2e4f16b3f2c86de193418d4203ab4243..94ec8f73df9f6c183e3d8347f7d91be060b43a7e 100644 --- a/frame/assets/src/lib.rs +++ b/frame/assets/src/lib.rs @@ -84,22 +84,24 @@ //! ### Simple Code Snippet //! //! ```rust,ignore -//! use support::{decl_module, dispatch::Result}; -//! use system::ensure_signed; +//! use pallet_assets as assets; +//! use frame_support::{decl_module, dispatch, ensure}; +//! use frame_system::{self as system, ensure_signed}; //! //! pub trait Trait: assets::Trait { } //! //! decl_module! { //! pub struct Module for enum Call where origin: T::Origin { -//! pub fn issue_token_airdrop(origin) -> Result { +//! pub fn issue_token_airdrop(origin) -> dispatch::DispatchResult { +//! let sender = ensure_signed(origin).map_err(|e| e.as_str())?; +//! //! const ACCOUNT_ALICE: u64 = 1; //! const ACCOUNT_BOB: u64 = 2; -//! const COUNT_AIRDROP_RECIPIENTS = 2; +//! const COUNT_AIRDROP_RECIPIENTS: u64 = 2; //! const TOKENS_FIXED_SUPPLY: u64 = 100; //! //! ensure!(!COUNT_AIRDROP_RECIPIENTS.is_zero(), "Divide by zero error."); //! -//! let sender = ensure_signed(origin)?; //! let asset_id = Self::next_asset_id(); //! //! >::mutate(|asset_id| *asset_id += 1); @@ -130,15 +132,15 @@ // Ensure we're `no_std` when compiling for Wasm. #![cfg_attr(not(feature = "std"), no_std)] -use support::{Parameter, decl_module, decl_event, decl_storage, ensure}; -use sr_primitives::traits::{Member, SimpleArithmetic, Zero, StaticLookup}; -use system::ensure_signed; -use sr_primitives::traits::One; +use frame_support::{Parameter, decl_module, decl_event, decl_storage, decl_error, ensure}; +use sp_runtime::traits::{Member, SimpleArithmetic, Zero, StaticLookup}; +use frame_system::{self as system, ensure_signed}; +use sp_runtime::traits::One; /// The module configuration trait. -pub trait Trait: system::Trait { +pub trait Trait: frame_system::Trait { /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// The units in which we record balances. type Balance: Member + Parameter + SimpleArithmetic + Default + Copy; @@ -149,6 +151,8 @@ pub trait Trait: system::Trait { decl_module! { pub struct Module for enum Call where origin: T::Origin { + type Error = Error; + fn deposit_event() = default; /// Issue a new class of fungible assets. There are, and will only ever be, `total` /// such assets and they'll all belong to the `origin` initially. It will have an @@ -175,8 +179,8 @@ decl_module! { let origin_account = (id, origin.clone()); let origin_balance = >::get(&origin_account); let target = T::Lookup::lookup(target)?; - ensure!(!amount.is_zero(), "transfer amount should be non-zero"); - ensure!(origin_balance >= amount, "origin account balance must be greater than or equal to the transfer amount"); + ensure!(!amount.is_zero(), Error::::AmountZero); + ensure!(origin_balance >= amount, Error::::BalanceLow); Self::deposit_event(RawEvent::Transferred(id, origin, target.clone(), amount)); >::insert(origin_account, origin_balance - amount); @@ -187,7 +191,7 @@ decl_module! { fn destroy(origin, #[compact] id: T::AssetId) { let origin = ensure_signed(origin)?; let balance = >::take((id, &origin)); - ensure!(!balance.is_zero(), "origin balance should be non-zero"); + ensure!(!balance.is_zero(), Error::::BalanceZero); >::mutate(id, |total_supply| *total_supply -= balance); Self::deposit_event(RawEvent::Destroyed(id, origin, balance)); @@ -195,9 +199,9 @@ decl_module! { } } -decl_event!( +decl_event! { pub enum Event where - ::AccountId, + ::AccountId, ::Balance, ::AssetId, { @@ -208,7 +212,19 @@ decl_event!( /// Some assets were destroyed. Destroyed(AssetId, AccountId, Balance), } -); +} + +decl_error! { + pub enum Error for Module { + /// Transfer amount should be non-zero + AmountZero, + /// Account balance must be greater than or equal to the transfer amount + BalanceLow, + /// Balance should be non-zero + BalanceZero, + } + +} decl_storage! { trait Store for Module as Assets { @@ -240,14 +256,14 @@ impl Module { mod tests { use super::*; - use support::{impl_outer_origin, assert_ok, assert_noop, parameter_types}; - use primitives::H256; + use frame_support::{impl_outer_origin, assert_ok, assert_noop, parameter_types, weights::Weight}; + use sp_core::H256; // The testing primitives are very useful for avoiding having to work with signatures // or public keys. `u64` is used as the `AccountId` and no `Signature`s are required. - use sr_primitives::{Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header}; + use sp_runtime::{Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header}; impl_outer_origin! { - pub enum Origin for Test {} + pub enum Origin for Test where system = frame_system {} } // For testing the module, we construct most of a mock runtime. This means @@ -257,11 +273,11 @@ mod tests { pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockWeight: Weight = 1024; pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } - impl system::Trait for Test { + impl frame_system::Trait for Test { type Origin = Origin; type Index = u64; type Call = (); @@ -277,6 +293,7 @@ mod tests { type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; type Version = (); + type ModuleToIndex = (); } impl Trait for Test { type Event = (); @@ -287,8 +304,8 @@ mod tests { // This function basically just builds a genesis storage key/value store according to // our desired mockup. - fn new_test_ext() -> runtime_io::TestExternalities { - system::GenesisConfig::default().build_storage::().unwrap().into() + fn new_test_ext() -> sp_io::TestExternalities { + frame_system::GenesisConfig::default().build_storage::().unwrap().into() } #[test] @@ -337,7 +354,7 @@ mod tests { assert_eq!(Assets::balance(0, 2), 50); assert_ok!(Assets::destroy(Origin::signed(1), 0)); assert_eq!(Assets::balance(0, 1), 0); - assert_noop!(Assets::transfer(Origin::signed(1), 0, 1, 50), "origin account balance must be greater than or equal to the transfer amount"); + assert_noop!(Assets::transfer(Origin::signed(1), 0, 1, 50), Error::::BalanceLow); }); } @@ -346,7 +363,7 @@ mod tests { new_test_ext().execute_with(|| { assert_ok!(Assets::issue(Origin::signed(1), 100)); assert_eq!(Assets::balance(0, 1), 100); - assert_noop!(Assets::transfer(Origin::signed(1), 0, 2, 0), "transfer amount should be non-zero"); + assert_noop!(Assets::transfer(Origin::signed(1), 0, 2, 0), Error::::AmountZero); }); } @@ -355,7 +372,7 @@ mod tests { new_test_ext().execute_with(|| { assert_ok!(Assets::issue(Origin::signed(1), 100)); assert_eq!(Assets::balance(0, 1), 100); - assert_noop!(Assets::transfer(Origin::signed(1), 0, 2, 101), "origin account balance must be greater than or equal to the transfer amount"); + assert_noop!(Assets::transfer(Origin::signed(1), 0, 2, 101), Error::::BalanceLow); }); } @@ -373,7 +390,7 @@ mod tests { new_test_ext().execute_with(|| { assert_ok!(Assets::issue(Origin::signed(1), 100)); assert_eq!(Assets::balance(0, 2), 0); - assert_noop!(Assets::destroy(Origin::signed(2), 0), "origin balance should be non-zero"); + assert_noop!(Assets::destroy(Origin::signed(2), 0), Error::::BalanceZero); }); } } diff --git a/frame/aura/Cargo.toml b/frame/aura/Cargo.toml index a6700dbaf82965b85a5c2842fb03b98beae53c08..26754458321fd19ca2284ed7e6d2d2579799c7a3 100644 --- a/frame/aura/Cargo.toml +++ b/frame/aura/Cargo.toml @@ -5,20 +5,20 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -app-crypto = { package = "substrate-application-crypto", path = "../../primitives/application-crypto", default-features = false } +sp-application-crypto = { version = "2.0.0", default-features = false, path = "../../primitives/application-crypto" } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -inherents = { package = "substrate-inherents", path = "../../primitives/inherents", default-features = false } -primitives = { package = "substrate-primitives", path = "../../primitives/core", default-features = false } -rstd = { package = "sr-std", path = "../../primitives/sr-std", default-features = false } +sp-inherents = { version = "2.0.0", default-features = false, path = "../../primitives/inherents" } +sp-core = { version = "2.0.0", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0", default-features = false, path = "../../primitives/std" } serde = { version = "1.0.101", optional = true } -session = { package = "pallet-session", path = "../session", default-features = false } -sr-primitives = { path = "../../primitives/sr-primitives", default-features = false } -runtime-io ={ package = "sr-io", path = "../../primitives/sr-io", default-features = false } -support = { package = "frame-support", path = "../support", default-features = false } -substrate-consensus-aura-primitives = { path = "../../primitives/consensus/aura", default-features = false} -system = { package = "frame-system", path = "../system", default-features = false } -sp-timestamp = { package = "sp-timestamp", path = "../../primitives/timestamp", default-features = false } -pallet-timestamp = { package = "pallet-timestamp", path = "../timestamp", default-features = false } +pallet-session = { version = "2.0.0", default-features = false, path = "../session" } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" } +sp-io ={ path = "../../primitives/io", default-features = false } +frame-support = { version = "2.0.0", default-features = false, path = "../support" } +sp-consensus-aura = { path = "../../primitives/consensus/aura", default-features = false} +frame-system = { version = "2.0.0", default-features = false, path = "../system" } +sp-timestamp = { version = "2.0.0", default-features = false, path = "../../primitives/timestamp" } +pallet-timestamp = { version = "2.0.0", default-features = false, path = "../timestamp" } [dev-dependencies] @@ -28,17 +28,17 @@ parking_lot = "0.9.0" [features] default = ["std"] std = [ - "app-crypto/std", + "sp-application-crypto/std", "codec/std", - "inherents/std", - "runtime-io/std", - "primitives/std", - "rstd/std", + "sp-inherents/std", + "sp-io/std", + "sp-core/std", + "sp-std/std", "serde", - "sr-primitives/std", - "support/std", - "substrate-consensus-aura-primitives/std", - "system/std", + "sp-runtime/std", + "frame-support/std", + "sp-consensus-aura/std", + "frame-system/std", "sp-timestamp/std", "pallet-timestamp/std", ] diff --git a/frame/aura/src/lib.rs b/frame/aura/src/lib.rs index f1ae121e00be1872158e97358227d3923fc3c049..462c30b648fd451543e34ebbf20b0f6e66d3abaf 100644 --- a/frame/aura/src/lib.rs +++ b/frame/aura/src/lib.rs @@ -40,26 +40,26 @@ //! //! If you're interested in hacking on this module, it is useful to understand the interaction with //! `substrate/primitives/inherents/src/lib.rs` and, specifically, the required implementation of -//! [`ProvideInherent`](../substrate_inherents/trait.ProvideInherent.html) and -//! [`ProvideInherentData`](../substrate_inherents/trait.ProvideInherentData.html) to create and check inherents. +//! [`ProvideInherent`](../sp_inherents/trait.ProvideInherent.html) and +//! [`ProvideInherentData`](../sp_inherents/trait.ProvideInherentData.html) to create and check inherents. #![cfg_attr(not(feature = "std"), no_std)] use pallet_timestamp; -use rstd::{result, prelude::*}; +use sp_std::{result, prelude::*}; use codec::{Encode, Decode}; -use support::{ +use frame_support::{ decl_storage, decl_module, Parameter, traits::{Get, FindAuthor}, ConsensusEngineId, }; -use sr_primitives::{ +use sp_runtime::{ RuntimeAppPublic, traits::{SaturatedConversion, Saturating, Zero, Member, IsMember}, generic::DigestItem, }; use sp_timestamp::OnTimestampSet; -use inherents::{InherentIdentifier, InherentData, ProvideInherent, MakeFatalError}; -use substrate_consensus_aura_primitives::{ +use sp_inherents::{InherentIdentifier, InherentData, ProvideInherent, MakeFatalError}; +use sp_consensus_aura::{ AURA_ENGINE_ID, ConsensusLog, AuthorityIndex, inherents::{INHERENT_IDENTIFIER, AuraInherentData}, }; @@ -98,7 +98,7 @@ impl Module { AURA_ENGINE_ID, ConsensusLog::AuthoritiesChange(new).encode() ); - >::deposit_log(log.into()); + >::deposit_log(log.into()); } fn initialize_authorities(authorities: &[T::AuthorityId]) { @@ -109,11 +109,11 @@ impl Module { } } -impl sr_primitives::BoundToRuntimeAppPublic for Module { +impl sp_runtime::BoundToRuntimeAppPublic for Module { type Public = T::AuthorityId; } -impl session::OneSessionHandler for Module { +impl pallet_session::OneSessionHandler for Module { type Key = T::AuthorityId; fn on_genesis_session<'a, I: 'a>(validators: I) @@ -142,7 +142,7 @@ impl session::OneSessionHandler for Module { ConsensusLog::::OnDisabled(i as AuthorityIndex).encode(), ); - >::deposit_log(log.into()); + >::deposit_log(log.into()); } } @@ -206,7 +206,7 @@ impl OnTimestampSet for Module { impl ProvideInherent for Module { type Call = pallet_timestamp::Call; - type Error = MakeFatalError; + type Error = MakeFatalError; const INHERENT_IDENTIFIER: InherentIdentifier = INHERENT_IDENTIFIER; fn create_inherent(_: &InherentData) -> Option { @@ -227,7 +227,7 @@ impl ProvideInherent for Module { if timestamp_based_slot == seal_slot { Ok(()) } else { - Err(inherents::Error::from("timestamp set in block doesn't match slot in seal").into()) + Err(sp_inherents::Error::from("timestamp set in block doesn't match slot in seal").into()) } } } diff --git a/frame/aura/src/mock.rs b/frame/aura/src/mock.rs index f476fd1826ae3a72c7c303ce9d1e00a9b87d58d7..fbab5a421cfa4504a7e87b7e36a941825f74ddbf 100644 --- a/frame/aura/src/mock.rs +++ b/frame/aura/src/mock.rs @@ -19,17 +19,17 @@ #![cfg(test)] use crate::{Trait, Module, GenesisConfig}; -use substrate_consensus_aura_primitives::ed25519::AuthorityId; -use sr_primitives::{ +use sp_consensus_aura::ed25519::AuthorityId; +use sp_runtime::{ traits::IdentityLookup, Perbill, testing::{Header, UintAuthorityId}, }; -use support::{impl_outer_origin, parameter_types}; -use runtime_io; -use primitives::H256; +use frame_support::{impl_outer_origin, parameter_types, weights::Weight}; +use sp_io; +use sp_core::H256; impl_outer_origin!{ - pub enum Origin for Test {} + pub enum Origin for Test where system = frame_system {} } // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. @@ -38,19 +38,19 @@ pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockWeight: Weight = 1024; pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); pub const MinimumPeriod: u64 = 1; } -impl system::Trait for Test { +impl frame_system::Trait for Test { type Origin = Origin; type Index = u64; type BlockNumber = u64; type Call = (); type Hash = H256; - type Hashing = ::sr_primitives::traits::BlakeTwo256; + type Hashing = ::sp_runtime::traits::BlakeTwo256; type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; @@ -60,6 +60,7 @@ impl system::Trait for Test { type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; type Version = (); + type ModuleToIndex = (); } impl pallet_timestamp::Trait for Test { @@ -72,8 +73,8 @@ impl Trait for Test { type AuthorityId = AuthorityId; } -pub fn new_test_ext(authorities: Vec) -> runtime_io::TestExternalities { - let mut t = system::GenesisConfig::default().build_storage::().unwrap(); +pub fn new_test_ext(authorities: Vec) -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); GenesisConfig::{ authorities: authorities.into_iter().map(|a| UintAuthorityId(a).to_public_key()).collect(), }.assimilate_storage(&mut t).unwrap(); diff --git a/frame/authority-discovery/Cargo.toml b/frame/authority-discovery/Cargo.toml index c0961671d8b6c3c5094e1abe958d6ade643d6e1e..3760d863d70ad1f2d0e02af4dcd23c84ddd42dd3 100644 --- a/frame/authority-discovery/Cargo.toml +++ b/frame/authority-discovery/Cargo.toml @@ -1,37 +1,37 @@ [package] name = "pallet-authority-discovery" -version = "0.1.0" +version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" [dependencies] -authority-discovery-primitives = { package = "substrate-authority-discovery-primitives", path = "../../primitives/authority-discovery", default-features = false } -app-crypto = { package = "substrate-application-crypto", path = "../../primitives/application-crypto", default-features = false } +sp-authority-discovery = { version = "2.0.0", default-features = false, path = "../../primitives/authority-discovery" } +sp-application-crypto = { version = "2.0.0", default-features = false, path = "../../primitives/application-crypto" } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -primitives = { package = "substrate-primitives", path = "../../primitives/core", default-features = false } -rstd = { package = "sr-std", path = "../../primitives/sr-std", default-features = false } +sp-core = { version = "2.0.0", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0", default-features = false, path = "../../primitives/std" } serde = { version = "1.0.101", optional = true } -runtime-io = { package = "sr-io", path = "../../primitives/sr-io", default-features = false } -session = { package = "pallet-session", path = "../session", default-features = false, features = [ "historical" ] } -sr-primitives = { path = "../../primitives/sr-primitives", default-features = false } -support = { package = "frame-support", path = "../support", default-features = false } -system = { package = "frame-system", path = "../system", default-features = false } +sp-io = { version = "2.0.0", default-features = false, path = "../../primitives/io" } +pallet-session = { version = "2.0.0", features = ["historical" ], path = "../session", default-features = false } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0", default-features = false, path = "../support" } +frame-system = { version = "2.0.0", default-features = false, path = "../system" } [dev-dependencies] -sr-staking-primitives = { path = "../../primitives/sr-staking-primitives", default-features = false } +sp-staking = { version = "2.0.0", default-features = false, path = "../../primitives/staking" } [features] default = ["std"] std = [ - "app-crypto/std", - "authority-discovery-primitives/std", + "sp-application-crypto/std", + "sp-authority-discovery/std", "codec/std", - "primitives/std", - "rstd/std", - "runtime-io/std", + "sp-core/std", + "sp-io/std", + "sp-std/std", "serde", - "session/std", - "sr-primitives/std", - "support/std", - "system/std", + "pallet-session/std", + "sp-runtime/std", + "frame-support/std", + "frame-system/std", ] diff --git a/frame/authority-discovery/src/lib.rs b/frame/authority-discovery/src/lib.rs index b3a5ebded56f492cec6090ece2a1a5e6d0a4b054..065005373f790a32c0d78cf5729284f42bfc14cd 100644 --- a/frame/authority-discovery/src/lib.rs +++ b/frame/authority-discovery/src/lib.rs @@ -16,18 +16,18 @@ //! # Authority discovery module. //! -//! This module is used by the `core/authority-discovery` to retrieve the +//! This module is used by the `client/authority-discovery` to retrieve the //! current set of authorities. // Ensure we're `no_std` when compiling for Wasm. #![cfg_attr(not(feature = "std"), no_std)] -use rstd::prelude::*; -use support::{decl_module, decl_storage}; -use authority_discovery_primitives::AuthorityId; +use sp_std::prelude::*; +use frame_support::{decl_module, decl_storage}; +use sp_authority_discovery::AuthorityId; /// The module's config trait. -pub trait Trait: system::Trait + session::Trait {} +pub trait Trait: frame_system::Trait + pallet_session::Trait {} decl_storage! { trait Store for Module as AuthorityDiscovery { @@ -59,11 +59,11 @@ impl Module { } } -impl sr_primitives::BoundToRuntimeAppPublic for Module { +impl sp_runtime::BoundToRuntimeAppPublic for Module { type Public = AuthorityId; } -impl session::OneSessionHandler for Module { +impl pallet_session::OneSessionHandler for Module { type Key = AuthorityId; fn on_genesis_session<'a, I: 'a>(authorities: I) @@ -92,15 +92,15 @@ impl session::OneSessionHandler for Module { #[cfg(test)] mod tests { use super::*; - use authority_discovery_primitives::{AuthorityPair}; - use app_crypto::Pair; - use primitives::{crypto::key_types, H256}; - use runtime_io::TestExternalities; - use sr_primitives::{ + use sp_authority_discovery::{AuthorityPair}; + use sp_application_crypto::Pair; + use sp_core::{crypto::key_types, H256}; + use sp_io::TestExternalities; + use sp_runtime::{ testing::{Header, UintAuthorityId}, traits::{ConvertInto, IdentityLookup, OpaqueKeys}, Perbill, KeyTypeId, }; - use support::{impl_outer_origin, parameter_types}; + use frame_support::{impl_outer_origin, parameter_types, weights::Weight}; type AuthorityDiscovery = Module; type SessionIndex = u32; @@ -110,7 +110,7 @@ mod tests { impl Trait for Test {} pub struct TestOnSessionEnding; - impl session::OnSessionEnding for TestOnSessionEnding { + impl pallet_session::OnSessionEnding for TestOnSessionEnding { fn on_session_ending(_: SessionIndex, _: SessionIndex) -> Option> { None } @@ -120,10 +120,10 @@ mod tests { pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(33); } - impl session::Trait for Test { + impl pallet_session::Trait for Test { type OnSessionEnding = TestOnSessionEnding; type Keys = UintAuthorityId; - type ShouldEndSession = session::PeriodicSessions; + type ShouldEndSession = pallet_session::PeriodicSessions; type SessionHandler = TestSessionHandler; type Event = (); type ValidatorId = AuthorityId; @@ -132,7 +132,7 @@ mod tests { type DisabledValidatorsThreshold = DisabledValidatorsThreshold; } - impl session::historical::Trait for Test { + impl pallet_session::historical::Trait for Test { type FullIdentification = (); type FullIdentificationOf = (); } @@ -144,18 +144,18 @@ mod tests { pub const Offset: BlockNumber = 0; pub const UncleGenerations: u64 = 0; pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockWeight: Weight = 1024; pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } - impl system::Trait for Test { + impl frame_system::Trait for Test { type Origin = Origin; type Index = u64; type BlockNumber = BlockNumber; type Call = (); type Hash = H256; - type Hashing = ::sr_primitives::traits::BlakeTwo256; + type Hashing = ::sp_runtime::traits::BlakeTwo256; type AccountId = AuthorityId; type Lookup = IdentityLookup; type Header = Header; @@ -165,14 +165,15 @@ mod tests { type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; type Version = (); + type ModuleToIndex = (); } impl_outer_origin! { - pub enum Origin for Test {} + pub enum Origin for Test where system = frame_system {} } pub struct TestSessionHandler; - impl session::SessionHandler for TestSessionHandler { + impl pallet_session::SessionHandler for TestSessionHandler { const KEY_TYPE_IDS: &'static [KeyTypeId] = &[key_types::DUMMY]; fn on_new_session( @@ -190,7 +191,7 @@ mod tests { #[test] fn authorities_returns_current_authority_set() { // The whole authority discovery module ignores account ids, but we still need it for - // `session::OneSessionHandler::on_new_session`, thus its safe to use the same value everywhere. + // `pallet_session::OneSessionHandler::on_new_session`, thus its safe to use the same value everywhere. let account_id = AuthorityPair::from_seed_slice(vec![10; 32].as_ref()).unwrap().public(); let first_authorities: Vec = vec![0, 1].into_iter() @@ -203,14 +204,14 @@ mod tests { .map(AuthorityId::from) .collect(); - // Needed for `session::OneSessionHandler::on_new_session`. + // Needed for `pallet_session::OneSessionHandler::on_new_session`. let second_authorities_and_account_ids: Vec<(&AuthorityId, AuthorityId)> = second_authorities.clone() .into_iter() .map(|id| (&account_id, id)) .collect(); // Build genesis. - let mut t = system::GenesisConfig::default() + let mut t = frame_system::GenesisConfig::default() .build_storage::() .unwrap(); @@ -224,7 +225,7 @@ mod tests { let mut externalities = TestExternalities::new(t); externalities.execute_with(|| { - use session::OneSessionHandler; + use pallet_session::OneSessionHandler; AuthorityDiscovery::on_genesis_session( first_authorities.iter().map(|id| (id, id.clone())) diff --git a/frame/authorship/Cargo.toml b/frame/authorship/Cargo.toml index 508df216ae3c5227ec39fc13c4a630f943e44bd1..298da65a2b02bd012e9533f2cdc30e29102afffc 100644 --- a/frame/authorship/Cargo.toml +++ b/frame/authorship/Cargo.toml @@ -1,32 +1,32 @@ [package] name = "pallet-authorship" -version = "0.1.0" +version = "2.0.0" description = "Block and Uncle Author tracking for the SRML" authors = ["Parity Technologies "] edition = "2018" [dependencies] -primitives = { package = "substrate-primitives", path = "../../primitives/core", default-features = false } +sp-core = { version = "2.0.0", default-features = false, path = "../../primitives/core" } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -inherents = { package = "substrate-inherents", path = "../../primitives/inherents", default-features = false } -sp-authorship = { path = "../../primitives/authorship", default-features = false } -rstd = { package = "sr-std", path = "../../primitives/sr-std", default-features = false } -sr-primitives = { path = "../../primitives/sr-primitives", default-features = false } -support = { package = "frame-support", path = "../support", default-features = false } -system = { package = "frame-system", path = "../system", default-features = false } -runtime-io ={ package = "sr-io", path = "../../primitives/sr-io", default-features = false } +sp-inherents = { version = "2.0.0", default-features = false, path = "../../primitives/inherents" } +sp-authorship = { version = "2.0.0", default-features = false, path = "../../primitives/authorship" } +sp-std = { version = "2.0.0", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0", default-features = false, path = "../support" } +frame-system = { version = "2.0.0", default-features = false, path = "../system" } +sp-io ={ path = "../../primitives/io", default-features = false } impl-trait-for-tuples = "0.1.3" [features] default = ["std"] std = [ "codec/std", - "primitives/std", - "inherents/std", - "sr-primitives/std", - "rstd/std", - "support/std", - "system/std", - "runtime-io/std", + "sp-core/std", + "sp-inherents/std", + "sp-runtime/std", + "sp-std/std", + "frame-support/std", + "frame-system/std", + "sp-io/std", "sp-authorship/std", ] diff --git a/frame/authorship/src/lib.rs b/frame/authorship/src/lib.rs index b4118b93a0d61a553c2d67c6eb8a61e3ca9051ad..5c2f9642200935a4241b5d1759202931e0db53d4 100644 --- a/frame/authorship/src/lib.rs +++ b/frame/authorship/src/lib.rs @@ -20,21 +20,20 @@ #![cfg_attr(not(feature = "std"), no_std)] -use rstd::{result, prelude::*}; -use rstd::collections::btree_set::BTreeSet; -use support::{decl_module, decl_storage}; -use support::traits::{FindAuthor, VerifySeal, Get}; -use support::dispatch::Result as DispatchResult; +use sp_std::{result, prelude::*}; +use sp_std::collections::btree_set::BTreeSet; +use frame_support::{decl_module, decl_storage, dispatch, ensure}; +use frame_support::traits::{FindAuthor, VerifySeal, Get}; use codec::{Encode, Decode}; -use system::ensure_none; -use sr_primitives::traits::{Header as HeaderT, One, Zero}; -use support::weights::SimpleDispatchInfo; -use inherents::{InherentIdentifier, ProvideInherent, InherentData, MakeFatalError}; -use sp_authorship::{ - INHERENT_IDENTIFIER, UnclesInherentData, -}; - -pub trait Trait: system::Trait { +use frame_system::ensure_none; +use sp_runtime::traits::{Header as HeaderT, One, Zero}; +use frame_support::weights::SimpleDispatchInfo; +use sp_inherents::{InherentIdentifier, ProvideInherent, InherentData}; +use sp_authorship::{INHERENT_IDENTIFIER, UnclesInherentData, InherentError}; + +const MAX_UNCLES: usize = 10; + +pub trait Trait: frame_system::Trait { /// Find the author of a block. type FindAuthor: FindAuthor; /// The number of blocks back we should accept uncles. @@ -98,7 +97,7 @@ impl FilterUncle for () { /// A filter on uncles which verifies seals and does no additional checks. /// This is well-suited to consensus modes such as PoW where the cost of /// equivocating is high. -pub struct SealVerify(rstd::marker::PhantomData); +pub struct SealVerify(sp_std::marker::PhantomData); impl> FilterUncle for SealVerify @@ -116,7 +115,7 @@ impl> FilterUncle /// one uncle included per author per height. /// /// This does O(n log n) work in the number of uncles included. -pub struct OnePerAuthorPerHeight(rstd::marker::PhantomData<(T, N)>); +pub struct OnePerAuthorPerHeight(sp_std::marker::PhantomData<(T, N)>); impl FilterUncle for OnePerAuthorPerHeight @@ -144,7 +143,7 @@ where } } -#[derive(Encode, Decode, sr_primitives::RuntimeDebug)] +#[derive(Encode, Decode, sp_runtime::RuntimeDebug)] #[cfg_attr(any(feature = "std", test), derive(PartialEq))] enum UncleEntryItem { InclusionHeight(BlockNumber), @@ -185,11 +184,12 @@ decl_module! { /// Provide a set of uncles. #[weight = SimpleDispatchInfo::FixedOperational(10_000)] - fn set_uncles(origin, new_uncles: Vec) -> DispatchResult { + fn set_uncles(origin, new_uncles: Vec) -> dispatch::DispatchResult { ensure_none(origin)?; + ensure!(new_uncles.len() <= MAX_UNCLES, "Too many uncles"); if ::DidSetUncles::get() { - return Err("Uncles already set in block."); + Err("Uncles already set in block.")? } ::DidSetUncles::put(true); @@ -209,7 +209,7 @@ impl Module { return author; } - let digest = >::digest(); + let digest = >::digest(); let pre_runtime_digests = digest.logs.iter().filter_map(|d| d.as_pre_runtime()); if let Some(author) = T::FindAuthor::find_author(pre_runtime_digests) { ::Author::put(&author); @@ -219,8 +219,8 @@ impl Module { } } - fn verify_and_import_uncles(new_uncles: Vec) -> DispatchResult { - let now = >::block_number(); + fn verify_and_import_uncles(new_uncles: Vec) -> dispatch::DispatchResult { + let now = >::block_number(); let mut uncles = ::Uncles::get(); uncles.push(UncleEntryItem::InclusionHeight(now)); @@ -253,7 +253,7 @@ impl Module { accumulator: &mut >::Accumulator, ) -> Result, &'static str> { - let now = >::block_number(); + let now = >::block_number(); let (minimum_height, maximum_height) = { let uncle_generations = T::UncleGenerations::get(); @@ -278,7 +278,7 @@ impl Module { { let parent_number = uncle.number().clone() - One::one(); - let parent_hash = >::block_hash(&parent_number); + let parent_hash = >::block_hash(&parent_number); if &parent_hash != uncle.parent_hash() { return Err("uncle parent not in chain"); } @@ -289,7 +289,7 @@ impl Module { } let duplicate = existing_uncles.into_iter().find(|h| **h == hash).is_some(); - let in_chain = >::block_hash(uncle.number()) == hash; + let in_chain = >::block_hash(uncle.number()) == hash; if duplicate || in_chain { return Err("uncle already included") @@ -314,7 +314,7 @@ impl Module { impl ProvideInherent for Module { type Call = Call; - type Error = MakeFatalError<()>; + type Error = InherentError; const INHERENT_IDENTIFIER: InherentIdentifier = INHERENT_IDENTIFIER; fn create_inherent(data: &InherentData) -> Option { @@ -338,6 +338,10 @@ impl ProvideInherent for Module { let hash = uncle.hash(); set_uncles.push(uncle); existing_hashes.push(hash); + + if set_uncles.len() == MAX_UNCLES { + break + } } Err(_) => { // skip this uncle @@ -353,22 +357,29 @@ impl ProvideInherent for Module { } } - fn check_inherent(_call: &Self::Call, _data: &InherentData) -> result::Result<(), Self::Error> { - Ok(()) + fn check_inherent(call: &Self::Call, _data: &InherentData) -> result::Result<(), Self::Error> { + match call { + Call::set_uncles(ref uncles) if uncles.len() > MAX_UNCLES => { + Err(InherentError::Uncles("Too many uncles".into())) + }, + _ => { + Ok(()) + }, + } } } #[cfg(test)] mod tests { use super::*; - use primitives::H256; - use sr_primitives::{ + use sp_core::H256; + use sp_runtime::{ traits::{BlakeTwo256, IdentityLookup}, testing::Header, generic::DigestItem, Perbill, }; - use support::{parameter_types, impl_outer_origin, ConsensusEngineId}; + use frame_support::{parameter_types, impl_outer_origin, ConsensusEngineId, weights::Weight}; impl_outer_origin!{ - pub enum Origin for Test {} + pub enum Origin for Test where system = frame_system {} } #[derive(Clone, Eq, PartialEq)] @@ -376,12 +387,12 @@ mod tests { parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockWeight: Weight = 1024; pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } - impl system::Trait for Test { + impl frame_system::Trait for Test { type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -397,6 +408,7 @@ mod tests { type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; type Version = (); + type ModuleToIndex = (); } parameter_types! { @@ -410,7 +422,7 @@ mod tests { type EventHandler = (); } - type System = system::Module; + type System = frame_system::Module; type Authorship = Module; const TEST_ID: ConsensusEngineId = [1, 2, 3, 4]; @@ -481,8 +493,8 @@ mod tests { ) } - fn new_test_ext() -> runtime_io::TestExternalities { - let t = system::GenesisConfig::default().build_storage::().unwrap(); + fn new_test_ext() -> sp_io::TestExternalities { + let t = frame_system::GenesisConfig::default().build_storage::().unwrap(); t.into() } @@ -554,7 +566,7 @@ mod tests { ); assert_eq!( Authorship::verify_and_import_uncles(vec![uncle_a.clone(), uncle_a.clone()]), - Err("uncle already included"), + Err("uncle already included".into()), ); } @@ -569,7 +581,7 @@ mod tests { assert_eq!( Authorship::verify_and_import_uncles(vec![uncle_a.clone()]), - Err("uncle already included"), + Err("uncle already included".into()), ); } @@ -579,7 +591,7 @@ mod tests { assert_eq!( Authorship::verify_and_import_uncles(vec![uncle_clone]), - Err("uncle already included"), + Err("uncle already included".into()), ); } @@ -588,7 +600,7 @@ mod tests { let unsealed = create_header(3, canon_chain.canon_hash(2), [2; 32].into()); assert_eq!( Authorship::verify_and_import_uncles(vec![unsealed]), - Err("no author"), + Err("no author".into()), ); } @@ -603,7 +615,7 @@ mod tests { assert_eq!( Authorship::verify_and_import_uncles(vec![gen_2]), - Err("uncle not recent enough to be included"), + Err("uncle not recent enough to be included".into()), ); } diff --git a/frame/babe/Cargo.toml b/frame/babe/Cargo.toml index 0ca099b84550dec033326e9ee1d3164f5c743a06..30dbda4e53c2933ab3549af45cb6dce2de48c706 100644 --- a/frame/babe/Cargo.toml +++ b/frame/babe/Cargo.toml @@ -8,39 +8,39 @@ edition = "2018" hex-literal = "0.2.1" codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } serde = { version = "1.0.101", optional = true } -inherents = { package = "substrate-inherents", path = "../../primitives/inherents", default-features = false } -rstd = { package = "sr-std", path = "../../primitives/sr-std", default-features = false } -sr-primitives = { path = "../../primitives/sr-primitives", default-features = false } -sr-staking-primitives = { path = "../../primitives/sr-staking-primitives", default-features = false } -support = { package = "frame-support", path = "../support", default-features = false } -system = { package = "frame-system", path = "../system", default-features = false } -timestamp = { package = "pallet-timestamp", path = "../timestamp", default-features = false } -sp-timestamp = { path = "../../primitives/timestamp", default-features = false } -session = { package = "pallet-session", path = "../session", default-features = false } -babe-primitives = { package = "substrate-consensus-babe-primitives", path = "../../primitives/consensus/babe", default-features = false } -runtime-io ={ package = "sr-io", path = "../../primitives/sr-io", default-features = false } +sp-inherents = { version = "2.0.0", default-features = false, path = "../../primitives/inherents" } +sp-std = { version = "2.0.0", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" } +sp-staking = { version = "2.0.0", default-features = false, path = "../../primitives/staking" } +frame-support = { version = "2.0.0", default-features = false, path = "../support" } +frame-system = { version = "2.0.0", default-features = false, path = "../system" } +pallet-timestamp = { version = "2.0.0", default-features = false, path = "../timestamp" } +sp-timestamp = { version = "2.0.0", default-features = false, path = "../../primitives/timestamp" } +pallet-session = { version = "2.0.0", default-features = false, path = "../session" } +sp-consensus-babe = { version = "0.8", default-features = false, path = "../../primitives/consensus/babe" } +sp-io ={ path = "../../primitives/io", default-features = false } [dev-dependencies] lazy_static = "1.4.0" parking_lot = "0.9.0" -sr-version = { path = "../../primitives/sr-version", default-features = false } -primitives = { package = "substrate-primitives", path = "../../primitives/core" } -test-runtime = { package = "substrate-test-runtime", path = "../../test/utils/runtime" } +sp-version = { version = "2.0.0", default-features = false, path = "../../primitives/version" } +sp-core = { version = "2.0.0", path = "../../primitives/core" } +substrate-test-runtime = { version = "2.0.0", path = "../../test-utils/runtime" } [features] default = ["std"] std = [ "serde", "codec/std", - "rstd/std", - "support/std", - "sr-primitives/std", - "sr-staking-primitives/std", - "system/std", - "timestamp/std", + "sp-std/std", + "frame-support/std", + "sp-runtime/std", + "sp-staking/std", + "frame-system/std", + "pallet-timestamp/std", "sp-timestamp/std", - "inherents/std", - "babe-primitives/std", - "session/std", - "runtime-io/std", + "sp-inherents/std", + "sp-consensus-babe/std", + "pallet-session/std", + "sp-io/std", ] diff --git a/frame/babe/src/lib.rs b/frame/babe/src/lib.rs index d0585b340f798f9a741bbd116905ff50f162cdf3..cdc29e203cca989e65c3fe0dbaac489cb2631971 100644 --- a/frame/babe/src/lib.rs +++ b/frame/babe/src/lib.rs @@ -20,26 +20,25 @@ #![cfg_attr(not(feature = "std"), no_std)] #![forbid(unused_must_use, unsafe_code, unused_variables, unused_must_use)] #![deny(unused_imports)] -pub use timestamp; -use sp_timestamp; +pub use pallet_timestamp; -use rstd::{result, prelude::*}; -use support::{decl_storage, decl_module, traits::FindAuthor, traits::Get}; +use sp_std::{result, prelude::*}; +use frame_support::{decl_storage, decl_module, traits::FindAuthor, traits::Get}; use sp_timestamp::OnTimestampSet; -use sr_primitives::{generic::DigestItem, ConsensusEngineId, Perbill}; -use sr_primitives::traits::{IsMember, SaturatedConversion, Saturating, RandomnessBeacon}; -use sr_staking_primitives::{ +use sp_runtime::{generic::DigestItem, ConsensusEngineId, Perbill}; +use sp_runtime::traits::{IsMember, SaturatedConversion, Saturating, RandomnessBeacon}; +use sp_staking::{ SessionIndex, offence::{Offence, Kind}, }; use codec::{Encode, Decode}; -use inherents::{InherentIdentifier, InherentData, ProvideInherent, MakeFatalError}; -use babe_primitives::{ +use sp_inherents::{InherentIdentifier, InherentData, ProvideInherent, MakeFatalError}; +use sp_consensus_babe::{ BABE_ENGINE_ID, ConsensusLog, BabeAuthorityWeight, NextEpochDescriptor, RawBabePreDigest, SlotNumber, inherents::{INHERENT_IDENTIFIER, BabeInherentData} }; -pub use babe_primitives::{AuthorityId, VRF_OUTPUT_LENGTH, PUBLIC_KEY_LENGTH}; +pub use sp_consensus_babe::{AuthorityId, VRF_OUTPUT_LENGTH, PUBLIC_KEY_LENGTH}; #[cfg(all(feature = "std", test))] mod tests; @@ -47,7 +46,7 @@ mod tests; #[cfg(all(feature = "std", test))] mod mock; -pub trait Trait: timestamp::Trait { +pub trait Trait: pallet_timestamp::Trait { /// The amount of time, in slots, that each epoch should last. type EpochDuration: Get; @@ -228,11 +227,11 @@ impl IsMember for Module { } } -impl session::ShouldEndSession for Module { +impl pallet_session::ShouldEndSession for Module { fn should_end_session(now: T::BlockNumber) -> bool { // it might be (and it is in current implementation) that session module is calling // should_end_session() from it's own on_initialize() handler - // => because session on_initialize() is called earlier than ours, let's ensure + // => because pallet_session on_initialize() is called earlier than ours, let's ensure // that we have synced with digest before checking if session should be ended. Self::do_initialize(now); @@ -292,7 +291,7 @@ impl Module { pub fn slot_duration() -> T::Moment { // we double the minimum block-period so each author can always propose within // the majority of their slot. - ::MinimumPeriod::get().saturating_mul(2.into()) + ::MinimumPeriod::get().saturating_mul(2.into()) } /// Determine whether an epoch change should take place at this block. @@ -306,7 +305,7 @@ impl Module { // epoch 0 as having started at the slot of block 1. We want to use // the same randomness and validator set as signalled in the genesis, // so we don't rotate the epoch. - now != sr_primitives::traits::One::one() && { + now != sp_runtime::traits::One::one() && { let diff = CurrentSlot::get().saturating_sub(Self::current_epoch_start()); diff >= T::EpochDuration::get() } @@ -367,7 +366,7 @@ impl Module { fn deposit_consensus(new: U) { let log: DigestItem = DigestItem::Consensus(BABE_ENGINE_ID, new.encode()); - >::deposit_log(log.into()) + >::deposit_log(log.into()) } fn deposit_vrf_output(vrf_output: &[u8; VRF_OUTPUT_LENGTH]) { @@ -393,7 +392,7 @@ impl Module { return; } - let maybe_pre_digest = >::digest() + let maybe_pre_digest = >::digest() .logs .iter() .filter_map(|s| s.as_pre_runtime()) @@ -445,7 +444,7 @@ impl Module { /// randomness. Returns the new randomness. fn randomness_change_epoch(next_epoch_index: u64) -> [u8; RANDOMNESS_LENGTH] { let this_randomness = NextRandomness::get(); - let segment_idx: u32 = ::mutate(|s| rstd::mem::replace(s, 0)); + let segment_idx: u32 = ::mutate(|s| sp_std::mem::replace(s, 0)); // overestimate to the segment being full. let rho_size = segment_idx.saturating_add(1) as usize * UNDER_CONSTRUCTION_SEGMENT_LENGTH; @@ -472,11 +471,11 @@ impl OnTimestampSet for Module { fn on_timestamp_set(_moment: T::Moment) { } } -impl sr_primitives::BoundToRuntimeAppPublic for Module { +impl sp_runtime::BoundToRuntimeAppPublic for Module { type Public = AuthorityId; } -impl session::OneSessionHandler for Module { +impl pallet_session::OneSessionHandler for Module { type Key = AuthorityId; fn on_genesis_session<'a, I: 'a>(validators: I) @@ -523,12 +522,12 @@ fn compute_randomness( s.extend_from_slice(&vrf_output[..]); } - runtime_io::hashing::blake2_256(&s) + sp_io::hashing::blake2_256(&s) } impl ProvideInherent for Module { - type Call = timestamp::Call; - type Error = MakeFatalError; + type Call = pallet_timestamp::Call; + type Error = MakeFatalError; const INHERENT_IDENTIFIER: InherentIdentifier = INHERENT_IDENTIFIER; fn create_inherent(_: &InherentData) -> Option { @@ -537,7 +536,7 @@ impl ProvideInherent for Module { fn check_inherent(call: &Self::Call, data: &InherentData) -> result::Result<(), Self::Error> { let timestamp = match call { - timestamp::Call::set(ref timestamp) => timestamp.clone(), + pallet_timestamp::Call::set(ref timestamp) => timestamp.clone(), _ => return Ok(()), }; @@ -547,7 +546,7 @@ impl ProvideInherent for Module { if timestamp_based_slot == seal_slot { Ok(()) } else { - Err(inherents::Error::from("timestamp set in block doesn't match slot in seal").into()) + Err(sp_inherents::Error::from("timestamp set in block doesn't match slot in seal").into()) } } } diff --git a/frame/babe/src/mock.rs b/frame/babe/src/mock.rs index d7aed7b42a3fe27e513ec7276ea3e1ccecd4d2d8..fb9804dfb77c49e70a4eead218afd6e820c79cfa 100644 --- a/frame/babe/src/mock.rs +++ b/frame/babe/src/mock.rs @@ -18,17 +18,17 @@ #![allow(dead_code, unused_imports)] use super::{Trait, Module, GenesisConfig}; -use babe_primitives::AuthorityId; -use sr_primitives::{ +use sp_consensus_babe::AuthorityId; +use sp_runtime::{ traits::IdentityLookup, Perbill, testing::{Header, UintAuthorityId}, impl_opaque_keys, }; -use sr_version::RuntimeVersion; -use support::{impl_outer_origin, parameter_types}; -use runtime_io; -use primitives::{H256, Blake2Hasher}; +use sp_version::RuntimeVersion; +use frame_support::{impl_outer_origin, parameter_types, weights::Weight}; +use sp_io; +use sp_core::{H256, Blake2Hasher}; impl_outer_origin!{ - pub enum Origin for Test {} + pub enum Origin for Test where system = frame_system {} } type DummyValidatorId = u64; @@ -39,24 +39,24 @@ pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockWeight: Weight = 1024; pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); pub const MinimumPeriod: u64 = 1; pub const EpochDuration: u64 = 3; pub const ExpectedBlockTime: u64 = 1; - pub const Version: RuntimeVersion = test_runtime::VERSION; + pub const Version: RuntimeVersion = substrate_test_runtime::VERSION; pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(16); } -impl system::Trait for Test { +impl frame_system::Trait for Test { type Origin = Origin; type Index = u64; type BlockNumber = u64; type Call = (); type Hash = H256; type Version = Version; - type Hashing = sr_primitives::traits::BlakeTwo256; + type Hashing = sp_runtime::traits::BlakeTwo256; type AccountId = DummyValidatorId; type Lookup = IdentityLookup; type Header = Header; @@ -65,6 +65,7 @@ impl system::Trait for Test { type MaximumBlockWeight = MaximumBlockWeight; type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; + type ModuleToIndex = (); } impl_opaque_keys! { @@ -73,9 +74,9 @@ impl_opaque_keys! { } } -impl session::Trait for Test { +impl pallet_session::Trait for Test { type Event = (); - type ValidatorId = ::AccountId; + type ValidatorId = ::AccountId; type ShouldEndSession = Babe; type SessionHandler = (Babe,Babe,); type OnSessionEnding = (); @@ -85,7 +86,7 @@ impl session::Trait for Test { type DisabledValidatorsThreshold = DisabledValidatorsThreshold; } -impl timestamp::Trait for Test { +impl pallet_timestamp::Trait for Test { type Moment = u64; type OnTimestampSet = Babe; type MinimumPeriod = MinimumPeriod; @@ -97,13 +98,13 @@ impl Trait for Test { type EpochChangeTrigger = crate::ExternalTrigger; } -pub fn new_test_ext(authorities: Vec) -> runtime_io::TestExternalities { - let mut t = system::GenesisConfig::default().build_storage::().unwrap(); +pub fn new_test_ext(authorities: Vec) -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); GenesisConfig { authorities: authorities.into_iter().map(|a| (UintAuthorityId(a).to_public_key(), 1)).collect(), }.assimilate_storage::(&mut t).unwrap(); t.into() } -pub type System = system::Module; +pub type System = frame_system::Module; pub type Babe = Module; diff --git a/frame/babe/src/tests.rs b/frame/babe/src/tests.rs index f860375de487a646cf7ed89efec13bb9a859d0ef..1ae57a6d6e71a448fbb0add4ef93eda06524b793 100644 --- a/frame/babe/src/tests.rs +++ b/frame/babe/src/tests.rs @@ -18,8 +18,8 @@ use super::*; use mock::{new_test_ext, Babe, Test}; -use sr_primitives::{traits::OnFinalize, testing::{Digest, DigestItem}}; -use session::ShouldEndSession; +use sp_runtime::{traits::OnFinalize, testing::{Digest, DigestItem}}; +use pallet_session::ShouldEndSession; const EMPTY_RANDOMNESS: [u8; 32] = [ 74, 25, 49, 128, 53, 97, 244, 49, @@ -29,18 +29,18 @@ const EMPTY_RANDOMNESS: [u8; 32] = [ ]; fn make_pre_digest( - authority_index: babe_primitives::AuthorityIndex, - slot_number: babe_primitives::SlotNumber, - vrf_output: [u8; babe_primitives::VRF_OUTPUT_LENGTH], - vrf_proof: [u8; babe_primitives::VRF_PROOF_LENGTH], + authority_index: sp_consensus_babe::AuthorityIndex, + slot_number: sp_consensus_babe::SlotNumber, + vrf_output: [u8; sp_consensus_babe::VRF_OUTPUT_LENGTH], + vrf_proof: [u8; sp_consensus_babe::VRF_PROOF_LENGTH], ) -> Digest { - let digest_data = babe_primitives::RawBabePreDigest::Primary { + let digest_data = sp_consensus_babe::RawBabePreDigest::Primary { authority_index, slot_number, vrf_output, vrf_proof, }; - let log = DigestItem::PreRuntime(babe_primitives::BABE_ENGINE_ID, digest_data.encode()); + let log = DigestItem::PreRuntime(sp_consensus_babe::BABE_ENGINE_ID, digest_data.encode()); Digest { logs: vec![log] } } @@ -66,7 +66,7 @@ fn check_module() { }) } -type System = system::Module; +type System = frame_system::Module; #[test] fn first_block_epoch_zero_start() { @@ -103,8 +103,8 @@ fn first_block_epoch_zero_start() { assert_eq!(header.digest.logs[0], pre_digest.logs[0]); let authorities = Babe::authorities(); - let consensus_log = babe_primitives::ConsensusLog::NextEpochData( - babe_primitives::NextEpochDescriptor { + let consensus_log = sp_consensus_babe::ConsensusLog::NextEpochData( + sp_consensus_babe::NextEpochDescriptor { authorities, randomness: Babe::randomness(), } diff --git a/frame/balances/Cargo.toml b/frame/balances/Cargo.toml index a2a69902b038eaad21d1659186ca56b48e049579..e5a3c4f2d76024499b617d9209316729db6f6939 100644 --- a/frame/balances/Cargo.toml +++ b/frame/balances/Cargo.toml @@ -8,15 +8,15 @@ edition = "2018" serde = { version = "1.0.101", optional = true } safe-mix = { version = "1.0.0", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -rstd = { package = "sr-std", path = "../../primitives/sr-std", default-features = false } -sr-primitives = { path = "../../primitives/sr-primitives", default-features = false } -support = { package = "frame-support", path = "../support", default-features = false } -system = { package = "frame-system", path = "../system", default-features = false } +sp-std = { version = "2.0.0", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0", default-features = false, path = "../support" } +frame-system = { version = "2.0.0", default-features = false, path = "../system" } [dev-dependencies] -runtime-io = { package = "sr-io", path = "../../primitives/sr-io" } -primitives = { package = "substrate-primitives", path = "../../primitives/core" } -transaction-payment = { package = "pallet-transaction-payment", path = "../transaction-payment" } +sp-io = { version = "2.0.0", path = "../../primitives/io" } +sp-core = { version = "2.0.0", path = "../../primitives/core" } +pallet-transaction-payment = { version = "2.0.0", path = "../transaction-payment" } [features] default = ["std"] @@ -24,8 +24,8 @@ std = [ "serde", "safe-mix/std", "codec/std", - "rstd/std", - "support/std", - "sr-primitives/std", - "system/std", + "sp-std/std", + "frame-support/std", + "sp-runtime/std", + "frame-system/std", ] diff --git a/frame/balances/src/lib.rs b/frame/balances/src/lib.rs index fd6ec99c0779e5b7ea4deeb89b9450f678d93af0..4b53f7189810fe6cb264eb09990e8384bd1c28fa 100644 --- a/frame/balances/src/lib.rs +++ b/frame/balances/src/lib.rs @@ -107,13 +107,13 @@ //! The Contract module uses the `Currency` trait to handle gas payment, and its types inherit from `Currency`: //! //! ``` -//! use support::traits::Currency; -//! # pub trait Trait: system::Trait { +//! use frame_support::traits::Currency; +//! # pub trait Trait: frame_system::Trait { //! # type Currency: Currency; //! # } //! -//! pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; -//! pub type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; +//! pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +//! pub type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; //! //! # fn main() {} //! ``` @@ -121,14 +121,14 @@ //! The Staking module uses the `LockableCurrency` trait to lock a stash account's funds: //! //! ``` -//! use support::traits::{WithdrawReasons, LockableCurrency}; -//! use sr_primitives::traits::Bounded; -//! pub trait Trait: system::Trait { +//! use frame_support::traits::{WithdrawReasons, LockableCurrency}; +//! use sp_runtime::traits::Bounded; +//! pub trait Trait: frame_system::Trait { //! type Currency: LockableCurrency; //! } //! # struct StakingLedger { -//! # stash: ::AccountId, -//! # total: <::Currency as support::traits::Currency<::AccountId>>::Balance, +//! # stash: ::AccountId, +//! # total: <::Currency as frame_support::traits::Currency<::AccountId>>::Balance, //! # phantom: std::marker::PhantomData, //! # } //! # const STAKING_ID: [u8; 8] = *b"staking "; @@ -159,27 +159,26 @@ #![cfg_attr(not(feature = "std"), no_std)] -use rstd::prelude::*; -use rstd::{cmp, result, mem, fmt::Debug}; +use sp_std::prelude::*; +use sp_std::{cmp, result, mem, fmt::Debug}; use codec::{Codec, Encode, Decode}; -use support::{ +use frame_support::{ StorageValue, Parameter, decl_event, decl_storage, decl_module, traits::{ UpdateBalanceOutcome, Currency, OnFreeBalanceZero, OnUnbalanced, TryDrop, WithdrawReason, WithdrawReasons, LockIdentifier, LockableCurrency, ExistenceRequirement, - Imbalance, SignedImbalance, ReservableCurrency, Get, + Imbalance, SignedImbalance, ReservableCurrency, Get, VestingCurrency, }, weights::SimpleDispatchInfo, - dispatch::Result, }; -use sr_primitives::{ - RuntimeDebug, +use sp_runtime::{ + RuntimeDebug, DispatchResult, DispatchError, traits::{ Zero, SimpleArithmetic, StaticLookup, Member, CheckedAdd, CheckedSub, MaybeSerializeDeserialize, Saturating, Bounded, }, }; -use system::{IsDeadAccount, OnNewAccount, ensure_signed, ensure_root}; +use frame_system::{self as system, IsDeadAccount, OnNewAccount, ensure_signed, ensure_root}; #[cfg(test)] mod mock; @@ -188,7 +187,7 @@ mod tests; pub use self::imbalances::{PositiveImbalance, NegativeImbalance}; -pub trait Subtrait: system::Trait { +pub trait Subtrait: frame_system::Trait { /// The balance of an account. type Balance: Parameter + Member + SimpleArithmetic + Codec + Default + Copy + MaybeSerializeDeserialize + Debug + From; @@ -212,7 +211,7 @@ pub trait Subtrait: system::Trait { type CreationFee: Get; } -pub trait Trait: system::Trait { +pub trait Trait: frame_system::Trait { /// The balance of an account. type Balance: Parameter + Member + SimpleArithmetic + Codec + Default + Copy + MaybeSerializeDeserialize + Debug + From; @@ -234,7 +233,7 @@ pub trait Trait: system::Trait { type DustRemoval: OnUnbalanced>; /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// The minimum amount required to keep an account open. type ExistentialDeposit: Get; @@ -257,15 +256,19 @@ impl, I: Instance> Subtrait for T { decl_event!( pub enum Event where - ::AccountId, + ::AccountId, >::Balance { /// A new account was created. NewAccount(AccountId, Balance), /// An account was reaped. - ReapedAccount(AccountId), + ReapedAccount(AccountId, Balance), /// Transfer succeeded (from, to, value, fees). Transfer(AccountId, AccountId, Balance, Balance), + /// A balance was set by root (who, free, reserved). + BalanceSet(AccountId, Balance, Balance), + /// Some amount was deposited (e.g. for transaction fees). + Deposit(AccountId, Balance), } ); @@ -328,7 +331,7 @@ decl_storage! { // Total genesis `balance` minus `liquid` equals funds locked for vesting let locked = balance.saturating_sub(liquid); // Number of units unlocked per block after `begin` - let per_block = locked / length.max(sr_primitives::traits::One::one()); + let per_block = locked / length.max(sp_runtime::traits::One::one()); (who.clone(), VestingSchedule { locked: locked, @@ -348,7 +351,7 @@ decl_storage! { /// is invoked, giving a chance to external modules to clean up data associated with /// the deleted account. /// - /// `system::AccountNonce` is also deleted if `ReservedBalance` is also zero (it also gets + /// `frame_system::AccountNonce` is also deleted if `ReservedBalance` is also zero (it also gets /// collapsed to zero if it ever becomes less than `ExistentialDeposit`. pub FreeBalance get(fn free_balance) build(|config: &GenesisConfig| config.balances.clone()): @@ -363,7 +366,7 @@ decl_storage! { /// When this balance falls below the value of `ExistentialDeposit`, then this 'reserve account' /// is deleted: specifically, `ReservedBalance`. /// - /// `system::AccountNonce` is also deleted if `FreeBalance` is also zero (it also gets + /// `frame_system::AccountNonce` is also deleted if `FreeBalance` is also zero (it also gets /// collapsed to zero if it ever becomes less than `ExistentialDeposit`.) pub ReservedBalance get(fn reserved_balance): map T::AccountId => T::Balance; @@ -439,7 +442,7 @@ decl_module! { /// This will alter `FreeBalance` and `ReservedBalance` in storage. it will /// also decrease the total issuance of the system (`TotalIssuance`). /// If the new free or reserved balance is below the existential deposit, - /// it will reset the account nonce (`system::AccountNonce`). + /// it will reset the account nonce (`frame_system::AccountNonce`). /// /// The dispatch origin for this call is `root`. /// @@ -456,6 +459,10 @@ decl_module! { ) { ensure_root(origin)?; let who = T::Lookup::lookup(who)?; + let existential_deposit = T::ExistentialDeposit::get(); + + let new_free = if new_free < existential_deposit { Zero::zero() } else { new_free }; + let new_reserved = if new_reserved < existential_deposit { Zero::zero() } else { new_reserved }; let current_free = >::get(&who); if new_free > current_free { @@ -472,6 +479,8 @@ decl_module! { mem::drop(NegativeImbalance::::new(current_reserved - new_reserved)); } Self::set_reserved_balance(&who, new_reserved); + + Self::deposit_event(RawEvent::BalanceSet(who, new_free, new_reserved)); } /// Exactly as `transfer`, except the origin must be root and the source account may be @@ -510,19 +519,6 @@ decl_module! { } impl, I: Instance> Module { - - // PUBLIC IMMUTABLES - - /// Get the amount that is currently being vested and cannot be transferred out of this account. - pub fn vesting_balance(who: &T::AccountId) -> T::Balance { - if let Some(v) = Self::vesting(who) { - Self::free_balance(who) - .min(v.locked_at(>::block_number())) - } else { - Zero::zero() - } - } - // PRIVATE MUTABLES /// Set the reserved balance of an account to some new value. Will enforce `ExistentialDeposit` @@ -577,9 +573,9 @@ impl, I: Instance> Module { /// Unregister an account. /// /// This just removes the nonce and leaves an event. - fn reap_account(who: &T::AccountId) { - >::remove(who); - Self::deposit_event(RawEvent::ReapedAccount(who.clone())); + fn reap_account(who: &T::AccountId, dust: T::Balance) { + >::remove(who); + Self::deposit_event(RawEvent::ReapedAccount(who.clone(), dust)); } /// Account's free balance has dropped below existential deposit. Kill its @@ -590,15 +586,23 @@ impl, I: Instance> Module { let dust = >::take(who); >::remove(who); - // underflow should never happen, but if it does, there's not much we can do about it. + T::OnFreeBalanceZero::on_free_balance_zero(who); + + let mut reserved_balance = Self::reserved_balance(who); + if !dust.is_zero() { - T::DustRemoval::on_unbalanced(NegativeImbalance::new(dust)); + if reserved_balance >= T::ExistentialDeposit::get() { + // any individual account cannot cause overflow in balance. + reserved_balance += dust; + Self::set_reserved_balance(who, reserved_balance); + } else { + // underflow should never happen, but if it does, there's not much we can do. + T::DustRemoval::on_unbalanced(NegativeImbalance::new(dust)); + } } - T::OnFreeBalanceZero::on_free_balance_zero(who); - - if Self::reserved_balance(who).is_zero() { - Self::reap_account(who); + if reserved_balance.is_zero() { + Self::reap_account(who, dust); } } @@ -609,13 +613,21 @@ impl, I: Instance> Module { fn on_reserved_too_low(who: &T::AccountId) { let dust = >::take(who); - // underflow should never happen, but it if does, there's nothing to be done here. + let mut free_balance = Self::free_balance(who); + if !dust.is_zero() { - T::DustRemoval::on_unbalanced(NegativeImbalance::new(dust)); + if free_balance >= T::ExistentialDeposit::get() { + // any individual account cannot cause overflow in balance. + free_balance += dust; + Self::set_free_balance(who, free_balance); + } else { + // underflow should never happen, but it if does, there's nothing to be done here. + T::DustRemoval::on_unbalanced(NegativeImbalance::new(dust)); + } } - if Self::free_balance(who).is_zero() { - Self::reap_account(who); + if free_balance.is_zero() { + Self::reap_account(who, dust); } } } @@ -627,7 +639,7 @@ mod imbalances { result, Subtrait, DefaultInstance, Imbalance, Trait, Zero, Instance, Saturating, StorageValue, TryDrop, }; - use rstd::mem; + use sp_std::mem; /// Opaque, move-only struct with private fields that serves as a token denoting that /// funds have been created without any equal and opposite accounting. @@ -794,7 +806,7 @@ impl, I: Instance> PartialEq for ElevatedTrait { fn eq(&self, _: &Self) -> bool { unimplemented!() } } impl, I: Instance> Eq for ElevatedTrait {} -impl, I: Instance> system::Trait for ElevatedTrait { +impl, I: Instance> frame_system::Trait for ElevatedTrait { type Origin = T::Origin; type Call = T::Call; type Index = T::Index; @@ -810,6 +822,7 @@ impl, I: Instance> system::Trait for ElevatedTrait { type MaximumBlockLength = T::MaximumBlockLength; type AvailableBlockRatio = T::AvailableBlockRatio; type Version = T::Version; + type ModuleToIndex = T::ModuleToIndex; } impl, I: Instance> Trait for ElevatedTrait { type Balance = T::Balance; @@ -880,18 +893,18 @@ where _amount: T::Balance, reasons: WithdrawReasons, new_balance: T::Balance, - ) -> Result { + ) -> DispatchResult { if reasons.intersects(WithdrawReason::Reserve | WithdrawReason::Transfer) && Self::vesting_balance(who) > new_balance { - return Err("vesting balance too high to send value"); + Err("vesting balance too high to send value")? } let locks = Self::locks(who); if locks.is_empty() { return Ok(()) } - let now = >::block_number(); + let now = >::block_number(); if locks.into_iter() .all(|l| now >= l.until @@ -901,7 +914,7 @@ where { Ok(()) } else { - Err("account liquidity restrictions prevent withdrawal") + Err("account liquidity restrictions prevent withdrawal".into()) } } @@ -910,22 +923,22 @@ where dest: &T::AccountId, value: Self::Balance, existence_requirement: ExistenceRequirement, - ) -> Result { + ) -> DispatchResult { let from_balance = Self::free_balance(transactor); let to_balance = Self::free_balance(dest); let would_create = to_balance.is_zero(); let fee = if would_create { T::CreationFee::get() } else { T::TransferFee::get() }; let liability = match value.checked_add(&fee) { Some(l) => l, - None => return Err("got overflow after adding a fee to value"), + None => Err("got overflow after adding a fee to value")?, }; let new_from_balance = match from_balance.checked_sub(&liability) { - None => return Err("balance too low to send value"), + None => Err("balance too low to send value")?, Some(b) => b, }; if would_create && value < T::ExistentialDeposit::get() { - return Err("value too low to create account"); + Err("value too low to create account")? } Self::ensure_can_withdraw(transactor, value, WithdrawReason::Transfer.into(), new_from_balance)?; @@ -933,13 +946,13 @@ where // but better to be safe than sorry. let new_to_balance = match to_balance.checked_add(&value) { Some(b) => b, - None => return Err("destination balance too high to receive value"), + None => Err("destination balance too high to receive value")?, }; if transactor != dest { if existence_requirement == ExistenceRequirement::KeepAlive { if new_from_balance < Self::minimum_balance() { - return Err("transfer would kill account"); + Err("transfer would kill account")? } } @@ -947,9 +960,14 @@ where if !>::exists(dest) { Self::new_account(dest, new_to_balance); } + + // Emit transfer event. + Self::deposit_event(RawEvent::Transfer(transactor.clone(), dest.clone(), value, fee)); + + // Take action on the set_free_balance call. + // This will emit events that _resulted_ from the transfer. Self::set_free_balance(dest, new_to_balance); T::TransferPayment::on_unbalanced(NegativeImbalance::new(fee)); - Self::deposit_event(RawEvent::Transfer(transactor.clone(), dest.clone(), value, fee)); } Ok(()) @@ -960,7 +978,7 @@ where value: Self::Balance, reasons: WithdrawReasons, liveness: ExistenceRequirement, - ) -> result::Result { + ) -> result::Result { let old_balance = Self::free_balance(who); if let Some(new_balance) = old_balance.checked_sub(&value) { // if we need to keep the account alive... @@ -970,13 +988,13 @@ where // ...yet is was alive before && old_balance >= T::ExistentialDeposit::get() { - return Err("payment would kill account") + Err("payment would kill account")? } Self::ensure_can_withdraw(who, value, reasons, new_balance)?; Self::set_free_balance(who, new_balance); Ok(NegativeImbalance::new(value)) } else { - Err("too few free funds in account") + Err("too few free funds in account")? } } @@ -986,6 +1004,7 @@ where ) -> (Self::NegativeImbalance, Self::Balance) { let free_balance = Self::free_balance(who); let free_slash = cmp::min(free_balance, value); + Self::set_free_balance(who, free_balance - free_slash); let remaining_slash = value - free_slash; // NOTE: `slash()` prefers free balance, but assumes that reserve balance can be drawn @@ -1005,9 +1024,9 @@ where fn deposit_into_existing( who: &T::AccountId, value: Self::Balance - ) -> result::Result { + ) -> result::Result { if Self::total_balance(who).is_zero() { - return Err("beneficiary account must pre-exist"); + Err("beneficiary account must pre-exist")? } Self::set_free_balance(who, Self::free_balance(who) + value); Ok(PositiveImbalance::new(value)) @@ -1087,10 +1106,10 @@ where >::get(who) } - fn reserve(who: &T::AccountId, value: Self::Balance) -> result::Result<(), &'static str> { + fn reserve(who: &T::AccountId, value: Self::Balance) -> result::Result<(), DispatchError> { let b = Self::free_balance(who); if b < value { - return Err("not enough free funds") + Err("not enough free funds")? } let new_balance = b - value; Self::ensure_can_withdraw(who, value, WithdrawReason::Reserve.into(), new_balance)?; @@ -1122,9 +1141,9 @@ where slashed: &T::AccountId, beneficiary: &T::AccountId, value: Self::Balance, - ) -> result::Result { + ) -> result::Result { if Self::total_balance(beneficiary).is_zero() { - return Err("beneficiary account must pre-exist"); + Err("beneficiary account must pre-exist")? } let b = Self::reserved_balance(slashed); let slash = cmp::min(b, value); @@ -1147,7 +1166,7 @@ where until: T::BlockNumber, reasons: WithdrawReasons, ) { - let now = >::block_number(); + let now = >::block_number(); let mut new_lock = Some(BalanceLock { id, amount, until, reasons }); let mut locks = Self::locks(who).into_iter().filter_map(|l| if l.id == id { @@ -1170,7 +1189,7 @@ where until: T::BlockNumber, reasons: WithdrawReasons, ) { - let now = >::block_number(); + let now = >::block_number(); let mut new_lock = Some(BalanceLock { id, amount, until, reasons }); let mut locks = Self::locks(who).into_iter().filter_map(|l| if l.id == id { @@ -1197,7 +1216,7 @@ where id: LockIdentifier, who: &T::AccountId, ) { - let now = >::block_number(); + let now = >::block_number(); let locks = Self::locks(who).into_iter().filter_map(|l| if l.until > now && l.id != id { Some(l) @@ -1208,6 +1227,50 @@ where } } +impl, I: Instance> VestingCurrency for Module +where + T::Balance: MaybeSerializeDeserialize + Debug +{ + type Moment = T::BlockNumber; + + /// Get the amount that is currently being vested and cannot be transferred out of this account. + fn vesting_balance(who: &T::AccountId) -> T::Balance { + if let Some(v) = Self::vesting(who) { + Self::free_balance(who) + .min(v.locked_at(>::block_number())) + } else { + Zero::zero() + } + } + + /// Adds a vesting schedule to a given account. + /// + /// If there already exists a vesting schedule for the given account, an `Err` is returned + /// and nothing is updated. + fn add_vesting_schedule( + who: &T::AccountId, + locked: T::Balance, + per_block: T::Balance, + starting_block: T::BlockNumber + ) -> DispatchResult { + if >::exists(who) { + Err("A vesting schedule already exists for this account.")? + } + let vesting_schedule = VestingSchedule { + locked, + per_block, + starting_block + }; + >::insert(who, vesting_schedule); + Ok(()) + } + + /// Remove a vesting schedule for a given account. + fn remove_vesting_schedule(who: &T::AccountId) { + >::remove(who); + } +} + impl, I: Instance> IsDeadAccount for Module where T::Balance: MaybeSerializeDeserialize + Debug diff --git a/frame/balances/src/mock.rs b/frame/balances/src/mock.rs index 62eabd1cf04d91494353a9d67e936675d06035c5..c54165d6ec077b1325c2de072d94dde3bb5530e9 100644 --- a/frame/balances/src/mock.rs +++ b/frame/balances/src/mock.rs @@ -16,15 +16,16 @@ //! Test utilities -use sr_primitives::{Perbill, traits::{ConvertInto, IdentityLookup}, testing::Header}; -use primitives::H256; -use runtime_io; -use support::{impl_outer_origin, parameter_types}; -use support::traits::Get; -use support::weights::{Weight, DispatchInfo}; +use sp_runtime::{Perbill, traits::{ConvertInto, IdentityLookup}, testing::Header}; +use sp_core::H256; +use sp_io; +use frame_support::{impl_outer_origin, parameter_types}; +use frame_support::traits::Get; +use frame_support::weights::{Weight, DispatchInfo}; use std::cell::RefCell; use crate::{GenesisConfig, Module, Trait}; +use frame_system as system; impl_outer_origin!{ pub enum Origin for Runtime {} } @@ -55,17 +56,17 @@ impl Get for CreationFee { pub struct Runtime; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockWeight: Weight = 1024; pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } -impl system::Trait for Runtime { +impl frame_system::Trait for Runtime { type Origin = Origin; type Index = u64; type BlockNumber = u64; type Call = (); type Hash = H256; - type Hashing = ::sr_primitives::traits::BlakeTwo256; + type Hashing = ::sp_runtime::traits::BlakeTwo256; type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; @@ -75,12 +76,13 @@ impl system::Trait for Runtime { type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); + type ModuleToIndex = (); } parameter_types! { pub const TransactionBaseFee: u64 = 0; pub const TransactionByteFee: u64 = 1; } -impl transaction_payment::Trait for Runtime { +impl pallet_transaction_payment::Trait for Runtime { type Currency = Module; type OnTransactionPayment = (); type TransactionBaseFee = TransactionBaseFee; @@ -148,9 +150,9 @@ impl ExtBuilder { TRANSFER_FEE.with(|v| *v.borrow_mut() = self.transfer_fee); CREATION_FEE.with(|v| *v.borrow_mut() = self.creation_fee); } - pub fn build(self) -> runtime_io::TestExternalities { + pub fn build(self) -> sp_io::TestExternalities { self.set_associated_consts(); - let mut t = system::GenesisConfig::default().build_storage::().unwrap(); + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); GenesisConfig:: { balances: if self.monied { vec![ @@ -177,10 +179,10 @@ impl ExtBuilder { } } -pub type System = system::Module; +pub type System = frame_system::Module; pub type Balances = Module; -pub const CALL: &::Call = &(); +pub const CALL: &::Call = &(); /// create a transaction info struct from weight. Handy to avoid building the whole struct. pub fn info_from_weight(w: Weight) -> DispatchInfo { diff --git a/frame/balances/src/tests.rs b/frame/balances/src/tests.rs index 3849df676425fa7436c0ae5f41add65ef0bc8077..fe0df11b3a09283fb98a0b49ed81205636b60832 100644 --- a/frame/balances/src/tests.rs +++ b/frame/balances/src/tests.rs @@ -18,14 +18,14 @@ use super::*; use mock::{Balances, ExtBuilder, Runtime, System, info_from_weight, CALL}; -use sr_primitives::traits::SignedExtension; -use support::{ +use sp_runtime::traits::{SignedExtension, BadOrigin}; +use frame_support::{ assert_noop, assert_ok, assert_err, traits::{LockableCurrency, LockIdentifier, WithdrawReason, WithdrawReasons, Currency, ReservableCurrency, ExistenceRequirement::AllowDeath} }; -use transaction_payment::ChargeTransactionPayment; -use system::RawOrigin; +use pallet_transaction_payment::ChargeTransactionPayment; +use frame_system::RawOrigin; const ID_1: LockIdentifier = *b"1 "; const ID_2: LockIdentifier = *b"2 "; @@ -248,7 +248,7 @@ fn reserved_balance_should_prevent_reclaim_count() { assert_ok!(Balances::reserve(&2, 256 * 19 + 1)); // account 2 becomes mostly reserved assert_eq!(Balances::free_balance(&2), 0); // "free" account deleted." - assert_eq!(Balances::total_balance(&2), 256 * 19 + 1); // reserve still exists. + assert_eq!(Balances::total_balance(&2), 256 * 20); // reserve still exists. assert_eq!(Balances::is_dead_account(&2), false); assert_eq!(System::account_nonce(&2), 1); @@ -257,7 +257,7 @@ fn reserved_balance_should_prevent_reclaim_count() { assert_eq!(Balances::total_balance(&5), 256 * 1 + 0x69); assert_eq!(Balances::is_dead_account(&5), false); - assert!(Balances::slash(&2, 256 * 18 + 2).1.is_zero()); // account 2 gets slashed + assert!(Balances::slash(&2, 256 * 19 + 2).1.is_zero()); // account 2 gets slashed // "reserve" account reduced to 255 (below ED) so account deleted assert_eq!(Balances::total_balance(&2), 0); assert_eq!(System::account_nonce(&2), 0); // nonce zero @@ -347,7 +347,7 @@ fn force_transfer_works() { let _ = Balances::deposit_creating(&1, 111); assert_noop!( Balances::force_transfer(Some(2).into(), 1, 2, 69), - "RequireRootOrigin", + BadOrigin, ); assert_ok!(Balances::force_transfer(RawOrigin::Root.into(), 1, 2, 69)); assert_eq!(Balances::total_balance(&1), 42); @@ -763,9 +763,48 @@ fn transfer_keep_alive_works() { #[should_panic="the balance of any account should always be more than existential deposit."] fn cannot_set_genesis_value_below_ed() { mock::EXISTENTIAL_DEPOSIT.with(|v| *v.borrow_mut() = 11); - let mut t = system::GenesisConfig::default().build_storage::().unwrap(); + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); let _ = GenesisConfig:: { balances: vec![(1, 10)], vesting: vec![], }.assimilate_storage(&mut t).unwrap(); } + +#[test] +fn dust_moves_between_free_and_reserved() { + ExtBuilder::default() + .existential_deposit(100) + .build() + .execute_with(|| { + // Set balance to free and reserved at the existential deposit + assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 100, 100)); + assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 2, 100, 100)); + // Check balance + assert_eq!(Balances::free_balance(1), 100); + assert_eq!(Balances::reserved_balance(1), 100); + assert_eq!(Balances::free_balance(2), 100); + assert_eq!(Balances::reserved_balance(2), 100); + + // Drop 1 free_balance below ED + assert_ok!(Balances::transfer(Some(1).into(), 2, 1)); + // Check balance, the other 99 should move to reserved_balance + assert_eq!(Balances::free_balance(1), 0); + assert_eq!(Balances::reserved_balance(1), 199); + + // Reset accounts + assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 100, 100)); + assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 2, 100, 100)); + + // Drop 2 reserved_balance below ED + Balances::unreserve(&2, 1); + // Check balance, all 100 should move to free_balance + assert_eq!(Balances::free_balance(2), 200); + assert_eq!(Balances::reserved_balance(2), 0); + + // An account with both too little free and reserved is completely killed + assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 99, 99)); + // Check balance is 0 for everything + assert_eq!(Balances::free_balance(1), 0); + assert_eq!(Balances::reserved_balance(1), 0); + }); +} diff --git a/frame/collective/Cargo.toml b/frame/collective/Cargo.toml index ed1244ff237ccd76f25ed9e97e7321f95222c3fc..6bf3c1b9b5c78566c4dc939e86d9b5e8777629b7 100644 --- a/frame/collective/Cargo.toml +++ b/frame/collective/Cargo.toml @@ -8,27 +8,27 @@ edition = "2018" serde = { version = "1.0.101", optional = true } safe-mix = { version = "1.0.0", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -primitives = { package = "substrate-primitives", path = "../../primitives/core", default-features = false } -rstd = { package = "sr-std", path = "../../primitives/sr-std", default-features = false } -runtime-io = { package = "sr-io", path = "../../primitives/sr-io", default-features = false } -sr-primitives = { path = "../../primitives/sr-primitives", default-features = false } -support = { package = "frame-support", path = "../support", default-features = false } -system = { package = "frame-system", path = "../system", default-features = false } +sp-core = { version = "2.0.0", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0", default-features = false, path = "../support" } +frame-system = { version = "2.0.0", default-features = false, path = "../system" } [dev-dependencies] hex-literal = "0.2.1" -balances = { package = "pallet-balances", path = "../balances" } +pallet-balances = { version = "2.0.0", path = "../balances" } [features] default = ["std"] std = [ "safe-mix/std", "codec/std", - "primitives/std", - "rstd/std", + "sp-core/std", + "sp-std/std", "serde", - "runtime-io/std", - "support/std", - "sr-primitives/std", - "system/std", + "sp-io/std", + "frame-support/std", + "sp-runtime/std", + "frame-system/std", ] diff --git a/frame/collective/src/lib.rs b/frame/collective/src/lib.rs index eff8366f0707c56f3f1f351780ed02f9c17432b6..617fb32e4ebed94f55e4cd6d88f684495cd507a5 100644 --- a/frame/collective/src/lib.rs +++ b/frame/collective/src/lib.rs @@ -23,17 +23,17 @@ #![cfg_attr(not(feature = "std"), no_std)] #![recursion_limit="128"] -use rstd::{prelude::*, result}; -use primitives::u32_trait::Value as U32; -use sr_primitives::RuntimeDebug; -use sr_primitives::traits::{Hash, EnsureOrigin}; -use support::weights::SimpleDispatchInfo; -use support::{ +use sp_std::{prelude::*, result}; +use sp_core::u32_trait::Value as U32; +use sp_runtime::RuntimeDebug; +use sp_runtime::traits::{Hash, EnsureOrigin}; +use frame_support::weights::SimpleDispatchInfo; +use frame_support::{ dispatch::{Dispatchable, Parameter}, codec::{Encode, Decode}, traits::{ChangeMembers, InitializeMembers}, decl_module, decl_event, - decl_storage, ensure, + decl_storage, decl_error, ensure, }; -use system::{self, ensure_signed, ensure_root}; +use frame_system::{self as system, ensure_signed, ensure_root}; /// Simple index type for proposal counting. pub type ProposalIndex = u32; @@ -44,7 +44,7 @@ pub type ProposalIndex = u32; /// vote exactly once, therefore also the number of votes for any given motion. pub type MemberCount = u32; -pub trait Trait: system::Trait { +pub trait Trait: frame_system::Trait { /// The outer origin type. type Origin: From>; @@ -52,7 +52,7 @@ pub trait Trait: system::Trait { type Proposal: Parameter + Dispatchable>::Origin>; /// The outer event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; } /// Origin for the collective module. @@ -63,11 +63,11 @@ pub enum RawOrigin { /// It has been condoned by a single member of the collective. Member(AccountId), /// Dummy to manage the fact we have instancing. - _Phantom(rstd::marker::PhantomData), + _Phantom(sp_std::marker::PhantomData), } /// Origin for the collective module. -pub type Origin = RawOrigin<::AccountId, I>; +pub type Origin = RawOrigin<::AccountId, I>; #[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] /// Info for keeping track of a motion being voted on. @@ -96,16 +96,16 @@ decl_storage! { pub Members get(fn members): Vec; } add_extra_genesis { - config(phantom): rstd::marker::PhantomData; + config(phantom): sp_std::marker::PhantomData; config(members): Vec; build(|config| Module::::initialize_members(&config.members)) } } -decl_event!( +decl_event! { pub enum Event where - ::Hash, - ::AccountId, + ::Hash, + ::AccountId, { /// A motion (given hash) has been proposed (by given account) with a threshold (given /// `MemberCount`). @@ -122,13 +122,32 @@ decl_event!( /// A single member did some action; `bool` is true if returned without error. MemberExecuted(Hash, bool), } -); +} + +decl_error! { + pub enum Error for Module, I: Instance> { + /// Account is not a member + NotMember, + /// Duplicate proposals not allowed + DuplicateProposal, + /// Proposal must exist + ProposalMissing, + /// Mismatched index + WrongIndex, + /// Duplicate vote ignored + DuplicateVote, + /// Members are already initialized! + AlreadyInitialized, + } +} // Note: this module is not benchmarked. The weights are obtained based on the similarity of the // executed logic with other democracy function. Note that councillor operations are assigned to the // operational class. decl_module! { - pub struct Module, I: Instance=DefaultInstance> for enum Call where origin: ::Origin { + pub struct Module, I: Instance=DefaultInstance> for enum Call where origin: ::Origin { + type Error = Error; + fn deposit_event() = default; /// Set the collective's membership manually to `new_members`. Be nice to the chain and @@ -152,7 +171,7 @@ decl_module! { #[weight = SimpleDispatchInfo::FixedOperational(100_000)] fn execute(origin, proposal: Box<>::Proposal>) { let who = ensure_signed(origin)?; - ensure!(Self::is_member(&who), "proposer not a member"); + ensure!(Self::is_member(&who), Error::::NotMember); let proposal_hash = T::Hashing::hash_of(&proposal); let ok = proposal.dispatch(RawOrigin::Member(who).into()).is_ok(); @@ -166,11 +185,11 @@ decl_module! { #[weight = SimpleDispatchInfo::FixedOperational(5_000_000)] fn propose(origin, #[compact] threshold: MemberCount, proposal: Box<>::Proposal>) { let who = ensure_signed(origin)?; - ensure!(Self::is_member(&who), "proposer not a member"); + ensure!(Self::is_member(&who), Error::::NotMember); let proposal_hash = T::Hashing::hash_of(&proposal); - ensure!(!>::exists(proposal_hash), "duplicate proposals not allowed"); + ensure!(!>::exists(proposal_hash), Error::::DuplicateProposal); if threshold < 2 { let seats = Self::members().len() as MemberCount; @@ -195,10 +214,10 @@ decl_module! { #[weight = SimpleDispatchInfo::FixedOperational(200_000)] fn vote(origin, proposal: T::Hash, #[compact] index: ProposalIndex, approve: bool) { let who = ensure_signed(origin)?; - ensure!(Self::is_member(&who), "voter not a member"); + ensure!(Self::is_member(&who), Error::::NotMember); - let mut voting = Self::voting(&proposal).ok_or("proposal must exist")?; - ensure!(voting.index == index, "mismatched index"); + let mut voting = Self::voting(&proposal).ok_or(Error::::ProposalMissing)?; + ensure!(voting.index == index, Error::::WrongIndex); let position_yes = voting.ayes.iter().position(|a| a == &who); let position_no = voting.nays.iter().position(|a| a == &who); @@ -207,7 +226,7 @@ decl_module! { if position_yes.is_none() { voting.ayes.push(who.clone()); } else { - return Err("duplicate vote ignored") + Err(Error::::DuplicateVote)? } if let Some(pos) = position_no { voting.nays.swap_remove(pos); @@ -216,7 +235,7 @@ decl_module! { if position_no.is_none() { voting.nays.push(who.clone()); } else { - return Err("duplicate vote ignored") + Err(Error::::DuplicateVote)? } if let Some(pos) = position_yes { voting.ayes.swap_remove(pos); @@ -242,6 +261,7 @@ decl_module! { } } else { // disapproved + >::remove(&proposal); Self::deposit_event(RawEvent::Disapproved(proposal)); } @@ -306,7 +326,7 @@ where } } -pub struct EnsureMember(rstd::marker::PhantomData<(AccountId, I)>); +pub struct EnsureMember(sp_std::marker::PhantomData<(AccountId, I)>); impl< O: Into, O>> + From>, AccountId, @@ -321,7 +341,7 @@ impl< } } -pub struct EnsureMembers(rstd::marker::PhantomData<(N, AccountId, I)>); +pub struct EnsureMembers(sp_std::marker::PhantomData<(N, AccountId, I)>); impl< O: Into, O>> + From>, N: U32, @@ -338,7 +358,7 @@ impl< } pub struct EnsureProportionMoreThan( - rstd::marker::PhantomData<(N, D, AccountId, I)> + sp_std::marker::PhantomData<(N, D, AccountId, I)> ); impl< O: Into, O>> + From>, @@ -357,7 +377,7 @@ impl< } pub struct EnsureProportionAtLeast( - rstd::marker::PhantomData<(N, D, AccountId, I)> + sp_std::marker::PhantomData<(N, D, AccountId, I)> ); impl< O: Into, O>> + From>, @@ -378,11 +398,11 @@ impl< #[cfg(test)] mod tests { use super::*; - use support::{Hashable, assert_ok, assert_noop, parameter_types}; - use system::{EventRecord, Phase}; + use frame_support::{Hashable, assert_ok, assert_noop, parameter_types, weights::Weight}; + use frame_system::{self as system, EventRecord, Phase}; use hex_literal::hex; - use primitives::H256; - use sr_primitives::{ + use sp_core::H256; + use sp_runtime::{ Perbill, traits::{BlakeTwo256, IdentityLookup, Block as BlockT}, testing::Header, BuildStorage, }; @@ -390,11 +410,11 @@ mod tests { parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockWeight: Weight = 1024; pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } - impl system::Trait for Test { + impl frame_system::Trait for Test { type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -410,6 +430,7 @@ mod tests { type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); + type ModuleToIndex = (); } impl Trait for Test { type Origin = Origin; @@ -422,10 +443,10 @@ mod tests { type Event = Event; } - pub type Block = sr_primitives::generic::Block; - pub type UncheckedExtrinsic = sr_primitives::generic::UncheckedExtrinsic; + pub type Block = sp_runtime::generic::Block; + pub type UncheckedExtrinsic = sp_runtime::generic::UncheckedExtrinsic; - support::construct_runtime!( + frame_support::construct_runtime!( pub enum Test where Block = Block, NodeBlock = Block, @@ -437,7 +458,7 @@ mod tests { } ); - fn make_ext() -> runtime_io::TestExternalities { + fn make_ext() -> sp_io::TestExternalities { GenesisConfig { collective_Instance1: Some(collective::GenesisConfig { members: vec![1, 2, 3], @@ -457,7 +478,7 @@ mod tests { } fn make_proposal(value: u64) -> Call { - Call::System(system::Call::remark(value.encode())) + Call::System(frame_system::Call::remark(value.encode())) } #[test] @@ -564,7 +585,7 @@ mod tests { let proposal = make_proposal(42); assert_noop!( Collective::propose(Origin::signed(42), 3, Box::new(proposal.clone())), - "proposer not a member" + Error::::NotMember ); }); } @@ -578,7 +599,7 @@ mod tests { assert_ok!(Collective::propose(Origin::signed(1), 3, Box::new(proposal.clone()))); assert_noop!( Collective::vote(Origin::signed(42), hash.clone(), 0, true), - "voter not a member", + Error::::NotMember, ); }); } @@ -592,7 +613,7 @@ mod tests { assert_ok!(Collective::propose(Origin::signed(1), 3, Box::new(proposal.clone()))); assert_noop!( Collective::vote(Origin::signed(2), hash.clone(), 1, true), - "mismatched index", + Error::::WrongIndex, ); }); } @@ -610,7 +631,7 @@ mod tests { ); assert_noop!( Collective::vote(Origin::signed(1), hash.clone(), 0, true), - "duplicate vote ignored", + Error::::DuplicateVote, ); assert_ok!(Collective::vote(Origin::signed(1), hash.clone(), 0, false)); assert_eq!( @@ -619,7 +640,7 @@ mod tests { ); assert_noop!( Collective::vote(Origin::signed(1), hash.clone(), 0, false), - "duplicate vote ignored", + Error::::DuplicateVote, ); assert_eq!(System::events(), vec![ @@ -648,6 +669,20 @@ mod tests { }); } + #[test] + fn motions_reproposing_disapproved_works() { + make_ext().execute_with(|| { + System::set_block_number(1); + let proposal = make_proposal(42); + let hash: H256 = proposal.blake2_256().into(); + assert_ok!(Collective::propose(Origin::signed(1), 3, Box::new(proposal.clone()))); + assert_ok!(Collective::vote(Origin::signed(2), hash.clone(), 0, false)); + assert_eq!(Collective::proposals(), vec![]); + assert_ok!(Collective::propose(Origin::signed(1), 2, Box::new(proposal.clone()))); + assert_eq!(Collective::proposals(), vec![hash]); + }); + } + #[test] fn motions_disapproval_works() { make_ext().execute_with(|| { diff --git a/frame/contracts/Cargo.toml b/frame/contracts/Cargo.toml index 2b4536dd8ace637f6a4f0e1c33b7b841da8229ff..c6102d23eabbe0d92c30779e0d1326ba230943b8 100644 --- a/frame/contracts/Cargo.toml +++ b/frame/contracts/Cargo.toml @@ -6,39 +6,38 @@ edition = "2018" [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } -pwasm-utils = { version = "0.11.0", default-features = false } +pwasm-utils = { version = "0.12.0", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -parity-wasm = { version = "0.40.3", default-features = false } -wasmi-validation = { version = "0.2.0", default-features = false } -primitives = { package = "substrate-primitives", path = "../../primitives/core", default-features = false } -sr-primitives = { path = "../../primitives/sr-primitives", default-features = false } -runtime-io = { package = "sr-io", path = "../../primitives/sr-io", default-features = false } -rstd = { package = "sr-std", path = "../../primitives/sr-std", default-features = false } -sandbox = { package = "sr-sandbox", path = "../../primitives/sr-sandbox", default-features = false } -support = { package = "frame-support", path = "../support", default-features = false } -system = { package = "frame-system", path = "../system", default-features = false } +parity-wasm = { version = "0.41.0", default-features = false } +wasmi-validation = { version = "0.3.0", default-features = false } +sp-core = { version = "2.0.0", default-features = false, path = "../../primitives/core" } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" } +sp-io = { version = "2.0.0", default-features = false, path = "../../primitives/io" } +sp-std = { version = "2.0.0", default-features = false, path = "../../primitives/std" } +sp-sandbox = { version = "2.0.0", default-features = false, path = "../../primitives/sandbox" } +frame-support = { version = "2.0.0", default-features = false, path = "../support" } +frame-system = { version = "2.0.0", default-features = false, path = "../system" } [dev-dependencies] wabt = "0.9.2" assert_matches = "1.3.0" hex-literal = "0.2.1" -balances = { package = "pallet-balances", path = "../balances" } -hex = "0.3.2" -timestamp = { package = "pallet-timestamp", path = "../timestamp" } -randomness-collective-flip = { package = "pallet-randomness-collective-flip", path = "../randomness-collective-flip" } +pallet-balances = { version = "2.0.0", path = "../balances" } +pallet-timestamp = { version = "2.0.0", path = "../timestamp" } +pallet-randomness-collective-flip = { version = "2.0.0", path = "../randomness-collective-flip" } [features] default = ["std"] std = [ "serde", "codec/std", - "primitives/std", - "sr-primitives/std", - "runtime-io/std", - "rstd/std", - "sandbox/std", - "support/std", - "system/std", + "sp-core/std", + "sp-runtime/std", + "sp-io/std", + "sp-std/std", + "sp-sandbox/std", + "frame-support/std", + "frame-system/std", "parity-wasm/std", "pwasm-utils/std", "wasmi-validation/std", diff --git a/frame/contracts/rpc/Cargo.toml b/frame/contracts/rpc/Cargo.toml index 06c8776ece77adb2f2563ef533f7b4f01b0ea638..3b5b495b0c7145c43f91c03dbf6ee01ec29e43d6 100644 --- a/frame/contracts/rpc/Cargo.toml +++ b/frame/contracts/rpc/Cargo.toml @@ -5,13 +5,16 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -client = { package = "substrate-client", path = "../../../client/" } codec = { package = "parity-scale-codec", version = "1.0.0" } jsonrpc-core = "14.0.3" jsonrpc-core-client = "14.0.3" jsonrpc-derive = "14.0.3" -primitives = { package = "substrate-primitives", path = "../../../primitives/core" } -rpc-primitives = { package = "substrate-rpc-primitives", path = "../../../primitives/rpc" } +sp-blockchain = { version = "2.0.0", path = "../../../primitives/blockchain" } +sp-core = { version = "2.0.0", path = "../../../primitives/core" } +sp-rpc = { version = "2.0.0", path = "../../../primitives/rpc" } serde = { version = "1.0.101", features = ["derive"] } -sr-primitives = { path = "../../../primitives/sr-primitives" } -pallet-contracts-rpc-runtime-api = { path = "./runtime-api" } +sp-runtime = { version = "2.0.0", path = "../../../primitives/runtime" } +pallet-contracts-rpc-runtime-api = { version = "2.0.0", path = "./runtime-api" } + +[dev-dependencies] +serde_json = "1.0.41" diff --git a/frame/contracts/rpc/runtime-api/Cargo.toml b/frame/contracts/rpc/runtime-api/Cargo.toml index 87749fcd194fb3674afcbcc6f349994d28bd8530..c8e183237cf4366959e4c7650094deb6fb2dc0cb 100644 --- a/frame/contracts/rpc/runtime-api/Cargo.toml +++ b/frame/contracts/rpc/runtime-api/Cargo.toml @@ -5,18 +5,16 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -sr-api = { path = "../../../../primitives/sr-api", default-features = false } +sp-api = { version = "2.0.0", default-features = false, path = "../../../../primitives/api" } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -rstd = { package = "sr-std", path = "../../../../primitives/sr-std", default-features = false } -serde = { version = "1.0.101", optional = true, features = ["derive"] } -sr-primitives = { path = "../../../../primitives/sr-primitives", default-features = false } +sp-std = { version = "2.0.0", default-features = false, path = "../../../../primitives/std" } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../../../primitives/runtime" } [features] default = ["std"] std = [ - "sr-api/std", + "sp-api/std", "codec/std", - "rstd/std", - "serde", - "sr-primitives/std", + "sp-std/std", + "sp-runtime/std", ] diff --git a/frame/contracts/rpc/runtime-api/src/lib.rs b/frame/contracts/rpc/runtime-api/src/lib.rs index 6d9c4a27b1febe9ea41d3bcfd1d4e0f35ab690b5..73e937cf6c458503cb8a10372a416d5e1e63060a 100644 --- a/frame/contracts/rpc/runtime-api/src/lib.rs +++ b/frame/contracts/rpc/runtime-api/src/lib.rs @@ -22,13 +22,12 @@ #![cfg_attr(not(feature = "std"), no_std)] -use rstd::vec::Vec; +use sp_std::vec::Vec; use codec::{Encode, Decode, Codec}; -use sr_primitives::RuntimeDebug; +use sp_runtime::RuntimeDebug; /// A result of execution of a contract. #[derive(Eq, PartialEq, Encode, Decode, RuntimeDebug)] -#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] pub enum ContractExecResult { /// The contract returned successfully. /// @@ -59,7 +58,7 @@ pub enum GetStorageError { IsTombstone, } -sr_api::decl_runtime_apis! { +sp_api::decl_runtime_apis! { /// The API to interact with contracts without using executive. pub trait ContractsApi where AccountId: Codec, diff --git a/frame/contracts/rpc/src/lib.rs b/frame/contracts/rpc/src/lib.rs index 9cc1aef938cfd34d805828b87fc5e73d3d33d3d3..01d346c66a7d957aa2558fbb39773eff24669dfb 100644 --- a/frame/contracts/rpc/src/lib.rs +++ b/frame/contracts/rpc/src/lib.rs @@ -18,14 +18,14 @@ use std::sync::Arc; -use client::blockchain::HeaderBackend; +use sp_blockchain::HeaderBackend; use codec::Codec; use jsonrpc_core::{Error, ErrorCode, Result}; use jsonrpc_derive::rpc; -use primitives::{H256, Bytes}; -use rpc_primitives::number; +use sp_core::{H256, Bytes}; +use sp_rpc::number; use serde::{Deserialize, Serialize}; -use sr_primitives::{ +use sp_runtime::{ generic::BlockId, traits::{Block as BlockT, ProvideRuntimeApi}, }; @@ -39,7 +39,16 @@ const RUNTIME_ERROR: i64 = 1; const CONTRACT_DOESNT_EXIST: i64 = 2; const CONTRACT_IS_A_TOMBSTONE: i64 = 3; -// A private newtype for converting `GetStorageError` into an RPC error. +/// A rough estimate of how much gas a decent hardware consumes per second, +/// using native execution. +/// This value is used to set the upper bound for maximal contract calls to +/// prevent blocking the RPC for too long. +/// +/// Based on W3F research spreadsheet: +/// https://docs.google.com/spreadsheets/d/1h0RqncdqiWI4KgxO0z9JIpZEJESXjX_ZCK6LFX6veDo/view +const GAS_PER_SECOND: u64 = 1_000_000_000; + +/// A private newtype for converting `GetStorageError` into an RPC error. struct GetStorageError(runtime_api::GetStorageError); impl From for Error { fn from(e: GetStorageError) -> Error { @@ -71,6 +80,35 @@ pub struct CallRequest { input_data: Bytes, } +/// An RPC serializable result of contract execution +#[derive(Serialize, Deserialize)] +#[serde(deny_unknown_fields)] +#[serde(rename_all = "camelCase")] +pub enum RpcContractExecResult { + /// Successful execution + Success { + /// Status code + status: u8, + /// Output data + data: Bytes, + }, + /// Error execution + Error(()), +} + +impl From for RpcContractExecResult { + fn from(r: ContractExecResult) -> Self { + match r { + ContractExecResult::Success { status, data } => { + RpcContractExecResult::Success { status, data: data.into() } + }, + ContractExecResult::Error => { + RpcContractExecResult::Error(()) + }, + } + } +} + /// Contracts RPC methods. #[rpc] pub trait ContractsApi { @@ -85,7 +123,7 @@ pub trait ContractsApi { &self, call_request: CallRequest, at: Option, - ) -> Result; + ) -> Result; /// Returns the value under a specified storage `key` in a contract given by `address` param, /// or `None` if it is not set. @@ -129,7 +167,7 @@ where &self, call_request: CallRequest, at: Option<::Hash>, - ) -> Result { + ) -> Result { let api = self.client.runtime_api(); let at = BlockId::hash(at.unwrap_or_else(|| // If the block hash is not supplied assume the best block. @@ -148,6 +186,19 @@ where data: None, })?; + let max_gas_limit = 5 * GAS_PER_SECOND; + if gas_limit > max_gas_limit { + return Err(Error { + code: ErrorCode::InvalidParams, + message: format!( + "Requested gas limit is greater than maximum allowed: {} > {}", + gas_limit, + max_gas_limit + ), + data: None, + }); + } + let exec_result = api .call(&at, origin, dest, value, gas_limit, input_data.to_vec()) .map_err(|e| Error { @@ -156,7 +207,7 @@ where data: Some(format!("{:?}", e).into()), })?; - Ok(exec_result) + Ok(exec_result.into()) } fn get_storage( @@ -185,3 +236,20 @@ where Ok(get_storage_result) } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn should_serialize_deserialize_properly() { + fn test(expected: &str) { + let res: RpcContractExecResult = serde_json::from_str(expected).unwrap(); + let actual = serde_json::to_string(&res).unwrap(); + assert_eq!(actual, expected); + } + + test(r#"{"success":{"status":5,"data":"0x1234"}}"#); + test(r#"{"error":null}"#); + } +} diff --git a/frame/contracts/src/account_db.rs b/frame/contracts/src/account_db.rs index 5aa3a64fd9bc820d98fc4541f4b9666683594204..866733cefaa90234c6099ab5b75f7aeaaabd101f 100644 --- a/frame/contracts/src/account_db.rs +++ b/frame/contracts/src/account_db.rs @@ -21,14 +21,14 @@ use super::{ TrieIdGenerator, }; use crate::exec::StorageKey; -use rstd::cell::RefCell; -use rstd::collections::btree_map::{BTreeMap, Entry}; -use rstd::prelude::*; -use runtime_io::hashing::blake2_256; -use sr_primitives::traits::{Bounded, Zero}; -use support::traits::{Currency, Get, Imbalance, SignedImbalance, UpdateBalanceOutcome}; -use support::{storage::child, StorageMap}; -use system; +use sp_std::cell::RefCell; +use sp_std::collections::btree_map::{BTreeMap, Entry}; +use sp_std::prelude::*; +use sp_io::hashing::blake2_256; +use sp_runtime::traits::{Bounded, Zero}; +use frame_support::traits::{Currency, Get, Imbalance, SignedImbalance, UpdateBalanceOutcome}; +use frame_support::{storage::child, StorageMap}; +use frame_system; // Note: we don't provide Option because we can't create // the trie_id in the overlay, thus we provide an overlay on the fields @@ -100,7 +100,7 @@ impl Default for ChangeEntry { } } -pub type ChangeSet = BTreeMap<::AccountId, ChangeEntry>; +pub type ChangeSet = BTreeMap<::AccountId, ChangeEntry>; pub trait AccountDb { /// Account is used when overlayed otherwise trie_id must be provided. @@ -128,7 +128,7 @@ impl AccountDb for DirectAccountDb { trie_id: Option<&TrieId>, location: &StorageKey ) -> Option> { - trie_id.and_then(|id| child::get_raw(id, &blake2_256(location))) + trie_id.and_then(|id| child::get_raw(id, crate::trie_unique_id(&id[..]), &blake2_256(location))) } fn get_code_hash(&self, account: &T::AccountId) -> Option> { >::get(account).and_then(|i| i.as_alive().map(|i| i.code_hash)) @@ -173,18 +173,18 @@ impl AccountDb for DirectAccountDb { (false, Some(info), _) => info, // Existing contract is being removed. (true, Some(info), None) => { - child::kill_storage(&info.trie_id); + child::kill_storage(&info.trie_id, info.child_trie_unique_id()); >::remove(&address); continue; } // Existing contract is being replaced by a new one. (true, Some(info), Some(code_hash)) => { - child::kill_storage(&info.trie_id); + child::kill_storage(&info.trie_id, info.child_trie_unique_id()); AliveContractInfo:: { code_hash, storage_size: T::StorageSizeOffset::get(), trie_id: ::TrieIdGenerator::trie_id(&address), - deduct_block: >::block_number(), + deduct_block: >::block_number(), rent_allowance: >::max_value(), last_write: None, } @@ -195,7 +195,7 @@ impl AccountDb for DirectAccountDb { code_hash, storage_size: T::StorageSizeOffset::get(), trie_id: ::TrieIdGenerator::trie_id(&address), - deduct_block: >::block_number(), + deduct_block: >::block_number(), rent_allowance: >::max_value(), last_write: None, } @@ -213,18 +213,22 @@ impl AccountDb for DirectAccountDb { } if !changed.storage.is_empty() { - new_info.last_write = Some(>::block_number()); + new_info.last_write = Some(>::block_number()); } for (k, v) in changed.storage.into_iter() { - if let Some(value) = child::get_raw(&new_info.trie_id[..], &blake2_256(&k)) { + if let Some(value) = child::get_raw( + &new_info.trie_id[..], + new_info.child_trie_unique_id(), + &blake2_256(&k), + ) { new_info.storage_size -= value.len() as u32; } if let Some(value) = v { new_info.storage_size += value.len() as u32; - child::put_raw(&new_info.trie_id[..], &blake2_256(&k), &value[..]); + child::put_raw(&new_info.trie_id[..], new_info.child_trie_unique_id(), &blake2_256(&k), &value[..]); } else { - child::kill(&new_info.trie_id[..], &blake2_256(&k)); + child::kill(&new_info.trie_id[..], new_info.child_trie_unique_id(), &blake2_256(&k)); } } diff --git a/frame/contracts/src/exec.rs b/frame/contracts/src/exec.rs index b71f54b18bd95016e90512cd9fba0f4091505021..261e4297b778b732fd4f12dbad63c0776c5fef8d 100644 --- a/frame/contracts/src/exec.rs +++ b/frame/contracts/src/exec.rs @@ -20,22 +20,22 @@ use crate::account_db::{AccountDb, DirectAccountDb, OverlayAccountDb}; use crate::gas::{Gas, GasMeter, Token, approx_gas_for_balance}; use crate::rent; -use rstd::prelude::*; -use sr_primitives::traits::{Bounded, CheckedAdd, CheckedSub, Zero}; -use support::{ - storage::unhashed, +use sp_std::prelude::*; +use sp_runtime::traits::{Bounded, CheckedAdd, CheckedSub, Zero}; +use frame_support::{ + storage::unhashed, dispatch::DispatchError, traits::{WithdrawReason, Currency, Time, Randomness}, }; -pub type AccountIdOf = ::AccountId; +pub type AccountIdOf = ::AccountId; pub type CallOf = ::Call; pub type MomentOf = <::Time as Time>::Moment; -pub type SeedOf = ::Hash; -pub type BlockNumberOf = ::BlockNumber; +pub type SeedOf = ::Hash; +pub type BlockNumberOf = ::BlockNumber; pub type StorageKey = [u8; 32]; /// A type that represents a topic of an event. At the moment a hash is used. -pub type TopicOf = ::Hash; +pub type TopicOf = ::Hash; /// A status code return to the source of a contract call or instantiation indicating success or /// failure. A code of 0 indicates success and that changes are applied. All other codes indicate @@ -64,9 +64,9 @@ impl ExecReturnValue { /// VM-specific errors during execution (eg. division by 0, OOB access, failure to satisfy some /// precondition of a system call, etc.) or errors with the orchestration (eg. out-of-gas errors, a /// non-existent destination contract, etc.). -#[cfg_attr(test, derive(sr_primitives::RuntimeDebug))] +#[cfg_attr(test, derive(sp_runtime::RuntimeDebug))] pub struct ExecError { - pub reason: &'static str, + pub reason: DispatchError, /// This is an allocated buffer that may be reused. The buffer must be cleared explicitly /// before reuse. pub buffer: Vec, @@ -83,7 +83,9 @@ macro_rules! try_or_exec_error { ($e:expr, $buffer:expr) => { match $e { Ok(val) => val, - Err(reason) => return Err($crate::exec::ExecError { reason, buffer: $buffer }), + Err(reason) => return Err( + $crate::exec::ExecError { reason: reason.into(), buffer: $buffer } + ), } } } @@ -239,7 +241,7 @@ impl Token for ExecFeeToken { } #[cfg_attr(any(feature = "std", test), derive(PartialEq, Eq, Clone))] -#[derive(sr_primitives::RuntimeDebug)] +#[derive(sp_runtime::RuntimeDebug)] pub enum DeferredAction { DepositEvent { /// A list of topics this event will be deposited with. @@ -304,7 +306,7 @@ where vm: &vm, loader: &loader, timestamp: T::Time::now(), - block_number: >::block_number(), + block_number: >::block_number(), } } @@ -336,7 +338,7 @@ where ) -> ExecResult { if self.depth == self.config.max_depth as usize { return Err(ExecError { - reason: "reached maximum depth, cannot make a call", + reason: "reached maximum depth, cannot make a call".into(), buffer: input_data, }); } @@ -346,7 +348,7 @@ where .is_out_of_gas() { return Err(ExecError { - reason: "not enough gas to pay base call fee", + reason: "not enough gas to pay base call fee".into(), buffer: input_data, }); } @@ -359,7 +361,7 @@ where // Calls to dead contracts always fail. if let Some(ContractInfo::Tombstone(_)) = contract_info { return Err(ExecError { - reason: "contract has been evicted", + reason: "contract has been evicted".into(), buffer: input_data, }); }; @@ -404,7 +406,7 @@ where .expect("a nested execution context must have a parent; qed"); if parent.is_live(&dest) { return Err(ExecError { - reason: "contract cannot be destroyed during recursive execution", + reason: "contract cannot be destroyed during recursive execution".into(), buffer: output.data, }); } @@ -428,7 +430,7 @@ where ) -> Result<(T::AccountId, ExecReturnValue), ExecError> { if self.depth == self.config.max_depth as usize { return Err(ExecError { - reason: "reached maximum depth, cannot instantiate", + reason: "reached maximum depth, cannot instantiate".into(), buffer: input_data, }); } @@ -438,7 +440,7 @@ where .is_out_of_gas() { return Err(ExecError { - reason: "not enough gas to pay base instantiate fee", + reason: "not enough gas to pay base instantiate fee".into(), buffer: input_data, }); } @@ -488,7 +490,7 @@ where // Error out if insufficient remaining balance. if nested.overlay.get_balance(&dest) < nested.config.existential_deposit { return Err(ExecError { - reason: "insufficient remaining balance", + reason: "insufficient remaining balance".into(), buffer: output.data, }); } @@ -603,7 +605,7 @@ fn transfer<'a, T: Trait, V: Vm, L: Loader>( dest: &T::AccountId, value: BalanceOf, ctx: &mut ExecutionContext<'a, T, V, L>, -) -> Result<(), &'static str> { +) -> Result<(), DispatchError> { use self::TransferCause::*; use self::TransferFeeKind::*; @@ -637,23 +639,28 @@ fn transfer<'a, T: Trait, V: Vm, L: Loader>( }; if gas_meter.charge(ctx.config, token).is_out_of_gas() { - return Err("not enough gas to pay transfer fee"); + Err("not enough gas to pay transfer fee")? } // We allow balance to go below the existential deposit here: let from_balance = ctx.overlay.get_balance(transactor); let new_from_balance = match from_balance.checked_sub(&value) { Some(b) => b, - None => return Err("balance too low to send value"), + None => Err("balance too low to send value")?, }; if would_create && value < ctx.config.existential_deposit { - return Err("value too low to create account"); + Err("value too low to create account")? } - T::Currency::ensure_can_withdraw(transactor, value, WithdrawReason::Transfer.into(), new_from_balance)?; + T::Currency::ensure_can_withdraw( + transactor, + value, + WithdrawReason::Transfer.into(), + new_from_balance, + )?; let new_to_balance = match to_balance.checked_add(&value) { Some(b) => b, - None => return Err("destination balance too high to receive value"), + None => Err("destination balance too high to receive value")?, }; if transactor != dest { @@ -821,6 +828,7 @@ mod tests { }; use std::{cell::RefCell, rc::Rc, collections::HashMap, marker::PhantomData}; use assert_matches::assert_matches; + use sp_runtime::DispatchError; const ALICE: u64 = 1; const BOB: u64 = 2; @@ -871,7 +879,7 @@ mod tests { fn insert(&mut self, f: impl Fn(MockCtx) -> ExecResult + 'a) -> CodeHash { // Generate code hashes as monotonically increasing values. - let code_hash = ::Hash::from_low_u64_be(self.counter); + let code_hash = ::Hash::from_low_u64_be(self.counter); self.counter += 1; self.map.insert(code_hash, MockExecutable::new(f)); @@ -1176,7 +1184,10 @@ mod tests { assert_matches!( result, - Err(ExecError { reason: "balance too low to send value", buffer: _ }) + Err(ExecError { + reason: DispatchError::Other("balance too low to send value"), + buffer: _, + }) ); assert_eq!(ctx.overlay.get_balance(&origin), 0); assert_eq!(ctx.overlay.get_balance(&dest), 0); @@ -1313,7 +1324,10 @@ mod tests { // Verify that we've got proper error and set `reached_bottom`. assert_matches!( r, - Err(ExecError { reason: "reached maximum depth, cannot make a call", buffer: _ }) + Err(ExecError { + reason: DispatchError::Other("reached maximum depth, cannot make a call"), + buffer: _, + }) ); *reached_bottom = true; } else { @@ -1583,7 +1597,7 @@ mod tests { let mut loader = MockLoader::empty(); let dummy_ch = loader.insert( - |_| Err(ExecError { reason: "It's a trap!", buffer: Vec::new() }) + |_| Err(ExecError { reason: "It's a trap!".into(), buffer: Vec::new() }) ); let instantiator_ch = loader.insert({ let dummy_ch = dummy_ch.clone(); @@ -1596,7 +1610,7 @@ mod tests { ctx.gas_meter, vec![] ), - Err(ExecError { reason: "It's a trap!", buffer: _ }) + Err(ExecError { reason: DispatchError::Other("It's a trap!"), buffer: _ }) ); exec_success() diff --git a/frame/contracts/src/gas.rs b/frame/contracts/src/gas.rs index 64997fbe81fdf6c697b752dbe62afa11c64a6726..af9236e2e5e5115ef1e8b9b6222cd26fde4c7523 100644 --- a/frame/contracts/src/gas.rs +++ b/frame/contracts/src/gas.rs @@ -15,12 +15,13 @@ // along with Substrate. If not, see . use crate::{GasSpent, Module, Trait, BalanceOf, NegativeImbalanceOf}; -use rstd::convert::TryFrom; -use sr_primitives::traits::{ +use sp_std::convert::TryFrom; +use sp_runtime::traits::{ CheckedMul, Zero, SaturatedConversion, SimpleArithmetic, UniqueSaturatedInto, }; -use support::{ +use frame_support::{ traits::{Currency, ExistenceRequirement, Imbalance, OnUnbalanced, WithdrawReason}, StorageValue, + dispatch::DispatchError, }; #[cfg(test)] @@ -201,7 +202,7 @@ impl GasMeter { pub fn buy_gas( transactor: &T::AccountId, gas_limit: Gas, -) -> Result<(GasMeter, NegativeImbalanceOf), &'static str> { +) -> Result<(GasMeter, NegativeImbalanceOf), DispatchError> { // Buy the specified amount of gas. let gas_price = >::gas_price(); let cost = if gas_price.is_zero() { diff --git a/frame/contracts/src/lib.rs b/frame/contracts/src/lib.rs index e84214a0195b5310b33184ce43ab137d4365e14a..d1bea0ca98affb39543fb65d28efb57559276d21 100644 --- a/frame/contracts/src/lib.rs +++ b/frame/contracts/src/lib.rs @@ -108,28 +108,28 @@ pub use crate::exec::{ExecResult, ExecReturnValue, ExecError, StatusCode}; #[cfg(feature = "std")] use serde::{Serialize, Deserialize}; -use primitives::crypto::UncheckedFrom; -use rstd::{prelude::*, marker::PhantomData, fmt::Debug}; +use sp_core::crypto::UncheckedFrom; +use sp_std::{prelude::*, marker::PhantomData, fmt::Debug}; use codec::{Codec, Encode, Decode}; -use runtime_io::hashing::blake2_256; -use sr_primitives::{ +use sp_io::hashing::blake2_256; +use sp_runtime::{ traits::{Hash, StaticLookup, Zero, MaybeSerializeDeserialize, Member, SignedExtension}, transaction_validity::{ ValidTransaction, InvalidTransaction, TransactionValidity, TransactionValidityError, }, RuntimeDebug, }; -use support::dispatch::{Result, Dispatchable}; -use support::{ +use frame_support::dispatch::{DispatchResult, Dispatchable}; +use frame_support::{ Parameter, decl_module, decl_event, decl_storage, storage::child, parameter_types, IsSubType, weights::DispatchInfo, }; -use support::traits::{OnFreeBalanceZero, OnUnbalanced, Currency, Get, Time, Randomness}; -use system::{ensure_signed, RawOrigin, ensure_root}; -use primitives::storage::well_known_keys::CHILD_STORAGE_KEY_PREFIX; +use frame_support::traits::{OnFreeBalanceZero, OnUnbalanced, Currency, Get, Time, Randomness}; +use frame_system::{self as system, ensure_signed, RawOrigin, ensure_root}; +use sp_core::storage::well_known_keys::CHILD_STORAGE_KEY_PREFIX; -pub type CodeHash = ::Hash; +pub type CodeHash = ::Hash; pub type TrieId = Vec; /// A function that generates an `AccountId` for a contract upon instantiation. @@ -203,7 +203,7 @@ impl ContractInfo { } pub type AliveContractInfo = - RawAliveContractInfo, BalanceOf, ::BlockNumber>; + RawAliveContractInfo, BalanceOf, ::BlockNumber>; /// Information for managing an account and its sub trie abstraction. /// This is the required info to cache for an account. @@ -223,8 +223,21 @@ pub struct RawAliveContractInfo { pub last_write: Option, } +impl RawAliveContractInfo { + /// Associated child trie unique id is built from the hash part of the trie id. + pub fn child_trie_unique_id(&self) -> child::ChildInfo { + trie_unique_id(&self.trie_id[..]) + } +} + +/// Associated child trie unique id is built from the hash part of the trie id. +pub(crate) fn trie_unique_id(trie_id: &[u8]) -> child::ChildInfo { + let start = CHILD_STORAGE_KEY_PREFIX.len() + b"default:".len(); + child::ChildInfo::new_default(&trie_id[start ..]) +} + pub type TombstoneContractInfo = - RawTombstoneContractInfo<::Hash, ::Hashing>; + RawTombstoneContractInfo<::Hash, ::Hashing>; #[derive(Encode, Decode, PartialEq, Eq, RuntimeDebug)] pub struct RawTombstoneContractInfo(H, PhantomData); @@ -233,7 +246,7 @@ impl RawTombstoneContractInfo where H: Member + MaybeSerializeDeserialize+ Debug + AsRef<[u8]> + AsMut<[u8]> + Copy + Default - + rstd::hash::Hash + Codec, + + sp_std::hash::Hash + Codec, Hasher: Hash, { fn new(storage_root: &[u8], code_hash: H) -> Self { @@ -290,9 +303,9 @@ where } } -pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; pub type NegativeImbalanceOf = - <::Currency as Currency<::AccountId>>::NegativeImbalance; + <::Currency as Currency<::AccountId>>::NegativeImbalance; parameter_types! { /// A reasonable default value for [`Trait::SignedClaimedHandicap`]. @@ -329,16 +342,16 @@ parameter_types! { pub const DefaultBlockGasLimit: u32 = 10_000_000; } -pub trait Trait: system::Trait { +pub trait Trait: frame_system::Trait { type Currency: Currency; type Time: Time; type Randomness: Randomness; /// The outer call dispatch type. - type Call: Parameter + Dispatchable::Origin> + IsSubType, Self>; + type Call: Parameter + Dispatchable::Origin> + IsSubType, Self>; /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// A function type to get the contract address given the instantiator. type DetermineContractAddress: ContractAddressFor, Self::AccountId>; @@ -456,7 +469,7 @@ impl ComputeDispatchFee<::Call, BalanceOf> for DefaultD decl_module! { /// Contracts module. - pub struct Module for enum Call where origin: ::Origin { + pub struct Module for enum Call where origin: ::Origin { /// Number of block delay an extrinsic claim surcharge has. /// /// When claim surcharge is called by an extrinsic the rent is checked @@ -526,10 +539,10 @@ decl_module! { /// Updates the schedule for metering contracts. /// /// The schedule must have a greater version than the stored schedule. - pub fn update_schedule(origin, schedule: Schedule) -> Result { + pub fn update_schedule(origin, schedule: Schedule) -> DispatchResult { ensure_root(origin)?; if >::current_schedule().version >= schedule.version { - return Err("new schedule must have a greater version than current"); + Err("new schedule must have a greater version than current")? } Self::deposit_event(RawEvent::ScheduleUpdated(schedule.version)); @@ -544,7 +557,7 @@ decl_module! { origin, #[compact] gas_limit: Gas, code: Vec - ) -> Result { + ) -> DispatchResult { let origin = ensure_signed(origin)?; let (mut gas_meter, imbalance) = gas::buy_gas::(&origin, gas_limit)?; @@ -557,7 +570,7 @@ decl_module! { gas::refund_unused_gas::(&origin, gas_meter, imbalance); - result.map(|_| ()) + result.map(|_| ()).map_err(Into::into) } /// Makes a call to an account, optionally transferring some balance. @@ -573,13 +586,13 @@ decl_module! { #[compact] value: BalanceOf, #[compact] gas_limit: Gas, data: Vec - ) -> Result { + ) -> DispatchResult { let origin = ensure_signed(origin)?; let dest = T::Lookup::lookup(dest)?; Self::bare_call(origin, dest, value, gas_limit, data) .map(|_| ()) - .map_err(|e| e.reason) + .map_err(|e| e.reason.into()) } /// Instantiates a new contract from the `codehash` generated by `put_code`, optionally transferring some balance. @@ -598,7 +611,7 @@ decl_module! { #[compact] gas_limit: Gas, code_hash: CodeHash, data: Vec - ) -> Result { + ) -> DispatchResult { let origin = ensure_signed(origin)?; Self::execute_wasm(origin, gas_limit, |ctx, gas_meter| { @@ -606,7 +619,7 @@ decl_module! { .map(|(_address, output)| output) }) .map(|_| ()) - .map_err(|e| e.reason) + .map_err(|e| e.reason.into()) } /// Allows block producers to claim a small reward for evicting a contract. If a block producer @@ -617,16 +630,16 @@ decl_module! { fn claim_surcharge(origin, dest: T::AccountId, aux_sender: Option) { let origin = origin.into(); let (signed, rewarded) = match (origin, aux_sender) { - (Ok(system::RawOrigin::Signed(account)), None) => { + (Ok(frame_system::RawOrigin::Signed(account)), None) => { (true, account) }, - (Ok(system::RawOrigin::None), Some(aux_sender)) => { + (Ok(frame_system::RawOrigin::None), Some(aux_sender)) => { (false, aux_sender) }, - _ => return Err( + _ => Err( "Invalid surcharge claim: origin must be signed or \ inherent and auxiliary sender only provided on inherent" - ), + )?, }; // Add some advantage for block producers (who send unsigned extrinsics) by @@ -680,7 +693,7 @@ impl Module { pub fn get_storage( address: T::AccountId, key: [u8; 32], - ) -> rstd::result::Result>, GetStorageError> { + ) -> sp_std::result::Result>, GetStorageError> { let contract_info = >::get(&address) .ok_or(GetStorageError::ContractDoesntExist)? .get_alive() @@ -738,7 +751,7 @@ impl Module { DepositEvent { topics, event, - } => >::deposit_event_indexed( + } => >::deposit_event_indexed( &*topics, ::Event::from(event).into(), ), @@ -770,15 +783,15 @@ impl Module { code_hash: CodeHash, rent_allowance: BalanceOf, delta: Vec - ) -> Result { + ) -> DispatchResult { let mut origin_contract = >::get(&origin) .and_then(|c| c.get_alive()) .ok_or("Cannot restore from inexisting or tombstone contract")?; - let current_block = >::block_number(); + let current_block = >::block_number(); if origin_contract.last_write == Some(current_block) { - return Err("Origin TrieId written in the current block"); + Err("Origin TrieId written in the current block")? } let dest_tombstone = >::get(&dest) @@ -793,8 +806,17 @@ impl Module { let key_values_taken = delta.iter() .filter_map(|key| { - child::get_raw(&origin_contract.trie_id, &blake2_256(key)).map(|value| { - child::kill(&origin_contract.trie_id, &blake2_256(key)); + child::get_raw( + &origin_contract.trie_id, + origin_contract.child_trie_unique_id(), + &blake2_256(key), + ).map(|value| { + child::kill( + &origin_contract.trie_id, + origin_contract.child_trie_unique_id(), + &blake2_256(key), + ); + (key, value) }) }) @@ -803,16 +825,23 @@ impl Module { let tombstone = >::new( // This operation is cheap enough because last_write (delta not included) // is not this block as it has been checked earlier. - &runtime_io::storage::child_root(&origin_contract.trie_id)[..], + &child::child_root( + &origin_contract.trie_id, + )[..], code_hash, ); if tombstone != dest_tombstone { for (key, value) in key_values_taken { - child::put_raw(&origin_contract.trie_id, &blake2_256(key), &value); + child::put_raw( + &origin_contract.trie_id, + origin_contract.child_trie_unique_id(), + &blake2_256(key), + &value, + ); } - return Err("Tombstones don't match"); + return Err("Tombstones don't match".into()); } origin_contract.storage_size -= key_values_taken.iter() @@ -841,8 +870,8 @@ decl_event! { pub enum Event where Balance = BalanceOf, - ::AccountId, - ::Hash + ::AccountId, + ::Hash { /// Transfer happened `from` to `to` with given `value` as part of a `call` or `instantiate`. Transfer(AccountId, AccountId, Balance), @@ -887,7 +916,7 @@ decl_storage! { impl OnFreeBalanceZero for Module { fn on_free_balance_zero(who: &T::AccountId) { if let Some(ContractInfo::Alive(info)) = >::take(who) { - child::kill_storage(&info.trie_id); + child::kill_storage(&info.trie_id, info.child_trie_unique_id()); } } } @@ -1018,14 +1047,14 @@ impl Default for CheckBlockGasLimit { } } -impl rstd::fmt::Debug for CheckBlockGasLimit { +impl sp_std::fmt::Debug for CheckBlockGasLimit { #[cfg(feature = "std")] - fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { write!(f, "CheckBlockGasLimit") } #[cfg(not(feature = "std"))] - fn fmt(&self, _: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { Ok(()) } } @@ -1037,7 +1066,7 @@ impl SignedExtension for CheckBlockGasLimit { type DispatchInfo = DispatchInfo; type Pre = (); - fn additional_signed(&self) -> rstd::result::Result<(), TransactionValidityError> { Ok(()) } + fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { Ok(()) } fn validate( &self, diff --git a/frame/contracts/src/rent.rs b/frame/contracts/src/rent.rs index e286ce307fcc86f4aa5c60b10d88114f76a95c06..c75dd97ff3d61e07ad1cc72e420c9174a555368e 100644 --- a/frame/contracts/src/rent.rs +++ b/frame/contracts/src/rent.rs @@ -15,10 +15,11 @@ // along with Substrate. If not, see . use crate::{BalanceOf, ContractInfo, ContractInfoOf, TombstoneContractInfo, Trait, AliveContractInfo}; -use sr_primitives::traits::{Bounded, CheckedDiv, CheckedMul, Saturating, Zero, +use sp_runtime::traits::{Bounded, CheckedDiv, CheckedMul, Saturating, Zero, SaturatedConversion}; -use support::traits::{Currency, ExistenceRequirement, Get, WithdrawReason, OnUnbalanced}; -use support::StorageMap; +use frame_support::traits::{Currency, ExistenceRequirement, Get, WithdrawReason, OnUnbalanced}; +use frame_support::StorageMap; +use frame_support::storage::child; #[derive(PartialEq, Eq, Copy, Clone)] #[must_use] @@ -57,7 +58,7 @@ fn try_evict_or_and_pay_rent( Some(ContractInfo::Alive(contract)) => contract, }; - let current_block_number = >::block_number(); + let current_block_number = >::block_number(); // How much block has passed since the last deduction for the contract. let blocks_passed = { @@ -99,7 +100,7 @@ fn try_evict_or_and_pay_rent( if balance < subsistence_threshold { // The contract cannot afford to leave a tombstone, so remove the contract info altogether. >::remove(account); - runtime_io::storage::child_storage_kill(&contract.trie_id); + child::kill_storage(&contract.trie_id, contract.child_trie_unique_id()); return (RentOutcome::Evicted, None); } @@ -146,7 +147,9 @@ fn try_evict_or_and_pay_rent( // threshold, so it leaves a tombstone. // Note: this operation is heavy. - let child_storage_root = runtime_io::storage::child_root(&contract.trie_id); + let child_storage_root = child::child_root( + &contract.trie_id, + ); let tombstone = >::new( &child_storage_root[..], @@ -155,7 +158,7 @@ fn try_evict_or_and_pay_rent( let tombstone_info = ContractInfo::Tombstone(tombstone); >::insert(account, &tombstone_info); - runtime_io::storage::child_storage_kill(&contract.trie_id); + child::kill_storage(&contract.trie_id, contract.child_trie_unique_id()); return (RentOutcome::Evicted, Some(tombstone_info)); } diff --git a/frame/contracts/src/tests.rs b/frame/contracts/src/tests.rs index 5532a0cc9aad32b0d604fc65380e36bf3ddf858c..7cf86b31c73029809faa89177472b187f83b4134 100644 --- a/frame/contracts/src/tests.rs +++ b/frame/contracts/src/tests.rs @@ -27,34 +27,37 @@ use crate::{ use assert_matches::assert_matches; use hex_literal::*; use codec::{Decode, Encode, KeyedVec}; -use sr_primitives::{ +use sp_runtime::{ Perbill, BuildStorage, transaction_validity::{InvalidTransaction, ValidTransaction}, traits::{BlakeTwo256, Hash, IdentityLookup, SignedExtension}, testing::{Digest, DigestItem, Header, UintAuthorityId, H256}, }; -use support::{ +use frame_support::{ assert_ok, assert_err, impl_outer_dispatch, impl_outer_event, impl_outer_origin, parameter_types, storage::child, StorageMap, StorageValue, traits::{Currency, Get}, - weights::{DispatchInfo, DispatchClass}, + weights::{DispatchInfo, DispatchClass, Weight}, }; use std::{cell::RefCell, sync::atomic::{AtomicUsize, Ordering}}; -use primitives::storage::well_known_keys; -use system::{self, EventRecord, Phase}; +use sp_core::storage::well_known_keys; +use frame_system::{self as system, EventRecord, Phase}; mod contract { // Re-export contents of the root. This basically // needs to give a name for the current crate. // This hack is required for `impl_outer_event!`. pub use super::super::*; - use support::impl_outer_event; + use frame_support::impl_outer_event; } + +use pallet_balances as balances; + impl_outer_event! { pub enum MetaEvent for Test { balances, contract, } } impl_outer_origin! { - pub enum Origin for Test { } + pub enum Origin for Test where system = frame_system { } } impl_outer_dispatch! { pub enum Call for Test where origin: Origin { @@ -94,11 +97,11 @@ impl Get for BlockGasLimit { pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockWeight: Weight = 1024; pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } -impl system::Trait for Test { +impl frame_system::Trait for Test { type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -114,8 +117,9 @@ impl system::Trait for Test { type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; type Version = (); + type ModuleToIndex = (); } -impl balances::Trait for Test { +impl pallet_balances::Trait for Test { type Balance = u64; type OnFreeBalanceZero = Contract; type OnNewAccount = (); @@ -129,7 +133,7 @@ impl balances::Trait for Test { parameter_types! { pub const MinimumPeriod: u64 = 1; } -impl timestamp::Trait for Test { +impl pallet_timestamp::Trait for Test { type Moment = u64; type OnTimestampSet = (); type MinimumPeriod = MinimumPeriod; @@ -178,11 +182,11 @@ impl Trait for Test { type BlockGasLimit = BlockGasLimit; } -type Balances = balances::Module; -type Timestamp = timestamp::Module; +type Balances = pallet_balances::Module; +type Timestamp = pallet_timestamp::Module; type Contract = Module; -type System = system::Module; -type Randomness = randomness_collective_flip::Module; +type System = frame_system::Module; +type Randomness = pallet_randomness_collective_flip::Module; pub struct DummyContractAddressFor; impl ContractAddressFor for DummyContractAddressFor { @@ -194,7 +198,7 @@ impl ContractAddressFor for DummyContractAddressFor { pub struct DummyTrieIdGenerator; impl TrieIdGenerator for DummyTrieIdGenerator { fn trie_id(account_id: &u64) -> TrieId { - use primitives::storage::well_known_keys; + use sp_core::storage::well_known_keys; let new_seed = super::AccountCounter::mutate(|v| { *v = v.wrapping_add(1); @@ -268,10 +272,10 @@ impl ExtBuilder { INSTANTIATION_FEE.with(|v| *v.borrow_mut() = self.instantiation_fee); BLOCK_GAS_LIMIT.with(|v| *v.borrow_mut() = self.block_gas_limit); } - pub fn build(self) -> runtime_io::TestExternalities { + pub fn build(self) -> sp_io::TestExternalities { self.set_associated_consts(); - let mut t = system::GenesisConfig::default().build_storage::().unwrap(); - balances::GenesisConfig:: { + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); + pallet_balances::GenesisConfig:: { balances: vec![], vesting: vec![], }.assimilate_storage(&mut t).unwrap(); @@ -282,14 +286,14 @@ impl ExtBuilder { }, gas_price: self.gas_price, }.assimilate_storage(&mut t).unwrap(); - runtime_io::TestExternalities::new(t) + sp_io::TestExternalities::new(t) } } /// Generate Wasm binary and code hash from wabt source. fn compile_module(wabt_module: &str) -> Result<(Vec, ::Output), wabt::Error> - where T: system::Trait + where T: frame_system::Trait { let wasm = wabt::wat2wasm(wabt_module)?; let code_hash = T::Hashing::hash(&wasm); @@ -426,7 +430,7 @@ fn instantiate_and_call_and_deposit_event() { assert_eq!(System::events(), vec![ EventRecord { phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::balances(balances::RawEvent::NewAccount(1, 1_000_000)), + event: MetaEvent::balances(pallet_balances::RawEvent::NewAccount(1, 1_000_000)), topics: vec![], }, EventRecord { @@ -437,7 +441,7 @@ fn instantiate_and_call_and_deposit_event() { EventRecord { phase: Phase::ApplyExtrinsic(0), event: MetaEvent::balances( - balances::RawEvent::NewAccount(BOB, 100) + pallet_balances::RawEvent::NewAccount(BOB, 100) ), topics: vec![], }, @@ -484,7 +488,7 @@ const CODE_DISPATCH_CALL: &str = r#" fn dispatch_call() { // This test can fail due to the encoding changes. In case it becomes too annoying // let's rewrite so as we use this module controlled call or we serialize it in runtime. - let encoded = Encode::encode(&Call::Balances(balances::Call::transfer(CHARLIE, 50))); + let encoded = Encode::encode(&Call::Balances(pallet_balances::Call::transfer(CHARLIE, 50))); assert_eq!(&encoded[..], &hex!("00000300000000000000C8")[..]); let (wasm, code_hash) = compile_module::(CODE_DISPATCH_CALL).unwrap(); @@ -499,7 +503,7 @@ fn dispatch_call() { assert_eq!(System::events(), vec![ EventRecord { phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::balances(balances::RawEvent::NewAccount(1, 1_000_000)), + event: MetaEvent::balances(pallet_balances::RawEvent::NewAccount(1, 1_000_000)), topics: vec![], }, EventRecord { @@ -528,7 +532,7 @@ fn dispatch_call() { assert_eq!(System::events(), vec![ EventRecord { phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::balances(balances::RawEvent::NewAccount(1, 1_000_000)), + event: MetaEvent::balances(pallet_balances::RawEvent::NewAccount(1, 1_000_000)), topics: vec![], }, EventRecord { @@ -539,7 +543,7 @@ fn dispatch_call() { EventRecord { phase: Phase::ApplyExtrinsic(0), event: MetaEvent::balances( - balances::RawEvent::NewAccount(BOB, 100) + pallet_balances::RawEvent::NewAccount(BOB, 100) ), topics: vec![], }, @@ -558,14 +562,14 @@ fn dispatch_call() { EventRecord { phase: Phase::ApplyExtrinsic(0), event: MetaEvent::balances( - balances::RawEvent::NewAccount(CHARLIE, 50) + pallet_balances::RawEvent::NewAccount(CHARLIE, 50) ), topics: vec![], }, EventRecord { phase: Phase::ApplyExtrinsic(0), event: MetaEvent::balances( - balances::RawEvent::Transfer(BOB, CHARLIE, 50, 0) + pallet_balances::RawEvent::Transfer(BOB, CHARLIE, 50, 0) ), topics: vec![], }, @@ -602,7 +606,7 @@ const CODE_DISPATCH_CALL_THEN_TRAP: &str = r#" fn dispatch_call_not_dispatched_after_top_level_transaction_failure() { // This test can fail due to the encoding changes. In case it becomes too annoying // let's rewrite so as we use this module controlled call or we serialize it in runtime. - let encoded = Encode::encode(&Call::Balances(balances::Call::transfer(CHARLIE, 50))); + let encoded = Encode::encode(&Call::Balances(pallet_balances::Call::transfer(CHARLIE, 50))); assert_eq!(&encoded[..], &hex!("00000300000000000000C8")[..]); let (wasm, code_hash) = compile_module::(CODE_DISPATCH_CALL_THEN_TRAP).unwrap(); @@ -617,7 +621,7 @@ fn dispatch_call_not_dispatched_after_top_level_transaction_failure() { assert_eq!(System::events(), vec![ EventRecord { phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::balances(balances::RawEvent::NewAccount(1, 1_000_000)), + event: MetaEvent::balances(pallet_balances::RawEvent::NewAccount(1, 1_000_000)), topics: vec![], }, EventRecord { @@ -650,7 +654,7 @@ fn dispatch_call_not_dispatched_after_top_level_transaction_failure() { assert_eq!(System::events(), vec![ EventRecord { phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::balances(balances::RawEvent::NewAccount(1, 1_000_000)), + event: MetaEvent::balances(pallet_balances::RawEvent::NewAccount(1, 1_000_000)), topics: vec![], }, EventRecord { @@ -661,7 +665,7 @@ fn dispatch_call_not_dispatched_after_top_level_transaction_failure() { EventRecord { phase: Phase::ApplyExtrinsic(0), event: MetaEvent::balances( - balances::RawEvent::NewAccount(BOB, 100) + pallet_balances::RawEvent::NewAccount(BOB, 100) ), topics: vec![], }, @@ -802,7 +806,7 @@ mod call { fn test_set_rent_code_and_hash() { // This test can fail due to the encoding changes. In case it becomes too annoying // let's rewrite so as we use this module controlled call or we serialize it in runtime. - let encoded = Encode::encode(&Call::Balances(balances::Call::transfer(CHARLIE, 50))); + let encoded = Encode::encode(&Call::Balances(pallet_balances::Call::transfer(CHARLIE, 50))); assert_eq!(&encoded[..], &hex!("00000300000000000000C8")[..]); let (wasm, code_hash) = compile_module::(CODE_SET_RENT).unwrap(); @@ -816,7 +820,7 @@ fn test_set_rent_code_and_hash() { assert_eq!(System::events(), vec![ EventRecord { phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::balances(balances::RawEvent::NewAccount(1, 1_000_000)), + event: MetaEvent::balances(pallet_balances::RawEvent::NewAccount(1, 1_000_000)), topics: vec![], }, EventRecord { @@ -841,7 +845,7 @@ fn storage_size() { Origin::signed(ALICE), 30_000, 100_000, code_hash.into(), - ::Balance::from(1_000u32).encode() // rent allowance + ::Balance::from(1_000u32).encode() // rent allowance )); let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); assert_eq!(bob_contract.storage_size, ::StorageSizeOffset::get() + 4); @@ -868,7 +872,7 @@ fn deduct_blocks() { Origin::signed(ALICE), 30_000, 100_000, code_hash.into(), - ::Balance::from(1_000u32).encode() // rent allowance + ::Balance::from(1_000u32).encode() // rent allowance )); // Check creation @@ -962,7 +966,7 @@ fn claim_surcharge(blocks: u64, trigger_call: impl Fn() -> bool, removes: bool) Origin::signed(ALICE), 100, 100_000, code_hash.into(), - ::Balance::from(1_000u32).encode() // rent allowance + ::Balance::from(1_000u32).encode() // rent allowance )); // Advance blocks @@ -995,7 +999,7 @@ fn removals(trigger_call: impl Fn() -> bool) { Origin::signed(ALICE), 100, 100_000, code_hash.into(), - ::Balance::from(1_000u32).encode() // rent allowance + ::Balance::from(1_000u32).encode() // rent allowance )); let subsistence_threshold = 50 /*existential_deposit*/ + 16 /*tombstone_deposit*/; @@ -1031,7 +1035,7 @@ fn removals(trigger_call: impl Fn() -> bool) { Origin::signed(ALICE), 1_000, 100_000, code_hash.into(), - ::Balance::from(100u32).encode() // rent allowance + ::Balance::from(100u32).encode() // rent allowance )); // Trigger rent must have no effect @@ -1066,7 +1070,7 @@ fn removals(trigger_call: impl Fn() -> bool) { Origin::signed(ALICE), 50+Balances::minimum_balance(), 100_000, code_hash.into(), - ::Balance::from(1_000u32).encode() // rent allowance + ::Balance::from(1_000u32).encode() // rent allowance )); // Trigger rent must have no effect @@ -1110,7 +1114,7 @@ fn call_removed_contract() { Origin::signed(ALICE), 100, 100_000, code_hash.into(), - ::Balance::from(1_000u32).encode() // rent allowance + ::Balance::from(1_000u32).encode() // rent allowance )); // Calling contract should succeed. @@ -1311,7 +1315,7 @@ fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage: assert_eq!(System::events(), vec![ EventRecord { phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::balances(balances::RawEvent::NewAccount(1, 1_000_000)), + event: MetaEvent::balances(pallet_balances::RawEvent::NewAccount(1, 1_000_000)), topics: vec![], }, EventRecord { @@ -1333,7 +1337,7 @@ fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage: 30_000, 100_000, set_rent_code_hash.into(), - ::Balance::from(0u32).encode() + ::Balance::from(0u32).encode() )); // Check if `BOB` was created successfully and that the rent allowance is @@ -1370,7 +1374,7 @@ fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage: 30_000, 100_000, restoration_code_hash.into(), - ::Balance::from(0u32).encode() + ::Balance::from(0u32).encode() )); // Before performing a call to `DJANGO` save its original trie id. @@ -2329,7 +2333,7 @@ fn cannot_self_destruct_in_constructor() { #[test] fn check_block_gas_limit_works() { ExtBuilder::default().block_gas_limit(50).build().execute_with(|| { - let info = DispatchInfo { weight: 100, class: DispatchClass::Normal }; + let info = DispatchInfo { weight: 100, class: DispatchClass::Normal, pays_fee: true }; let check = CheckBlockGasLimit::(Default::default()); let call: Call = crate::Call::put_code(1000, vec![]).into(); @@ -2425,7 +2429,7 @@ fn get_runtime_storage() { ExtBuilder::default().existential_deposit(50).build().execute_with(|| { Balances::deposit_creating(&ALICE, 1_000_000); - support::storage::unhashed::put_raw( + frame_support::storage::unhashed::put_raw( &[1, 2, 3, 4], 0x14144020u32.to_le_bytes().to_vec().as_ref() ); diff --git a/frame/contracts/src/wasm/code_cache.rs b/frame/contracts/src/wasm/code_cache.rs index e6702d29cf5c71b1fbfa8d1a0026cefc6c48a86e..ada28ffc159626af6fe86dbcaf7a4b3ed53dbc89 100644 --- a/frame/contracts/src/wasm/code_cache.rs +++ b/frame/contracts/src/wasm/code_cache.rs @@ -29,9 +29,9 @@ use crate::gas::{Gas, GasMeter, Token}; use crate::wasm::{prepare, runtime::Env, PrefabWasmModule}; use crate::{CodeHash, CodeStorage, PristineCode, Schedule, Trait}; -use rstd::prelude::*; -use sr_primitives::traits::{Hash, Bounded}; -use support::StorageMap; +use sp_std::prelude::*; +use sp_runtime::traits::{Hash, Bounded}; +use frame_support::StorageMap; /// Gas metering token that used for charging storing code into the code storage. /// diff --git a/frame/contracts/src/wasm/env_def/macros.rs b/frame/contracts/src/wasm/env_def/macros.rs index af83c366233c64c696fde07b9ab913b05c4dcf31..e02be90b8ec612ebddbcda8547e221c703825646 100644 --- a/frame/contracts/src/wasm/env_def/macros.rs +++ b/frame/contracts/src/wasm/env_def/macros.rs @@ -96,7 +96,7 @@ macro_rules! unmarshall_then_body { #[inline(always)] pub fn constrain_closure(f: F) -> F where - F: FnOnce() -> Result, + F: FnOnce() -> Result, { f } @@ -110,14 +110,14 @@ macro_rules! unmarshall_then_body_then_marshall { unmarshall_then_body!($body, $ctx, $args_iter, $( $names : $params ),*) }); let r = body()?; - return Ok(sandbox::ReturnValue::Value({ use $crate::wasm::env_def::ConvertibleToWasm; r.to_typed_value() })) + return Ok(sp_sandbox::ReturnValue::Value({ use $crate::wasm::env_def::ConvertibleToWasm; r.to_typed_value() })) }); ( $args_iter:ident, $ctx:ident, ( $( $names:ident : $params:ty ),* ) => $body:tt ) => ({ let body = $crate::wasm::env_def::macros::constrain_closure::<(), _>(|| { unmarshall_then_body!($body, $ctx, $args_iter, $( $names : $params ),*) }); body()?; - return Ok(sandbox::ReturnValue::Unit) + return Ok(sp_sandbox::ReturnValue::Unit) }) } @@ -126,8 +126,8 @@ macro_rules! define_func { ( < E: $ext_ty:tt > $name:ident ( $ctx: ident $(, $names:ident : $params:ty)*) $(-> $returns:ty)* => $body:tt ) => { fn $name< E: $ext_ty >( $ctx: &mut $crate::wasm::Runtime, - args: &[sandbox::TypedValue], - ) -> Result { + args: &[sp_sandbox::TypedValue], + ) -> Result { #[allow(unused)] let mut args = args.iter(); @@ -195,8 +195,8 @@ macro_rules! define_env { mod tests { use parity_wasm::elements::FunctionType; use parity_wasm::elements::ValueType; - use sr_primitives::traits::Zero; - use sandbox::{self, ReturnValue, TypedValue}; + use sp_runtime::traits::Zero; + use sp_sandbox::{self, ReturnValue, TypedValue}; use crate::wasm::tests::MockExt; use crate::wasm::Runtime; use crate::exec::Ext; @@ -206,15 +206,15 @@ mod tests { fn macro_unmarshall_then_body_then_marshall_value_or_trap() { fn test_value( _ctx: &mut u32, - args: &[sandbox::TypedValue], - ) -> Result { + args: &[sp_sandbox::TypedValue], + ) -> Result { let mut args = args.iter(); unmarshall_then_body_then_marshall!( args, _ctx, (a: u32, b: u32) -> u32 => { if b == 0 { - Err(sandbox::HostError) + Err(sp_sandbox::HostError) } else { Ok(a / b) } @@ -234,8 +234,8 @@ mod tests { fn macro_unmarshall_then_body_then_marshall_unit() { fn test_unit( ctx: &mut u32, - args: &[sandbox::TypedValue], - ) -> Result { + args: &[sp_sandbox::TypedValue], + ) -> Result { let mut args = args.iter(); unmarshall_then_body_then_marshall!( args, @@ -260,11 +260,11 @@ mod tests { if !amount.is_zero() { Ok(()) } else { - Err(sandbox::HostError) + Err(sp_sandbox::HostError) } }); - let _f: fn(&mut Runtime, &[sandbox::TypedValue]) - -> Result = ext_gas::; + let _f: fn(&mut Runtime, &[sp_sandbox::TypedValue]) + -> Result = ext_gas::; } #[test] @@ -312,7 +312,7 @@ mod tests { if !amount.is_zero() { Ok(()) } else { - Err(sandbox::HostError) + Err(sp_sandbox::HostError) } }, ); diff --git a/frame/contracts/src/wasm/env_def/mod.rs b/frame/contracts/src/wasm/env_def/mod.rs index d51a157910d5c2c46470913ada843d0dd19f881c..30c1b5455d7fa1ddb804b0234625d10e82fad518 100644 --- a/frame/contracts/src/wasm/env_def/mod.rs +++ b/frame/contracts/src/wasm/env_def/mod.rs @@ -17,7 +17,7 @@ use super::Runtime; use crate::exec::Ext; -use sandbox::{self, TypedValue}; +use sp_sandbox::{self, TypedValue}; use parity_wasm::elements::{FunctionType, ValueType}; #[macro_use] @@ -69,8 +69,8 @@ impl ConvertibleToWasm for u64 { pub(crate) type HostFunc = fn( &mut Runtime, - &[sandbox::TypedValue] - ) -> Result; + &[sp_sandbox::TypedValue] + ) -> Result; pub(crate) trait FunctionImplProvider { fn impls)>(f: &mut F); diff --git a/frame/contracts/src/wasm/mod.rs b/frame/contracts/src/wasm/mod.rs index b1010d7b1447985ea7a40651578a4876bc92b4ff..28b05fcd1a73e19885dc6311f385451e5ee8c8b1 100644 --- a/frame/contracts/src/wasm/mod.rs +++ b/frame/contracts/src/wasm/mod.rs @@ -22,9 +22,9 @@ use crate::wasm::env_def::FunctionImplProvider; use crate::exec::{Ext, ExecResult}; use crate::gas::GasMeter; -use rstd::prelude::*; +use sp_std::prelude::*; use codec::{Encode, Decode}; -use sandbox; +use sp_sandbox; #[macro_use] mod env_def; @@ -114,7 +114,7 @@ impl<'a, T: Trait> crate::exec::Vm for WasmVm<'a> { gas_meter: &mut GasMeter, ) -> ExecResult { let memory = - sandbox::Memory::new(exec.prefab_module.initial, Some(exec.prefab_module.maximum)) + sp_sandbox::Memory::new(exec.prefab_module.initial, Some(exec.prefab_module.maximum)) .unwrap_or_else(|_| { // unlike `.expect`, explicit panic preserves the source location. // Needed as we can't use `RUST_BACKTRACE` in here. @@ -125,7 +125,7 @@ impl<'a, T: Trait> crate::exec::Vm for WasmVm<'a> { ) }); - let mut imports = sandbox::EnvironmentDefinitionBuilder::new(); + let mut imports = sp_sandbox::EnvironmentDefinitionBuilder::new(); imports.add_memory("env", "memory", memory.clone()); runtime::Env::impls(&mut |name, func_ptr| { imports.add_host_func("env", name, func_ptr); @@ -141,7 +141,7 @@ impl<'a, T: Trait> crate::exec::Vm for WasmVm<'a> { // Instantiate the instance from the instrumented module code and invoke the contract // entrypoint. - let result = sandbox::Instance::new(&exec.prefab_module.code, &imports, &mut runtime) + let result = sp_sandbox::Instance::new(&exec.prefab_module.code, &imports, &mut runtime) .and_then(|mut instance| instance.invoke(exec.entrypoint_name, &[], &mut runtime)); to_execution_result(runtime, result) } @@ -152,7 +152,7 @@ mod tests { use super::*; use std::collections::HashMap; use std::cell::RefCell; - use primitives::H256; + use sp_core::H256; use crate::exec::{Ext, StorageKey, ExecError, ExecReturnValue, STATUS_SUCCESS}; use crate::gas::{Gas, GasMeter}; use crate::tests::{Test, Call}; @@ -161,6 +161,7 @@ mod tests { use wabt; use hex_literal::hex; use assert_matches::assert_matches; + use sp_runtime::DispatchError; #[derive(Debug, PartialEq, Eq)] struct DispatchEntry(Call); @@ -1111,7 +1112,7 @@ mod tests { assert_eq!( &mock_ext.dispatches, &[DispatchEntry( - Call::Balances(balances::Call::set_balance(42, 1337, 0)), + Call::Balances(pallet_balances::Call::set_balance(42, 1337, 0)), )] ); } @@ -1429,7 +1430,7 @@ mod tests { MockExt::default(), &mut gas_meter ), - Err(ExecError { reason: "during execution", buffer: _ }) + Err(ExecError { reason: DispatchError::Other("during execution"), buffer: _ }) ); } @@ -1471,7 +1472,7 @@ mod tests { MockExt::default(), &mut gas_meter ), - Err(ExecError { reason: "during execution", buffer: _ }) + Err(ExecError { reason: DispatchError::Other("during execution"), buffer: _ }) ); } diff --git a/frame/contracts/src/wasm/prepare.rs b/frame/contracts/src/wasm/prepare.rs index 41269772a8551cd56803df8444f7215e81b97c85..f9a40489d94aa949398ddf4aa1220f3448be1099 100644 --- a/frame/contracts/src/wasm/prepare.rs +++ b/frame/contracts/src/wasm/prepare.rs @@ -25,8 +25,8 @@ use crate::Schedule; use parity_wasm::elements::{self, Internal, External, MemoryType, Type, ValueType}; use pwasm_utils; use pwasm_utils::rules; -use rstd::prelude::*; -use sr_primitives::traits::{SaturatedConversion}; +use sp_std::prelude::*; +use sp_runtime::traits::{SaturatedConversion}; struct ContractModule<'a> { /// A deserialized module. The module is valid (this is Guaranteed by `new` method). diff --git a/frame/contracts/src/wasm/runtime.rs b/frame/contracts/src/wasm/runtime.rs index e53cadaf7b23c303758f85fcc598a0301bd0e1cc..cbf666dde2d679f02ffd847279a616cbcece4943 100644 --- a/frame/contracts/src/wasm/runtime.rs +++ b/frame/contracts/src/wasm/runtime.rs @@ -21,13 +21,13 @@ use crate::exec::{ Ext, ExecResult, ExecError, ExecReturnValue, StorageKey, TopicOf, STATUS_SUCCESS, }; use crate::gas::{Gas, GasMeter, Token, GasMeterResult, approx_gas_for_balance}; -use sandbox; -use system; -use rstd::prelude::*; -use rstd::convert::TryInto; -use rstd::mem; +use sp_sandbox; +use frame_system; +use sp_std::prelude::*; +use sp_std::convert::TryInto; +use sp_std::mem; use codec::{Decode, Encode}; -use sr_primitives::traits::{Bounded, SaturatedConversion}; +use sp_runtime::traits::{Bounded, SaturatedConversion}; /// The value returned from ext_call and ext_instantiate contract external functions if the call or /// instantiation traps. This value is chosen as if the execution does not trap, the return value @@ -48,7 +48,7 @@ pub(crate) struct Runtime<'a, E: Ext + 'a> { ext: &'a mut E, scratch_buf: Vec, schedule: &'a Schedule, - memory: sandbox::Memory, + memory: sp_sandbox::Memory, gas_meter: &'a mut GasMeter, special_trap: Option, } @@ -57,7 +57,7 @@ impl<'a, E: Ext + 'a> Runtime<'a, E> { ext: &'a mut E, input_data: Vec, schedule: &'a Schedule, - memory: sandbox::Memory, + memory: sp_sandbox::Memory, gas_meter: &'a mut GasMeter, ) -> Self { Runtime { @@ -74,7 +74,7 @@ impl<'a, E: Ext + 'a> Runtime<'a, E> { pub(crate) fn to_execution_result( runtime: Runtime, - sandbox_result: Result, + sandbox_result: Result, ) -> ExecResult { // Special case. The trap was the result of the execution `return` host function. if let Some(SpecialTrap::Return(data)) = runtime.special_trap { @@ -84,12 +84,12 @@ pub(crate) fn to_execution_result( // Check the exact type of the error. match sandbox_result { // No traps were generated. Proceed normally. - Ok(sandbox::ReturnValue::Unit) => { + Ok(sp_sandbox::ReturnValue::Unit) => { let mut buffer = runtime.scratch_buf; buffer.clear(); Ok(ExecReturnValue { status: STATUS_SUCCESS, data: buffer }) } - Ok(sandbox::ReturnValue::Value(sandbox::TypedValue::I32(exit_code))) => { + Ok(sp_sandbox::ReturnValue::Value(sp_sandbox::TypedValue::I32(exit_code))) => { let status = (exit_code & 0xFF).try_into() .expect("exit_code is masked into the range of a u8; qed"); Ok(ExecReturnValue { status, data: runtime.scratch_buf }) @@ -98,18 +98,18 @@ pub(crate) fn to_execution_result( // validated by the code preparation process. However, because panics are really // undesirable in the runtime code, we treat this as a trap for now. Eventually, we might // want to revisit this. - Ok(_) => Err(ExecError { reason: "return type error", buffer: runtime.scratch_buf }), + Ok(_) => Err(ExecError { reason: "return type error".into(), buffer: runtime.scratch_buf }), // `Error::Module` is returned only if instantiation or linking failed (i.e. // wasm binary tried to import a function that is not provided by the host). // This shouldn't happen because validation process ought to reject such binaries. // // Because panics are really undesirable in the runtime code, we treat this as // a trap for now. Eventually, we might want to revisit this. - Err(sandbox::Error::Module) => - Err(ExecError { reason: "validation error", buffer: runtime.scratch_buf }), + Err(sp_sandbox::Error::Module) => + Err(ExecError { reason: "validation error".into(), buffer: runtime.scratch_buf }), // Any other kind of a trap should result in a failure. - Err(sandbox::Error::Execution) | Err(sandbox::Error::OutOfBounds) => - Err(ExecError { reason: "during execution", buffer: runtime.scratch_buf }), + Err(sp_sandbox::Error::Execution) | Err(sp_sandbox::Error::OutOfBounds) => + Err(ExecError { reason: "during execution".into(), buffer: runtime.scratch_buf }), } } @@ -182,10 +182,10 @@ fn charge_gas>( gas_meter: &mut GasMeter, metadata: &Tok::Metadata, token: Tok, -) -> Result<(), sandbox::HostError> { +) -> Result<(), sp_sandbox::HostError> { match gas_meter.charge(metadata, token) { GasMeterResult::Proceed => Ok(()), - GasMeterResult::OutOfGas => Err(sandbox::HostError), + GasMeterResult::OutOfGas => Err(sp_sandbox::HostError), } } @@ -201,11 +201,11 @@ fn read_sandbox_memory( ctx: &mut Runtime, ptr: u32, len: u32, -) -> Result, sandbox::HostError> { +) -> Result, sp_sandbox::HostError> { charge_gas(ctx.gas_meter, ctx.schedule, RuntimeToken::ReadMemory(len))?; let mut buf = vec![0u8; len as usize]; - ctx.memory.get(ptr, buf.as_mut_slice()).map_err(|_| sandbox::HostError)?; + ctx.memory.get(ptr, buf.as_mut_slice()).map_err(|_| sp_sandbox::HostError)?; Ok(buf) } @@ -221,11 +221,11 @@ fn read_sandbox_memory_into_scratch( ctx: &mut Runtime, ptr: u32, len: u32, -) -> Result<(), sandbox::HostError> { +) -> Result<(), sp_sandbox::HostError> { charge_gas(ctx.gas_meter, ctx.schedule, RuntimeToken::ReadMemory(len))?; ctx.scratch_buf.resize(len as usize, 0); - ctx.memory.get(ptr, ctx.scratch_buf.as_mut_slice()).map_err(|_| sandbox::HostError)?; + ctx.memory.get(ptr, ctx.scratch_buf.as_mut_slice()).map_err(|_| sp_sandbox::HostError)?; Ok(()) } @@ -241,7 +241,7 @@ fn read_sandbox_memory_into_buf( ctx: &mut Runtime, ptr: u32, buf: &mut [u8], -) -> Result<(), sandbox::HostError> { +) -> Result<(), sp_sandbox::HostError> { charge_gas(ctx.gas_meter, ctx.schedule, RuntimeToken::ReadMemory(buf.len() as u32))?; ctx.memory.get(ptr, buf).map_err(Into::into) @@ -260,9 +260,9 @@ fn read_sandbox_memory_as( ctx: &mut Runtime, ptr: u32, len: u32, -) -> Result { +) -> Result { let buf = read_sandbox_memory(ctx, ptr, len)?; - D::decode(&mut &buf[..]).map_err(|_| sandbox::HostError) + D::decode(&mut &buf[..]).map_err(|_| sp_sandbox::HostError) } /// Write the given buffer to the designated location in the sandbox memory, consuming @@ -276,10 +276,10 @@ fn read_sandbox_memory_as( fn write_sandbox_memory( schedule: &Schedule, gas_meter: &mut GasMeter, - memory: &sandbox::Memory, + memory: &sp_sandbox::Memory, ptr: u32, buf: &[u8], -) -> Result<(), sandbox::HostError> { +) -> Result<(), sp_sandbox::HostError> { charge_gas(gas_meter, schedule, RuntimeToken::WriteMemory(buf.len() as u32))?; memory.set(ptr, buf)?; @@ -318,7 +318,7 @@ define_env!(Env, , // - value_len: the length of the value. If `value_non_null` is set to 0, then this parameter is ignored. ext_set_storage(ctx, key_ptr: u32, value_non_null: u32, value_ptr: u32, value_len: u32) => { if value_non_null != 0 && ctx.ext.max_value_size() < value_len { - return Err(sandbox::HostError); + return Err(sp_sandbox::HostError); } let mut key: StorageKey = [0; 32]; read_sandbox_memory_into_buf(ctx, key_ptr, &mut key)?; @@ -328,7 +328,7 @@ define_env!(Env, , } else { None }; - ctx.ext.set_storage(key, value).map_err(|_| sandbox::HostError)?; + ctx.ext.set_storage(key, value).map_err(|_| sp_sandbox::HostError)?; Ok(()) }, @@ -382,7 +382,7 @@ define_env!(Env, , input_data_ptr: u32, input_data_len: u32 ) -> u32 => { - let callee: <::T as system::Trait>::AccountId = + let callee: <::T as frame_system::Trait>::AccountId = read_sandbox_memory_as(ctx, callee_ptr, callee_len)?; let value: BalanceOf<::T> = read_sandbox_memory_as(ctx, value_ptr, value_len)?; @@ -532,7 +532,7 @@ define_env!(Env, , // The trap mechanism is used to immediately terminate the execution. // This trap should be handled appropriately before returning the result // to the user of this crate. - Err(sandbox::HostError) + Err(sp_sandbox::HostError) }, // Stores the address of the caller into the scratch buffer. @@ -597,7 +597,7 @@ define_env!(Env, , ext_random(ctx, subject_ptr: u32, subject_len: u32) => { // The length of a subject can't exceed `max_subject_len`. if subject_len > ctx.schedule.max_subject_len { - return Err(sandbox::HostError); + return Err(sp_sandbox::HostError); } let subject_buf = read_sandbox_memory(ctx, subject_ptr, subject_len)?; @@ -675,7 +675,7 @@ define_env!(Env, , delta_ptr: u32, delta_count: u32 ) => { - let dest: <::T as system::Trait>::AccountId = + let dest: <::T as frame_system::Trait>::AccountId = read_sandbox_memory_as(ctx, dest_ptr, dest_len)?; let code_hash: CodeHash<::T> = read_sandbox_memory_as(ctx, code_hash_ptr, code_hash_len)?; @@ -696,7 +696,7 @@ define_env!(Env, , delta.push(delta_key); // Offset key_ptr to the next element. - key_ptr = key_ptr.checked_add(KEY_SIZE as u32).ok_or_else(|| sandbox::HostError)?; + key_ptr = key_ptr.checked_add(KEY_SIZE as u32).ok_or_else(|| sp_sandbox::HostError)?; } delta @@ -729,13 +729,13 @@ define_env!(Env, , let offset = offset as usize; if offset > ctx.scratch_buf.len() { // Offset can't be larger than scratch buffer length. - return Err(sandbox::HostError); + return Err(sp_sandbox::HostError); } // This can't panic since `offset <= ctx.scratch_buf.len()`. let src = &ctx.scratch_buf[offset..]; if src.len() != len as usize { - return Err(sandbox::HostError); + return Err(sp_sandbox::HostError); } // Finally, perform the write. @@ -775,12 +775,12 @@ define_env!(Env, , // If there are more than `max_event_topics`, then trap. if topics.len() > ctx.schedule.max_event_topics as usize { - return Err(sandbox::HostError); + return Err(sp_sandbox::HostError); } // Check for duplicate topics. If there are any, then trap. if has_duplicates(&mut topics) { - return Err(sandbox::HostError); + return Err(sp_sandbox::HostError); } let event_data = read_sandbox_memory(ctx, data_ptr, data_len)?; @@ -824,7 +824,7 @@ define_env!(Env, , ext_println(ctx, str_ptr: u32, str_len: u32) => { let data = read_sandbox_memory(ctx, str_ptr, str_len)?; if let Ok(utf8) = core::str::from_utf8(&data) { - sr_primitives::print(utf8); + sp_runtime::print(utf8); } Ok(()) }, diff --git a/frame/democracy/Cargo.toml b/frame/democracy/Cargo.toml index b607e8af733fbb81ea810a989c5eb221cc938f5b..8e1aa13fc67f9de2f83364f5952dff85c8c68d9f 100644 --- a/frame/democracy/Cargo.toml +++ b/frame/democracy/Cargo.toml @@ -8,15 +8,15 @@ edition = "2018" serde = { version = "1.0.101", optional = true, features = ["derive"] } safe-mix = { version = "1.0.0", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -rstd = { package = "sr-std", path = "../../primitives/sr-std", default-features = false } -runtime-io = { package = "sr-io", path = "../../primitives/sr-io", default-features = false } -sr-primitives = { path = "../../primitives/sr-primitives", default-features = false } -support = { package = "frame-support", path = "../support", default-features = false } -system = { package = "frame-system", path = "../system", default-features = false } +sp-std = { version = "2.0.0", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0", default-features = false, path = "../support" } +frame-system = { version = "2.0.0", default-features = false, path = "../system" } [dev-dependencies] -primitives = { package = "substrate-primitives", path = "../../primitives/core" } -balances = { package = "pallet-balances", path = "../balances" } +sp-core = { version = "2.0.0", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0", path = "../balances" } [features] default = ["std"] @@ -24,9 +24,9 @@ std = [ "serde", "safe-mix/std", "codec/std", - "rstd/std", - "runtime-io/std", - "support/std", - "sr-primitives/std", - "system/std", + "sp-std/std", + "sp-io/std", + "frame-support/std", + "sp-runtime/std", + "frame-system/std", ] diff --git a/frame/democracy/src/lib.rs b/frame/democracy/src/lib.rs index 3ff6c1e2ecc72a2e1bc18a7c7a7354b586fa78ec..3bbe01149750474ea4906dc83fd5c466911e37bc 100644 --- a/frame/democracy/src/lib.rs +++ b/frame/democracy/src/lib.rs @@ -18,24 +18,22 @@ #![recursion_limit="128"] #![cfg_attr(not(feature = "std"), no_std)] -use rstd::prelude::*; -use rstd::{result, convert::TryFrom}; -use sr_primitives::{ - RuntimeDebug, - traits::{Zero, Bounded, CheckedMul, CheckedDiv, EnsureOrigin, Hash, Dispatchable}, +use sp_std::prelude::*; +use sp_std::{result, convert::TryFrom}; +use sp_runtime::{ + RuntimeDebug, DispatchResult, + traits::{Zero, Bounded, CheckedMul, CheckedDiv, EnsureOrigin, Hash, Dispatchable, Saturating}, }; -use codec::{Ref, Encode, Decode, Input, Output, Error}; -use support::{ - decl_module, decl_storage, decl_event, ensure, - Parameter, +use codec::{Ref, Encode, Decode, Input, Output}; +use frame_support::{ + decl_module, decl_storage, decl_event, decl_error, ensure, Parameter, weights::SimpleDispatchInfo, traits::{ Currency, ReservableCurrency, LockableCurrency, WithdrawReason, LockIdentifier, Get, - OnFreeBalanceZero + OnFreeBalanceZero, OnUnbalanced } }; -use support::dispatch::Result; -use system::{ensure_signed, ensure_root}; +use frame_system::{self as system, ensure_signed, ensure_root}; mod vote_threshold; pub use vote_threshold::{Approved, VoteThreshold}; @@ -163,21 +161,23 @@ impl Encode for Vote { impl codec::EncodeLike for Vote {} impl Decode for Vote { - fn decode(input: &mut I) -> core::result::Result { + fn decode(input: &mut I) -> core::result::Result { let b = input.read_byte()?; Ok(Vote { aye: (b & 0b1000_0000) == 0b1000_0000, conviction: Conviction::try_from(b & 0b0111_1111) - .map_err(|_| Error::from("Invalid conviction"))?, + .map_err(|_| codec::Error::from("Invalid conviction"))?, }) } } -type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +type NegativeImbalanceOf = +<::Currency as Currency<::AccountId>>::NegativeImbalance; -pub trait Trait: system::Trait + Sized { +pub trait Trait: frame_system::Trait + Sized { type Proposal: Parameter + Dispatchable; - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// Currency type for this module. type Currency: ReservableCurrency @@ -227,30 +227,36 @@ pub trait Trait: system::Trait + Sized { /// Period in blocks where an external proposal may not be re-submitted after being vetoed. type CooloffPeriod: Get; + + /// The amount of balance that must be deposited per byte of preimage stored. + type PreimageByteDeposit: Get>; + + /// Handler for the unbalanced reduction when slashing a preimage deposit. + type Slash: OnUnbalanced>; } /// Info regarding an ongoing referendum. #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)] -pub struct ReferendumInfo { +pub struct ReferendumInfo { /// When voting on this referendum will end. end: BlockNumber, - /// The proposal being voted on. - proposal: Proposal, + /// The hash of the proposal being voted on. + proposal_hash: Hash, /// The thresholding mechanism to determine whether it passed. threshold: VoteThreshold, /// The delay (in blocks) to wait after a successful referendum before deploying. delay: BlockNumber, } -impl ReferendumInfo { +impl ReferendumInfo { /// Create a new instance. pub fn new( end: BlockNumber, - proposal: Proposal, + proposal_hash: Hash, threshold: VoteThreshold, delay: BlockNumber ) -> Self { - ReferendumInfo { end, proposal, threshold, delay } + ReferendumInfo { end, proposal_hash, threshold, delay } } } @@ -258,21 +264,24 @@ decl_storage! { trait Store for Module as Democracy { /// The number of (public) proposals that have been made so far. pub PublicPropCount get(fn public_prop_count) build(|_| 0 as PropIndex) : PropIndex; - /// The public proposals. Unsorted. - pub PublicProps get(fn public_props): Vec<(PropIndex, T::Proposal, T::AccountId)>; + /// The public proposals. Unsorted. The second item is the proposal's hash. + pub PublicProps get(fn public_props): Vec<(PropIndex, T::Hash, T::AccountId)>; + /// Map of hashes to the proposal preimage, along with who registered it and their deposit. + /// The block number is the block at which it was deposited. + pub Preimages: map T::Hash => Option<(Vec, T::AccountId, BalanceOf, T::BlockNumber)>; /// Those who have locked a deposit. pub DepositOf get(fn deposit_of): map PropIndex => Option<(BalanceOf, Vec)>; /// The next free referendum index, aka the number of referenda started so far. pub ReferendumCount get(fn referendum_count) build(|_| 0 as ReferendumIndex): ReferendumIndex; - /// The next referendum index that should be tallied. - pub NextTally get(fn next_tally) build(|_| 0 as ReferendumIndex): ReferendumIndex; + /// The lowest referendum index representing an unbaked referendum. Equal to + /// `ReferendumCount` if there isn't a unbaked referendum. + pub LowestUnbaked get(fn lowest_unbaked) build(|_| 0 as ReferendumIndex): ReferendumIndex; /// Information concerning any given referendum. pub ReferendumInfoOf get(fn referendum_info): - map ReferendumIndex => Option<(ReferendumInfo)>; - /// Queue of successful referenda to be dispatched. - pub DispatchQueue get(fn dispatch_queue): - map T::BlockNumber => Vec>; + map ReferendumIndex => Option>; + /// Queue of successful referenda to be dispatched. Stored ordered by block number. + pub DispatchQueue get(fn dispatch_queue): Vec<(T::BlockNumber, T::Hash, ReferendumIndex)>; /// Get the voters for the current proposal. pub VotersFor get(fn voters_for): map ReferendumIndex => Vec; @@ -298,7 +307,7 @@ decl_storage! { /// This happens when a referendum needs to be tabled and one of two conditions are met: /// - `LastTabledWasExternal` is `false`; or /// - `PublicProps` is empty. - pub NextExternal: Option<(T::Proposal, VoteThreshold)>; + pub NextExternal: Option<(T::Hash, VoteThreshold)>; /// A record of who vetoed what. Maps proposal hash to a possible existent block number /// (until when it may not be resubmitted) and who vetoed it. @@ -309,29 +318,100 @@ decl_storage! { } } -decl_event!( +decl_event! { pub enum Event where Balance = BalanceOf, - ::AccountId, - ::Hash, - ::BlockNumber, + ::AccountId, + ::Hash, + ::BlockNumber, { + /// A motion has been proposed by a public account. Proposed(PropIndex, Balance), + /// A public proposal has been tabled for referendum vote. Tabled(PropIndex, Balance, Vec), + /// An external proposal has been tabled. ExternalTabled, + /// A referendum has begun. Started(ReferendumIndex, VoteThreshold), + /// A proposal has been approved by referendum. Passed(ReferendumIndex), + /// A proposal has been rejected by referendum. NotPassed(ReferendumIndex), + /// A referendum has been cancelled. Cancelled(ReferendumIndex), + /// A proposal has been enacted. Executed(ReferendumIndex, bool), + /// An account has delegated their vote to another account. Delegated(AccountId, AccountId), + /// An account has cancelled a previous delegation operation. Undelegated(AccountId), + /// An external proposal has been vetoed. Vetoed(AccountId, Hash, BlockNumber), + /// A proposal's preimage was noted, and the deposit taken. + PreimageNoted(Hash, AccountId, Balance), + /// A proposal preimage was removed and used (the deposit was returned). + PreimageUsed(Hash, AccountId, Balance), + /// A proposal could not be executed because its preimage was invalid. + PreimageInvalid(Hash, ReferendumIndex), + /// A proposal could not be executed because its preimage was missing. + PreimageMissing(Hash, ReferendumIndex), + /// A registered preimage was removed and the deposit collected by the reaper (last item). + PreimageReaped(Hash, AccountId, Balance, AccountId), } -); +} + +decl_error! { + pub enum Error for Module { + /// Value too low + ValueLow, + /// Proposal does not exist + ProposalMissing, + /// Not a proxy + NotProxy, + /// Unknown index + BadIndex, + /// Cannot cancel the same proposal twice + AlreadyCanceled, + /// Proposal already made + DuplicateProposal, + /// Proposal still blacklisted + ProposalBlacklisted, + /// Next external proposal not simple majority + NotSimpleMajority, + /// Invalid hash + InvalidHash, + /// No external proposal + NoProposal, + /// Identity may not veto a proposal twice + AlreadyVetoed, + /// Already a proxy + AlreadyProxy, + /// Wrong proxy + WrongProxy, + /// Not delegated + NotDelegated, + /// Preimage already noted + DuplicatePreimage, + /// Not imminent + NotImminent, + /// Too early + Early, + /// Imminent + Imminent, + /// Preimage not found + PreimageMissing, + /// Vote given for invalid referendum + ReferendumInvalid, + /// Invalid preimage + PreimageInvalid, + /// No proposals waiting + NoneWaiting, + } +} decl_module! { pub struct Module for enum Call where origin: T::Origin { + type Error = Error; /// The minimum period of locking and the period between a proposal being approved and enacted. /// /// It should generally be a little more than the unstake period to ensure that @@ -354,6 +434,9 @@ decl_module! { /// Period in blocks where an external proposal may not be re-submitted after being vetoed. const CooloffPeriod: T::BlockNumber = T::CooloffPeriod::get(); + /// The amount of balance that must be deposited per byte of preimage stored. + const PreimageByteDeposit: BalanceOf = T::PreimageByteDeposit::get(); + fn deposit_event() = default; /// Propose a sensitive action to be taken. @@ -364,20 +447,18 @@ decl_module! { /// # #[weight = SimpleDispatchInfo::FixedNormal(5_000_000)] fn propose(origin, - proposal: Box, + proposal_hash: T::Hash, #[compact] value: BalanceOf ) { let who = ensure_signed(origin)?; - - ensure!(value >= T::MinimumDeposit::get(), "value too low"); - T::Currency::reserve(&who, value) - .map_err(|_| "proposer's balance too low")?; + ensure!(value >= T::MinimumDeposit::get(), Error::::ValueLow); + T::Currency::reserve(&who, value)?; let index = Self::public_prop_count(); PublicPropCount::put(index + 1); >::insert(index, (value, &[&who][..])); - let new_prop = (index, proposal, who); + let new_prop = (index, proposal_hash, who); >::append_or_put(&[Ref::from(&new_prop)][..]); Self::deposit_event(RawEvent::Proposed(index, value)); @@ -393,9 +474,8 @@ decl_module! { fn second(origin, #[compact] proposal: PropIndex) { let who = ensure_signed(origin)?; let mut deposit = Self::deposit_of(proposal) - .ok_or("can only second an existing proposal")?; - T::Currency::reserve(&who, deposit.0) - .map_err(|_| "seconder's balance too low")?; + .ok_or(Error::::ProposalMissing)?; + T::Currency::reserve(&who, deposit.0)?; deposit.1.push(who); >::insert(proposal, deposit); } @@ -411,7 +491,7 @@ decl_module! { fn vote(origin, #[compact] ref_index: ReferendumIndex, vote: Vote - ) -> Result { + ) -> DispatchResult { let who = ensure_signed(origin)?; Self::do_vote(who, ref_index, vote) } @@ -427,8 +507,8 @@ decl_module! { fn proxy_vote(origin, #[compact] ref_index: ReferendumIndex, vote: Vote - ) -> Result { - let who = Self::proxy(ensure_signed(origin)?).ok_or("not a proxy")?; + ) -> DispatchResult { + let who = Self::proxy(ensure_signed(origin)?).ok_or(Error::::NotProxy)?; Self::do_vote(who, ref_index, vote) } @@ -438,9 +518,9 @@ decl_module! { fn emergency_cancel(origin, ref_index: ReferendumIndex) { T::CancellationOrigin::ensure_origin(origin)?; - let info = Self::referendum_info(ref_index).ok_or("unknown index")?; - let h = T::Hashing::hash_of(&info.proposal); - ensure!(!>::exists(h), "cannot cancel the same proposal twice"); + let info = Self::referendum_info(ref_index).ok_or(Error::::BadIndex)?; + let h = info.proposal_hash; + ensure!(!>::exists(h), Error::::AlreadyCanceled); >::insert(h, true); Self::clear_referendum(ref_index); @@ -449,14 +529,16 @@ decl_module! { /// Schedule a referendum to be tabled once it is legal to schedule an external /// referendum. #[weight = SimpleDispatchInfo::FixedNormal(5_000_000)] - fn external_propose(origin, proposal: Box) { + fn external_propose(origin, proposal_hash: T::Hash) { T::ExternalOrigin::ensure_origin(origin)?; - ensure!(!>::exists(), "proposal already made"); - let proposal_hash = T::Hashing::hash_of(&proposal); + ensure!(!>::exists(), Error::::DuplicateProposal); if let Some((until, _)) = >::get(proposal_hash) { - ensure!(>::block_number() >= until, "proposal still blacklisted"); + ensure!( + >::block_number() >= until, + Error::::ProposalBlacklisted, + ); } - >::put((*proposal, VoteThreshold::SuperMajorityApprove)); + >::put((proposal_hash, VoteThreshold::SuperMajorityApprove)); } /// Schedule a majority-carries referendum to be tabled next once it is legal to schedule @@ -465,9 +547,9 @@ decl_module! { /// Unlike `external_propose`, blacklisting has no effect on this and it may replace a /// pre-scheduled `external_propose` call. #[weight = SimpleDispatchInfo::FixedNormal(5_000_000)] - fn external_propose_majority(origin, proposal: Box) { + fn external_propose_majority(origin, proposal_hash: T::Hash) { T::ExternalMajorityOrigin::ensure_origin(origin)?; - >::put((*proposal, VoteThreshold::SimpleMajority)); + >::put((proposal_hash, VoteThreshold::SimpleMajority)); } /// Schedule a negative-turnout-bias referendum to be tabled next once it is legal to @@ -476,9 +558,9 @@ decl_module! { /// Unlike `external_propose`, blacklisting has no effect on this and it may replace a /// pre-scheduled `external_propose` call. #[weight = SimpleDispatchInfo::FixedNormal(5_000_000)] - fn external_propose_default(origin, proposal: Box) { + fn external_propose_default(origin, proposal_hash: T::Hash) { T::ExternalDefaultOrigin::ensure_origin(origin)?; - >::put((*proposal, VoteThreshold::SuperMajorityAgainst)); + >::put((proposal_hash, VoteThreshold::SuperMajorityAgainst)); } /// Schedule the currently externally-proposed majority-carries referendum to be tabled @@ -497,15 +579,18 @@ decl_module! { delay: T::BlockNumber ) { T::FastTrackOrigin::ensure_origin(origin)?; - let (proposal, threshold) = >::get().ok_or("no proposal made")?; - ensure!(threshold != VoteThreshold::SuperMajorityApprove, "next external proposal not simple majority"); - ensure!(proposal_hash == T::Hashing::hash_of(&proposal), "invalid hash"); + let (e_proposal_hash, threshold) = >::get().ok_or(Error::::ProposalMissing)?; + ensure!( + threshold != VoteThreshold::SuperMajorityApprove, + Error::::NotSimpleMajority, + ); + ensure!(proposal_hash == e_proposal_hash, Error::::InvalidHash); >::kill(); - let now = >::block_number(); + let now = >::block_number(); // We don't consider it an error if `vote_period` is too low, like `emergency_propose`. let period = voting_period.max(T::EmergencyVotingPeriod::get()); - Self::inject_referendum(now + period, proposal, threshold, delay).map(|_| ())?; + Self::inject_referendum(now + period, proposal_hash, threshold, delay); } /// Veto and blacklist the external proposal hash. @@ -513,20 +598,20 @@ decl_module! { fn veto_external(origin, proposal_hash: T::Hash) { let who = T::VetoOrigin::ensure_origin(origin)?; - if let Some((proposal, _)) = >::get() { - ensure!(proposal_hash == T::Hashing::hash_of(&proposal), "unknown proposal"); + if let Some((e_proposal_hash, _)) = >::get() { + ensure!(proposal_hash == e_proposal_hash, Error::::ProposalMissing); } else { - Err("no external proposal")?; + Err(Error::::NoProposal)?; } let mut existing_vetoers = >::get(&proposal_hash) .map(|pair| pair.1) .unwrap_or_else(Vec::new); let insert_position = existing_vetoers.binary_search(&who) - .err().ok_or("identity may not veto a proposal twice")?; + .err().ok_or(Error::::AlreadyVetoed)?; existing_vetoers.insert(insert_position, who.clone()); - let until = >::block_number() + T::CooloffPeriod::get(); + let until = >::block_number() + T::CooloffPeriod::get(); >::insert(&proposal_hash, (until, existing_vetoers)); Self::deposit_event(RawEvent::Vetoed(who, proposal_hash, until)); @@ -542,26 +627,18 @@ decl_module! { /// Cancel a proposal queued for enactment. #[weight = SimpleDispatchInfo::FixedOperational(10_000)] - fn cancel_queued( - origin, - #[compact] when: T::BlockNumber, - #[compact] which: u32, - #[compact] what: ReferendumIndex - ) { + fn cancel_queued(origin, which: ReferendumIndex) { ensure_root(origin)?; - let which = which as usize; - let mut items = >::get(when); - if items.get(which).and_then(Option::as_ref).map_or(false, |x| x.1 == what) { - items[which] = None; - >::insert(when, items); - } else { - Err("proposal not found")? - } + let mut items = >::get(); + let original_len = items.len(); + items.retain(|i| i.2 != which); + ensure!(items.len() < original_len, Error::::ProposalMissing); + >::put(items); } fn on_initialize(n: T::BlockNumber) { - if let Err(e) = Self::end_block(n) { - sr_primitives::print(e); + if let Err(e) = Self::begin_block(n) { + sp_runtime::print(e); } } @@ -573,7 +650,7 @@ decl_module! { #[weight = SimpleDispatchInfo::FixedNormal(100_000)] fn set_proxy(origin, proxy: T::AccountId) { let who = ensure_signed(origin)?; - ensure!(!>::exists(&proxy), "already a proxy"); + ensure!(!>::exists(&proxy), Error::::AlreadyProxy); >::insert(proxy, who) } @@ -596,7 +673,10 @@ decl_module! { #[weight = SimpleDispatchInfo::FixedNormal(100_000)] fn remove_proxy(origin, proxy: T::AccountId) { let who = ensure_signed(origin)?; - ensure!(&Self::proxy(&proxy).ok_or("not a proxy")? == &who, "wrong proxy"); + ensure!( + &Self::proxy(&proxy).ok_or(Error::::NotProxy)? == &who, + Error::::WrongProxy, + ); >::remove(proxy); } @@ -628,10 +708,10 @@ decl_module! { #[weight = SimpleDispatchInfo::FixedNormal(500_000)] fn undelegate(origin) { let who = ensure_signed(origin)?; - ensure!(>::exists(&who), "not delegated"); + ensure!(>::exists(&who), Error::::NotDelegated); let (_, conviction) = >::take(&who); // Indefinite lock is reduced to the maximum voting lock that could be possible. - let now = >::block_number(); + let now = >::block_number(); let locked_until = now + T::EnactmentPeriod::get() * conviction.lock_periods().into(); T::Currency::set_lock( DEMOCRACY_ID, @@ -642,6 +722,73 @@ decl_module! { ); Self::deposit_event(RawEvent::Undelegated(who)); } + + /// Veto and blacklist the proposal hash. Must be from Root origin. + #[weight = SimpleDispatchInfo::FixedNormal(10_000)] + fn clear_public_proposals(origin) { + ensure_root(origin)?; + + >::kill(); + } + + /// Register the preimage for an upcoming proposal. This doesn't require the proposal to be + /// in the dispatch queue but does require a deposit, returned once enacted. + #[weight = SimpleDispatchInfo::FixedNormal(100_000)] + fn note_preimage(origin, encoded_proposal: Vec) { + let who = ensure_signed(origin)?; + let proposal_hash = T::Hashing::hash(&encoded_proposal[..]); + ensure!(!>::exists(&proposal_hash), Error::::DuplicatePreimage); + + let deposit = >::from(encoded_proposal.len() as u32) + .saturating_mul(T::PreimageByteDeposit::get()); + T::Currency::reserve(&who, deposit)?; + + let now = >::block_number(); + >::insert(proposal_hash, (encoded_proposal, who.clone(), deposit, now)); + + Self::deposit_event(RawEvent::PreimageNoted(proposal_hash, who, deposit)); + } + + /// Register the preimage for an upcoming proposal. This requires the proposal to be + /// in the dispatch queue. No deposit is needed. + #[weight = SimpleDispatchInfo::FixedNormal(100_000)] + fn note_imminent_preimage(origin, encoded_proposal: Vec) { + let who = ensure_signed(origin)?; + let proposal_hash = T::Hashing::hash(&encoded_proposal[..]); + ensure!(!>::exists(&proposal_hash), Error::::DuplicatePreimage); + let queue = >::get(); + ensure!(queue.iter().any(|item| &item.1 == &proposal_hash), Error::::NotImminent); + + let now = >::block_number(); + let free = >::zero(); + >::insert(proposal_hash, (encoded_proposal, who.clone(), free, now)); + + Self::deposit_event(RawEvent::PreimageNoted(proposal_hash, who, free)); + } + + /// Remove an expired proposal preimage and collect the deposit. + /// + /// This will only work after `VotingPeriod` blocks from the time that the preimage was + /// noted, if it's the same account doing it. If it's a different account, then it'll only + /// work an additional `EnactmentPeriod` later. + #[weight = SimpleDispatchInfo::FixedNormal(10_000)] + fn reap_preimage(origin, proposal_hash: T::Hash) { + let who = ensure_signed(origin)?; + + let (_, old, deposit, then) = >::get(&proposal_hash) + .ok_or(Error::::PreimageMissing)?; + let now = >::block_number(); + let (voting, enactment) = (T::VotingPeriod::get(), T::EnactmentPeriod::get()); + let additional = if who == old { Zero::zero() } else { enactment }; + ensure!(now >= then + voting + additional, Error::::Early); + + let queue = >::get(); + ensure!(!queue.iter().any(|item| &item.1 == &proposal_hash), Error::::Imminent); + + let _ = T::Currency::repatriate_reserved(&old, &who, deposit); + >::remove(&proposal_hash); + Self::deposit_event(RawEvent::PreimageReaped(proposal_hash, old, deposit, who)); + } } } @@ -661,9 +808,9 @@ impl Module { /// Get all referenda currently active. pub fn active_referenda() - -> Vec<(ReferendumIndex, ReferendumInfo)> + -> Vec<(ReferendumIndex, ReferendumInfo)> { - let next = Self::next_tally(); + let next = Self::lowest_unbaked(); let last = Self::referendum_count(); (next..last).into_iter() .filter_map(|i| Self::referendum_info(i).map(|info| (i, info))) @@ -673,12 +820,12 @@ impl Module { /// Get all referenda ready for tally at block `n`. pub fn maturing_referenda_at( n: T::BlockNumber - ) -> Vec<(ReferendumIndex, ReferendumInfo)> { - let next = Self::next_tally(); + ) -> Vec<(ReferendumIndex, ReferendumInfo)> { + let next = Self::lowest_unbaked(); let last = Self::referendum_count(); (next..last).into_iter() .filter_map(|i| Self::referendum_info(i).map(|info| (i, info))) - .take_while(|&(_, ref info)| info.end == n) + .filter(|&(_, ref info)| info.end == n) .collect() } @@ -764,13 +911,13 @@ impl Module { /// Start a referendum. pub fn internal_start_referendum( - proposal: T::Proposal, + proposal_hash: T::Hash, threshold: VoteThreshold, delay: T::BlockNumber - ) -> result::Result { + ) -> ReferendumIndex { >::inject_referendum( - >::block_number() + T::VotingPeriod::get(), - proposal, + >::block_number() + T::VotingPeriod::get(), + proposal_hash, threshold, delay ) @@ -785,8 +932,8 @@ impl Module { // private. /// Actually enact a vote, if legit. - fn do_vote(who: T::AccountId, ref_index: ReferendumIndex, vote: Vote) -> Result { - ensure!(Self::is_active_referendum(ref_index), "vote given for invalid referendum."); + fn do_vote(who: T::AccountId, ref_index: ReferendumIndex, vote: Vote) -> DispatchResult { + ensure!(Self::is_active_referendum(ref_index), Error::::ReferendumInvalid); if !>::exists((ref_index, &who)) { >::append_or_insert(ref_index, &[&who][..]); } @@ -797,29 +944,30 @@ impl Module { /// Start a referendum fn inject_referendum( end: T::BlockNumber, - proposal: T::Proposal, + proposal_hash: T::Hash, threshold: VoteThreshold, delay: T::BlockNumber, - ) -> result::Result { + ) -> ReferendumIndex { let ref_index = Self::referendum_count(); - if ref_index.checked_sub(1) - .and_then(Self::referendum_info) - .map(|i| i.end > end) - .unwrap_or(false) - { - Err("Cannot inject a referendum that ends earlier than preceeding referendum")? - } - ReferendumCount::put(ref_index + 1); - let item = ReferendumInfo { end, proposal, threshold, delay }; + let item = ReferendumInfo { end, proposal_hash, threshold, delay }; >::insert(ref_index, item); Self::deposit_event(RawEvent::Started(ref_index, threshold)); - Ok(ref_index) + ref_index } /// Remove all info on a referendum. fn clear_referendum(ref_index: ReferendumIndex) { >::remove(ref_index); + + + LowestUnbaked::mutate(|i| if *i == ref_index { + *i += 1; + let end = ReferendumCount::get(); + while !Self::is_active_referendum(*i) && *i < end { + *i += 1; + } + }); >::remove(ref_index); for v in Self::voters_for(ref_index) { >::remove((ref_index, v)); @@ -827,22 +975,38 @@ impl Module { } /// Enact a proposal from a referendum. - fn enact_proposal(proposal: T::Proposal, index: ReferendumIndex) { - let ok = proposal.dispatch(system::RawOrigin::Root.into()).is_ok(); - Self::deposit_event(RawEvent::Executed(index, ok)); + fn enact_proposal(proposal_hash: T::Hash, index: ReferendumIndex) -> DispatchResult { + if let Some((encoded_proposal, who, amount, _)) = >::take(&proposal_hash) { + if let Ok(proposal) = T::Proposal::decode(&mut &encoded_proposal[..]) { + let _ = T::Currency::unreserve(&who, amount); + Self::deposit_event(RawEvent::PreimageUsed(proposal_hash, who, amount)); + + let ok = proposal.dispatch(frame_system::RawOrigin::Root.into()).is_ok(); + Self::deposit_event(RawEvent::Executed(index, ok)); + + Ok(()) + } else { + T::Slash::on_unbalanced(T::Currency::slash_reserved(&who, amount).0); + Self::deposit_event(RawEvent::PreimageInvalid(proposal_hash, index)); + Err(Error::::PreimageInvalid.into()) + } + } else { + Self::deposit_event(RawEvent::PreimageMissing(proposal_hash, index)); + Err(Error::::PreimageMissing.into()) + } } /// Table the next waiting proposal for a vote. - fn launch_next(now: T::BlockNumber) -> Result { + fn launch_next(now: T::BlockNumber) -> DispatchResult { if LastTabledWasExternal::take() { Self::launch_public(now).or_else(|_| Self::launch_external(now)) } else { Self::launch_external(now).or_else(|_| Self::launch_public(now)) - }.map_err(|_| "No proposals waiting") + }.map_err(|_| Error::::NoneWaiting.into()) } /// Table the waiting external proposal for a vote, if there is one. - fn launch_external(now: T::BlockNumber) -> Result { + fn launch_external(now: T::BlockNumber) -> DispatchResult { if let Some((proposal, threshold)) = >::take() { LastTabledWasExternal::put(true); Self::deposit_event(RawEvent::ExternalTabled); @@ -851,15 +1015,15 @@ impl Module { proposal, threshold, T::EnactmentPeriod::get(), - )?; + ); Ok(()) } else { - Err("No external proposal waiting") + Err(Error::::NoneWaiting)? } } /// Table the waiting public proposal with the highest backing for a vote. - fn launch_public(now: T::BlockNumber) -> Result { + fn launch_public(now: T::BlockNumber) -> DispatchResult { let mut public_props = Self::public_props(); if let Some((winner_index, _)) = public_props.iter() .enumerate() @@ -880,11 +1044,11 @@ impl Module { proposal, VoteThreshold::SuperMajorityApprove, T::EnactmentPeriod::get(), - )?; + ); } Ok(()) } else { - Err("No public proposals waiting") + Err(Error::::NoneWaiting)? } } @@ -892,8 +1056,8 @@ impl Module { fn bake_referendum( now: T::BlockNumber, index: ReferendumIndex, - info: ReferendumInfo - ) -> Result { + info: ReferendumInfo + ) -> DispatchResult { let (approve, against, capital) = Self::tally(index); let total_issuance = T::Currency::total_issuance(); let approved = info.threshold.approved(approve, against, capital, total_issuance); @@ -905,7 +1069,7 @@ impl Module { .map(|a| (a.clone(), Self::vote_of((index, a)))) // ^^^ defensive only: all items come from `voters`; for an item to be in `voters` // there must be a vote registered; qed - .filter(|&(_, vote)| vote.aye == approved) // Just the winning coins + .filter(|&(_, vote)| vote.aye == approved) // Just the winning coins { // now plus: the base lock period multiplied by the number of periods this voter // offered to lock should they win... @@ -921,27 +1085,27 @@ impl Module { } Self::clear_referendum(index); + if approved { Self::deposit_event(RawEvent::Passed(index)); if info.delay.is_zero() { - Self::enact_proposal(info.proposal, index); + let _ = Self::enact_proposal(info.proposal_hash, index); } else { - >::append_or_insert( - now + info.delay, - &[Some((info.proposal, index))][..] - ); + let item = (now + info.delay,info.proposal_hash, index); + >::mutate(|queue| { + let pos = queue.binary_search_by_key(&item.0, |x| x.0).unwrap_or_else(|e| e); + queue.insert(pos, item); + }); } } else { Self::deposit_event(RawEvent::NotPassed(index)); } - NextTally::put(index + 1); Ok(()) } /// Current era is ending; we should finish up any proposals. - // TODO: move to initialize_block #2779 - fn end_block(now: T::BlockNumber) -> Result { + fn begin_block(now: T::BlockNumber) -> DispatchResult { // pick out another public referendum if it's time. if (now % T::LaunchPeriod::get()).is_zero() { // Errors come from the queue being empty. we don't really care about that, and even if @@ -954,8 +1118,15 @@ impl Module { Self::bake_referendum(now, index, info)?; } - for (proposal, index) in >::take(now).into_iter().filter_map(|x| x) { - Self::enact_proposal(proposal, index); + let queue = >::get(); + let mut used = 0; + // It's stored in order, so the earliest will always be at the start. + for &(_, proposal_hash, index) in queue.iter().take_while(|x| x.0 == now) { + let _ = Self::enact_proposal(proposal_hash.clone(), index); + used += 1; + } + if used != 0 { + >::put(&queue[used..]); } Ok(()) } @@ -970,14 +1141,19 @@ impl OnFreeBalanceZero for Module { #[cfg(test)] mod tests { use super::*; - use support::{ + use std::cell::RefCell; + use frame_support::{ impl_outer_origin, impl_outer_dispatch, assert_noop, assert_ok, parameter_types, - traits::Contains + traits::Contains, + weights::Weight, }; - use primitives::H256; - use sr_primitives::{traits::{BlakeTwo256, IdentityLookup, Bounded}, testing::Header, Perbill}; - use balances::BalanceLock; - use system::EnsureSignedBy; + use sp_core::H256; + use sp_runtime::{ + traits::{BlakeTwo256, IdentityLookup, Bounded, BadOrigin}, + testing::Header, Perbill, + }; + use pallet_balances::BalanceLock; + use frame_system::EnsureSignedBy; const AYE: Vote = Vote{ aye: true, conviction: Conviction::None }; const NAY: Vote = Vote{ aye: false, conviction: Conviction::None }; @@ -985,12 +1161,12 @@ mod tests { const BIG_NAY: Vote = Vote{ aye: false, conviction: Conviction::Locked1x }; impl_outer_origin! { - pub enum Origin for Test {} + pub enum Origin for Test where system = frame_system {} } impl_outer_dispatch! { pub enum Call for Test where origin: Origin { - balances::Balances, + pallet_balances::Balances, democracy::Democracy, } } @@ -1000,11 +1176,11 @@ mod tests { pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockWeight: Weight = 1024; pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } - impl system::Trait for Test { + impl frame_system::Trait for Test { type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -1020,13 +1196,14 @@ mod tests { type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); + type ModuleToIndex = (); } parameter_types! { pub const ExistentialDeposit: u64 = 0; pub const TransferFee: u64 = 0; pub const CreationFee: u64 = 0; } - impl balances::Trait for Test { + impl pallet_balances::Trait for Test { type Balance = u64; type OnFreeBalanceZero = (); type OnNewAccount = (); @@ -1056,10 +1233,17 @@ mod tests { *n >= 1 && *n <= 5 } } + thread_local! { + static PREIMAGE_BYTE_DEPOSIT: RefCell = RefCell::new(0); + } + pub struct PreimageByteDeposit; + impl Get for PreimageByteDeposit { + fn get() -> u64 { PREIMAGE_BYTE_DEPOSIT.with(|v| *v.borrow()) } + } impl super::Trait for Test { type Proposal = Call; type Event = (); - type Currency = balances::Module; + type Currency = pallet_balances::Module; type EnactmentPeriod = EnactmentPeriod; type LaunchPeriod = LaunchPeriod; type VotingPeriod = VotingPeriod; @@ -1072,20 +1256,22 @@ mod tests { type CancellationOrigin = EnsureSignedBy; type VetoOrigin = EnsureSignedBy; type CooloffPeriod = CooloffPeriod; + type PreimageByteDeposit = PreimageByteDeposit; + type Slash = (); } - fn new_test_ext() -> runtime_io::TestExternalities { - let mut t = system::GenesisConfig::default().build_storage::().unwrap(); - balances::GenesisConfig::{ + fn new_test_ext() -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); + pallet_balances::GenesisConfig::{ balances: vec![(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)], vesting: vec![], }.assimilate_storage(&mut t).unwrap(); GenesisConfig::default().assimilate_storage(&mut t).unwrap(); - runtime_io::TestExternalities::new(t) + sp_io::TestExternalities::new(t) } - type System = system::Module; - type Balances = balances::Module; + type System = frame_system::Module; + type Balances = pallet_balances::Module; type Democracy = Module; #[test] @@ -1097,21 +1283,44 @@ mod tests { }); } - fn set_balance_proposal(value: u64) -> Call { - Call::Balances(balances::Call::set_balance(42, value, 0)) + fn set_balance_proposal(value: u64) -> Vec { + Call::Balances(pallet_balances::Call::set_balance(42, value, 0)).encode() + } + + fn set_balance_proposal_hash(value: u64) -> H256 { + BlakeTwo256::hash(&set_balance_proposal(value)[..]) + } + + fn set_balance_proposal_hash_and_note(value: u64) -> H256 { + let p = set_balance_proposal(value); + let h = BlakeTwo256::hash(&p[..]); + match Democracy::note_preimage(Origin::signed(6), p) { + Ok(_) => (), + Err(x) if x == Error::::DuplicatePreimage.into() => (), + Err(x) => panic!(x), + } + h } - fn propose_set_balance(who: u64, value: u64, delay: u64) -> super::Result { + fn propose_set_balance(who: u64, value: u64, delay: u64) -> DispatchResult { Democracy::propose( Origin::signed(who), - Box::new(set_balance_proposal(value)), + set_balance_proposal_hash(value), + delay + ) + } + + fn propose_set_balance_and_note(who: u64, value: u64, delay: u64) -> DispatchResult { + Democracy::propose( + Origin::signed(who), + set_balance_proposal_hash_and_note(value), delay ) } fn next_block() { - assert_eq!(Democracy::end_block(System::block_number()), Ok(())); System::set_block_number(System::block_number() + 1); + assert_eq!(Democracy::begin_block(System::block_number()), Ok(())); } fn fast_forward_to(n: u64) { @@ -1120,24 +1329,169 @@ mod tests { } } + #[test] + fn missing_preimage_should_fail() { + new_test_ext().execute_with(|| { + System::set_block_number(1); + let r = Democracy::inject_referendum( + 2, + set_balance_proposal_hash(2), + VoteThreshold::SuperMajorityApprove, + 0 + ); + assert_ok!(Democracy::vote(Origin::signed(1), r, AYE)); + + next_block(); + next_block(); + + assert_eq!(Balances::free_balance(&42), 0); + }); + } + + #[test] + fn preimage_deposit_should_be_required_and_returned() { + new_test_ext().execute_with(|| { + System::set_block_number(1); + // fee of 100 is too much. + PREIMAGE_BYTE_DEPOSIT.with(|v| *v.borrow_mut() = 100); + assert_noop!( + Democracy::note_preimage(Origin::signed(6), vec![0; 500]), + "not enough free funds", + ); + // fee of 1 is reasonable. + PREIMAGE_BYTE_DEPOSIT.with(|v| *v.borrow_mut() = 1); + let r = Democracy::inject_referendum( + 2, + set_balance_proposal_hash_and_note(2), + VoteThreshold::SuperMajorityApprove, + 0 + ); + assert_ok!(Democracy::vote(Origin::signed(1), r, AYE)); + + assert_eq!(Balances::reserved_balance(6), 12); + + next_block(); + next_block(); + + assert_eq!(Balances::reserved_balance(6), 0); + assert_eq!(Balances::free_balance(6), 60); + assert_eq!(Balances::free_balance(42), 2); + }); + } + + #[test] + fn preimage_deposit_should_be_reapable_earlier_by_owner() { + new_test_ext().execute_with(|| { + System::set_block_number(1); + PREIMAGE_BYTE_DEPOSIT.with(|v| *v.borrow_mut() = 1); + assert_ok!(Democracy::note_preimage(Origin::signed(6), set_balance_proposal(2))); + + assert_eq!(Balances::reserved_balance(6), 12); + + next_block(); + assert_noop!( + Democracy::reap_preimage(Origin::signed(6), set_balance_proposal_hash(2)), + Error::::Early + ); + next_block(); + assert_ok!(Democracy::reap_preimage(Origin::signed(6), set_balance_proposal_hash(2))); + + assert_eq!(Balances::reserved_balance(6), 0); + assert_eq!(Balances::free_balance(6), 60); + }); + } + + #[test] + fn preimage_deposit_should_be_reapable() { + new_test_ext().execute_with(|| { + System::set_block_number(1); + assert_noop!( + Democracy::reap_preimage(Origin::signed(5), set_balance_proposal_hash(2)), + Error::::PreimageMissing + ); + + PREIMAGE_BYTE_DEPOSIT.with(|v| *v.borrow_mut() = 1); + assert_ok!(Democracy::note_preimage(Origin::signed(6), set_balance_proposal(2))); + assert_eq!(Balances::reserved_balance(6), 12); + + next_block(); + next_block(); + next_block(); + assert_noop!( + Democracy::reap_preimage(Origin::signed(5), set_balance_proposal_hash(2)), + Error::::Early + ); + + next_block(); + assert_ok!(Democracy::reap_preimage(Origin::signed(5), set_balance_proposal_hash(2))); + assert_eq!(Balances::reserved_balance(6), 0); + assert_eq!(Balances::free_balance(6), 48); + assert_eq!(Balances::free_balance(5), 62); + }); + } + + #[test] + fn noting_imminent_preimage_for_free_should_work() { + new_test_ext().execute_with(|| { + System::set_block_number(1); + PREIMAGE_BYTE_DEPOSIT.with(|v| *v.borrow_mut() = 1); + + let r = Democracy::inject_referendum( + 2, + set_balance_proposal_hash(2), + VoteThreshold::SuperMajorityApprove, + 1 + ); + assert_ok!(Democracy::vote(Origin::signed(1), r, AYE)); + + assert_noop!( + Democracy::note_imminent_preimage(Origin::signed(7), set_balance_proposal(2)), + Error::::NotImminent + ); + + next_block(); + + // Now we're in the dispatch queue it's all good. + assert_ok!(Democracy::note_imminent_preimage(Origin::signed(7), set_balance_proposal(2))); + + next_block(); + + assert_eq!(Balances::free_balance(42), 2); + }); + } + + #[test] + fn reaping_imminent_preimage_should_fail() { + new_test_ext().execute_with(|| { + System::set_block_number(1); + let h = set_balance_proposal_hash_and_note(2); + let r = Democracy::inject_referendum(3, h, VoteThreshold::SuperMajorityApprove, 1); + assert_ok!(Democracy::vote(Origin::signed(1), r, AYE)); + next_block(); + next_block(); + // now imminent. + assert_noop!(Democracy::reap_preimage(Origin::signed(6), h), Error::::Imminent); + }); + } + #[test] fn external_and_public_interleaving_works() { new_test_ext().execute_with(|| { System::set_block_number(0); assert_ok!(Democracy::external_propose( Origin::signed(2), - Box::new(set_balance_proposal(1)), + set_balance_proposal_hash_and_note(1), )); - assert_ok!(propose_set_balance(6, 2, 2)); + assert_ok!(propose_set_balance_and_note(6, 2, 2)); - fast_forward_to(1); + fast_forward_to(2); // both waiting: external goes first. assert_eq!( Democracy::referendum_info(0), Some(ReferendumInfo { - end: 2, - proposal: set_balance_proposal(1), + end: 4, + proposal_hash: set_balance_proposal_hash_and_note(1), threshold: VoteThreshold::SuperMajorityApprove, delay: 2 }) @@ -1145,31 +1499,31 @@ mod tests { // replenish external assert_ok!(Democracy::external_propose( Origin::signed(2), - Box::new(set_balance_proposal(3)), + set_balance_proposal_hash_and_note(3), )); - fast_forward_to(3); + fast_forward_to(4); // both waiting: public goes next. assert_eq!( Democracy::referendum_info(1), Some(ReferendumInfo { - end: 4, - proposal: set_balance_proposal(2), + end: 6, + proposal_hash: set_balance_proposal_hash_and_note(2), threshold: VoteThreshold::SuperMajorityApprove, delay: 2 }) ); // don't replenish public - fast_forward_to(5); + fast_forward_to(6); // it's external "turn" again, though since public is empty that doesn't really matter assert_eq!( Democracy::referendum_info(2), Some(ReferendumInfo { - end: 6, - proposal: set_balance_proposal(3), + end: 8, + proposal_hash: set_balance_proposal_hash_and_note(3), threshold: VoteThreshold::SuperMajorityApprove, delay: 2 }) @@ -1177,17 +1531,17 @@ mod tests { // replenish external assert_ok!(Democracy::external_propose( Origin::signed(2), - Box::new(set_balance_proposal(5)), + set_balance_proposal_hash_and_note(5), )); - fast_forward_to(7); + fast_forward_to(8); // external goes again because there's no public waiting. assert_eq!( Democracy::referendum_info(3), Some(ReferendumInfo { - end: 8, - proposal: set_balance_proposal(5), + end: 10, + proposal_hash: set_balance_proposal_hash_and_note(5), threshold: VoteThreshold::SuperMajorityApprove, delay: 2 }) @@ -1195,36 +1549,36 @@ mod tests { // replenish both assert_ok!(Democracy::external_propose( Origin::signed(2), - Box::new(set_balance_proposal(7)), + set_balance_proposal_hash_and_note(7), )); - assert_ok!(propose_set_balance(6, 4, 2)); + assert_ok!(propose_set_balance_and_note(6, 4, 2)); - fast_forward_to(9); + fast_forward_to(10); // public goes now since external went last time. assert_eq!( Democracy::referendum_info(4), Some(ReferendumInfo { - end: 10, - proposal: set_balance_proposal(4), + end: 12, + proposal_hash: set_balance_proposal_hash_and_note(4), threshold: VoteThreshold::SuperMajorityApprove, delay: 2 }) ); // replenish public again - assert_ok!(propose_set_balance(6, 6, 2)); + assert_ok!(propose_set_balance_and_note(6, 6, 2)); // cancel external - let h = BlakeTwo256::hash_of(&set_balance_proposal(7)); + let h = set_balance_proposal_hash_and_note(7); assert_ok!(Democracy::veto_external(Origin::signed(3), h)); - fast_forward_to(11); + fast_forward_to(12); // public goes again now since there's no external waiting. assert_eq!( Democracy::referendum_info(5), Some(ReferendumInfo { - end: 12, - proposal: set_balance_proposal(6), + end: 14, + proposal_hash: set_balance_proposal_hash_and_note(6), threshold: VoteThreshold::SuperMajorityApprove, delay: 2 }) @@ -1239,13 +1593,13 @@ mod tests { System::set_block_number(0); let r = Democracy::inject_referendum( 2, - set_balance_proposal(2), + set_balance_proposal_hash_and_note(2), VoteThreshold::SuperMajorityApprove, 2 - ).unwrap(); + ); assert!(Democracy::referendum_info(r).is_some()); - assert_noop!(Democracy::emergency_cancel(Origin::signed(3), r), "Invalid origin"); + assert_noop!(Democracy::emergency_cancel(Origin::signed(3), r), BadOrigin); assert_ok!(Democracy::emergency_cancel(Origin::signed(4), r)); assert!(Democracy::referendum_info(r).is_none()); @@ -1253,12 +1607,12 @@ mod tests { let r = Democracy::inject_referendum( 2, - set_balance_proposal(2), + set_balance_proposal_hash_and_note(2), VoteThreshold::SuperMajorityApprove, 2 - ).unwrap(); + ); assert!(Democracy::referendum_info(r).is_some()); - assert_noop!(Democracy::emergency_cancel(Origin::signed(4), r), "cannot cancel the same proposal twice"); + assert_noop!(Democracy::emergency_cancel(Origin::signed(4), r), Error::::AlreadyCanceled); }); } @@ -1268,39 +1622,39 @@ mod tests { System::set_block_number(0); assert_ok!(Democracy::external_propose( Origin::signed(2), - Box::new(set_balance_proposal(2)), + set_balance_proposal_hash_and_note(2), )); assert!(>::exists()); - let h = BlakeTwo256::hash_of(&set_balance_proposal(2)); + let h = set_balance_proposal_hash_and_note(2); assert_ok!(Democracy::veto_external(Origin::signed(3), h.clone())); // cancelled. assert!(!>::exists()); // fails - same proposal can't be resubmitted. assert_noop!(Democracy::external_propose( Origin::signed(2), - Box::new(set_balance_proposal(2)), - ), "proposal still blacklisted"); + set_balance_proposal_hash(2), + ), Error::::ProposalBlacklisted); fast_forward_to(1); // fails as we're still in cooloff period. assert_noop!(Democracy::external_propose( Origin::signed(2), - Box::new(set_balance_proposal(2)), - ), "proposal still blacklisted"); + set_balance_proposal_hash(2), + ), Error::::ProposalBlacklisted); fast_forward_to(2); // works; as we're out of the cooloff period. assert_ok!(Democracy::external_propose( Origin::signed(2), - Box::new(set_balance_proposal(2)), + set_balance_proposal_hash_and_note(2), )); assert!(>::exists()); // 3 can't veto the same thing twice. assert_noop!( Democracy::veto_external(Origin::signed(3), h.clone()), - "identity may not veto a proposal twice" + Error::::AlreadyVetoed ); // 4 vetoes. @@ -1312,12 +1666,12 @@ mod tests { // same proposal fails as we're still in cooloff assert_noop!(Democracy::external_propose( Origin::signed(2), - Box::new(set_balance_proposal(2)), - ), "proposal still blacklisted"); + set_balance_proposal_hash(2), + ), Error::::ProposalBlacklisted); // different proposal works fine. assert_ok!(Democracy::external_propose( Origin::signed(2), - Box::new(set_balance_proposal(3)), + set_balance_proposal_hash_and_note(3), )); }); } @@ -1326,24 +1680,27 @@ mod tests { fn external_referendum_works() { new_test_ext().execute_with(|| { System::set_block_number(0); - assert_noop!(Democracy::external_propose( - Origin::signed(1), - Box::new(set_balance_proposal(2)), - ), "Invalid origin"); + assert_noop!( + Democracy::external_propose( + Origin::signed(1), + set_balance_proposal_hash(2), + ), + BadOrigin, + ); assert_ok!(Democracy::external_propose( Origin::signed(2), - Box::new(set_balance_proposal(2)), + set_balance_proposal_hash_and_note(2), )); assert_noop!(Democracy::external_propose( Origin::signed(2), - Box::new(set_balance_proposal(1)), - ), "proposal already made"); - fast_forward_to(1); + set_balance_proposal_hash(1), + ), Error::::DuplicateProposal); + fast_forward_to(2); assert_eq!( Democracy::referendum_info(0), Some(ReferendumInfo { - end: 2, - proposal: set_balance_proposal(2), + end: 4, + proposal_hash: set_balance_proposal_hash(2), threshold: VoteThreshold::SuperMajorityApprove, delay: 2 }) @@ -1355,20 +1712,23 @@ mod tests { fn external_majority_referendum_works() { new_test_ext().execute_with(|| { System::set_block_number(0); - assert_noop!(Democracy::external_propose_majority( - Origin::signed(1), - Box::new(set_balance_proposal(2)) - ), "Invalid origin"); + assert_noop!( + Democracy::external_propose_majority( + Origin::signed(1), + set_balance_proposal_hash(2) + ), + BadOrigin, + ); assert_ok!(Democracy::external_propose_majority( Origin::signed(3), - Box::new(set_balance_proposal(2)) + set_balance_proposal_hash_and_note(2) )); - fast_forward_to(1); + fast_forward_to(2); assert_eq!( Democracy::referendum_info(0), Some(ReferendumInfo { - end: 2, - proposal: set_balance_proposal(2), + end: 4, + proposal_hash: set_balance_proposal_hash(2), threshold: VoteThreshold::SimpleMajority, delay: 2, }) @@ -1380,20 +1740,23 @@ mod tests { fn external_default_referendum_works() { new_test_ext().execute_with(|| { System::set_block_number(0); - assert_noop!(Democracy::external_propose_default( - Origin::signed(3), - Box::new(set_balance_proposal(2)) - ), "Invalid origin"); + assert_noop!( + Democracy::external_propose_default( + Origin::signed(3), + set_balance_proposal_hash(2) + ), + BadOrigin, + ); assert_ok!(Democracy::external_propose_default( Origin::signed(1), - Box::new(set_balance_proposal(2)) + set_balance_proposal_hash_and_note(2) )); - fast_forward_to(1); + fast_forward_to(2); assert_eq!( Democracy::referendum_info(0), Some(ReferendumInfo { - end: 2, - proposal: set_balance_proposal(2), + end: 4, + proposal_hash: set_balance_proposal_hash(2), threshold: VoteThreshold::SuperMajorityAgainst, delay: 2, }) @@ -1405,19 +1768,19 @@ mod tests { fn fast_track_referendum_works() { new_test_ext().execute_with(|| { System::set_block_number(0); - let h = BlakeTwo256::hash_of(&set_balance_proposal(2)); - assert_noop!(Democracy::fast_track(Origin::signed(5), h, 3, 2), "no proposal made"); + let h = set_balance_proposal_hash_and_note(2); + assert_noop!(Democracy::fast_track(Origin::signed(5), h, 3, 2), Error::::ProposalMissing); assert_ok!(Democracy::external_propose_majority( Origin::signed(3), - Box::new(set_balance_proposal(2)) + set_balance_proposal_hash_and_note(2) )); - assert_noop!(Democracy::fast_track(Origin::signed(1), h, 3, 2), "Invalid origin"); + assert_noop!(Democracy::fast_track(Origin::signed(1), h, 3, 2), BadOrigin); assert_ok!(Democracy::fast_track(Origin::signed(5), h, 0, 0)); assert_eq!( Democracy::referendum_info(0), Some(ReferendumInfo { end: 1, - proposal: set_balance_proposal(2), + proposal_hash: set_balance_proposal_hash_and_note(2), threshold: VoteThreshold::SimpleMajority, delay: 0, }) @@ -1429,14 +1792,14 @@ mod tests { fn fast_track_referendum_fails_when_no_simple_majority() { new_test_ext().execute_with(|| { System::set_block_number(0); - let h = BlakeTwo256::hash_of(&set_balance_proposal(2)); + let h = set_balance_proposal_hash_and_note(2); assert_ok!(Democracy::external_propose( Origin::signed(2), - Box::new(set_balance_proposal(2)) + set_balance_proposal_hash_and_note(2) )); assert_noop!( Democracy::fast_track(Origin::signed(5), h, 3, 2), - "next external proposal not simple majority" + Error::::NotSimpleMajority ); }); } @@ -1445,9 +1808,9 @@ mod tests { fn locked_for_should_work() { new_test_ext().execute_with(|| { System::set_block_number(1); - assert_ok!(propose_set_balance(1, 2, 2)); - assert_ok!(propose_set_balance(1, 4, 4)); - assert_ok!(propose_set_balance(1, 3, 3)); + assert_ok!(propose_set_balance_and_note(1, 2, 2)); + assert_ok!(propose_set_balance_and_note(1, 4, 4)); + assert_ok!(propose_set_balance_and_note(1, 3, 3)); assert_eq!(Democracy::locked_for(0), Some(2)); assert_eq!(Democracy::locked_for(1), Some(4)); assert_eq!(Democracy::locked_for(2), Some(3)); @@ -1458,11 +1821,11 @@ mod tests { fn single_proposal_should_work() { new_test_ext().execute_with(|| { System::set_block_number(0); - assert_ok!(propose_set_balance(1, 2, 1)); + assert_ok!(propose_set_balance_and_note(1, 2, 1)); assert!(Democracy::referendum_info(0).is_none()); - // end of 0 => next referendum scheduled. - fast_forward_to(1); + // start of 2 => next referendum scheduled. + fast_forward_to(2); let r = 0; assert_ok!(Democracy::vote(Origin::signed(1), r, AYE)); @@ -1471,8 +1834,8 @@ mod tests { assert_eq!( Democracy::referendum_info(0), Some(ReferendumInfo { - end: 2, - proposal: set_balance_proposal(2), + end: 4, + proposal_hash: set_balance_proposal_hash_and_note(2), threshold: VoteThreshold::SuperMajorityApprove, delay: 2 }) @@ -1481,21 +1844,21 @@ mod tests { assert_eq!(Democracy::vote_of((r, 1)), AYE); assert_eq!(Democracy::tally(r), (1, 0, 1)); - fast_forward_to(2); + fast_forward_to(3); // referendum still running assert!(Democracy::referendum_info(0).is_some()); - // referendum runs during 1 and 2, ends @ end of 2. - fast_forward_to(3); + // referendum runs during 2 and 3, ends @ start of 4. + fast_forward_to(4); assert!(Democracy::referendum_info(0).is_none()); - assert_eq!(Democracy::dispatch_queue(4), vec![ - Some((set_balance_proposal(2), 0)) + assert_eq!(Democracy::dispatch_queue(), vec![ + (6, set_balance_proposal_hash_and_note(2), 0) ]); // referendum passes and wait another two blocks for enactment. - fast_forward_to(5); + fast_forward_to(6); assert_eq!(Balances::free_balance(&42), 2); }); @@ -1505,23 +1868,22 @@ mod tests { fn cancel_queued_should_work() { new_test_ext().execute_with(|| { System::set_block_number(0); - assert_ok!(propose_set_balance(1, 2, 1)); + assert_ok!(propose_set_balance_and_note(1, 2, 1)); - // end of 0 => next referendum scheduled. - fast_forward_to(1); + // start of 2 => next referendum scheduled. + fast_forward_to(2); assert_ok!(Democracy::vote(Origin::signed(1), 0, AYE)); - fast_forward_to(3); + fast_forward_to(4); - assert_eq!(Democracy::dispatch_queue(4), vec![ - Some((set_balance_proposal(2), 0)) + assert_eq!(Democracy::dispatch_queue(), vec![ + (6, set_balance_proposal_hash_and_note(2), 0) ]); - assert_noop!(Democracy::cancel_queued(Origin::ROOT, 3, 0, 0), "proposal not found"); - assert_noop!(Democracy::cancel_queued(Origin::ROOT, 4, 1, 0), "proposal not found"); - assert_ok!(Democracy::cancel_queued(Origin::ROOT, 4, 0, 0)); - assert_eq!(Democracy::dispatch_queue(4), vec![None]); + assert_noop!(Democracy::cancel_queued(Origin::ROOT, 1), Error::::ProposalMissing); + assert_ok!(Democracy::cancel_queued(Origin::ROOT, 0)); + assert_eq!(Democracy::dispatch_queue(), vec![]); }); } @@ -1533,7 +1895,7 @@ mod tests { assert_eq!(Democracy::proxy(10), Some(1)); // Can't set when already set. - assert_noop!(Democracy::set_proxy(Origin::signed(2), 10), "already a proxy"); + assert_noop!(Democracy::set_proxy(Origin::signed(2), 10), Error::::AlreadyProxy); // But this works because 11 isn't proxying. assert_ok!(Democracy::set_proxy(Origin::signed(2), 11)); @@ -1541,7 +1903,7 @@ mod tests { assert_eq!(Democracy::proxy(11), Some(2)); // 2 cannot fire 1's proxy: - assert_noop!(Democracy::remove_proxy(Origin::signed(2), 10), "wrong proxy"); + assert_noop!(Democracy::remove_proxy(Origin::signed(2), 10), Error::::WrongProxy); // 1 fires his proxy: assert_ok!(Democracy::remove_proxy(Origin::signed(1), 10)); @@ -1559,9 +1921,9 @@ mod tests { fn single_proposal_should_work_with_proxy() { new_test_ext().execute_with(|| { System::set_block_number(0); - assert_ok!(propose_set_balance(1, 2, 1)); + assert_ok!(propose_set_balance_and_note(1, 2, 1)); - fast_forward_to(1); + fast_forward_to(2); let r = 0; assert_ok!(Democracy::set_proxy(Origin::signed(1), 10)); assert_ok!(Democracy::proxy_vote(Origin::signed(10), r, AYE)); @@ -1570,7 +1932,7 @@ mod tests { assert_eq!(Democracy::vote_of((r, 1)), AYE); assert_eq!(Democracy::tally(r), (1, 0, 1)); - fast_forward_to(5); + fast_forward_to(6); assert_eq!(Balances::free_balance(&42), 2); }); } @@ -1580,9 +1942,9 @@ mod tests { new_test_ext().execute_with(|| { System::set_block_number(0); - assert_ok!(propose_set_balance(1, 2, 1)); + assert_ok!(propose_set_balance_and_note(1, 2, 1)); - fast_forward_to(1); + fast_forward_to(2); // Delegate vote. assert_ok!(Democracy::delegate(Origin::signed(2), 1, Conviction::max_value())); @@ -1594,7 +1956,7 @@ mod tests { // Delegated vote is counted. assert_eq!(Democracy::tally(r), (3, 0, 3)); - fast_forward_to(5); + fast_forward_to(6); assert_eq!(Balances::free_balance(&42), 2); }); @@ -1605,9 +1967,9 @@ mod tests { new_test_ext().execute_with(|| { System::set_block_number(0); - assert_ok!(propose_set_balance(1, 2, 1)); + assert_ok!(propose_set_balance_and_note(1, 2, 1)); - fast_forward_to(1); + fast_forward_to(2); // Check behavior with cycle. assert_ok!(Democracy::delegate(Origin::signed(2), 1, Conviction::max_value())); @@ -1620,7 +1982,7 @@ mod tests { // Delegated vote is counted. assert_eq!(Democracy::tally(r), (6, 0, 6)); - fast_forward_to(5); + fast_forward_to(6); assert_eq!(Balances::free_balance(&42), 2); }); @@ -1632,9 +1994,9 @@ mod tests { new_test_ext().execute_with(|| { System::set_block_number(0); - assert_ok!(propose_set_balance(1, 2, 1)); + assert_ok!(propose_set_balance_and_note(1, 2, 1)); - fast_forward_to(1); + fast_forward_to(2); let r = 0; assert_ok!(Democracy::vote(Origin::signed(1), r, AYE)); @@ -1647,7 +2009,7 @@ mod tests { // Delegated vote is not counted. assert_eq!(Democracy::tally(r), (3, 0, 3)); - fast_forward_to(5); + fast_forward_to(6); assert_eq!(Balances::free_balance(&42), 2); }); @@ -1658,13 +2020,13 @@ mod tests { new_test_ext().execute_with(|| { System::set_block_number(0); - assert_ok!(propose_set_balance(1, 2, 1)); + assert_ok!(propose_set_balance_and_note(1, 2, 1)); // Delegate and undelegate vote. assert_ok!(Democracy::delegate(Origin::signed(2), 1, Conviction::max_value())); assert_ok!(Democracy::undelegate(Origin::signed(2))); - fast_forward_to(1); + fast_forward_to(2); let r = 0; assert_ok!(Democracy::vote(Origin::signed(1), r, AYE)); @@ -1675,7 +2037,7 @@ mod tests { // Delegated vote is not counted. assert_eq!(Democracy::tally(r), (1, 0, 1)); - fast_forward_to(5); + fast_forward_to(6); assert_eq!(Balances::free_balance(&42), 2); }); @@ -1687,9 +2049,9 @@ mod tests { new_test_ext().execute_with(|| { System::set_block_number(0); - assert_ok!(propose_set_balance(1, 2, 1)); + assert_ok!(propose_set_balance_and_note(1, 2, 1)); - fast_forward_to(1); + fast_forward_to(2); let r = 0; assert_ok!(Democracy::vote(Origin::signed(1), r, AYE)); @@ -1707,7 +2069,7 @@ mod tests { // Delegated vote is not counted. assert_eq!(Democracy::tally(r), (3, 0, 3)); - fast_forward_to(5); + fast_forward_to(6); assert_eq!(Balances::free_balance(&42), 2); }); @@ -1717,7 +2079,7 @@ mod tests { fn deposit_for_proposals_should_be_taken() { new_test_ext().execute_with(|| { System::set_block_number(1); - assert_ok!(propose_set_balance(1, 2, 5)); + assert_ok!(propose_set_balance_and_note(1, 2, 5)); assert_ok!(Democracy::second(Origin::signed(2), 0)); assert_ok!(Democracy::second(Origin::signed(5), 0)); assert_ok!(Democracy::second(Origin::signed(5), 0)); @@ -1732,7 +2094,7 @@ mod tests { fn deposit_for_proposals_should_be_returned() { new_test_ext().execute_with(|| { System::set_block_number(1); - assert_ok!(propose_set_balance(1, 2, 5)); + assert_ok!(propose_set_balance_and_note(1, 2, 5)); assert_ok!(Democracy::second(Origin::signed(2), 0)); assert_ok!(Democracy::second(Origin::signed(5), 0)); assert_ok!(Democracy::second(Origin::signed(5), 0)); @@ -1748,7 +2110,7 @@ mod tests { fn proposal_with_deposit_below_minimum_should_not_work() { new_test_ext().execute_with(|| { System::set_block_number(1); - assert_noop!(propose_set_balance(1, 2, 0), "value too low"); + assert_noop!(propose_set_balance(1, 2, 0), Error::::ValueLow); }); } @@ -1756,7 +2118,7 @@ mod tests { fn poor_proposer_should_not_work() { new_test_ext().execute_with(|| { System::set_block_number(1); - assert_noop!(propose_set_balance(1, 2, 11), "proposer\'s balance too low"); + assert_noop!(propose_set_balance(1, 2, 11), "not enough free funds"); }); } @@ -1764,8 +2126,8 @@ mod tests { fn poor_seconder_should_not_work() { new_test_ext().execute_with(|| { System::set_block_number(1); - assert_ok!(propose_set_balance(2, 2, 11)); - assert_noop!(Democracy::second(Origin::signed(1), 0), "seconder\'s balance too low"); + assert_ok!(propose_set_balance_and_note(2, 2, 11)); + assert_noop!(Democracy::second(Origin::signed(1), 0), "not enough free funds"); }); } @@ -1773,28 +2135,63 @@ mod tests { fn runners_up_should_come_after() { new_test_ext().execute_with(|| { System::set_block_number(0); - assert_ok!(propose_set_balance(1, 2, 2)); - assert_ok!(propose_set_balance(1, 4, 4)); - assert_ok!(propose_set_balance(1, 3, 3)); - fast_forward_to(1); + assert_ok!(propose_set_balance_and_note(1, 2, 2)); + assert_ok!(propose_set_balance_and_note(1, 4, 4)); + assert_ok!(propose_set_balance_and_note(1, 3, 3)); + fast_forward_to(2); assert_ok!(Democracy::vote(Origin::signed(1), 0, AYE)); - fast_forward_to(3); + fast_forward_to(4); assert_ok!(Democracy::vote(Origin::signed(1), 1, AYE)); - fast_forward_to(5); + fast_forward_to(6); assert_ok!(Democracy::vote(Origin::signed(1), 2, AYE)); }); } + #[test] + fn ooo_inject_referendums_should_work() { + new_test_ext().execute_with(|| { + System::set_block_number(1); + let r1 = Democracy::inject_referendum( + 3, + set_balance_proposal_hash_and_note(3), + VoteThreshold::SuperMajorityApprove, + 0 + ); + let r2 = Democracy::inject_referendum( + 2, + set_balance_proposal_hash_and_note(2), + VoteThreshold::SuperMajorityApprove, + 0 + ); + + assert_ok!(Democracy::vote(Origin::signed(1), r2, AYE)); + assert_eq!(Democracy::voters_for(r2), vec![1]); + assert_eq!(Democracy::vote_of((r2, 1)), AYE); + assert_eq!(Democracy::tally(r2), (1, 0, 1)); + + next_block(); + assert_eq!(Balances::free_balance(&42), 2); + + assert_ok!(Democracy::vote(Origin::signed(1), r1, AYE)); + assert_eq!(Democracy::voters_for(r1), vec![1]); + assert_eq!(Democracy::vote_of((r1, 1)), AYE); + assert_eq!(Democracy::tally(r1), (1, 0, 1)); + + next_block(); + assert_eq!(Balances::free_balance(&42), 3); + }); + } + #[test] fn simple_passing_should_work() { new_test_ext().execute_with(|| { System::set_block_number(1); let r = Democracy::inject_referendum( - 1, - set_balance_proposal(2), + 2, + set_balance_proposal_hash_and_note(2), VoteThreshold::SuperMajorityApprove, 0 - ).unwrap(); + ); assert_ok!(Democracy::vote(Origin::signed(1), r, AYE)); assert_eq!(Democracy::voters_for(r), vec![1]); @@ -1813,11 +2210,11 @@ mod tests { new_test_ext().execute_with(|| { System::set_block_number(1); let r = Democracy::inject_referendum( - 1, - set_balance_proposal(2), + 2, + set_balance_proposal_hash_and_note(2), VoteThreshold::SuperMajorityApprove, 0 - ).unwrap(); + ); assert_ok!(Democracy::vote(Origin::signed(1), r, AYE)); assert_ok!(Democracy::cancel_referendum(Origin::ROOT, r.into())); @@ -1833,11 +2230,11 @@ mod tests { new_test_ext().execute_with(|| { System::set_block_number(1); let r = Democracy::inject_referendum( - 1, - set_balance_proposal(2), + 2, + set_balance_proposal_hash_and_note(2), VoteThreshold::SuperMajorityApprove, 0 - ).unwrap(); + ); assert_ok!(Democracy::vote(Origin::signed(1), r, NAY)); assert_eq!(Democracy::voters_for(r), vec![1]); @@ -1856,11 +2253,12 @@ mod tests { new_test_ext().execute_with(|| { System::set_block_number(1); let r = Democracy::inject_referendum( - 1, - set_balance_proposal(2), + 2, + set_balance_proposal_hash_and_note(2), VoteThreshold::SuperMajorityApprove, 0 - ).unwrap(); + ); + assert_ok!(Democracy::vote(Origin::signed(1), r, BIG_AYE)); assert_ok!(Democracy::vote(Origin::signed(2), r, BIG_NAY)); assert_ok!(Democracy::vote(Origin::signed(3), r, BIG_NAY)); @@ -1882,11 +2280,11 @@ mod tests { new_test_ext().execute_with(|| { System::set_block_number(1); let r = Democracy::inject_referendum( - 1, - set_balance_proposal(2), + 2, + set_balance_proposal_hash_and_note(2), VoteThreshold::SuperMajorityApprove, 1 - ).unwrap(); + ); assert_ok!(Democracy::vote(Origin::signed(1), r, AYE)); assert_ok!(Democracy::vote(Origin::signed(2), r, AYE)); assert_ok!(Democracy::vote(Origin::signed(3), r, AYE)); @@ -1910,11 +2308,11 @@ mod tests { new_test_ext().execute_with(|| { System::set_block_number(1); let r = Democracy::inject_referendum( - 1, - set_balance_proposal(2), + 2, + set_balance_proposal_hash_and_note(2), VoteThreshold::SuperMajorityApprove, 0 - ).unwrap(); + ); assert_ok!(Democracy::vote(Origin::signed(5), r, BIG_NAY)); assert_ok!(Democracy::vote(Origin::signed(6), r, BIG_AYE)); @@ -1935,11 +2333,11 @@ mod tests { System::set_block_number(1); let r = Democracy::inject_referendum( - 1, - set_balance_proposal(2), + 2, + set_balance_proposal_hash_and_note(2), VoteThreshold::SuperMajorityApprove, 0 - ).unwrap(); + ); assert_ok!(Democracy::vote(Origin::signed(4), r, BIG_AYE)); assert_ok!(Democracy::vote(Origin::signed(5), r, BIG_NAY)); assert_ok!(Democracy::vote(Origin::signed(6), r, BIG_AYE)); @@ -1958,11 +2356,11 @@ mod tests { new_test_ext().execute_with(|| { System::set_block_number(0); let r = Democracy::inject_referendum( - 1, - set_balance_proposal(2), + 2, + set_balance_proposal_hash_and_note(2), VoteThreshold::SuperMajorityApprove, 0 - ).unwrap(); + ); assert_ok!(Democracy::vote(Origin::signed(1), r, Vote { aye: false, conviction: Conviction::Locked5x @@ -1992,19 +2390,19 @@ mod tests { assert_eq!(Balances::locks(2), vec![BalanceLock { id: DEMOCRACY_ID, amount: u64::max_value(), - until: 17, + until: 18, reasons: WithdrawReason::Transfer.into() }]); assert_eq!(Balances::locks(3), vec![BalanceLock { id: DEMOCRACY_ID, amount: u64::max_value(), - until: 9, + until: 10, reasons: WithdrawReason::Transfer.into() }]); assert_eq!(Balances::locks(4), vec![BalanceLock { id: DEMOCRACY_ID, amount: u64::max_value(), - until: 5, + until: 6, reasons: WithdrawReason::Transfer.into() }]); assert_eq!(Balances::locks(5), vec![]); @@ -2018,11 +2416,11 @@ mod tests { new_test_ext().execute_with(|| { System::set_block_number(1); let r = Democracy::inject_referendum( - 1, - set_balance_proposal(2), + 2, + set_balance_proposal_hash_and_note(2), VoteThreshold::SuperMajorityApprove, 0 - ).unwrap(); + ); assert_ok!(Democracy::vote(Origin::signed(1), r, Vote { aye: false, conviction: Conviction::Locked5x diff --git a/frame/democracy/src/vote_threshold.rs b/frame/democracy/src/vote_threshold.rs index 61e7e6535941ab6d797c6f9bbdcc14eefc63e0f4..d5e215fe32169dfa098afeb73d14117defd9e6fe 100644 --- a/frame/democracy/src/vote_threshold.rs +++ b/frame/democracy/src/vote_threshold.rs @@ -19,11 +19,11 @@ #[cfg(feature = "std")] use serde::{Serialize, Deserialize}; use codec::{Encode, Decode}; -use sr_primitives::traits::{Zero, IntegerSquareRoot}; -use rstd::ops::{Add, Mul, Div, Rem}; +use sp_runtime::traits::{Zero, IntegerSquareRoot}; +use sp_std::ops::{Add, Mul, Div, Rem}; /// A means of determining if a vote is past pass threshold. -#[derive(Clone, Copy, PartialEq, Eq, Encode, Decode, sr_primitives::RuntimeDebug)] +#[derive(Clone, Copy, PartialEq, Eq, Encode, Decode, sp_runtime::RuntimeDebug)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub enum VoteThreshold { /// A supermajority of approvals is needed to pass this vote. diff --git a/frame/elections-phragmen/Cargo.toml b/frame/elections-phragmen/Cargo.toml index bf17df628d07fc1928b0fd7be3d0dee6411870d5..9d0c3ed61c3b94bb6c6204b86fd675cc1587aa92 100644 --- a/frame/elections-phragmen/Cargo.toml +++ b/frame/elections-phragmen/Cargo.toml @@ -6,26 +6,27 @@ edition = "2018" [dependencies] codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -sr-primitives = { path = "../../primitives/sr-primitives", default-features = false } -phragmen = { package = "substrate-phragmen", path = "../../primitives/phragmen", default-features = false } -support = { package = "frame-support", path = "../support", default-features = false } -system = { package = "frame-system", path = "../system", default-features = false } -rstd = { package = "sr-std", path = "../../primitives/sr-std", default-features = false } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" } +sp-phragmen = { version = "2.0.0", default-features = false, path = "../../primitives/phragmen" } +frame-support = { version = "2.0.0", default-features = false, path = "../support" } +frame-system = { version = "2.0.0", default-features = false, path = "../system" } +sp-std = { version = "2.0.0", default-features = false, path = "../../primitives/std" } [dev-dependencies] -runtime_io = { package = "sr-io", path = "../../primitives/sr-io" } +sp-io = { version = "2.0.0", path = "../../primitives/io" } hex-literal = "0.2.1" -balances = { package = "pallet-balances", path = "../balances" } -primitives = { package = "substrate-primitives", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0", path = "../balances" } +sp-core = { version = "2.0.0", path = "../../primitives/core" } +substrate-test-utils = { version = "2.0.0", path = "../../test-utils" } serde = { version = "1.0.101" } [features] default = ["std"] std = [ "codec/std", - "support/std", - "sr-primitives/std", - "phragmen/std", - "system/std", - "rstd/std", + "frame-support/std", + "sp-runtime/std", + "sp-phragmen/std", + "frame-system/std", + "sp-std/std", ] diff --git a/frame/elections-phragmen/src/lib.rs b/frame/elections-phragmen/src/lib.rs index 978a2be0d79cb70b98499c9fa6de1b415a0dce06..8e937756498f5bef827a24de23e885fcfb7e8f15 100644 --- a/frame/elections-phragmen/src/lib.rs +++ b/frame/elections-phragmen/src/lib.rs @@ -52,15 +52,21 @@ //! //! Candidates also reserve a bond as they submit candidacy. A candidate cannot take their candidacy //! back. A candidate can end up in one of the below situations: -//! - **Winner**: A winner is kept as a _member_. They must still have a bond in reserve and they -//! are automatically counted as a candidate for the next election. -//! - **Loser**: Any of the candidate who are not a winner are left as losers. A loser might be an -//! _outgoing member_, meaning that they are an active member who failed to keep their spot. In -//! this case, the outgoing member will get their bond back. Otherwise, the bond is slashed from -//! the loser candidate. +//! - **Winner**: A winner is kept as a _member_. They must still have a bond in reserve and they +//! are automatically counted as a candidate for the next election. //! - **Runner-up**: Runners-up are the best candidates immediately after the winners. The number -//! of runners_up to keep is configurable. Runners-up are used, in order that they are elected, -//! as replacements when a candidate is kicked by `remove_member()`. +//! of runners_up to keep is configurable. Runners-up are used, in order that they are elected, +//! as replacements when a candidate is kicked by `[remove_member]`, or when an active member +//! renounces their candidacy. Runners are automatically counted as a candidate for the next +//! election. +//! - **Loser**: Any of the candidate who are not a winner are left as losers. A loser might be an +//! _outgoing member or runner_, meaning that they are an active member who failed to keep their +//! spot. An outgoing will always lose their bond. +//! +//! ##### Renouncing candidacy. +//! +//! All candidates, elected or not, can renounce their candidacy. A call to [`renounce_candidacy`] +//! will always cause the candidacy bond to be refunded. //! //! Note that with the members being the default candidates for the next round and votes persisting //! in storage, the election system is entirely stable given no further input. This means that if @@ -70,39 +76,36 @@ //! //! ### Module Information //! -//! - [`election_phragmen::Trait`](./trait.Trait.html) +//! - [`election_sp_phragmen::Trait`](./trait.Trait.html) //! - [`Call`](./enum.Call.html) //! - [`Module`](./struct.Module.html) #![cfg_attr(not(feature = "std"), no_std)] -use rstd::prelude::*; -use codec::Decode; -use sr_primitives::{print, traits::{Zero, StaticLookup, Bounded, Convert}}; -use support::weights::SimpleDispatchInfo; -use support::{ - decl_storage, decl_event, ensure, decl_module, dispatch, - storage::unhashed, +use sp_std::prelude::*; +use sp_runtime::{print, DispatchResult, traits::{Zero, StaticLookup, Bounded, Convert}}; +use frame_support::{ + decl_storage, decl_event, ensure, decl_module, weights::SimpleDispatchInfo, traits::{ Currency, Get, LockableCurrency, LockIdentifier, ReservableCurrency, WithdrawReasons, ChangeMembers, OnUnbalanced, WithdrawReason } }; -use phragmen::ExtendedBalance; -use system::{self, ensure_signed, ensure_root}; +use sp_phragmen::ExtendedBalance; +use frame_system::{self as system, ensure_signed, ensure_root}; const MODULE_ID: LockIdentifier = *b"phrelect"; /// The maximum votes allowed per voter. pub const MAXIMUM_VOTE: usize = 16; -type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; type NegativeImbalanceOf = - <::Currency as Currency<::AccountId>>::NegativeImbalance; + <::Currency as Currency<::AccountId>>::NegativeImbalance; -pub trait Trait: system::Trait { +pub trait Trait: frame_system::Trait { /// The overarching event type.c - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// The currency that people are electing with. type Currency: @@ -161,11 +164,6 @@ decl_storage! { /// The present candidate list. Sorted based on account id. A current member can never enter /// this vector and is always implicitly assumed to be a candidate. pub Candidates get(fn candidates): Vec; - - /// Has the storage format been updated? - /// NOTE: Only use and set to false if you have used an early version of this module. Should - /// be set to true otherwise. - DidMigrate: bool; } } @@ -315,6 +313,7 @@ decl_module! { let index = is_candidate.unwrap_err(); ensure!(!Self::is_member(&who), "member cannot re-submit candidacy"); + ensure!(!Self::is_runner(&who), "runner cannot re-submit candidacy"); T::Currency::reserve(&who, T::CandidacyBond::get()) .map_err(|_| "candidate does not have enough funds")?; @@ -322,7 +321,63 @@ decl_module! { >::mutate(|c| c.insert(index, who)); } - /// Remove a particular member from the set. This is effective immediately. + /// Renounce one's intention to be a candidate for the next election round. 3 potential + /// outcomes exist: + /// - `origin` is a candidate and not elected in any set. In this case, the bond is + /// unreserved, returned and origin is removed as a candidate. + /// - `origin` is a current runner up. In this case, the bond is unreserved, returned and + /// origin is removed as a runner. + /// - `origin` is a current member. In this case, the bond is unreserved and origin is + /// removed as a member, consequently not being a candidate for the next round anymore. + /// Similar to [`remove_voter`], if replacement runners exists, they are immediately used. + #[weight = SimpleDispatchInfo::FixedOperational(2_000_000)] + fn renounce_candidacy(origin) { + let who = ensure_signed(origin)?; + + // NOTE: this function attempts the 3 conditions (being a candidate, member, runner) and + // fails if none are matched. Unlike other Palette functions and modules where checks + // happen first and then execution happens, this function is written the other way + // around. The main intention is that reading all of the candidates, members and runners + // from storage is expensive. Furthermore, we know (soft proof) that they are always + // mutually exclusive. Hence, we try one, and only then decode more storage. + + if let Ok(_replacement) = Self::remove_and_replace_member(&who) { + T::Currency::unreserve(&who, T::CandidacyBond::get()); + Self::deposit_event(RawEvent::MemberRenounced(who.clone())); + + // safety guard to make sure we do only one arm. Better to read runners later. + return Ok(()); + } + + let mut runners_up_with_stake = Self::runners_up(); + if let Some(index) = runners_up_with_stake.iter() + .position(|(ref r, ref _s)| r == &who) + { + runners_up_with_stake.remove(index); + // unreserve the bond + T::Currency::unreserve(&who, T::CandidacyBond::get()); + // update storage. + >::put(runners_up_with_stake); + // safety guard to make sure we do only one arm. Better to read runners later. + return Ok(()); + } + + let mut candidates = Self::candidates(); + if let Ok(index) = candidates.binary_search(&who) { + candidates.remove(index); + // unreserve the bond + T::Currency::unreserve(&who, T::CandidacyBond::get()); + // update storage. + >::put(candidates); + // safety guard to make sure we do only one arm. Better to read runners later. + return Ok(()); + } + + Err("origin is not a candidate, member or a runner up.")? + } + + /// Remove a particular member from the set. This is effective immediately and the bond of + /// the outgoing member is slashed. /// /// If a runner-up is available, then the best runner-up will be removed and replaces the /// outgoing member. Otherwise, a new phragmen round is started. @@ -335,55 +390,23 @@ decl_module! { /// Writes: O(do_phragmen) /// # #[weight = SimpleDispatchInfo::FixedOperational(2_000_000)] - fn remove_member(origin, who: ::Source) { + fn remove_member(origin, who: ::Source) -> DispatchResult { ensure_root(origin)?; let who = T::Lookup::lookup(who)?; - let mut members_with_stake = Self::members(); - if let Ok(index) = members_with_stake.binary_search_by(|(ref m, ref _s)| m.cmp(&who)) { - // remove, slash, emit event. - members_with_stake.remove(index); + Self::remove_and_replace_member(&who).map(|had_replacement| { let (imbalance, _) = T::Currency::slash_reserved(&who, T::CandidacyBond::get()); T::KickedMember::on_unbalanced(imbalance); Self::deposit_event(RawEvent::MemberKicked(who.clone())); - let mut runners_up = Self::runners_up(); - if let Some((replacement, stake)) = runners_up.pop() { - // replace the outgoing with the best runner up. - if let Err(index) = members_with_stake - .binary_search_by(|(ref m, ref _s)| m.cmp(&replacement)) - { - members_with_stake.insert(index, (replacement.clone(), stake)); - ElectionRounds::mutate(|v| *v += 1); - T::ChangeMembers::change_members_sorted( - &[replacement], - &[who], - &members_with_stake - .iter() - .map(|(m, _)| m.clone()) - .collect::>(), - ); - } - // else it would mean that the runner up was already a member. This cannot - // happen. If it does, not much that we can do about it. - - >::put(members_with_stake); - >::put(runners_up); - } else { - // update `Members` storage -- `do_phragmen` adds this to the candidate list. - >::put(members_with_stake); - // trigger a new phragmen. grab a cup of coffee. This might take a while. + if !had_replacement { Self::do_phragmen(); } - } + }).map_err(Into::into) } /// What to do at the end of each block. Checks if an election needs to happen or not. fn on_initialize(n: T::BlockNumber) { - if !DidMigrate::exists() { - DidMigrate::put(true); - Self::do_migrate(); - } if let Err(e) = Self::end_block(n) { print("Guru meditation"); print(e); @@ -395,7 +418,7 @@ decl_module! { decl_event!( pub enum Event where Balance = BalanceOf, - ::AccountId, + ::AccountId, { /// A new term with new members. This indicates that enough candidates existed, not that /// enough have has been elected. The inner value must be examined for this purpose. @@ -405,6 +428,8 @@ decl_event!( /// A member has been removed. This should always be followed by either `NewTerm` ot /// `EmptyTerm`. MemberKicked(AccountId), + /// A member has renounced their candidacy. + MemberRenounced(AccountId), /// A voter (first element) was reported (byt the second element) with the the report being /// successful or not (third element). VoterReported(AccountId, AccountId, bool), @@ -412,6 +437,42 @@ decl_event!( ); impl Module { + /// Attempts to remove a member `who`. If a runner up exists, it is used as the replacement. + /// Otherwise, `Ok(false)` is returned to signal the caller. + /// + /// In both cases, [`Members`], [`ElectionRounds`] and [`RunnersUp`] storage are updated + /// accordingly. Furthermore, the membership change is reported. + /// + /// O(phragmen) in the worse case. + fn remove_and_replace_member(who: &T::AccountId) -> Result { + let mut members_with_stake = Self::members(); + if let Ok(index) = members_with_stake.binary_search_by(|(ref m, ref _s)| m.cmp(who)) { + members_with_stake.remove(index); + + let next_up = >::mutate(|runners_up| runners_up.pop()); + let maybe_replacement = next_up.and_then(|(replacement, stake)| + members_with_stake.binary_search_by(|(ref m, ref _s)| m.cmp(&replacement)) + .err() + .map(|index| { + members_with_stake.insert(index, (replacement.clone(), stake)); + replacement + }) + ); + + >::put(&members_with_stake); + let members = members_with_stake.into_iter().map(|m| m.0).collect::>(); + let result = Ok(maybe_replacement.is_some()); + let old = [who.clone()]; + match maybe_replacement { + Some(new) => T::ChangeMembers::change_members_sorted(&[new], &old, &members), + None => T::ChangeMembers::change_members_sorted(&[], &old, &members), + } + result + } else { + Err("not a member") + } + } + /// Check if `who` is a candidate. It returns the insert index if the element does not exists as /// an error. /// @@ -431,7 +492,14 @@ impl Module { /// /// Limited number of members. Binary search. Constant time factor. O(1) fn is_member(who: &T::AccountId) -> bool { - Self::members_ids().binary_search(who).is_ok() + Self::members().binary_search_by(|(a, _b)| a.cmp(who)).is_ok() + } + + /// Check if `who` is currently an active runner. + /// + /// Limited number of runners-up. Binary search. Constant time factor. O(1) + fn is_runner(who: &T::AccountId) -> bool { + Self::runners_up().binary_search_by(|(a, _b)| a.cmp(who)).is_ok() } /// Returns number of desired members. @@ -468,7 +536,7 @@ impl Module { if Self::is_voter(who) { Self::votes_of(who) .iter() - .all(|v| !Self::is_member(v) && !Self::is_candidate(v).is_ok()) + .all(|v| !Self::is_member(v) && !Self::is_runner(v) && !Self::is_candidate(v).is_ok()) } else { false } @@ -498,7 +566,7 @@ impl Module { /// /// Runs phragmen election and cleans all the previous candidate state. The voter state is NOT /// cleaned and voters must themselves submit a transaction to retract. - fn end_block(block_number: T::BlockNumber) -> dispatch::Result { + fn end_block(block_number: T::BlockNumber) -> DispatchResult { if !Self::term_duration().is_zero() { if (block_number % Self::term_duration()).is_zero() { Self::do_phragmen(); @@ -524,19 +592,17 @@ impl Module { let mut candidates = Self::candidates(); // candidates who explicitly called `submit_candidacy`. Only these folks are at the risk of // losing their bond. - let mut exposed_candidates = candidates.clone(); + let exposed_candidates = candidates.clone(); // current members are always a candidate for the next round as well. // this is guaranteed to not create any duplicates. candidates.append(&mut Self::members_ids()); // previous runners_up are also always candidates for the next round. candidates.append(&mut Self::runners_up_ids()); - // and exposed to being an outgoing in case they are no longer elected. - exposed_candidates.append(&mut Self::runners_up_ids()); let voters_and_votes = >::enumerate() .map(|(v, i)| (v, i)) .collect::)>>(); - let maybe_phragmen_result = phragmen::elect::<_, _, _, T::CurrencyToVote>( + let maybe_phragmen_result = sp_phragmen::elect::<_, _, _, T::CurrencyToVote>( num_to_elect, 0, candidates, @@ -544,9 +610,14 @@ impl Module { Self::locked_stake_of, ); - let mut to_release_bond: Vec = Vec::with_capacity(desired_seats); - let old_members = >::take(); if let Some(phragmen_result) = maybe_phragmen_result { + let old_members_ids = >::take().into_iter() + .map(|(m, _)| m) + .collect::>(); + let old_runners_up_ids = >::take().into_iter() + .map(|(r, _)| r) + .collect::>(); + // filter out those who had literally no votes at all. // AUDIT/NOTE: the need to do this is because all candidates, even those who have no // vote are still considered by phragmen and when good candidates are scarce, then these @@ -558,7 +629,7 @@ impl Module { .filter_map(|(m, a)| if a.is_zero() { None } else { Some(m) } ) .collect::>(); - let support_map = phragmen::build_support_map::<_, _, _, T::CurrencyToVote>( + let support_map = sp_phragmen::build_support_map::<_, _, _, T::CurrencyToVote>( &new_set, &phragmen_result.assignments, Self::locked_stake_of, @@ -578,111 +649,110 @@ impl Module { }) .collect::)>>(); - // split new set into winners and runner ups. + // split new set into winners and runners up. let split_point = desired_seats.min(new_set_with_stake.len()); let mut new_members = (&new_set_with_stake[..split_point]).to_vec(); - let runners_up = &new_set_with_stake[split_point..] + + // save the runners up as-is. They are sorted based on desirability. + // sort and save the members. + new_members.sort_by(|i, j| i.0.cmp(&j.0)); + + // new_members_ids is sorted by account id. + let new_members_ids = new_members + .iter() + .map(|(m, _)| m.clone()) + .collect::>(); + + let new_runners_up = &new_set_with_stake[split_point..] .into_iter() .cloned() .rev() .collect::)>>(); - - // sort and save the members. - new_members.sort(); - >::put(&new_members); - - // save the runners as-is - >::put(runners_up); + // new_runners_up remains sorted by desirability. + let new_runners_up_ids = new_runners_up + .iter() + .map(|(r, _)| r.clone()) + .collect::>(); // report member changes. We compute diff because we need the outgoing list. let (incoming, outgoing) = T::ChangeMembers::compute_members_diff( - &Self::members_ids(), - &old_members.into_iter().map(|(m, _)| m).collect::>(), + &new_members_ids, + &old_members_ids, ); T::ChangeMembers::change_members_sorted( &incoming, &outgoing.clone(), - &Self::members_ids(), + &new_members_ids, ); - // unlike exposed_candidates, these are members who were in the list and no longer - // exist. They must get their bond back. - to_release_bond = outgoing.to_vec(); + // outgoing candidates lose their bond. + let mut to_burn_bond = outgoing.to_vec(); + + // compute the outgoing of runners up as well and append them to the `to_burn_bond` + { + let (_, outgoing) = T::ChangeMembers::compute_members_diff( + &new_runners_up_ids, + &old_runners_up_ids, + ); + to_burn_bond.extend(outgoing); + } // Burn loser bond. members list is sorted. O(NLogM) (N candidates, M members) // runner up list is not sorted. O(K*N) given K runner ups. Overall: O(NLogM + N*K) + // both the member and runner counts are bounded. exposed_candidates.into_iter().for_each(|c| { // any candidate who is not a member and not a runner up. if new_members.binary_search_by_key(&c, |(m, _)| m.clone()).is_err() - && !Self::runners_up_ids().contains(&c) + && !new_runners_up_ids.contains(&c) { let (imbalance, _) = T::Currency::slash_reserved(&c, T::CandidacyBond::get()); T::LoserCandidate::on_unbalanced(imbalance); } }); - Self::deposit_event(RawEvent::NewTerm(new_members.to_vec())); + + // Burn outgoing bonds + to_burn_bond.into_iter().for_each(|x| { + let (imbalance, _) = T::Currency::slash_reserved(&x, T::CandidacyBond::get()); + T::LoserCandidate::on_unbalanced(imbalance); + }); + + >::put(&new_members); + >::put(new_runners_up); + + Self::deposit_event(RawEvent::NewTerm(new_members.clone().to_vec())); } else { Self::deposit_event(RawEvent::EmptyTerm); } - // unreserve the bond of all the outgoings. - to_release_bond.iter().for_each(|m| { - T::Currency::unreserve(&m, T::CandidacyBond::get()); - }); - // clean candidates. >::kill(); ElectionRounds::mutate(|v| *v += 1); } - - /// Perform the storage update needed to migrate the module from the initial version of the - /// storage. - /// - /// If decoding the old storage fails in any way, the consequence is that we start with an empty - /// set. - fn do_migrate() { - // old storage format. - let old_members: Vec = unhashed::get_raw(&>::hashed_key()) - .and_then(|bytes| Decode::decode(&mut &*bytes).ok()).unwrap_or_default(); - let old_runners: Vec = unhashed::get_raw(&>::hashed_key()) - .and_then(|bytes| Decode::decode(&mut &*bytes).ok()).unwrap_or_default(); - - // new storage format. - let new_runners: Vec<(T::AccountId, BalanceOf)> = old_runners - .into_iter() - .map(|r| (r, Zero::zero())) - .collect(); - let new_members: Vec<(T::AccountId, BalanceOf)> = old_members - .into_iter() - .map(|r| (r, Zero::zero())) - .collect(); - - >::put(new_members); - >::put(new_runners); - } } #[cfg(test)] mod tests { use super::*; use std::cell::RefCell; - use support::{assert_ok, assert_noop, parameter_types, assert_eq_uvec}; - use primitives::H256; - use sr_primitives::{ + use frame_support::{assert_ok, assert_noop, parameter_types, weights::Weight}; + use substrate_test_utils::assert_eq_uvec; + use sp_core::H256; + use sp_runtime::{ Perbill, testing::Header, BuildStorage, - traits::{OnInitialize, BlakeTwo256, IdentityLookup, Block as BlockT}, + traits::{BlakeTwo256, IdentityLookup, Block as BlockT}, }; use crate as elections; + use frame_system as system; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockWeight: Weight = 1024; pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } - impl system::Trait for Test { + impl frame_system::Trait for Test { type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -698,6 +768,7 @@ mod tests { type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); + type ModuleToIndex = (); } parameter_types! { @@ -706,7 +777,7 @@ mod tests { pub const CreationFee: u64 = 0; } - impl balances::Trait for Test { + impl pallet_balances::Trait for Test { type Balance = u64; type OnNewAccount = (); type OnFreeBalanceZero = (); @@ -749,9 +820,43 @@ mod tests { fn get() -> u64 { TERM_DURATION.with(|v| *v.borrow()) } } + thread_local! { + pub static MEMBERS: RefCell> = RefCell::new(vec![]); + } + pub struct TestChangeMembers; impl ChangeMembers for TestChangeMembers { - fn change_members_sorted(_: &[u64], _: &[u64], _: &[u64]) {} + fn change_members_sorted(incoming: &[u64], outgoing: &[u64], new: &[u64]) { + // new, incoming, outgoing must be sorted. + let mut new_sorted = new.to_vec(); + new_sorted.sort(); + assert_eq!(new, &new_sorted[..]); + + let mut incoming_sorted = incoming.to_vec(); + incoming_sorted.sort(); + assert_eq!(incoming, &incoming_sorted[..]); + + let mut outgoing_sorted = outgoing.to_vec(); + outgoing_sorted.sort(); + assert_eq!(outgoing, &outgoing_sorted[..]); + + // incoming and outgoing must be disjoint + for x in incoming.iter() { + assert!(outgoing.binary_search(x).is_err()); + } + + let mut old_plus_incoming = MEMBERS.with(|m| m.borrow().to_vec()); + old_plus_incoming.extend_from_slice(incoming); + old_plus_incoming.sort(); + + let mut new_plus_outgoing = new.to_vec(); + new_plus_outgoing.extend_from_slice(outgoing); + new_plus_outgoing.sort(); + + assert_eq!(old_plus_incoming, new_plus_outgoing); + + MEMBERS.with(|m| *m.borrow_mut() = new.to_vec()); + } } /// Simple structure that exposes how u64 currency can be represented as... u64. @@ -780,17 +885,17 @@ mod tests { type BadReport = (); } - pub type Block = sr_primitives::generic::Block; - pub type UncheckedExtrinsic = sr_primitives::generic::UncheckedExtrinsic; + pub type Block = sp_runtime::generic::Block; + pub type UncheckedExtrinsic = sp_runtime::generic::UncheckedExtrinsic; - support::construct_runtime!( + frame_support::construct_runtime!( pub enum Test where Block = Block, NodeBlock = Block, UncheckedExtrinsic = UncheckedExtrinsic { System: system::{Module, Call, Event}, - Balances: balances::{Module, Call, Event, Config}, + Balances: pallet_balances::{Module, Call, Event, Config}, Elections: elections::{Module, Call, Event}, } ); @@ -826,12 +931,12 @@ mod tests { self.term_duration = duration; self } - pub fn build(self) -> runtime_io::TestExternalities { + pub fn build(self) -> sp_io::TestExternalities { VOTING_BOND.with(|v| *v.borrow_mut() = self.voter_bond); TERM_DURATION.with(|v| *v.borrow_mut() = self.term_duration); DESIRED_RUNNERS_UP.with(|v| *v.borrow_mut() = self.desired_runners_up); GenesisConfig { - balances: Some(balances::GenesisConfig::{ + pallet_balances: Some(pallet_balances::GenesisConfig::{ balances: vec![ (1, 10 * self.balance_factor), (2, 20 * self.balance_factor), @@ -860,30 +965,6 @@ mod tests { lock.amount } - #[test] - fn temp_migration_works() { - ExtBuilder::default().build().execute_with(|| { - use support::storage::unhashed; - use codec::Encode; - - let old_members = vec![1u64, 2]; - let old_runners = vec![3u64]; - - let members_key = >::hashed_key(); - let runners_key = >::hashed_key(); - - unhashed::put_raw(&members_key, &old_members.encode()[..]); - unhashed::put_raw(&runners_key, &old_runners.encode()[..]); - - assert_eq!(DidMigrate::get(), false); - >::on_initialize(1); - assert_eq!(DidMigrate::get(), true); - - assert_eq!(Elections::members(), vec![(1, 0), (2, 0)]); - assert_eq!(Elections::runners_up(), vec![(3, 0)]); - }); - } - #[test] fn params_should_work() { ExtBuilder::default().build().execute_with(|| { @@ -1017,13 +1098,36 @@ mod tests { }); } + #[test] + fn runner_candidate_submission_should_not_work() { + ExtBuilder::default().desired_runners_up(2).build().execute_with(|| { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + assert_ok!(Elections::submit_candidacy(Origin::signed(3))); + + assert_ok!(Elections::vote(Origin::signed(2), vec![5, 4], 20)); + assert_ok!(Elections::vote(Origin::signed(1), vec![3], 10)); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members_ids(), vec![4, 5]); + assert_eq!(Elections::runners_up_ids(), vec![3]); + + assert_noop!( + Elections::submit_candidacy(Origin::signed(3)), + "runner cannot re-submit candidacy", + ); + }); + } + #[test] fn poor_candidate_submission_should_not_work() { ExtBuilder::default().build().execute_with(|| { assert_eq!(Elections::candidates(), Vec::::new()); assert_noop!( Elections::submit_candidacy(Origin::signed(7)), - "candidate does not have enough funds" + "candidate does not have enough funds", ); }); } @@ -1089,7 +1193,6 @@ mod tests { #[test] fn can_vote_for_old_members_even_when_no_new_candidates() { - // let allowed_votes = candidates_count as usize + Self::members().len() ExtBuilder::default().build().execute_with(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); @@ -1114,7 +1217,7 @@ mod tests { assert_noop!( Elections::vote(Origin::signed(2), vec![10, 20, 30], 20), - "cannot vote more than candidates" + "cannot vote more than candidates", ); }); } @@ -1127,7 +1230,7 @@ mod tests { assert_noop!( Elections::vote(Origin::signed(2), vec![4], 1), - "cannot vote with stake less than minimum balance" + "cannot vote with stake less than minimum balance", ); }) } @@ -1222,13 +1325,15 @@ mod tests { #[test] fn can_detect_defunct_voter() { - ExtBuilder::default().build().execute_with(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + ExtBuilder::default().desired_runners_up(2).build().execute_with(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::submit_candidacy(Origin::signed(6))); assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); assert_ok!(Elections::vote(Origin::signed(2), vec![4, 5], 20)); + assert_ok!(Elections::vote(Origin::signed(6), vec![6], 30)); // will be soon a defunct voter. assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); @@ -1236,12 +1341,14 @@ mod tests { assert_ok!(Elections::end_block(System::block_number())); assert_eq!(Elections::members_ids(), vec![4, 5]); + assert_eq!(Elections::runners_up_ids(), vec![6]); assert_eq!(Elections::candidates(), vec![]); - // all of them have a member that they voted for. + // all of them have a member or runner-up that they voted for. assert_eq!(Elections::is_defunct_voter(&5), false); assert_eq!(Elections::is_defunct_voter(&4), false); assert_eq!(Elections::is_defunct_voter(&2), false); + assert_eq!(Elections::is_defunct_voter(&6), false); // defunct assert_eq!(Elections::is_defunct_voter(&3), true); @@ -1484,7 +1591,6 @@ mod tests { System::set_block_number(5); assert_ok!(Elections::end_block(System::block_number())); assert_eq!(Elections::members_ids(), vec![4, 5]); - assert_eq!(Elections::runners_up_ids(), vec![2]); assert_eq!(balances(&2), (15, 5)); @@ -1493,16 +1599,63 @@ mod tests { System::set_block_number(10); assert_ok!(Elections::end_block(System::block_number())); - assert_eq!(Elections::members_ids(), vec![4, 5]); assert_eq!(Elections::runners_up_ids(), vec![3]); - assert_eq!(balances(&3), (25, 5)); assert_eq!(balances(&2), (15, 2)); }); } #[test] - fn current_members_are_always_implicitly_next_candidate() { + fn members_lose_bond_once_outgoing() { + ExtBuilder::default().build().execute_with(|| { + assert_eq!(balances(&5), (50, 0)); + + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_eq!(balances(&5), (47, 3)); + + assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); + assert_eq!(balances(&5), (45, 5)); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + assert_eq!(Elections::members_ids(), vec![5]); + + assert_ok!(Elections::remove_voter(Origin::signed(5))); + assert_eq!(balances(&5), (47, 3)); + + System::set_block_number(10); + assert_ok!(Elections::end_block(System::block_number())); + assert_eq!(Elections::members_ids(), vec![]); + + assert_eq!(balances(&5), (47, 0)); + }); + } + + #[test] + fn losers_will_lose_the_bond() { + ExtBuilder::default().build().execute_with(|| { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::submit_candidacy(Origin::signed(3))); + + assert_ok!(Elections::vote(Origin::signed(4), vec![5], 40)); + + assert_eq!(balances(&5), (47, 3)); + assert_eq!(balances(&3), (27, 3)); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members_ids(), vec![5]); + + // winner + assert_eq!(balances(&5), (47, 3)); + // loser + assert_eq!(balances(&3), (27, 0)); + }); + } + + #[test] + fn current_members_are_always_next_candidate() { ExtBuilder::default().build().execute_with(|| { assert_ok!(Elections::submit_candidacy(Origin::signed(5))); assert_ok!(Elections::submit_candidacy(Origin::signed(4))); @@ -1630,55 +1783,6 @@ mod tests { }); } - #[test] - fn outgoing_will_get_the_bond_back() { - ExtBuilder::default().build().execute_with(|| { - assert_eq!(balances(&5), (50, 0)); - - assert_ok!(Elections::submit_candidacy(Origin::signed(5))); - assert_eq!(balances(&5), (47, 3)); - - assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); - assert_eq!(balances(&5), (45, 5)); - - System::set_block_number(5); - assert_ok!(Elections::end_block(System::block_number())); - assert_eq!(Elections::members_ids(), vec![5]); - - assert_ok!(Elections::remove_voter(Origin::signed(5))); - assert_eq!(balances(&5), (47, 3)); - - System::set_block_number(10); - assert_ok!(Elections::end_block(System::block_number())); - assert_eq!(Elections::members_ids(), vec![]); - - assert_eq!(balances(&5), (50, 0)); - }); - } - - #[test] - fn losers_will_lose_the_bond() { - ExtBuilder::default().build().execute_with(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(5))); - assert_ok!(Elections::submit_candidacy(Origin::signed(3))); - - assert_ok!(Elections::vote(Origin::signed(4), vec![5], 40)); - - assert_eq!(balances(&5), (47, 3)); - assert_eq!(balances(&3), (27, 3)); - - System::set_block_number(5); - assert_ok!(Elections::end_block(System::block_number())); - - assert_eq!(Elections::members_ids(), vec![5]); - - // winner - assert_eq!(balances(&5), (47, 3)); - // loser - assert_eq!(balances(&3), (27, 0)); - }); - } - #[test] fn incoming_outgoing_are_reported() { ExtBuilder::default().build().execute_with(|| { @@ -1717,8 +1821,8 @@ mod tests { // 1 is a loser, slashed by 3. assert_eq!(balances(&1), (5, 2)); - // 5 is an outgoing loser, it will get their bond back. - assert_eq!(balances(&5), (48, 2)); + // 5 is an outgoing loser. will also get slashed. + assert_eq!(balances(&5), (45, 2)); assert_eq!( System::events()[0].event, @@ -1766,4 +1870,170 @@ mod tests { assert_eq!(Elections::runners_up(), vec![(3, 20), (2, 30)]); }); } + + #[test] + fn candidates_are_sorted() { + ExtBuilder::default().build().execute_with(|| { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::submit_candidacy(Origin::signed(3))); + + assert_eq!(Elections::candidates(), vec![3, 5]); + + assert_ok!(Elections::submit_candidacy(Origin::signed(2))); + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + assert_ok!(Elections::renounce_candidacy(Origin::signed(3))); + + assert_eq!(Elections::candidates(), vec![2, 4, 5]); + }) + } + + #[test] + fn runner_up_replacement_maintains_members_order() { + ExtBuilder::default().desired_runners_up(2).build().execute_with(|| { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + assert_ok!(Elections::submit_candidacy(Origin::signed(2))); + + assert_ok!(Elections::vote(Origin::signed(2), vec![5], 20)); + assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); + assert_ok!(Elections::vote(Origin::signed(5), vec![2], 50)); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members_ids(), vec![2, 4]); + assert_ok!(Elections::remove_member(Origin::ROOT, 2)); + assert_eq!(Elections::members_ids(), vec![4, 5]); + }); + } + + #[test] + fn runner_up_replacement_works_when_out_of_order() { + ExtBuilder::default().desired_runners_up(2).build().execute_with(|| { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + assert_ok!(Elections::submit_candidacy(Origin::signed(3))); + assert_ok!(Elections::submit_candidacy(Origin::signed(2))); + + assert_ok!(Elections::vote(Origin::signed(2), vec![5], 20)); + assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); + assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); + assert_ok!(Elections::vote(Origin::signed(5), vec![2], 50)); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members_ids(), vec![2, 4]); + assert_ok!(Elections::renounce_candidacy(Origin::signed(3))); + }); + } + + #[test] + fn can_renounce_candidacy_member_with_runners_bond_is_refunded() { + ExtBuilder::default().desired_runners_up(2).build().execute_with(|| { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + assert_ok!(Elections::submit_candidacy(Origin::signed(3))); + assert_ok!(Elections::submit_candidacy(Origin::signed(2))); + + assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); + assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); + assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); + assert_ok!(Elections::vote(Origin::signed(2), vec![2], 20)); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members_ids(), vec![4, 5]); + assert_eq!(Elections::runners_up_ids(), vec![2, 3]); + + assert_ok!(Elections::renounce_candidacy(Origin::signed(4))); + assert_eq!(balances(&4), (38, 2)); // 2 is voting bond. + + assert_eq!(Elections::members_ids(), vec![3, 5]); + assert_eq!(Elections::runners_up_ids(), vec![2]); + }) + } + + #[test] + fn can_renounce_candidacy_member_without_runners_bond_is_refunded() { + ExtBuilder::default().desired_runners_up(2).build().execute_with(|| { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + + assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); + assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + + assert_ok!(Elections::submit_candidacy(Origin::signed(3))); + assert_ok!(Elections::submit_candidacy(Origin::signed(2))); + assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); + assert_ok!(Elections::vote(Origin::signed(2), vec![2], 20)); + + assert_eq!(Elections::members_ids(), vec![4, 5]); + assert_eq!(Elections::runners_up_ids(), vec![]); + assert_eq!(Elections::candidates(), vec![2, 3]); + + assert_ok!(Elections::renounce_candidacy(Origin::signed(4))); + assert_eq!(balances(&4), (38, 2)); // 2 is voting bond. + + // no replacement + assert_eq!(Elections::members_ids(), vec![5]); + assert_eq!(Elections::runners_up_ids(), vec![]); + // still candidate + assert_eq!(Elections::candidates(), vec![2, 3]); + }) + } + + #[test] + fn can_renounce_candidacy_runner() { + ExtBuilder::default().desired_runners_up(2).build().execute_with(|| { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + assert_ok!(Elections::submit_candidacy(Origin::signed(3))); + assert_ok!(Elections::submit_candidacy(Origin::signed(2))); + + assert_ok!(Elections::vote(Origin::signed(5), vec![4], 50)); + assert_ok!(Elections::vote(Origin::signed(4), vec![5], 40)); + assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); + assert_ok!(Elections::vote(Origin::signed(2), vec![2], 20)); + + System::set_block_number(5); + assert_ok!(Elections::end_block(System::block_number())); + + assert_eq!(Elections::members_ids(), vec![4, 5]); + assert_eq!(Elections::runners_up_ids(), vec![2, 3]); + + assert_ok!(Elections::renounce_candidacy(Origin::signed(3))); + assert_eq!(balances(&3), (28, 2)); // 2 is voting bond. + + assert_eq!(Elections::members_ids(), vec![4, 5]); + assert_eq!(Elections::runners_up_ids(), vec![2]); + }) + } + + #[test] + fn can_renounce_candidacy_candidate() { + ExtBuilder::default().build().execute_with(|| { + assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_eq!(balances(&5), (47, 3)); + assert_eq!(Elections::candidates(), vec![5]); + + assert_ok!(Elections::renounce_candidacy(Origin::signed(5))); + assert_eq!(balances(&5), (50, 0)); + assert_eq!(Elections::candidates(), vec![]); + }) + } + + #[test] + fn wrong_renounce_candidacy_should_fail() { + ExtBuilder::default().build().execute_with(|| { + assert_noop!( + Elections::renounce_candidacy(Origin::signed(5)), + "origin is not a candidate, member or a runner up.", + ); + }) + } } diff --git a/frame/elections/Cargo.toml b/frame/elections/Cargo.toml index 62986f758dd76e6bcafd91cbd8b208de89794353..44d624b9862408afb817516ab31c9fb5b5347827 100644 --- a/frame/elections/Cargo.toml +++ b/frame/elections/Cargo.toml @@ -8,27 +8,27 @@ edition = "2018" serde = { version = "1.0.101", optional = true } safe-mix = { version = "1.0.0", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -primitives = { package = "substrate-primitives", path = "../../primitives/core", default-features = false } -rstd = { package = "sr-std", path = "../../primitives/sr-std", default-features = false } -runtime-io = { package = "sr-io", path = "../../primitives/sr-io", default-features = false } -sr-primitives = { path = "../../primitives/sr-primitives", default-features = false } -support = { package = "frame-support", path = "../support", default-features = false } -system = { package = "frame-system", path = "../system", default-features = false } +sp-core = { version = "2.0.0", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0", default-features = false, path = "../support" } +frame-system = { version = "2.0.0", default-features = false, path = "../system" } [dev-dependencies] hex-literal = "0.2.1" -balances = { package = "pallet-balances", path = "../balances" } +pallet-balances = { version = "2.0.0", path = "../balances" } [features] default = ["std"] std = [ "safe-mix/std", "codec/std", - "primitives/std", - "rstd/std", + "sp-core/std", + "sp-std/std", "serde", - "runtime-io/std", - "support/std", - "sr-primitives/std", - "system/std", + "sp-io/std", + "frame-support/std", + "sp-runtime/std", + "frame-system/std", ] diff --git a/frame/elections/src/lib.rs b/frame/elections/src/lib.rs index e4426c22d810925866fb438e3e6f41930dbecc45..1435c059518f04d9a4f4fbeb458b20ad81b7649d 100644 --- a/frame/elections/src/lib.rs +++ b/frame/elections/src/lib.rs @@ -23,14 +23,13 @@ #![cfg_attr(not(feature = "std"), no_std)] #![recursion_limit="128"] -use rstd::prelude::*; -use sr_primitives::{ - RuntimeDebug, - print, +use sp_std::prelude::*; +use sp_runtime::{ + RuntimeDebug, DispatchResult, print, traits::{Zero, One, StaticLookup, Bounded, Saturating}, }; -use support::{ - dispatch::Result, decl_storage, decl_event, ensure, decl_module, +use frame_support::{ + decl_storage, decl_event, ensure, decl_module, weights::SimpleDispatchInfo, traits::{ Currency, ExistenceRequirement, Get, LockableCurrency, LockIdentifier, @@ -38,7 +37,7 @@ use support::{ } }; use codec::{Encode, Decode}; -use system::{self, ensure_signed, ensure_root}; +use frame_system::{self as system, ensure_signed, ensure_root}; mod mock; mod tests; @@ -134,9 +133,9 @@ pub const VOTER_SET_SIZE: usize = 64; /// NUmber of approvals grouped in one chunk. pub const APPROVAL_SET_SIZE: usize = 8; -type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; type NegativeImbalanceOf = - <::Currency as Currency<::AccountId>>::NegativeImbalance; + <::Currency as Currency<::AccountId>>::NegativeImbalance; /// Index used to access chunks. type SetIndex = u32; @@ -147,8 +146,8 @@ type ApprovalFlag = u32; /// Number of approval flags that can fit into [`ApprovalFlag`] type. const APPROVAL_FLAG_LEN: usize = 32; -pub trait Trait: system::Trait { - type Event: From> + Into<::Event>; +pub trait Trait: frame_system::Trait { + type Event: From> + Into<::Event>; /// The currency that people are electing with. type Currency: @@ -346,7 +345,7 @@ decl_module! { #[compact] index: VoteIndex, hint: SetIndex, #[compact] value: BalanceOf - ) -> Result { + ) -> DispatchResult { let who = ensure_signed(origin)?; Self::do_set_approvals(who, votes, index, hint, value) } @@ -363,7 +362,7 @@ decl_module! { #[compact] index: VoteIndex, hint: SetIndex, #[compact] value: BalanceOf - ) -> Result { + ) -> DispatchResult { let who = Self::proxy(ensure_signed(origin)?).ok_or("not a proxy")?; Self::do_set_approvals(who, votes, index, hint, value) } @@ -526,7 +525,7 @@ decl_module! { candidate: ::Source, #[compact] total: BalanceOf, #[compact] index: VoteIndex - ) -> Result { + ) -> DispatchResult { let who = ensure_signed(origin)?; ensure!( !total.is_zero(), @@ -587,7 +586,7 @@ decl_module! { // better safe than sorry. let imbalance = T::Currency::slash(&who, bad_presentation_punishment).0; T::BadPresentation::on_unbalanced(imbalance); - Err(if dupe { "duplicate presentation" } else { "incorrect total" }) + Err(if dupe { "duplicate presentation" } else { "incorrect total" })? } } @@ -643,7 +642,7 @@ decl_module! { } decl_event!( - pub enum Event where ::AccountId { + pub enum Event where ::AccountId { /// reaped voter, reaper VoterReaped(AccountId, AccountId), /// slashed reaper @@ -695,7 +694,7 @@ impl Module { // if there's a tally in progress, then next tally can begin immediately afterwards (tally_end, c.len() - leavers.len() + comers as usize, comers) } else { - (>::block_number(), c.len(), 0) + (>::block_number(), c.len(), 0) }; if count < desired_seats as usize { Some(next_possible) @@ -714,7 +713,7 @@ impl Module { // Private /// Check there's nothing to do this block - fn end_block(block_number: T::BlockNumber) -> Result { + fn end_block(block_number: T::BlockNumber) -> DispatchResult { if (block_number % T::VotingPeriod::get()).is_zero() { if let Some(number) = Self::next_tally() { if block_number == number { @@ -750,7 +749,7 @@ impl Module { index: VoteIndex, hint: SetIndex, value: BalanceOf, - ) -> Result { + ) -> DispatchResult { let candidates_len = ::Candidates::decode_len().unwrap_or(0_usize); ensure!(!Self::presentation_active(), "no approval changes during presentation period"); @@ -851,7 +850,7 @@ impl Module { fn start_tally() { let members = Self::members(); let desired_seats = Self::desired_seats() as usize; - let number = >::block_number(); + let number = >::block_number(); let expiring = members.iter().take_while(|i| i.1 <= number).map(|i| i.0.clone()).collect::>(); let retaining_seats = members.len() - expiring.len(); @@ -873,13 +872,13 @@ impl Module { /// approved candidates in their place. If the total number of members is less than the desired /// membership a new vote is started. Clears all presented candidates, returning the bond of the /// elected ones. - fn finalize_tally() -> Result { + fn finalize_tally() -> DispatchResult { let (_, coming, expiring): (T::BlockNumber, u32, Vec) = >::take() .ok_or("finalize can only be called after a tally is started.")?; let leaderboard: Vec<(BalanceOf, T::AccountId)> = >::take() .unwrap_or_default(); - let new_expiry = >::block_number() + Self::term_duration(); + let new_expiry = >::block_number() + Self::term_duration(); // return bond to winners. let candidacy_bond = T::CandidacyBond::get(); diff --git a/frame/elections/src/mock.rs b/frame/elections/src/mock.rs index 77b13d74a139f42d7aab7ad6a76741cdd70c8342..c53789f7adf5e5ba6d8c8e2040e093c87dd2111c 100644 --- a/frame/elections/src/mock.rs +++ b/frame/elections/src/mock.rs @@ -19,12 +19,13 @@ #![cfg(test)] use std::cell::RefCell; -use support::{ +use frame_support::{ StorageValue, StorageMap, parameter_types, assert_ok, - traits::{Get, ChangeMembers, Currency} + traits::{Get, ChangeMembers, Currency}, + weights::Weight, }; -use primitives::H256; -use sr_primitives::{ +use sp_core::H256; +use sp_runtime::{ Perbill, BuildStorage, testing::Header, traits::{BlakeTwo256, IdentityLookup, Block as BlockT}, }; use crate as elections; @@ -32,11 +33,11 @@ use crate as elections; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockWeight: Weight = 1024; pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } -impl system::Trait for Test { +impl frame_system::Trait for Test { type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -52,6 +53,7 @@ impl system::Trait for Test { type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); + type ModuleToIndex = (); } parameter_types! { @@ -59,7 +61,7 @@ parameter_types! { pub const TransferFee: u64 = 0; pub const CreationFee: u64 = 0; } -impl balances::Trait for Test { +impl pallet_balances::Trait for Test { type Balance = u64; type OnNewAccount = (); type OnFreeBalanceZero = (); @@ -141,17 +143,18 @@ impl elections::Trait for Test { type DecayRatio = DecayRatio; } -pub type Block = sr_primitives::generic::Block; -pub type UncheckedExtrinsic = sr_primitives::generic::UncheckedExtrinsic; +pub type Block = sp_runtime::generic::Block; +pub type UncheckedExtrinsic = sp_runtime::generic::UncheckedExtrinsic; -support::construct_runtime!( +use frame_system as system; +frame_support::construct_runtime!( pub enum Test where Block = Block, NodeBlock = Block, UncheckedExtrinsic = UncheckedExtrinsic { System: system::{Module, Call, Event}, - Balances: balances::{Module, Call, Event, Config, Error}, + Balances: pallet_balances::{Module, Call, Event, Config, Error}, Elections: elections::{Module, Call, Event, Config}, } ); @@ -203,13 +206,13 @@ impl ExtBuilder { self.desired_seats = seats; self } - pub fn build(self) -> runtime_io::TestExternalities { + pub fn build(self) -> sp_io::TestExternalities { VOTER_BOND.with(|v| *v.borrow_mut() = self.voter_bond); VOTING_FEE.with(|v| *v.borrow_mut() = self.voting_fee); PRESENT_SLASH_PER_VOTER.with(|v| *v.borrow_mut() = self.bad_presentation_punishment); DECAY_RATIO.with(|v| *v.borrow_mut() = self.decay_ratio); GenesisConfig { - balances: Some(balances::GenesisConfig::{ + pallet_balances: Some(pallet_balances::GenesisConfig::{ balances: vec![ (1, 10 * self.balance_factor), (2, 20 * self.balance_factor), @@ -273,7 +276,7 @@ pub(crate) fn locks(who: &u64) -> Vec { Balances::locks(who).iter().map(|l| l.amount).collect::>() } -pub(crate) fn new_test_ext_with_candidate_holes() -> runtime_io::TestExternalities { +pub(crate) fn new_test_ext_with_candidate_holes() -> sp_io::TestExternalities { let mut t = ExtBuilder::default().build(); t.execute_with(|| { >::put(vec![0, 0, 1]); diff --git a/frame/elections/src/tests.rs b/frame/elections/src/tests.rs index c9bb054ab23538edf62dfbcfb67b648f278c7a96..d7d7e8718b0fc5875e39604b67e49d5ed6e393c1 100644 --- a/frame/elections/src/tests.rs +++ b/frame/elections/src/tests.rs @@ -21,7 +21,7 @@ use crate::mock::*; use crate::*; -use support::{assert_ok, assert_err, assert_noop}; +use frame_support::{assert_ok, assert_err, assert_noop}; #[test] fn params_should_work() { @@ -1034,7 +1034,10 @@ fn election_double_presentations_should_be_punished() { System::set_block_number(6); assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20, 0)); assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 0)); - assert_eq!(Elections::present_winner(Origin::signed(4), 5, 50, 0), Err("duplicate presentation")); + assert_eq!( + Elections::present_winner(Origin::signed(4), 5, 50, 0), + Err("duplicate presentation".into()), + ); assert_ok!(Elections::end_block(System::block_number())); assert_eq!(Elections::members(), vec![(5, 11), (2, 11)]); diff --git a/frame/evm/Cargo.toml b/frame/evm/Cargo.toml index 2318fe59a44cd3b902fdd3c1b08a8a8012206a26..933b450ee448a4945f23e8f4fd03c2a280d1c2af 100644 --- a/frame/evm/Cargo.toml +++ b/frame/evm/Cargo.toml @@ -7,14 +7,14 @@ edition = "2018" [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false } -support = { package = "frame-support", path = "../support", default-features = false } -system = { package = "frame-system", path = "../system", default-features = false } -timestamp = { package = "pallet-timestamp", path = "../timestamp", default-features = false } -balances = { package = "pallet-balances", path = "../balances", default-features = false } -primitives = { package = "substrate-primitives", path = "../../primitives/core", default-features = false } -sr-primitives = { path = "../../primitives/sr-primitives", default-features = false } -rstd = { package = "sr-std", path = "../../primitives/sr-std", default-features = false } -runtime-io = { package = "sr-io", path = "../../primitives/sr-io", default-features = false } +frame-support = { version = "2.0.0", default-features = false, path = "../support" } +frame-system = { version = "2.0.0", default-features = false, path = "../system" } +pallet-timestamp = { version = "2.0.0", default-features = false, path = "../timestamp" } +pallet-balances = { version = "2.0.0", default-features = false, path = "../balances" } +sp-core = { version = "2.0.0", default-features = false, path = "../../primitives/core" } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0", default-features = false, path = "../../primitives/io" } primitive-types = { version = "0.6", default-features = false, features = ["rlp"] } rlp = { version = "0.4", default-features = false } evm = { version = "0.14", default-features = false } @@ -25,16 +25,16 @@ default = ["std"] std = [ "serde", "codec/std", - "primitives/std", - "sr-primitives/std", - "support/std", - "system/std", - "balances/std", - "runtime-io/std", - "rstd/std", + "sp-core/std", + "sp-runtime/std", + "frame-support/std", + "frame-system/std", + "pallet-balances/std", + "sp-io/std", + "sp-std/std", "sha3/std", "rlp/std", "primitive-types/std", "evm/std", - "timestamp/std", + "pallet-timestamp/std", ] diff --git a/frame/evm/src/backend.rs b/frame/evm/src/backend.rs index 1f3dfe309b4eebcec29a57dbee6c62008706fe29..b6c3078a3339a2d27c43c08a732599ae9972e84f 100644 --- a/frame/evm/src/backend.rs +++ b/frame/evm/src/backend.rs @@ -1,11 +1,11 @@ -use rstd::marker::PhantomData; -use rstd::vec::Vec; +use sp_std::marker::PhantomData; +use sp_std::vec::Vec; #[cfg(feature = "std")] use serde::{Serialize, Deserialize}; use codec::{Encode, Decode}; -use primitives::{U256, H256, H160}; -use sr_primitives::traits::UniqueSaturatedInto; -use support::storage::{StorageMap, StorageDoubleMap}; +use sp_core::{U256, H256, H160}; +use sp_runtime::traits::UniqueSaturatedInto; +use frame_support::storage::{StorageMap, StorageDoubleMap}; use sha3::{Keccak256, Digest}; use evm::Config; use evm::backend::{Backend as BackendT, ApplyBackend, Apply}; @@ -69,12 +69,12 @@ impl<'vicinity, T: Trait> BackendT for Backend<'vicinity, T> { H256::default() } else { let number = T::BlockNumber::from(number.as_u32()); - H256::from_slice(system::Module::::block_hash(number).as_ref()) + H256::from_slice(frame_system::Module::::block_hash(number).as_ref()) } } fn block_number(&self) -> U256 { - let number: u128 = system::Module::::block_number().unique_saturated_into(); + let number: u128 = frame_system::Module::::block_number().unique_saturated_into(); U256::from(number) } @@ -83,7 +83,7 @@ impl<'vicinity, T: Trait> BackendT for Backend<'vicinity, T> { } fn block_timestamp(&self) -> U256 { - let now: u128 = timestamp::Module::::get().unique_saturated_into(); + let now: u128 = pallet_timestamp::Module::::get().unique_saturated_into(); U256::from(now) } @@ -96,7 +96,7 @@ impl<'vicinity, T: Trait> BackendT for Backend<'vicinity, T> { } fn chain_id(&self) -> U256 { - U256::from(runtime_io::misc::chain_id()) + U256::from(sp_io::misc::chain_id()) } fn exists(&self, _address: H160) -> bool { diff --git a/frame/evm/src/lib.rs b/frame/evm/src/lib.rs index 9a602d9077e52fca2958e31e38ec5988e4173a4a..891729e71af455ce8a764d014c0e1cc5b8be351c 100644 --- a/frame/evm/src/lib.rs +++ b/frame/evm/src/lib.rs @@ -23,14 +23,17 @@ mod backend; pub use crate::backend::{Account, Log, Vicinity, Backend}; -use rstd::vec::Vec; -use support::{dispatch::Result, decl_module, decl_storage, decl_event}; -use support::traits::{Currency, WithdrawReason, ExistenceRequirement}; -use system::ensure_signed; -use sr_primitives::ModuleId; -use support::weights::SimpleDispatchInfo; -use sr_primitives::traits::{UniqueSaturatedInto, AccountIdConversion}; -use primitives::{U256, H256, H160}; +use sp_std::{vec::Vec, marker::PhantomData}; +use frame_support::{ensure, decl_module, decl_storage, decl_event, decl_error}; +use frame_support::weights::{Weight, WeighData, ClassifyDispatch, DispatchClass, PaysFee}; +use frame_support::traits::{Currency, WithdrawReason, ExistenceRequirement}; +use frame_system::{self as system, ensure_signed}; +use sp_runtime::ModuleId; +use frame_support::weights::SimpleDispatchInfo; +use sp_core::{U256, H256, H160, Hasher}; +use sp_runtime::{ + DispatchResult, traits::{UniqueSaturatedInto, AccountIdConversion, SaturatedConversion}, +}; use evm::{ExitReason, ExitSucceed, ExitError}; use evm::executor::StackExecutor; use evm::backend::ApplyBackend; @@ -38,12 +41,16 @@ use evm::backend::ApplyBackend; const MODULE_ID: ModuleId = ModuleId(*b"py/ethvm"); /// Type alias for currency balance. -pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; /// Trait that outputs the current transaction gas price. pub trait FeeCalculator { - /// Return the current gas price. - fn gas_price() -> U256; + /// Return the minimal required gas price. + fn min_gas_price() -> U256; +} + +impl FeeCalculator for () { + fn min_gas_price() -> U256 { U256::zero() } } /// Trait for converting account ids of `balances` module into @@ -58,6 +65,32 @@ pub trait ConvertAccountId { fn convert_account_id(account_id: &A) -> H160; } +/// Hash and then truncate the account id, taking the last 160-bit as the Ethereum address. +pub struct HashTruncateConvertAccountId(PhantomData); + +impl Default for HashTruncateConvertAccountId { + fn default() -> Self { + Self(PhantomData) + } +} + +impl> ConvertAccountId for HashTruncateConvertAccountId { + fn convert_account_id(account_id: &A) -> H160 { + let account_id = H::hash(account_id.as_ref()); + let account_id_len = account_id.as_ref().len(); + let mut value = [0u8; 20]; + let value_len = value.len(); + + if value_len > account_id_len { + value[(value_len - account_id_len)..].copy_from_slice(account_id.as_ref()); + } else { + value.copy_from_slice(&account_id.as_ref()[(account_id_len - value_len)..]); + } + + H160::from(value) + } +} + /// Custom precompiles to be used by EVM engine. pub trait Precompiles { /// Try to execute the code address as precompile. If the code address is not @@ -82,8 +115,40 @@ impl Precompiles for () { } } +struct WeightForCallCreate; + +impl WeighData<(&H160, &Vec, &U256, &u32, &U256)> for WeightForCallCreate { + fn weigh_data( + &self, + (_, _, _, gas_provided, gas_price): (&H160, &Vec, &U256, &u32, &U256) + ) -> Weight { + (*gas_price).saturated_into::().saturating_mul(*gas_provided) + } +} + +impl WeighData<(&Vec, &U256, &u32, &U256)> for WeightForCallCreate { + fn weigh_data( + &self, + (_, _, gas_provided, gas_price): (&Vec, &U256, &u32, &U256) + ) -> Weight { + (*gas_price).saturated_into::().saturating_mul(*gas_provided) + } +} + +impl ClassifyDispatch for WeightForCallCreate { + fn classify_dispatch(&self, _: T) -> DispatchClass { + DispatchClass::Normal + } +} + +impl PaysFee for WeightForCallCreate { + fn pays_fee(&self) -> bool { + true + } +} + /// EVM module trait -pub trait Trait: system::Trait + timestamp::Trait { +pub trait Trait: frame_system::Trait + pallet_timestamp::Trait { /// Calculator for current gas price. type FeeCalculator: FeeCalculator; /// Convert account ID to H160; @@ -91,7 +156,7 @@ pub trait Trait: system::Trait + timestamp::Trait { /// Currency type for deposit and withdraw. type Currency: Currency; /// The overarching event type. - type Event: From + Into<::Event>; + type Event: From + Into<::Event>; /// Precompiles associated with this EVM engine. type Precompiles: Precompiles; } @@ -104,20 +169,44 @@ decl_storage! { } } -decl_event!( +decl_event! { /// EVM events pub enum Event { /// Ethereum events from contracts. Log(Log), } -); +} + +decl_error! { + pub enum Error for Module { + /// Not enough balance to perform action + BalanceLow, + /// Calculating total fee overflowed + FeeOverflow, + /// Calculating total payment overflowed + PaymentOverflow, + /// Withdraw fee failed + WithdrawFailed, + /// Gas price is too low. + GasPriceTooLow, + /// Call failed + ExitReasonFailed, + /// Call reverted + ExitReasonRevert, + /// Call returned VM fatal error + ExitReasonFatal, + } +} decl_module! { pub struct Module for enum Call where origin: T::Origin { + type Error = Error; + fn deposit_event() = default; + /// Despoit balance from currency/balances module into EVM. #[weight = SimpleDispatchInfo::FixedNormal(10_000)] - fn deposit_balance(origin, value: BalanceOf) -> Result { + fn deposit_balance(origin, value: BalanceOf) { let sender = ensure_signed(origin)?; let imbalance = T::Currency::withdraw( @@ -133,19 +222,18 @@ decl_module! { Accounts::mutate(&address, |account| { account.balance += bvalue; }); - - Ok(()) } + /// Withdraw balance from EVM into currency/balances module. #[weight = SimpleDispatchInfo::FixedNormal(10_000)] - fn withdraw_balance(origin, value: BalanceOf) -> Result { + fn withdraw_balance(origin, value: BalanceOf) { let sender = ensure_signed(origin)?; let address = T::ConvertAccountId::convert_account_id(&sender); let bvalue = U256::from(UniqueSaturatedInto::::unique_saturated_into(value)); let mut account = Accounts::get(&address); account.balance = account.balance.checked_sub(bvalue) - .ok_or("Not enough balance to withdraw")?; + .ok_or(Error::::BalanceLow)?; let imbalance = T::Currency::withdraw( &Self::account_id(), @@ -157,15 +245,21 @@ decl_module! { Accounts::insert(&address, account); T::Currency::resolve_creating(&sender, imbalance); - - Ok(()) } - #[weight = SimpleDispatchInfo::FixedNormal(10_000)] - fn call(origin, target: H160, input: Vec, value: U256, gas_limit: u32) -> Result { + /// Issue an EVM call operation. This is similar to a message call transaction in Ethereum. + #[weight = WeightForCallCreate] + fn call( + origin, + target: H160, + input: Vec, + value: U256, + gas_limit: u32, + gas_price: U256, + ) -> DispatchResult { let sender = ensure_signed(origin)?; + ensure!(gas_price >= T::FeeCalculator::min_gas_price(), Error::::GasPriceTooLow); let source = T::ConvertAccountId::convert_account_id(&sender); - let gas_price = T::FeeCalculator::gas_price(); let vicinity = Vicinity { gas_price, @@ -181,13 +275,13 @@ decl_module! { ); let total_fee = gas_price.checked_mul(U256::from(gas_limit)) - .ok_or("Calculating total fee overflowed")?; + .ok_or(Error::::FeeOverflow)?; if Accounts::get(&source).balance < - value.checked_add(total_fee).ok_or("Calculating total payment overflowed")? + value.checked_add(total_fee).ok_or(Error::::PaymentOverflow)? { - return Err("Not enough balance to pay transaction fee") + Err(Error::::BalanceLow)? } - executor.withdraw(source, total_fee).map_err(|_| "Withdraw fee failed")?; + executor.withdraw(source, total_fee).map_err(|_| Error::::WithdrawFailed)?; let reason = executor.transact_call( source, @@ -199,9 +293,9 @@ decl_module! { let ret = match reason { ExitReason::Succeed(_) => Ok(()), - ExitReason::Error(_) => Err("Execute message call failed"), - ExitReason::Revert(_) => Err("Execute message call reverted"), - ExitReason::Fatal(_) => Err("Execute message call returned VM fatal error"), + ExitReason::Error(_) => Err(Error::::ExitReasonFailed), + ExitReason::Revert(_) => Err(Error::::ExitReasonRevert), + ExitReason::Fatal(_) => Err(Error::::ExitReasonFatal), }; let actual_fee = executor.fee(gas_price); executor.deposit(source, total_fee.saturating_sub(actual_fee)); @@ -209,14 +303,23 @@ decl_module! { let (values, logs) = executor.deconstruct(); backend.apply(values, logs, true); - ret + ret.map_err(Into::into) } - #[weight = SimpleDispatchInfo::FixedNormal(10_000)] - fn create(origin, init: Vec, value: U256, gas_limit: u32) -> Result { + /// Issue an EVM create operation. This is similar to a contract creation transaction in + /// Ethereum. + #[weight = WeightForCallCreate] + fn create( + origin, + init: Vec, + value: U256, + gas_limit: u32, + gas_price: U256, + ) -> DispatchResult { let sender = ensure_signed(origin)?; + ensure!(gas_price >= T::FeeCalculator::min_gas_price(), Error::::GasPriceTooLow); + let source = T::ConvertAccountId::convert_account_id(&sender); - let gas_price = T::FeeCalculator::gas_price(); let vicinity = Vicinity { gas_price, @@ -232,13 +335,13 @@ decl_module! { ); let total_fee = gas_price.checked_mul(U256::from(gas_limit)) - .ok_or("Calculating total fee overflowed")?; + .ok_or(Error::::FeeOverflow)?; if Accounts::get(&source).balance < - value.checked_add(total_fee).ok_or("Calculating total payment overflowed")? + value.checked_add(total_fee).ok_or(Error::::PaymentOverflow)? { - return Err("Not enough balance to pay transaction fee") + Err(Error::::BalanceLow)? } - executor.withdraw(source, total_fee).map_err(|_| "Withdraw fee failed")?; + executor.withdraw(source, total_fee).map_err(|_| Error::::WithdrawFailed)?; let reason = executor.transact_create( source, @@ -249,9 +352,9 @@ decl_module! { let ret = match reason { ExitReason::Succeed(_) => Ok(()), - ExitReason::Error(_) => Err("Execute contract creation failed"), - ExitReason::Revert(_) => Err("Execute contract creation reverted"), - ExitReason::Fatal(_) => Err("Execute contract creation returned VM fatal error"), + ExitReason::Error(_) => Err(Error::::ExitReasonFailed), + ExitReason::Revert(_) => Err(Error::::ExitReasonRevert), + ExitReason::Fatal(_) => Err(Error::::ExitReasonFatal), }; let actual_fee = executor.fee(gas_price); executor.deposit(source, total_fee.saturating_sub(actual_fee)); @@ -259,7 +362,7 @@ decl_module! { let (values, logs) = executor.deconstruct(); backend.apply(values, logs, true); - ret + ret.map_err(Into::into) } } } diff --git a/frame/example/Cargo.toml b/frame/example/Cargo.toml index bcad107a0764dbebeb2f08761c18495f52f70b4c..fd80d8b8df1793ffd408b3c3ca3f07c2944a15ac 100644 --- a/frame/example/Cargo.toml +++ b/frame/example/Cargo.toml @@ -7,25 +7,25 @@ edition = "2018" [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false } -support = { package = "frame-support", path = "../support", default-features = false } -system = { package = "frame-system", path = "../system", default-features = false } -balances = { package = "pallet-balances", path = "../balances", default-features = false } -sr-primitives = { path = "../../primitives/sr-primitives", default-features = false } -rstd = { package = "sr-std", path = "../../primitives/sr-std", default-features = false } -runtime-io = { package = "sr-io", path = "../../primitives/sr-io", default-features = false } +frame-support = { version = "2.0.0", default-features = false, path = "../support" } +frame-system = { version = "2.0.0", default-features = false, path = "../system" } +pallet-balances = { version = "2.0.0", default-features = false, path = "../balances" } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0", default-features = false, path = "../../primitives/io" } [dev-dependencies] -primitives = { package = "substrate-primitives", path = "../../primitives/core" } +sp-core = { version = "2.0.0", path = "../../primitives/core" } [features] default = ["std"] std = [ "serde", "codec/std", - "sr-primitives/std", - "support/std", - "system/std", - "balances/std", - "runtime-io/std", - "rstd/std" + "sp-runtime/std", + "frame-support/std", + "frame-system/std", + "pallet-balances/std", + "sp-io/std", + "sp-std/std" ] diff --git a/frame/example/src/lib.rs b/frame/example/src/lib.rs index 8956de7249ce3672093cced77e4311ebd1055db1..f13a78db566a1265ef51318432df90632102cc6c 100644 --- a/frame/example/src/lib.rs +++ b/frame/example/src/lib.rs @@ -253,14 +253,14 @@ // Ensure we're `no_std` when compiling for Wasm. #![cfg_attr(not(feature = "std"), no_std)] -use rstd::marker::PhantomData; -use support::{ - dispatch::Result, decl_module, decl_storage, decl_event, - weights::{SimpleDispatchInfo, DispatchInfo, DispatchClass, ClassifyDispatch, WeighData, Weight}, +use sp_std::marker::PhantomData; +use frame_support::{ + dispatch::DispatchResult, decl_module, decl_storage, decl_event, + weights::{SimpleDispatchInfo, DispatchInfo, DispatchClass, ClassifyDispatch, WeighData, Weight, PaysFee}, }; -use system::{ensure_signed, ensure_root}; +use frame_system::{self as system, ensure_signed, ensure_root}; use codec::{Encode, Decode}; -use sr_primitives::{ +use sp_runtime::{ traits::{SignedExtension, Bounded, SaturatedConversion}, transaction_validity::{ ValidTransaction, TransactionValidityError, InvalidTransaction, TransactionValidity, @@ -281,17 +281,17 @@ use sr_primitives::{ // - The final weight of each dispatch is calculated as the argument of the call multiplied by the // parameter given to the `WeightForSetDummy`'s constructor. // - assigns a dispatch class `operational` if the argument of the call is more than 1000. -struct WeightForSetDummy(BalanceOf); +struct WeightForSetDummy(BalanceOf); -impl WeighData<(&BalanceOf,)> for WeightForSetDummy +impl WeighData<(&BalanceOf,)> for WeightForSetDummy { fn weigh_data(&self, target: (&BalanceOf,)) -> Weight { let multiplier = self.0; - (*target.0 * multiplier).saturated_into::() + (*target.0 * multiplier).saturated_into::() } } -impl ClassifyDispatch<(&BalanceOf,)> for WeightForSetDummy { +impl ClassifyDispatch<(&BalanceOf,)> for WeightForSetDummy { fn classify_dispatch(&self, target: (&BalanceOf,)) -> DispatchClass { if *target.0 > >::from(1000u32) { DispatchClass::Operational @@ -301,17 +301,23 @@ impl ClassifyDispatch<(&BalanceOf,)> for WeightForSetDumm } } +impl PaysFee for WeightForSetDummy { + fn pays_fee(&self) -> bool { + true + } +} + /// A type alias for the balance type from this module's point of view. -type BalanceOf = ::Balance; +type BalanceOf = ::Balance; /// Our module's configuration trait. All our types and constants go in here. If the /// module is dependent on specific other modules, then their configuration traits /// should be added to our implied traits list. /// -/// `system::Trait` should always be included in our implied traits. -pub trait Trait: balances::Trait { +/// `frame_system::Trait` should always be included in our implied traits. +pub trait Trait: pallet_balances::Trait { /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; } decl_storage! { @@ -336,8 +342,8 @@ decl_storage! { // e.g. pub Bar get(fn bar): map T::AccountId => Vec<(T::Balance, u64)>; // // For basic value items, you'll get a type which implements - // `support::StorageValue`. For map items, you'll get a type which - // implements `support::StorageMap`. + // `frame_support::StorageValue`. For map items, you'll get a type which + // implements `frame_support::StorageMap`. // // If they have a getter (`get(getter_name)`), then your module will come // equipped with `fn getter_name() -> Type` for basic value items or @@ -356,7 +362,7 @@ decl_event!( /// Events are a simple means of reporting specific conditions and /// circumstances that have happened that users, Dapps and/or chain explorers would find /// interesting and otherwise difficult to detect. - pub enum Event where B = ::Balance { + pub enum Event where B = ::Balance { // Just a normal `enum`, here's a dummy event to ensure it compiles. /// Dummy event, just here so there's a generic type that's used. Dummy(B), @@ -392,7 +398,7 @@ decl_event!( // // `fn foo(origin: T::Origin, bar: Bar, baz: Baz) { ... }` // -// There are three entries in the `system::Origin` enum that correspond +// There are three entries in the `frame_system::Origin` enum that correspond // to the above bullets: `::Signed(AccountId)`, `::Root` and `::None`. You should always match // against them as the first thing you do in your function. There are three convenience calls // in system that do the matching for you and return a convenient result: `ensure_signed`, @@ -454,7 +460,7 @@ decl_module! { // transaction and the latter demonstrates the [`DispatchClass`] of the call. A higher // weight means a larger transaction (less of which can be placed in a single block). #[weight = SimpleDispatchInfo::FixedNormal(10_000)] - fn accumulate_dummy(origin, increase_by: T::Balance) -> Result { + fn accumulate_dummy(origin, increase_by: T::Balance) -> DispatchResult { // This is a public call, so we ensure that the origin is some signed account. let _sender = ensure_signed(origin)?; @@ -524,7 +530,7 @@ decl_module! { fn offchain_worker(_n: T::BlockNumber) { // We don't do anything here. // but we could dispatch extrinsic (transaction/unsigned/inherent) using - // runtime_io::submit_extrinsic + // sp_io::submit_extrinsic } } } @@ -537,7 +543,7 @@ decl_module! { impl Module { // Add public immutables and private mutables. #[allow(dead_code)] - fn accumulate_foo(origin: T::Origin, increase_by: T::Balance) -> Result { + fn accumulate_foo(origin: T::Origin, increase_by: T::Balance) -> DispatchResult { let _sender = ensure_signed(origin)?; let prev = >::get(); @@ -575,7 +581,7 @@ impl Module { // sender of the transaction (if signed) are also provided. // // The full list of hooks that can be added to a signed extension can be found -// [here](https://crates.parity.io/sr_primitives/traits/trait.SignedExtension.html). +// [here](https://crates.parity.io/sp_runtime/traits/trait.SignedExtension.html). // // The signed extensions are aggregated in the runtime file of a substrate chain. All extensions // should be aggregated in a tuple and passed to the `CheckedExtrinsic` and `UncheckedExtrinsic` @@ -590,8 +596,8 @@ impl Module { #[derive(Encode, Decode, Clone, Eq, PartialEq)] pub struct WatchDummy(PhantomData); -impl rstd::fmt::Debug for WatchDummy { - fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { +impl sp_std::fmt::Debug for WatchDummy { + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { write!(f, "WatchDummy") } } @@ -599,7 +605,7 @@ impl rstd::fmt::Debug for WatchDummy { impl SignedExtension for WatchDummy { type AccountId = T::AccountId; // Note that this could also be assigned to the top-level call enum. It is passed into the - // balances module directly and since `Trait: balances::Trait`, you could also use `T::Call`. + // balances module directly and since `Trait: pallet_balances::Trait`, you could also use `T::Call`. // In that case, you would have had access to all call variants and could match on variants from // other modules. type Call = Call; @@ -607,7 +613,7 @@ impl SignedExtension for WatchDummy { type DispatchInfo = DispatchInfo; type Pre = (); - fn additional_signed(&self) -> rstd::result::Result<(), TransactionValidityError> { Ok(()) } + fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { Ok(()) } fn validate( &self, @@ -624,7 +630,7 @@ impl SignedExtension for WatchDummy { // check for `set_dummy` match call { Call::set_dummy(..) => { - sr_primitives::print("set_dummy was received."); + sp_runtime::print("set_dummy was received."); let mut valid_tx = ValidTransaction::default(); valid_tx.priority = Bounded::max_value(); @@ -639,17 +645,17 @@ impl SignedExtension for WatchDummy { mod tests { use super::*; - use support::{assert_ok, impl_outer_origin, parameter_types, weights::GetDispatchInfo}; - use primitives::H256; + use frame_support::{assert_ok, impl_outer_origin, parameter_types, weights::GetDispatchInfo}; + use sp_core::H256; // The testing primitives are very useful for avoiding having to work with signatures // or public keys. `u64` is used as the `AccountId` and no `Signature`s are required. - use sr_primitives::{ + use sp_runtime::{ Perbill, testing::Header, traits::{BlakeTwo256, OnInitialize, OnFinalize, IdentityLookup}, }; impl_outer_origin! { - pub enum Origin for Test {} + pub enum Origin for Test where system = frame_system {} } // For testing the module, we construct most of a mock runtime. This means @@ -659,11 +665,11 @@ mod tests { pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockWeight: Weight = 1024; pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } - impl system::Trait for Test { + impl frame_system::Trait for Test { type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -679,13 +685,14 @@ mod tests { type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); + type ModuleToIndex = (); } parameter_types! { pub const ExistentialDeposit: u64 = 0; pub const TransferFee: u64 = 0; pub const CreationFee: u64 = 0; } - impl balances::Trait for Test { + impl pallet_balances::Trait for Test { type Balance = u64; type OnFreeBalanceZero = (); type OnNewAccount = (); @@ -703,10 +710,10 @@ mod tests { // This function basically just builds a genesis storage key/value store according to // our desired mockup. - fn new_test_ext() -> runtime_io::TestExternalities { - let mut t = system::GenesisConfig::default().build_storage::().unwrap(); + fn new_test_ext() -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); // We use default for brevity, but you can configure as desired if needed. - balances::GenesisConfig::::default().assimilate_storage(&mut t).unwrap(); + pallet_balances::GenesisConfig::::default().assimilate_storage(&mut t).unwrap(); GenesisConfig::{ dummy: 42, // we configure the map with (key, value) pairs. diff --git a/frame/executive/Cargo.toml b/frame/executive/Cargo.toml index bc10d71f425940e19f18009d7aeabb08b74b735e..b58d4a67907301c1c0673741ac65221624a10555 100644 --- a/frame/executive/Cargo.toml +++ b/frame/executive/Cargo.toml @@ -7,27 +7,27 @@ edition = "2018" [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -rstd = { package = "sr-std", path = "../../primitives/sr-std", default-features = false } -runtime-io ={ package = "sr-io", path = "../../primitives/sr-io", default-features = false } -sr-primitives = { path = "../../primitives/sr-primitives", default-features = false } -support = { package = "frame-support", path = "../support", default-features = false } -system = { package = "frame-system", path = "../system", default-features = false } +sp-std = { version = "2.0.0", default-features = false, path = "../../primitives/std" } +sp-io ={ path = "../../primitives/io", default-features = false } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0", default-features = false, path = "../support" } +frame-system = { version = "2.0.0", default-features = false, path = "../system" } [dev-dependencies] hex-literal = "0.2.1" -primitives = { package = "substrate-primitives", path = "../../primitives/core" } -pallet-indices = { path = "../indices" } -balances = { package = "pallet-balances", path = "../balances" } -transaction-payment = { package = "pallet-transaction-payment", path = "../transaction-payment" } +sp-core = { version = "2.0.0", path = "../../primitives/core" } +pallet-indices = { version = "2.0.0", path = "../indices" } +pallet-balances = { version = "2.0.0", path = "../balances" } +pallet-transaction-payment = { version = "2.0.0", path = "../transaction-payment" } [features] default = ["std"] std = [ - "rstd/std", - "support/std", + "sp-std/std", + "frame-support/std", "serde", "codec/std", - "sr-primitives/std", - "runtime-io/std", - "system/std", + "sp-runtime/std", + "sp-io/std", + "frame-system/std", ] diff --git a/frame/executive/src/lib.rs b/frame/executive/src/lib.rs index f6b50143a7094e837c7016ce5ec28ef380cae308..fd05c410d9f7020677764824dc646c8eca50ceb5 100644 --- a/frame/executive/src/lib.rs +++ b/frame/executive/src/lib.rs @@ -50,18 +50,18 @@ //! `Executive` type declaration from the node template. //! //! ``` -//! # use sr_primitives::generic; +//! # use sp_runtime::generic; //! # use frame_executive as executive; //! # pub struct UncheckedExtrinsic {}; //! # pub struct Header {}; -//! # type Context = system::ChainContext; +//! # type Context = frame_system::ChainContext; //! # pub type Block = generic::Block; //! # pub type Balances = u64; //! # pub type AllModules = u64; //! # pub enum Runtime {}; -//! # use sr_primitives::transaction_validity::{TransactionValidity, UnknownTransaction}; +//! # use sp_runtime::transaction_validity::{TransactionValidity, UnknownTransaction}; //! # #[allow(deprecated)] -//! # use sr_primitives::traits::ValidateUnsigned; +//! # use sp_runtime::traits::ValidateUnsigned; //! # #[allow(deprecated)] //! # impl ValidateUnsigned for Runtime { //! # type Call = (); @@ -76,9 +76,9 @@ #![cfg_attr(not(feature = "std"), no_std)] -use rstd::{prelude::*, marker::PhantomData}; -use support::weights::{GetDispatchInfo, WeighBlock, DispatchInfo}; -use sr_primitives::{ +use sp_std::{prelude::*, marker::PhantomData}; +use frame_support::weights::{GetDispatchInfo, WeighBlock, DispatchInfo}; +use sp_runtime::{ generic::Digest, ApplyExtrinsicResult, traits::{ self, Header, Zero, One, Checkable, Applyable, CheckEqual, OnFinalize, OnInitialize, @@ -87,9 +87,9 @@ use sr_primitives::{ transaction_validity::TransactionValidity, }; #[allow(deprecated)] -use sr_primitives::traits::ValidateUnsigned; +use sp_runtime::traits::ValidateUnsigned; use codec::{Codec, Encode}; -use system::{extrinsics_root, DigestOf}; +use frame_system::{extrinsics_root, DigestOf}; /// Trait that can be used to execute a block. pub trait ExecuteBlock { @@ -107,7 +107,7 @@ pub struct Executive( #[allow(deprecated)] // Allow ValidateUnsigned, remove the attribute when the trait is removed. impl< - System: system::Trait, + System: frame_system::Trait, Block: traits::Block, Context: Default, UnsignedValidator, @@ -133,7 +133,7 @@ where #[allow(deprecated)] // Allow ValidateUnsigned, remove the attribute when the trait is removed. impl< - System: system::Trait, + System: frame_system::Trait, Block: traits::Block, Context: Default, UnsignedValidator, @@ -165,12 +165,12 @@ where extrinsics_root: &System::Hash, digest: &Digest, ) { - >::initialize(block_number, parent_hash, extrinsics_root, digest); + >::initialize(block_number, parent_hash, extrinsics_root, digest); >::on_initialize(*block_number); - >::register_extra_weight_unchecked( + >::register_extra_weight_unchecked( >::on_initialize(*block_number) ); - >::register_extra_weight_unchecked( + >::register_extra_weight_unchecked( >::on_finalize(*block_number) ); } @@ -182,7 +182,7 @@ where let n = header.number().clone(); assert!( n > System::BlockNumber::zero() - && >::block_hash(n - System::BlockNumber::one()) == *header.parent_hash(), + && >::block_hash(n - System::BlockNumber::one()) == *header.parent_hash(), "Parent hash should be valid." ); @@ -213,19 +213,19 @@ where extrinsics.into_iter().for_each(Self::apply_extrinsic_no_note); // post-extrinsics book-keeping - >::note_finished_extrinsics(); + >::note_finished_extrinsics(); >::on_finalize(block_number); } /// Finalize the block - it is up the caller to ensure that all header fields are valid /// except state-root. pub fn finalize_block() -> System::Header { - >::note_finished_extrinsics(); - >::on_finalize(>::block_number()); + >::note_finished_extrinsics(); + >::on_finalize(>::block_number()); // set up extrinsics - >::derive_extrinsics(); - >::finalize() + >::derive_extrinsics(); + >::finalize() } /// Apply extrinsic outside of the block execution function. @@ -243,7 +243,7 @@ where let l = uxt.encode().len(); match Self::apply_extrinsic_with_len(uxt, l, None) { Ok(Ok(())) => (), - Ok(Err(e)) => sr_primitives::print(e), + Ok(Err(e)) => sp_runtime::print(e), Err(e) => { let err: &'static str = e.into(); panic!(err) }, } } @@ -261,7 +261,7 @@ where // executed to prevent it from leaking in storage since at this point, it will either // execute or panic (and revert storage changes). if let Some(encoded) = to_note { - >::note_extrinsic(encoded); + >::note_extrinsic(encoded); } // AUDIT: Under no circumstances may this function panic from here onwards. @@ -270,14 +270,14 @@ where let dispatch_info = xt.get_dispatch_info(); let r = Applyable::apply::(xt, dispatch_info, encoded_len)?; - >::note_applied_extrinsic(&r, encoded_len as u32, dispatch_info); + >::note_applied_extrinsic(&r, encoded_len as u32, dispatch_info); Ok(r) } fn final_checks(header: &System::Header) { // remove temporaries - let new_header = >::finalize(); + let new_header = >::finalize(); // check digest assert_eq!( @@ -311,7 +311,7 @@ where /// Start an offchain worker and generate extrinsics. pub fn offchain_worker(n: System::BlockNumber) { - >::generate_extrinsics(n) + >::offchain_worker(n) } } @@ -319,40 +319,40 @@ where #[cfg(test)] mod tests { use super::*; - use primitives::H256; - use sr_primitives::{ + use sp_core::H256; + use sp_runtime::{ generic::Era, Perbill, DispatchError, testing::{Digest, Header, Block}, traits::{Bounded, Header as HeaderT, BlakeTwo256, IdentityLookup, ConvertInto}, transaction_validity::{InvalidTransaction, UnknownTransaction, TransactionValidityError}, }; - use support::{ + use frame_support::{ impl_outer_event, impl_outer_origin, parameter_types, impl_outer_dispatch, weights::Weight, traits::{Currency, LockIdentifier, LockableCurrency, WithdrawReasons, WithdrawReason}, }; - use system::{Call as SystemCall, ChainContext}; - use balances::Call as BalancesCall; + use frame_system::{self as system, Call as SystemCall, ChainContext}; + use pallet_balances::Call as BalancesCall; use hex_literal::hex; mod custom { - use support::weights::SimpleDispatchInfo; + use frame_support::weights::SimpleDispatchInfo; - pub trait Trait: system::Trait {} + pub trait Trait: frame_system::Trait {} - support::decl_module! { + frame_support::decl_module! { pub struct Module for enum Call where origin: T::Origin { #[weight = SimpleDispatchInfo::FixedNormal(100)] fn some_function(origin) { // NOTE: does not make any different. - let _ = system::ensure_signed(origin); + let _ = frame_system::ensure_signed(origin); } #[weight = SimpleDispatchInfo::FixedOperational(200)] fn some_root_operation(origin) { - let _ = system::ensure_root(origin); + let _ = frame_system::ensure_root(origin); } #[weight = SimpleDispatchInfo::FreeNormal] fn some_unsigned_message(origin) { - let _ = system::ensure_none(origin); + let _ = frame_system::ensure_none(origin); } // module hooks. @@ -369,10 +369,12 @@ mod tests { } } - type System = system::Module; - type Balances = balances::Module; + type System = frame_system::Module; + type Balances = pallet_balances::Module; type Custom = custom::Module; + use pallet_balances as balances; + impl_outer_origin! { pub enum Origin for Runtime { } } @@ -384,8 +386,8 @@ mod tests { } impl_outer_dispatch! { pub enum Call for Runtime where origin: Origin { - system::System, - balances::Balances, + frame_system::System, + pallet_balances::Balances, } } @@ -393,16 +395,16 @@ mod tests { pub struct Runtime; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockWeight: Weight = 1024; pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } - impl system::Trait for Runtime { + impl frame_system::Trait for Runtime { type Origin = Origin; type Index = u64; type Call = Call; type BlockNumber = u64; - type Hash = primitives::H256; + type Hash = sp_core::H256; type Hashing = BlakeTwo256; type AccountId = u64; type Lookup = IdentityLookup; @@ -413,13 +415,14 @@ mod tests { type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; type Version = (); + type ModuleToIndex = (); } parameter_types! { pub const ExistentialDeposit: u64 = 0; pub const TransferFee: u64 = 0; pub const CreationFee: u64 = 0; } - impl balances::Trait for Runtime { + impl pallet_balances::Trait for Runtime { type Balance = u64; type OnFreeBalanceZero = (); type OnNewAccount = (); @@ -435,7 +438,7 @@ mod tests { pub const TransactionBaseFee: u64 = 10; pub const TransactionByteFee: u64 = 0; } - impl transaction_payment::Trait for Runtime { + impl pallet_transaction_payment::Trait for Runtime { type Currency = Balances; type OnTransactionPayment = (); type TransactionBaseFee = TransactionBaseFee; @@ -462,21 +465,21 @@ mod tests { } type SignedExtra = ( - system::CheckEra, - system::CheckNonce, - system::CheckWeight, - transaction_payment::ChargeTransactionPayment + frame_system::CheckEra, + frame_system::CheckNonce, + frame_system::CheckWeight, + pallet_transaction_payment::ChargeTransactionPayment ); type AllModules = (System, Balances, Custom); - type TestXt = sr_primitives::testing::TestXt; + type TestXt = sp_runtime::testing::TestXt; type Executive = super::Executive, ChainContext, Runtime, AllModules>; fn extra(nonce: u64, fee: u64) -> SignedExtra { ( - system::CheckEra::from(Era::Immortal), - system::CheckNonce::from(nonce), - system::CheckWeight::new(), - transaction_payment::ChargeTransactionPayment::from(fee) + frame_system::CheckEra::from(Era::Immortal), + frame_system::CheckNonce::from(nonce), + frame_system::CheckWeight::new(), + pallet_transaction_payment::ChargeTransactionPayment::from(fee) ) } @@ -486,14 +489,14 @@ mod tests { #[test] fn balance_transfer_dispatch_works() { - let mut t = system::GenesisConfig::default().build_storage::().unwrap(); - balances::GenesisConfig:: { + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); + pallet_balances::GenesisConfig:: { balances: vec![(1, 211)], vesting: vec![], }.assimilate_storage(&mut t).unwrap(); - let xt = sr_primitives::testing::TestXt(sign_extra(1, 0, 0), Call::Balances(BalancesCall::transfer(2, 69))); + let xt = sp_runtime::testing::TestXt(sign_extra(1, 0, 0), Call::Balances(BalancesCall::transfer(2, 69))); let weight = xt.get_dispatch_info().weight as u64; - let mut t = runtime_io::TestExternalities::new(t); + let mut t = sp_io::TestExternalities::new(t); t.execute_with(|| { Executive::initialize_block(&Header::new( 1, @@ -504,14 +507,14 @@ mod tests { )); let r = Executive::apply_extrinsic(xt); assert!(r.is_ok()); - assert_eq!(>::total_balance(&1), 142 - 10 - weight); - assert_eq!(>::total_balance(&2), 69); + assert_eq!(>::total_balance(&1), 142 - 10 - weight); + assert_eq!(>::total_balance(&2), 69); }); } - fn new_test_ext(balance_factor: u64) -> runtime_io::TestExternalities { - let mut t = system::GenesisConfig::default().build_storage::().unwrap(); - balances::GenesisConfig:: { + fn new_test_ext(balance_factor: u64) -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); + pallet_balances::GenesisConfig:: { balances: vec![(1, 111 * balance_factor)], vesting: vec![], }.assimilate_storage(&mut t).unwrap(); @@ -525,7 +528,7 @@ mod tests { header: Header { parent_hash: [69u8; 32].into(), number: 1, - state_root: hex!("f0d1d66255c2e5b40580eb8b93ddbe732491478487f85e358e1d167d369e398e").into(), + state_root: hex!("c6b01b27df520ba23adb96e7fc032acb7c586ba1b477c6282de43184111f2091").into(), extrinsics_root: hex!("03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314").into(), digest: Digest { logs: vec![], }, }, @@ -572,7 +575,7 @@ mod tests { fn bad_extrinsic_not_inserted() { let mut t = new_test_ext(1); // bad nonce check! - let xt = sr_primitives::testing::TestXt(sign_extra(1, 30, 0), Call::Balances(BalancesCall::transfer(33, 69))); + let xt = sp_runtime::testing::TestXt(sign_extra(1, 30, 0), Call::Balances(BalancesCall::transfer(33, 69))); t.execute_with(|| { Executive::initialize_block(&Header::new( 1, @@ -582,7 +585,7 @@ mod tests { Digest::default(), )); assert!(Executive::apply_extrinsic(xt).is_err()); - assert_eq!(>::extrinsic_index(), Some(0)); + assert_eq!(>::extrinsic_index(), Some(0)); }); } @@ -590,7 +593,7 @@ mod tests { fn block_weight_limit_enforced() { let mut t = new_test_ext(10000); // given: TestXt uses the encoded len as fixed Len: - let xt = sr_primitives::testing::TestXt(sign_extra(1, 0, 0), Call::Balances(BalancesCall::transfer(33, 0))); + let xt = sp_runtime::testing::TestXt(sign_extra(1, 0, 0), Call::Balances(BalancesCall::transfer(33, 0))); let encoded = xt.encode(); let encoded_len = encoded.len() as Weight; let limit = AvailableBlockRatio::get() * MaximumBlockWeight::get() - 175; @@ -604,20 +607,20 @@ mod tests { Digest::default(), )); // Initial block weight form the custom module. - assert_eq!(>::all_extrinsics_weight(), 175); + assert_eq!(>::all_extrinsics_weight(), 175); for nonce in 0..=num_to_exhaust_block { - let xt = sr_primitives::testing::TestXt( + let xt = sp_runtime::testing::TestXt( sign_extra(1, nonce.into(), 0), Call::Balances(BalancesCall::transfer(33, 0)), ); let res = Executive::apply_extrinsic(xt); if nonce != num_to_exhaust_block { assert!(res.is_ok()); assert_eq!( - >::all_extrinsics_weight(), + >::all_extrinsics_weight(), encoded_len * (nonce + 1) + 175, ); - assert_eq!(>::extrinsic_index(), Some(nonce as u32 + 1)); + assert_eq!(>::extrinsic_index(), Some(nonce as u32 + 1)); } else { assert_eq!(res, Err(InvalidTransaction::ExhaustsResources.into())); } @@ -627,45 +630,38 @@ mod tests { #[test] fn block_weight_and_size_is_stored_per_tx() { - let xt = sr_primitives::testing::TestXt(sign_extra(1, 0, 0), Call::Balances(BalancesCall::transfer(33, 0))); - let x1 = sr_primitives::testing::TestXt(sign_extra(1, 1, 0), Call::Balances(BalancesCall::transfer(33, 0))); - let x2 = sr_primitives::testing::TestXt(sign_extra(1, 2, 0), Call::Balances(BalancesCall::transfer(33, 0))); + let xt = sp_runtime::testing::TestXt(sign_extra(1, 0, 0), Call::Balances(BalancesCall::transfer(33, 0))); + let x1 = sp_runtime::testing::TestXt(sign_extra(1, 1, 0), Call::Balances(BalancesCall::transfer(33, 0))); + let x2 = sp_runtime::testing::TestXt(sign_extra(1, 2, 0), Call::Balances(BalancesCall::transfer(33, 0))); let len = xt.clone().encode().len() as u32; let mut t = new_test_ext(1); t.execute_with(|| { - assert_eq!(>::all_extrinsics_weight(), 0); - assert_eq!(>::all_extrinsics_weight(), 0); + assert_eq!(>::all_extrinsics_weight(), 0); + assert_eq!(>::all_extrinsics_weight(), 0); assert!(Executive::apply_extrinsic(xt.clone()).unwrap().is_ok()); assert!(Executive::apply_extrinsic(x1.clone()).unwrap().is_ok()); assert!(Executive::apply_extrinsic(x2.clone()).unwrap().is_ok()); // default weight for `TestXt` == encoded length. - assert_eq!(>::all_extrinsics_weight(), (3 * len) as u32); - assert_eq!(>::all_extrinsics_len(), 3 * len); + assert_eq!(>::all_extrinsics_weight(), (3 * len) as Weight); + assert_eq!(>::all_extrinsics_len(), 3 * len); - let _ = >::finalize(); + let _ = >::finalize(); - assert_eq!(>::all_extrinsics_weight(), 0); - assert_eq!(>::all_extrinsics_weight(), 0); + assert_eq!(>::all_extrinsics_weight(), 0); + assert_eq!(>::all_extrinsics_weight(), 0); }); } #[test] fn validate_unsigned() { - let xt = sr_primitives::testing::TestXt(None, Call::Balances(BalancesCall::set_balance(33, 69, 69))); + let xt = sp_runtime::testing::TestXt(None, Call::Balances(BalancesCall::set_balance(33, 69, 69))); let mut t = new_test_ext(1); t.execute_with(|| { assert_eq!(Executive::validate_transaction(xt.clone()), Ok(Default::default())); - assert_eq!( - Executive::apply_extrinsic(xt), - Ok( - Err( - DispatchError { module: Some(1), error: 0, message: Some("RequireRootOrigin") } - ) - ) - ); + assert_eq!(Executive::apply_extrinsic(xt), Ok(Err(DispatchError::BadOrigin))); }); } @@ -675,14 +671,14 @@ mod tests { let execute_with_lock = |lock: WithdrawReasons| { let mut t = new_test_ext(1); t.execute_with(|| { - as LockableCurrency>::set_lock( + as LockableCurrency>::set_lock( id, &1, 110, Bounded::max_value(), lock, ); - let xt = sr_primitives::testing::TestXt( + let xt = sp_runtime::testing::TestXt( sign_extra(1, 0, 0), Call::System(SystemCall::remark(vec![1u8])), ); @@ -698,13 +694,13 @@ mod tests { if lock == WithdrawReasons::except(WithdrawReason::TransactionPayment) { assert!(Executive::apply_extrinsic(xt).unwrap().is_ok()); // tx fee has been deducted. - assert_eq!(>::total_balance(&1), 111 - 10 - weight); + assert_eq!(>::total_balance(&1), 111 - 10 - weight); } else { assert_eq!( Executive::apply_extrinsic(xt), Err(InvalidTransaction::Payment.into()), ); - assert_eq!(>::total_balance(&1), 111); + assert_eq!(>::total_balance(&1), 111); } }); }; @@ -720,7 +716,7 @@ mod tests { Executive::initialize_block(&Header::new_from_number(1)); // NOTE: might need updates over time if system and balance introduce new weights. For // now only accounts for the custom module. - assert_eq!(>::all_extrinsics_weight(), 150 + 25); + assert_eq!(>::all_extrinsics_weight(), 150 + 25); }) } } diff --git a/frame/finality-tracker/Cargo.toml b/frame/finality-tracker/Cargo.toml index 6fb767f0d0c8a6618c8b66e1844d58695c1d05b8..22e1380e656972e238b943a6fe56babff2d26718 100644 --- a/frame/finality-tracker/Cargo.toml +++ b/frame/finality-tracker/Cargo.toml @@ -7,27 +7,27 @@ edition = "2018" [dependencies] serde = { version = "1.0.101", default-features = false, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false } -inherents = { package = "substrate-inherents", path = "../../primitives/inherents", default-features = false } -rstd = { package = "sr-std", path = "../../primitives/sr-std", default-features = false } -sr-primitives = { path = "../../primitives/sr-primitives", default-features = false } -sp-finality-tracker = { path = "../../primitives/finality-tracker", default-features = false } -support = { package = "frame-support", path = "../support", default-features = false } -frame-system = { path = "../system", default-features = false } +sp-inherents = { version = "2.0.0", default-features = false, path = "../../primitives/inherents" } +sp-std = { version = "2.0.0", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" } +sp-finality-tracker = { version = "2.0.0", default-features = false, path = "../../primitives/finality-tracker" } +frame-support = { version = "2.0.0", default-features = false, path = "../support" } +frame-system = { version = "2.0.0", default-features = false, path = "../system" } impl-trait-for-tuples = "0.1.3" [dev-dependencies] -primitives = { package = "substrate-primitives", path = "../../primitives/core", default-features = false } -runtime-io = { package = "sr-io", path = "../../primitives/sr-io", default-features = false } +sp-core = { version = "2.0.0", default-features = false, path = "../../primitives/core" } +sp-io = { version = "2.0.0", default-features = false, path = "../../primitives/io" } [features] default = ["std"] std = [ "serde/std", "codec/std", - "rstd/std", - "support/std", - "sr-primitives/std", + "sp-std/std", + "frame-support/std", + "sp-runtime/std", "frame-system/std", "sp-finality-tracker/std", - "inherents/std", + "sp-inherents/std", ] diff --git a/frame/finality-tracker/src/lib.rs b/frame/finality-tracker/src/lib.rs index 7d03f1bc7d7d796864bf32c595559bf05eb995d4..5fbf2b953110a854398c8443349da644a7b2eff0 100644 --- a/frame/finality-tracker/src/lib.rs +++ b/frame/finality-tracker/src/lib.rs @@ -18,11 +18,11 @@ #![cfg_attr(not(feature = "std"), no_std)] -use inherents::{InherentIdentifier, ProvideInherent, InherentData, MakeFatalError}; -use sr_primitives::traits::{One, Zero, SaturatedConversion}; -use rstd::{prelude::*, result, cmp, vec}; -use support::{decl_module, decl_storage}; -use support::traits::Get; +use sp_inherents::{InherentIdentifier, ProvideInherent, InherentData, MakeFatalError}; +use sp_runtime::traits::{One, Zero, SaturatedConversion}; +use sp_std::{prelude::*, result, cmp, vec}; +use frame_support::{decl_module, decl_storage, decl_error, ensure}; +use frame_support::traits::Get; use frame_system::{ensure_none, Trait as SystemTrait}; use sp_finality_tracker::{INHERENT_IDENTIFIER, FinalizedInherentData}; @@ -56,8 +56,18 @@ decl_storage! { } } +decl_error! { + pub enum Error for Module { + /// Final hint must be updated only once in the block + AlreadyUpdated, + /// Finalized height above block number + BadHint, + } +} + decl_module! { pub struct Module for enum Call where origin: T::Origin { + type Error = Error; /// The number of recent samples to keep from this chain. Default is 101. const WindowSize: T::BlockNumber = T::WindowSize::get(); @@ -68,10 +78,10 @@ decl_module! { /// block is the given number. fn final_hint(origin, #[compact] hint: T::BlockNumber) { ensure_none(origin)?; - assert!(!::Update::exists(), "Final hint must be updated only once in the block"); - assert!( + ensure!(!::Update::exists(), Error::::AlreadyUpdated); + ensure!( frame_system::Module::::block_number() >= hint, - "Finalized height above block number", + Error::::BadHint, ); ::Update::put(hint); } @@ -193,13 +203,13 @@ impl ProvideInherent for Module { mod tests { use super::*; - use runtime_io::TestExternalities; - use primitives::H256; - use sr_primitives::{ + use sp_io::TestExternalities; + use sp_core::H256; + use sp_runtime::{ testing::Header, Perbill, traits::{BlakeTwo256, IdentityLookup, OnFinalize, Header as HeaderT}, }; - use support::{assert_ok, impl_outer_origin, parameter_types}; + use frame_support::{assert_ok, impl_outer_origin, parameter_types, weights::Weight}; use frame_system as system; use std::cell::RefCell; @@ -213,7 +223,7 @@ mod tests { pub struct Test; impl_outer_origin! { - pub enum Origin for Test {} + pub enum Origin for Test where system = frame_system {} } thread_local! { @@ -230,7 +240,7 @@ mod tests { parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockWeight: Weight = 1024; pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } @@ -250,6 +260,7 @@ mod tests { type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; type Version = (); + type ModuleToIndex = (); } parameter_types! { pub const WindowSize: u64 = 11; diff --git a/frame/generic-asset/Cargo.toml b/frame/generic-asset/Cargo.toml index f8ea4c020fb890e4bbe60d5640094af106414037..87f4c9d1cf81ff2892aacb8efee9f7d5e37945bf 100644 --- a/frame/generic-asset/Cargo.toml +++ b/frame/generic-asset/Cargo.toml @@ -7,22 +7,22 @@ edition = "2018" [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -rstd = { package = "sr-std", path = "../../primitives/sr-std", default-features = false } -sr-primitives = { path = "../../primitives/sr-primitives", default-features = false } -support = { package = "frame-support", path = "../support", default-features = false } -system = { package = "frame-system", path = "../system", default-features = false } +sp-std = { version = "2.0.0", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0", default-features = false, path = "../support" } +frame-system = { version = "2.0.0", default-features = false, path = "../system" } [dev-dependencies] -runtime-io ={ package = "sr-io", path = "../../primitives/sr-io" } -primitives = { package = "substrate-primitives", path = "../../primitives/core" } +sp-io ={ version = "2.0.0", path = "../../primitives/io" } +sp-core = { version = "2.0.0", path = "../../primitives/core" } [features] default = ["std"] std =[ "serde/std", "codec/std", - "rstd/std", - "sr-primitives/std", - "support/std", - "system/std", + "sp-std/std", + "sp-runtime/std", + "frame-support/std", + "frame-system/std", ] diff --git a/frame/generic-asset/src/lib.rs b/frame/generic-asset/src/lib.rs index a552880a34b62b323ee89b41e15203a37e5d06a1..de63ba2f1244c404ee88b9c1b488e39c153395d8 100644 --- a/frame/generic-asset/src/lib.rs +++ b/frame/generic-asset/src/lib.rs @@ -114,16 +114,16 @@ //! The Fees module uses the `Currency` trait to handle fee charge/refund, and its types inherit from `Currency`: //! //! ``` -//! use support::{ +//! use frame_support::{ +//! dispatch, //! traits::{Currency, ExistenceRequirement, WithdrawReason}, -//! dispatch::Result, //! }; -//! # pub trait Trait: system::Trait { +//! # pub trait Trait: frame_system::Trait { //! # type Currency: Currency; //! # } -//! type AssetOf = <::Currency as Currency<::AccountId>>::Balance; +//! type AssetOf = <::Currency as Currency<::AccountId>>::Balance; //! -//! fn charge_fee(transactor: &T::AccountId, amount: AssetOf) -> Result { +//! fn charge_fee(transactor: &T::AccountId, amount: AssetOf) -> dispatch::DispatchResult { //! // ... //! T::Currency::withdraw( //! transactor, @@ -135,7 +135,7 @@ //! Ok(()) //! } //! -//! fn refund_fee(transactor: &T::AccountId, amount: AssetOf) -> Result { +//! fn refund_fee(transactor: &T::AccountId, amount: AssetOf) -> dispatch::DispatchResult { //! // ... //! T::Currency::deposit_into_existing(transactor, amount)?; //! // ... @@ -153,31 +153,30 @@ use codec::{Decode, Encode, HasCompact, Input, Output, Error}; -use sr_primitives::RuntimeDebug; -use sr_primitives::traits::{ +use sp_runtime::{RuntimeDebug, DispatchResult, DispatchError}; +use sp_runtime::traits::{ CheckedAdd, CheckedSub, MaybeSerializeDeserialize, Member, One, Saturating, SimpleArithmetic, Zero, Bounded, }; -use rstd::prelude::*; -use rstd::{cmp, result, fmt::Debug}; -use support::dispatch::Result; -use support::{ - decl_event, decl_module, decl_storage, ensure, +use sp_std::prelude::*; +use sp_std::{cmp, result, fmt::Debug}; +use frame_support::{ + decl_event, decl_module, decl_storage, ensure, dispatch, traits::{ Currency, ExistenceRequirement, Imbalance, LockIdentifier, LockableCurrency, ReservableCurrency, SignedImbalance, UpdateBalanceOutcome, WithdrawReason, WithdrawReasons, TryDrop, }, Parameter, StorageMap, }; -use system::{ensure_signed, ensure_root}; +use frame_system::{self as system, ensure_signed, ensure_root}; mod mock; mod tests; pub use self::imbalances::{NegativeImbalance, PositiveImbalance}; -pub trait Trait: system::Trait { +pub trait Trait: frame_system::Trait { type Balance: Parameter + Member + SimpleArithmetic @@ -186,10 +185,10 @@ pub trait Trait: system::Trait { + MaybeSerializeDeserialize + Debug; type AssetId: Parameter + Member + SimpleArithmetic + Default + Copy; - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; } -pub trait Subtrait: system::Trait { +pub trait Subtrait: frame_system::Trait { type Balance: Parameter + Member + SimpleArithmetic @@ -326,7 +325,7 @@ decl_module! { fn deposit_event() = default; /// Create a new kind of asset. - fn create(origin, options: AssetOptions) -> Result { + fn create(origin, options: AssetOptions) -> dispatch::DispatchResult { let origin = ensure_signed(origin)?; let id = Self::next_asset_id(); @@ -359,7 +358,7 @@ decl_module! { origin, #[compact] asset_id: T::AssetId, new_permission: PermissionLatest - ) -> Result { + ) -> dispatch::DispatchResult { let origin = ensure_signed(origin)?; let permissions: PermissionVersions = new_permission.into(); @@ -371,13 +370,15 @@ decl_module! { Ok(()) } else { - Err("Origin does not have enough permission to update permissions.") + Err("Origin does not have enough permission to update permissions.")? } } /// Mints an asset, increases its total issuance. /// The origin must have `mint` permissions. - fn mint(origin, #[compact] asset_id: T::AssetId, to: T::AccountId, amount: T::Balance) -> Result { + fn mint(origin, #[compact] asset_id: T::AssetId, to: T::AccountId, amount: T::Balance) + -> dispatch::DispatchResult + { let origin = ensure_signed(origin)?; if Self::check_permission(&asset_id, &origin, &PermissionType::Mint) { let original_free_balance = Self::free_balance(&asset_id, &to); @@ -394,14 +395,16 @@ decl_module! { Ok(()) } else { - Err("The origin does not have permission to mint an asset.") + Err("The origin does not have permission to mint an asset.")? } } /// Burns an asset, decreases its total issuance. /// /// The `origin` must have `burn` permissions. - fn burn(origin, #[compact] asset_id: T::AssetId, to: T::AccountId, amount: T::Balance) -> Result { + fn burn(origin, #[compact] asset_id: T::AssetId, to: T::AccountId, amount: T::Balance) + -> dispatch::DispatchResult + { let origin = ensure_signed(origin)?; if Self::check_permission(&asset_id, &origin, &PermissionType::Burn) { @@ -421,13 +424,17 @@ decl_module! { Ok(()) } else { - Err("The origin does not have permission to burn an asset.") + Err("The origin does not have permission to burn an asset.")? } } /// Can be used to create reserved tokens. /// Requires Root call. - fn create_reserved(origin, asset_id: T::AssetId, options: AssetOptions) -> Result { + fn create_reserved( + origin, + asset_id: T::AssetId, + options: AssetOptions + ) -> dispatch::DispatchResult { ensure_root(origin)?; Self::create_asset(Some(asset_id), None, options) } @@ -488,10 +495,10 @@ decl_storage! { decl_event!( pub enum Event where - ::AccountId, + ::AccountId, ::Balance, ::AssetId, - AssetOptions = AssetOptions<::Balance, ::AccountId> + AssetOptions = AssetOptions<::Balance, ::AccountId> { /// Asset created (asset_id, creator, asset_options). Created(AssetId, AccountId, AssetOptions), @@ -536,7 +543,7 @@ impl Module { asset_id: Option, from_account: Option, options: AssetOptions, - ) -> Result { + ) -> dispatch::DispatchResult { let asset_id = if let Some(asset_id) = asset_id { ensure!(!>::exists(&asset_id), "Asset id already taken."); ensure!(asset_id < Self::next_asset_id(), "Asset id not available."); @@ -569,7 +576,7 @@ impl Module { from: &T::AccountId, to: &T::AccountId, amount: T::Balance - ) -> Result { + ) -> dispatch::DispatchResult { let new_balance = Self::free_balance(asset_id, from) .checked_sub(&amount) .ok_or_else(|| "balance too low to send amount")?; @@ -590,7 +597,7 @@ impl Module { from: &T::AccountId, to: &T::AccountId, amount: T::Balance, - ) -> Result { + ) -> dispatch::DispatchResult { Self::make_transfer(asset_id, from, to, amount)?; if from != to { @@ -604,12 +611,14 @@ impl Module { /// /// If the free balance is lower than `amount`, then no funds will be moved and an `Err` will /// be returned. This is different behavior than `unreserve`. - pub fn reserve(asset_id: &T::AssetId, who: &T::AccountId, amount: T::Balance) -> Result { + pub fn reserve(asset_id: &T::AssetId, who: &T::AccountId, amount: T::Balance) + -> dispatch::DispatchResult + { // Do we need to consider that this is an atomic transaction? let original_reserve_balance = Self::reserved_balance(asset_id, who); let original_free_balance = Self::free_balance(asset_id, who); if original_free_balance < amount { - return Err("not enough free funds"); + Err("not enough free funds")? } let new_reserve_balance = original_reserve_balance + amount; Self::set_reserved_balance(asset_id, who, new_reserve_balance); @@ -625,7 +634,7 @@ impl Module { /// NOTE: This is different behavior than `reserve`. pub fn unreserve(asset_id: &T::AssetId, who: &T::AccountId, amount: T::Balance) -> T::Balance { let b = Self::reserved_balance(asset_id, who); - let actual = rstd::cmp::min(b, amount); + let actual = sp_std::cmp::min(b, amount); let original_free_balance = Self::free_balance(asset_id, who); let new_free_balance = original_free_balance + actual; Self::set_free_balance(asset_id, who, new_free_balance); @@ -642,7 +651,7 @@ impl Module { /// the caller will do this. fn slash(asset_id: &T::AssetId, who: &T::AccountId, amount: T::Balance) -> Option { let free_balance = Self::free_balance(asset_id, who); - let free_slash = rstd::cmp::min(free_balance, amount); + let free_slash = sp_std::cmp::min(free_balance, amount); let new_free_balance = free_balance - free_slash; Self::set_free_balance(asset_id, who, new_free_balance); if free_slash < amount { @@ -660,7 +669,7 @@ impl Module { /// the caller will do this. fn slash_reserved(asset_id: &T::AssetId, who: &T::AccountId, amount: T::Balance) -> Option { let original_reserve_balance = Self::reserved_balance(asset_id, who); - let slash = rstd::cmp::min(original_reserve_balance, amount); + let slash = sp_std::cmp::min(original_reserve_balance, amount); let new_reserve_balance = original_reserve_balance - slash; Self::set_reserved_balance(asset_id, who, new_reserve_balance); if amount == slash { @@ -684,7 +693,7 @@ impl Module { amount: T::Balance, ) -> T::Balance { let b = Self::reserved_balance(asset_id, who); - let slash = rstd::cmp::min(b, amount); + let slash = sp_std::cmp::min(b, amount); let original_free_balance = Self::free_balance(asset_id, beneficiary); let new_free_balance = original_free_balance + slash; @@ -742,7 +751,7 @@ impl Module { _amount: T::Balance, reasons: WithdrawReasons, new_balance: T::Balance, - ) -> Result { + ) -> dispatch::DispatchResult { if asset_id != &Self::staking_asset_id() { return Ok(()); } @@ -751,14 +760,14 @@ impl Module { if locks.is_empty() { return Ok(()); } - let now = >::block_number(); + let now = >::block_number(); if Self::locks(who) .into_iter() .all(|l| now >= l.until || new_balance >= l.amount || !l.reasons.intersects(reasons)) { Ok(()) } else { - Err("account liquidity restrictions prevent withdrawal") + Err("account liquidity restrictions prevent withdrawal")? } } @@ -783,7 +792,7 @@ impl Module { until: T::BlockNumber, reasons: WithdrawReasons, ) { - let now = >::block_number(); + let now = >::block_number(); let mut new_lock = Some(BalanceLock { id, amount, @@ -815,7 +824,7 @@ impl Module { until: T::BlockNumber, reasons: WithdrawReasons, ) { - let now = >::block_number(); + let now = >::block_number(); let mut new_lock = Some(BalanceLock { id, amount, @@ -846,7 +855,7 @@ impl Module { } fn remove_lock(id: LockIdentifier, who: &T::AccountId) { - let now = >::block_number(); + let now = >::block_number(); let locks = >::locks(who) .into_iter() .filter_map(|l| if l.until > now && l.id != id { Some(l) } else { None }) @@ -866,14 +875,14 @@ mod imbalances { use super::{ result, AssetIdProvider, Imbalance, Saturating, StorageMap, Subtrait, Zero, TryDrop }; - use rstd::mem; + use sp_std::mem; /// Opaque, move-only struct with private fields that serves as a token denoting that /// funds have been created without any equal and opposite accounting. #[must_use] pub struct PositiveImbalance>( T::Balance, - rstd::marker::PhantomData, + sp_std::marker::PhantomData, ); impl PositiveImbalance where @@ -890,7 +899,7 @@ mod imbalances { #[must_use] pub struct NegativeImbalance>( T::Balance, - rstd::marker::PhantomData, + sp_std::marker::PhantomData, ); impl NegativeImbalance where @@ -1067,7 +1076,7 @@ impl PartialEq for ElevatedTrait { } } impl Eq for ElevatedTrait {} -impl system::Trait for ElevatedTrait { +impl frame_system::Trait for ElevatedTrait { type Origin = T::Origin; type Call = T::Call; type Index = T::Index; @@ -1083,6 +1092,7 @@ impl system::Trait for ElevatedTrait { type AvailableBlockRatio = T::AvailableBlockRatio; type BlockHashCount = T::BlockHashCount; type Version = T::Version; + type ModuleToIndex = (); } impl Trait for ElevatedTrait { type Balance = T::Balance; @@ -1091,7 +1101,7 @@ impl Trait for ElevatedTrait { } #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)] -pub struct AssetCurrency(rstd::marker::PhantomData, rstd::marker::PhantomData); +pub struct AssetCurrency(sp_std::marker::PhantomData, sp_std::marker::PhantomData); impl Currency for AssetCurrency where @@ -1124,7 +1134,7 @@ where dest: &T::AccountId, value: Self::Balance, _: ExistenceRequirement, // no existential deposit policy for generic asset - ) -> Result { + ) -> DispatchResult { >::make_transfer(&U::asset_id(), transactor, dest, value) } @@ -1133,7 +1143,7 @@ where amount: Self::Balance, reasons: WithdrawReasons, new_balance: Self::Balance, - ) -> Result { + ) -> DispatchResult { >::ensure_can_withdraw(&U::asset_id(), who, amount, reasons, new_balance) } @@ -1142,7 +1152,7 @@ where value: Self::Balance, reasons: WithdrawReasons, _: ExistenceRequirement, // no existential deposit policy for generic asset - ) -> result::Result { + ) -> result::Result { let new_balance = Self::free_balance(who) .checked_sub(&value) .ok_or_else(|| "account has too few funds")?; @@ -1154,7 +1164,7 @@ where fn deposit_into_existing( who: &T::AccountId, value: Self::Balance, - ) -> result::Result { + ) -> result::Result { // No existential deposit rule and creation fee in GA. `deposit_into_existing` is same with `deposit_creating`. Ok(Self::deposit_creating(who, value)) } @@ -1239,7 +1249,7 @@ where >::reserved_balance(&U::asset_id(), &who) } - fn reserve(who: &T::AccountId, value: Self::Balance) -> result::Result<(), &'static str> { + fn reserve(who: &T::AccountId, value: Self::Balance) -> DispatchResult { >::reserve(&U::asset_id(), who, value) } @@ -1259,12 +1269,12 @@ where slashed: &T::AccountId, beneficiary: &T::AccountId, value: Self::Balance, - ) -> result::Result { + ) -> result::Result { Ok(>::repatriate_reserved(&U::asset_id(), slashed, beneficiary, value)) } } -pub struct StakingAssetIdProvider(rstd::marker::PhantomData); +pub struct StakingAssetIdProvider(sp_std::marker::PhantomData); impl AssetIdProvider for StakingAssetIdProvider { type AssetId = T::AssetId; @@ -1273,7 +1283,7 @@ impl AssetIdProvider for StakingAssetIdProvider { } } -pub struct SpendingAssetIdProvider(rstd::marker::PhantomData); +pub struct SpendingAssetIdProvider(sp_std::marker::PhantomData); impl AssetIdProvider for SpendingAssetIdProvider { type AssetId = T::AssetId; diff --git a/frame/generic-asset/src/mock.rs b/frame/generic-asset/src/mock.rs index 57b13760fa03d2ed90d59dd8a33dfb9abbc62b77..09ec8f69fbdb069cb04f85202a85a02a8454385a 100644 --- a/frame/generic-asset/src/mock.rs +++ b/frame/generic-asset/src/mock.rs @@ -20,18 +20,18 @@ #![cfg(test)] -use sr_primitives::{ +use sp_runtime::{ Perbill, testing::Header, traits::{BlakeTwo256, IdentityLookup}, }; -use primitives::H256; -use support::{parameter_types, impl_outer_event, impl_outer_origin}; +use sp_core::H256; +use frame_support::{parameter_types, impl_outer_event, impl_outer_origin, weights::Weight}; use super::*; impl_outer_origin! { - pub enum Origin for Test {} + pub enum Origin for Test where system = frame_system {} } // For testing the module, we construct most of a mock runtime. This means @@ -41,11 +41,11 @@ impl_outer_origin! { pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockWeight: Weight = 1024; pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } -impl system::Trait for Test { +impl frame_system::Trait for Test { type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -61,6 +61,7 @@ impl system::Trait for Test { type AvailableBlockRatio = AvailableBlockRatio; type BlockHashCount = BlockHashCount; type Version = (); + type ModuleToIndex = (); } impl Trait for Test { @@ -73,6 +74,7 @@ mod generic_asset { pub use crate::Event; } +use frame_system as system; impl_outer_event! { pub enum TestEvent for Test { generic_asset, @@ -81,7 +83,7 @@ impl_outer_event! { pub type GenericAsset = Module; -pub type System = system::Module; +pub type System = frame_system::Module; pub struct ExtBuilder { asset_id: u32, @@ -117,8 +119,8 @@ impl ExtBuilder { } // builds genesis config - pub fn build(self) -> runtime_io::TestExternalities { - let mut t = system::GenesisConfig::default().build_storage::().unwrap(); + pub fn build(self) -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); GenesisConfig:: { assets: vec![self.asset_id], @@ -136,8 +138,8 @@ impl ExtBuilder { // This function basically just builds a genesis storage key/value store according to // our desired mockup. -pub fn new_test_ext() -> runtime_io::TestExternalities { - system::GenesisConfig::default() +pub fn new_test_ext() -> sp_io::TestExternalities { + frame_system::GenesisConfig::default() .build_storage::() .unwrap() .into() diff --git a/frame/generic-asset/src/tests.rs b/frame/generic-asset/src/tests.rs index 165936d0215a6e86133f59b2ce652fb830b55f33..1f9f458b2ccece72db954f4d89ceb9d53433c028 100644 --- a/frame/generic-asset/src/tests.rs +++ b/frame/generic-asset/src/tests.rs @@ -22,7 +22,7 @@ use super::*; use crate::mock::{new_test_ext, ExtBuilder, GenericAsset, Origin, System, Test, TestEvent}; -use support::{assert_noop, assert_ok}; +use frame_support::{assert_noop, assert_ok}; #[test] fn issuing_asset_units_to_issuer_should_work() { @@ -906,7 +906,7 @@ fn update_permission_should_throw_error_when_lack_of_permissions() { fn create_asset_works_with_given_asset_id_and_from_account() { ExtBuilder::default().next_asset_id(10).build().execute_with(|| { let origin = 1; - let from_account: Option<::AccountId> = Some(1); + let from_account: Option<::AccountId> = Some(1); let default_permission = PermissionLatest { update: Owner::Address(origin), @@ -943,7 +943,7 @@ fn create_asset_works_with_given_asset_id_and_from_account() { fn create_asset_with_non_reserved_asset_id_should_not_work() { ExtBuilder::default().next_asset_id(10).build().execute_with(|| { let origin = 1; - let from_account: Option<::AccountId> = Some(1); + let from_account: Option<::AccountId> = Some(1); let default_permission = PermissionLatest { update: Owner::Address(origin), @@ -977,7 +977,7 @@ fn create_asset_with_non_reserved_asset_id_should_not_work() { fn create_asset_with_a_taken_asset_id_should_not_work() { ExtBuilder::default().next_asset_id(10).build().execute_with(|| { let origin = 1; - let from_account: Option<::AccountId> = Some(1); + let from_account: Option<::AccountId> = Some(1); let default_permission = PermissionLatest { update: Owner::Address(origin), @@ -1022,7 +1022,7 @@ fn create_asset_with_a_taken_asset_id_should_not_work() { fn create_asset_should_create_a_reserved_asset_when_from_account_is_none() { ExtBuilder::default().next_asset_id(10).build().execute_with(|| { let origin = 1; - let from_account: Option<::AccountId> = None; + let from_account: Option<::AccountId> = None; let default_permission = PermissionLatest { update: Owner::Address(origin), @@ -1065,7 +1065,7 @@ fn create_asset_should_create_a_reserved_asset_when_from_account_is_none() { fn create_asset_should_create_a_user_asset() { ExtBuilder::default().next_asset_id(10).build().execute_with(|| { let origin = 1; - let from_account: Option<::AccountId> = None; + let from_account: Option<::AccountId> = None; let default_permission = PermissionLatest { update: Owner::Address(origin), diff --git a/frame/grandpa/Cargo.toml b/frame/grandpa/Cargo.toml index f086968a2280d8cbe31ffdcc299bffb9dea5331a..ab5b34c91fd9f1f9edd6d183ccbc3044eb71f8ce 100644 --- a/frame/grandpa/Cargo.toml +++ b/frame/grandpa/Cargo.toml @@ -7,32 +7,32 @@ edition = "2018" [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -primitives = { package = "substrate-primitives", path = "../../primitives/core", default-features = false } -substrate-finality-grandpa-primitives = { path = "../../primitives/finality-grandpa", default-features = false } -rstd = { package = "sr-std", path = "../../primitives/sr-std", default-features = false } -sr-primitives = { path = "../../primitives/sr-primitives", default-features = false } -sr-staking-primitives = { path = "../../primitives/sr-staking-primitives", default-features = false } -support = { package = "frame-support", path = "../support", default-features = false } -system = { package = "frame-system", path = "../system", default-features = false } -session = { package = "pallet-session", path = "../session", default-features = false } -finality-tracker = { package = "pallet-finality-tracker", path = "../finality-tracker", default-features = false } +sp-core = { version = "2.0.0", default-features = false, path = "../../primitives/core" } +sp-finality-grandpa = { version = "2.0.0", default-features = false, path = "../../primitives/finality-grandpa" } +sp-std = { version = "2.0.0", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" } +sp-staking = { version = "2.0.0", default-features = false, path = "../../primitives/staking" } +frame-support = { version = "2.0.0", default-features = false, path = "../support" } +frame-system = { version = "2.0.0", default-features = false, path = "../system" } +pallet-session = { version = "2.0.0", default-features = false, path = "../session" } +pallet-finality-tracker = { version = "2.0.0", default-features = false, path = "../finality-tracker" } [dev-dependencies] -runtime-io ={ package = "sr-io", path = "../../primitives/sr-io" } +sp-io ={ version = "2.0.0", path = "../../primitives/io" } [features] default = ["std"] std = [ "serde", "codec/std", - "primitives/std", - "substrate-finality-grandpa-primitives/std", - "rstd/std", - "support/std", - "sr-primitives/std", - "sr-staking-primitives/std", - "system/std", - "session/std", - "finality-tracker/std", + "sp-core/std", + "sp-finality-grandpa/std", + "sp-std/std", + "frame-support/std", + "sp-runtime/std", + "sp-staking/std", + "frame-system/std", + "pallet-session/std", + "pallet-finality-tracker/std", ] migrate-authorities = [] diff --git a/frame/grandpa/src/lib.rs b/frame/grandpa/src/lib.rs index 877521c9746d9f1cb36f32ac64fa31e1e3678f23..99777cb8931f6f817165e8aaf5754440a001932a 100644 --- a/frame/grandpa/src/lib.rs +++ b/frame/grandpa/src/lib.rs @@ -28,15 +28,15 @@ #![cfg_attr(not(feature = "std"), no_std)] // re-export since this is necessary for `impl_apis` in runtime. -pub use substrate_finality_grandpa_primitives as fg_primitives; +pub use sp_finality_grandpa as fg_primitives; -use rstd::prelude::*; -use codec::{self as codec, Encode, Decode, Error}; -use support::{decl_event, decl_storage, decl_module, dispatch::Result, storage}; -use sr_primitives::{ - generic::{DigestItem, OpaqueDigestItemId}, traits::Zero, Perbill, +use sp_std::prelude::*; +use codec::{self as codec, Encode, Decode}; +use frame_support::{decl_event, decl_storage, decl_module, decl_error, storage}; +use sp_runtime::{ + DispatchResult, generic::{DigestItem, OpaqueDigestItemId}, traits::Zero, Perbill, }; -use sr_staking_primitives::{ +use sp_staking::{ SessionIndex, offence::{Offence, Kind}, }; @@ -44,14 +44,14 @@ use fg_primitives::{ GRANDPA_AUTHORITIES_KEY, GRANDPA_ENGINE_ID, ScheduledChange, ConsensusLog, SetId, RoundNumber, }; pub use fg_primitives::{AuthorityId, AuthorityList, AuthorityWeight, VersionedAuthorityList}; -use system::{ensure_signed, DigestOf}; +use frame_system::{self as system, ensure_signed, DigestOf}; mod mock; mod tests; -pub trait Trait: system::Trait { +pub trait Trait: frame_system::Trait { /// The event type of this module. - type Event: From + Into<::Event>; + type Event: From + Into<::Event>; } /// A stored pending change, old format. @@ -82,7 +82,7 @@ pub struct StoredPendingChange { } impl Decode for StoredPendingChange { - fn decode(value: &mut I) -> core::result::Result { + fn decode(value: &mut I) -> core::result::Result { let old = OldStoredPendingChange::decode(value)?; let forced = >::decode(value).unwrap_or(None); @@ -123,7 +123,7 @@ pub enum StoredState { }, } -decl_event!( +decl_event! { pub enum Event { /// New authority set has been applied. NewAuthorities(AuthorityList), @@ -132,7 +132,22 @@ decl_event!( /// Current authority set has been resumed. Resumed, } -); +} + +decl_error! { + pub enum Error for Module { + /// Attempt to signal GRANDPA pause when the authority set isn't live + /// (either paused or already pending pause). + PauseFailed, + /// Attempt to signal GRANDPA resume when the authority set isn't paused + /// (either live or already pending resume). + ResumeFailed, + /// Attempt to signal GRANDPA change with one already pending. + ChangePending, + /// Cannot signal forced change so soon after last. + TooSoon, + } +} decl_storage! { trait Store for Module as GrandpaFinality { @@ -170,6 +185,8 @@ decl_storage! { decl_module! { pub struct Module for enum Call where origin: T::Origin { + type Error = Error; + fn deposit_event() = default; /// Report some misbehavior. @@ -264,9 +281,9 @@ impl Module { /// Schedule GRANDPA to pause starting in the given number of blocks. /// Cannot be done when already paused. - pub fn schedule_pause(in_blocks: T::BlockNumber) -> Result { + pub fn schedule_pause(in_blocks: T::BlockNumber) -> DispatchResult { if let StoredState::Live = >::get() { - let scheduled_at = >::block_number(); + let scheduled_at = >::block_number(); >::put(StoredState::PendingPause { delay: in_blocks, scheduled_at, @@ -274,15 +291,14 @@ impl Module { Ok(()) } else { - Err("Attempt to signal GRANDPA pause when the authority set isn't live \ - (either paused or already pending pause).") + Err(Error::::PauseFailed)? } } /// Schedule a resume of GRANDPA after pausing. - pub fn schedule_resume(in_blocks: T::BlockNumber) -> Result { + pub fn schedule_resume(in_blocks: T::BlockNumber) -> DispatchResult { if let StoredState::Paused = >::get() { - let scheduled_at = >::block_number(); + let scheduled_at = >::block_number(); >::put(StoredState::PendingResume { delay: in_blocks, scheduled_at, @@ -290,8 +306,7 @@ impl Module { Ok(()) } else { - Err("Attempt to signal GRANDPA resume when the authority set isn't paused \ - (either live or already pending resume).") + Err(Error::::ResumeFailed)? } } @@ -313,13 +328,13 @@ impl Module { next_authorities: AuthorityList, in_blocks: T::BlockNumber, forced: Option, - ) -> Result { + ) -> DispatchResult { if !>::exists() { - let scheduled_at = >::block_number(); + let scheduled_at = >::block_number(); if let Some(_) = forced { if Self::next_forced().map_or(false, |next| next > scheduled_at) { - return Err("Cannot signal forced change so soon after last."); + Err(Error::::TooSoon)? } // only allow the next forced change when twice the window has passed since @@ -336,14 +351,14 @@ impl Module { Ok(()) } else { - Err("Attempt to signal GRANDPA change with one already pending.") + Err(Error::::ChangePending)? } } /// Deposit one of this module's logs. fn deposit_log(log: ConsensusLog) { let log: DigestItem = DigestItem::Consensus(GRANDPA_ENGINE_ID, log.encode()); - >::deposit_log(log.into()); + >::deposit_log(log.into()); } fn initialize_authorities(authorities: &AuthorityList) { @@ -400,12 +415,12 @@ impl Module { } } -impl sr_primitives::BoundToRuntimeAppPublic for Module { +impl sp_runtime::BoundToRuntimeAppPublic for Module { type Public = AuthorityId; } -impl session::OneSessionHandler for Module - where T: session::Trait +impl pallet_session::OneSessionHandler for Module + where T: pallet_session::Trait { type Key = AuthorityId; @@ -438,7 +453,7 @@ impl session::OneSessionHandler for Module // if we didn't issue a change, we update the mapping to note that the current // set corresponds to the latest equivalent session (i.e. now). - let session_index = >::current_index(); + let session_index = >::current_index(); SetIdSession::insert(current_set_id, &session_index); } @@ -447,9 +462,9 @@ impl session::OneSessionHandler for Module } } -impl finality_tracker::OnFinalizationStalled for Module { +impl pallet_finality_tracker::OnFinalizationStalled for Module { fn on_stalled(further_wait: T::BlockNumber, median: T::BlockNumber) { - // when we record old authority sets, we can use `finality_tracker::median` + // when we record old authority sets, we can use `pallet_finality_tracker::median` // to figure out _who_ failed. until then, we can't meaningfully guard // against `next == last` the way that normal session changes do. >::put((further_wait, median)); diff --git a/frame/grandpa/src/mock.rs b/frame/grandpa/src/mock.rs index c6ea2075575c545ecb16f09129ec5346f6f3068f..87eadea70614fe14538c52582d95fb3e13bab626 100644 --- a/frame/grandpa/src/mock.rs +++ b/frame/grandpa/src/mock.rs @@ -18,16 +18,17 @@ #![cfg(test)] -use sr_primitives::{Perbill, DigestItem, traits::IdentityLookup, testing::{Header, UintAuthorityId}}; -use runtime_io; -use support::{impl_outer_origin, impl_outer_event, parameter_types}; -use primitives::H256; +use sp_runtime::{Perbill, DigestItem, traits::IdentityLookup, testing::{Header, UintAuthorityId}}; +use sp_io; +use frame_support::{impl_outer_origin, impl_outer_event, parameter_types, weights::Weight}; +use sp_core::H256; use codec::{Encode, Decode}; use crate::{AuthorityId, AuthorityList, GenesisConfig, Trait, Module, ConsensusLog}; -use substrate_finality_grandpa_primitives::GRANDPA_ENGINE_ID; +use sp_finality_grandpa::GRANDPA_ENGINE_ID; +use frame_system as system; impl_outer_origin!{ - pub enum Origin for Test {} + pub enum Origin for Test where system = frame_system {} } pub fn grandpa_log(log: ConsensusLog) -> DigestItem { @@ -43,17 +44,17 @@ impl Trait for Test { } parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockWeight: Weight = 1024; pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } -impl system::Trait for Test { +impl frame_system::Trait for Test { type Origin = Origin; type Index = u64; type BlockNumber = u64; type Call = (); type Hash = H256; - type Hashing = sr_primitives::traits::BlakeTwo256; + type Hashing = sp_runtime::traits::BlakeTwo256; type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; @@ -63,6 +64,7 @@ impl system::Trait for Test { type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); + type ModuleToIndex = (); } mod grandpa { @@ -81,13 +83,13 @@ pub fn to_authorities(vec: Vec<(u64, u64)>) -> AuthorityList { .collect() } -pub fn new_test_ext(authorities: Vec<(u64, u64)>) -> runtime_io::TestExternalities { - let mut t = system::GenesisConfig::default().build_storage::().unwrap(); +pub fn new_test_ext(authorities: Vec<(u64, u64)>) -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); GenesisConfig { authorities: to_authorities(authorities), }.assimilate_storage::(&mut t).unwrap(); t.into() } -pub type System = system::Module; +pub type System = frame_system::Module; pub type Grandpa = Module; diff --git a/frame/grandpa/src/tests.rs b/frame/grandpa/src/tests.rs index 3d6a8752c5de3bd653ec0198c78e8ac87c2367b5..5ad26d22f4204b5732c6d017a6adc410f9c8ace8 100644 --- a/frame/grandpa/src/tests.rs +++ b/frame/grandpa/src/tests.rs @@ -18,9 +18,9 @@ #![cfg(test)] -use sr_primitives::{testing::Digest, traits::{Header, OnFinalize}}; +use sp_runtime::{testing::Digest, traits::{Header, OnFinalize}}; use crate::mock::*; -use system::{EventRecord, Phase}; +use frame_system::{EventRecord, Phase}; use codec::{Decode, Encode}; use fg_primitives::ScheduledChange; use super::*; @@ -312,7 +312,7 @@ fn time_slot_have_sane_ord() { #[test] #[cfg(feature = "migrate-authorities")] fn authorities_migration() { - use sr_primitives::traits::OnInitialize; + use sp_runtime::traits::OnInitialize; with_externalities(&mut new_test_ext(vec![]), || { let authorities = to_authorities(vec![(1, 1), (2, 1), (3, 1)]); diff --git a/frame/identity/Cargo.toml b/frame/identity/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..7962c2a1c62bfe539bb5f50bcf93cef23d5689b7 --- /dev/null +++ b/frame/identity/Cargo.toml @@ -0,0 +1,31 @@ +[package] +name = "pallet-identity" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +serde = { version = "1.0.101", optional = true } +codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } +enumflags2 = { version = "0.6.2" } +sp-std = { version = "2.0.0", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0", default-features = false, path = "../support" } +frame-system = { version = "2.0.0", default-features = false, path = "../system" } + +[dev-dependencies] +sp-core = { version = "2.0.0", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0", path = "../balances" } + +[features] +default = ["std"] +std = [ + "serde", + "codec/std", + "sp-std/std", + "sp-io/std", + "sp-runtime/std", + "frame-support/std", + "frame-system/std", +] diff --git a/frame/identity/src/lib.rs b/frame/identity/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..095739665823cb7b60c0a2f307efbe13888976fa --- /dev/null +++ b/frame/identity/src/lib.rs @@ -0,0 +1,1147 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! # Identity Module +//! +//! - [`identity::Trait`](./trait.Trait.html) +//! - [`Call`](./enum.Call.html) +//! +//! ## Overview +//! +//! A federated naming system, allowing for multiple registrars to be added from a specified origin. +//! Registrars can set a fee to provide identity-verification service. Anyone can put forth a +//! proposed identity for a fixed deposit and ask for review by any number of registrars (paying +//! each of their fees). Registrar judgements are given as an `enum`, allowing for sophisticated, +//! multi-tier opinions. +//! +//! Some judgements are identified as *sticky*, which means they cannot be removed except by +//! complete removal of the identity, or by the registrar. Judgements are allowed to represent a +//! portion of funds that have been reserved for the registrar. +//! +//! A super-user can remove accounts and in doing so, slash the deposit. +//! +//! All accounts may also have a limited number of sub-accounts which may be specified by the owner; +//! by definition, these have equivalent ownership and each has an individual name. +//! +//! The number of registrars should be limited, and the deposit made sufficiently large, to ensure +//! no state-bloat attack is viable. +//! +//! ## Interface +//! +//! ### Dispatchable Functions +//! +//! #### For general users +//! * `set_identity` - Set the associated identity of an account; a small deposit is reserved if not +//! already taken. +//! * `set_subs` - Set the sub-accounts of an identity. +//! * `clear_identity` - Remove an account's associated identity; the deposit is returned. +//! * `request_judgement` - Request a judgement from a registrar, paying a fee. +//! * `cancel_request` - Cancel the previous request for a judgement. +//! +//! #### For registrars +//! * `set_fee` - Set the fee required to be paid for a judgement to be given by the registrar. +//! * `set_fields` - Set the fields that a registrar cares about in their judgements. +//! * `provide_judgement` - Provide a judgement to an identity. +//! +//! #### For super-users +//! * `add_registrar` - Add a new registrar to the system. +//! * `kill_identity` - Forcibly remove the associated identity; the deposit is lost. +//! +//! [`Call`]: ./enum.Call.html +//! [`Trait`]: ./trait.Trait.html + +#![cfg_attr(not(feature = "std"), no_std)] + +use sp_std::prelude::*; +use sp_std::{fmt::Debug, ops::Add, iter::once}; +use enumflags2::BitFlags; +use codec::{Encode, Decode}; +use sp_runtime::{DispatchResult, traits::{StaticLookup, EnsureOrigin, Zero}, RuntimeDebug}; +use frame_support::{ + decl_module, decl_event, decl_storage, ensure, + traits::{Currency, ReservableCurrency, OnUnbalanced, Get}, + weights::SimpleDispatchInfo, +}; +use frame_system::{self as system, ensure_signed, ensure_root}; + +type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; + +pub trait Trait: frame_system::Trait { + /// The overarching event type. + type Event: From> + Into<::Event>; + + /// The currency trait. + type Currency: ReservableCurrency; + + /// The amount held on deposit for a registered identity. + type BasicDeposit: Get>; + + /// The amount held on deposit per additional field for a registered identity. + type FieldDeposit: Get>; + + /// The amount held on deposit for a registered subaccount. This should account for the fact + /// that one storage item's value will increase by the size of an account ID, and there will be + /// another trie item whose value is the size of an account ID plus 32 bytes. + type SubAccountDeposit: Get>; + + /// The maximum number of sub-accounts allowed per identified account. + type MaximumSubAccounts: Get; + + /// What to do with slashed funds. + type Slashed: OnUnbalanced>; + + /// The origin which may forcibly set or remove a name. Root can always do this. + type ForceOrigin: EnsureOrigin; + + /// The origin which may add or remove registrars. Root can always do this. + type RegistrarOrigin: EnsureOrigin; +} + +/// Either underlying data blob if it is at most 32 bytes, or a hash of it. If the data is greater +/// than 32-bytes then it will be truncated when encoding. +/// +/// Can also be `None`. +#[derive(Clone, Eq, PartialEq, RuntimeDebug)] +pub enum Data { + /// No data here. + None, + /// The data is stored directly. + Raw(Vec), + /// Only the Blake2 hash of the data is stored. The preimage of the hash may be retrieved + /// through some hash-lookup service. + BlakeTwo256([u8; 32]), + /// Only the SHA2-256 hash of the data is stored. The preimage of the hash may be retrieved + /// through some hash-lookup service. + Sha256([u8; 32]), + /// Only the Keccak-256 hash of the data is stored. The preimage of the hash may be retrieved + /// through some hash-lookup service. + Keccak256([u8; 32]), + /// Only the SHA3-256 hash of the data is stored. The preimage of the hash may be retrieved + /// through some hash-lookup service. + ShaThree256([u8; 32]), +} + +impl Decode for Data { + fn decode(input: &mut I) -> sp_std::result::Result { + let b = input.read_byte()?; + Ok(match b { + 0 => Data::None, + n @ 1 ..= 33 => { + let mut r = vec![0u8; n as usize - 1]; + input.read(&mut r[..])?; + Data::Raw(r) + } + 34 => Data::BlakeTwo256(<[u8; 32]>::decode(input)?), + 35 => Data::Sha256(<[u8; 32]>::decode(input)?), + 36 => Data::Keccak256(<[u8; 32]>::decode(input)?), + 37 => Data::ShaThree256(<[u8; 32]>::decode(input)?), + _ => return Err(codec::Error::from("invalid leading byte")), + }) + } +} + +impl Encode for Data { + fn encode(&self) -> Vec { + match self { + Data::None => vec![0u8; 1], + Data::Raw(ref x) => { + let l = x.len().min(32); + let mut r = vec![l as u8 + 1; l + 1]; + &mut r[1..].copy_from_slice(&x[..l as usize]); + r + } + Data::BlakeTwo256(ref h) => once(34u8).chain(h.iter().cloned()).collect(), + Data::Sha256(ref h) => once(35u8).chain(h.iter().cloned()).collect(), + Data::Keccak256(ref h) => once(36u8).chain(h.iter().cloned()).collect(), + Data::ShaThree256(ref h) => once(37u8).chain(h.iter().cloned()).collect(), + } + } +} +impl codec::EncodeLike for Data {} + +impl Default for Data { + fn default() -> Self { + Self::None + } +} + +/// An identifier for a single name registrar/identity verification service. +pub type RegistrarIndex = u32; + +/// An attestation of a registrar over how accurate some `IdentityInfo` is in describing an account. +/// +/// NOTE: Registrars may pay little attention to some fields. Registrars may want to make clear +/// which fields their attestation is relevant for by off-chain means. +#[derive(Copy, Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug)] +pub enum Judgement< + Balance: Encode + Decode + Copy + Clone + Debug + Eq + PartialEq +> { + /// The default value; no opinion is held. + Unknown, + /// No judgement is yet in place, but a deposit is reserved as payment for providing one. + FeePaid(Balance), + /// The data appears to be reasonably acceptable in terms of its accuracy, however no in depth + /// checks (such as in-person meetings or formal KYC) have been conducted. + Reasonable, + /// The target is known directly by the registrar and the registrar can fully attest to the + /// the data's accuracy. + KnownGood, + /// The data was once good but is currently out of date. There is no malicious intent in the + /// inaccuracy. This judgement can be removed through updating the data. + OutOfDate, + /// The data is imprecise or of sufficiently low-quality to be problematic. It is not + /// indicative of malicious intent. This judgement can be removed through updating the data. + LowQuality, + /// The data is erroneous. This may be indicative of malicious intent. This cannot be removed + /// except by the registrar. + Erroneous, +} + +impl< + Balance: Encode + Decode + Copy + Clone + Debug + Eq + PartialEq +> Judgement { + /// Returns `true` if this judgement is indicative of a deposit being currently held. This means + /// it should not be cleared or replaced except by an operation which utilizes the deposit. + fn has_deposit(&self) -> bool { + match self { + Judgement::FeePaid(_) => true, + _ => false, + } + } + + /// Returns `true` if this judgement is one that should not be generally be replaced outside + /// of specialized handlers. Examples include "malicious" judgements and deposit-holding + /// judgements. + fn is_sticky(&self) -> bool { + match self { + Judgement::FeePaid(_) | Judgement::Erroneous => true, + _ => false, + } + } +} + +/// The fields that we use to identify the owner of an account with. Each corresponds to a field +/// in the `IdentityInfo` struct. +#[repr(u64)] +#[derive(Encode, Decode, Clone, Copy, PartialEq, Eq, BitFlags, RuntimeDebug)] +pub enum IdentityField { + Display = 0b0000000000000000000000000000000000000000000000000000000000000001, + Legal = 0b0000000000000000000000000000000000000000000000000000000000000010, + Web = 0b0000000000000000000000000000000000000000000000000000000000000100, + Riot = 0b0000000000000000000000000000000000000000000000000000000000001000, + Email = 0b0000000000000000000000000000000000000000000000000000000000010000, + PgpFingerprint = 0b0000000000000000000000000000000000000000000000000000000000100000, + Image = 0b0000000000000000000000000000000000000000000000000000000001000000, +} + +/// Wrapper type for `BitFlags` that implements `Codec`. +#[derive(Clone, Copy, PartialEq, Default, RuntimeDebug)] +pub struct IdentityFields(BitFlags); + +impl Eq for IdentityFields {} +impl Encode for IdentityFields { + fn using_encoded R>(&self, f: F) -> R { + self.0.bits().using_encoded(f) + } +} +impl Decode for IdentityFields { + fn decode(input: &mut I) -> sp_std::result::Result { + let field = u64::decode(input)?; + Ok(Self(>::from_bits(field as u64).map_err(|_| "invalid value")?)) + } +} + +/// Information concerning the identity of the controller of an account. +/// +/// NOTE: This should be stored at the end of the storage item to facilitate the addition of extra +/// fields in a backwards compatible way through a specialized `Decode` impl. +#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug)] +#[cfg_attr(test, derive(Default))] +pub struct IdentityInfo { + /// Additional fields of the identity that are not catered for with the struct's explicit + /// fields. + pub additional: Vec<(Data, Data)>, + + /// A reasonable display name for the controller of the account. This should be whatever it is + /// that it is typically known as and should not be confusable with other entities, given + /// reasonable context. + /// + /// Stored as UTF-8. + pub display: Data, + + /// The full legal name in the local jurisdiction of the entity. This might be a bit + /// long-winded. + /// + /// Stored as UTF-8. + pub legal: Data, + + /// A representative website held by the controller of the account. + /// + /// NOTE: `https://` is automatically prepended. + /// + /// Stored as UTF-8. + pub web: Data, + + /// The Riot handle held by the controller of the account. + /// + /// Stored as UTF-8. + pub riot: Data, + + /// The email address of the controller of the account. + /// + /// Stored as UTF-8. + pub email: Data, + + /// The PGP/GPG public key of the controller of the account. + pub pgp_fingerprint: Option<[u8; 20]>, + + /// A graphic image representing the controller of the account. Should be a company, + /// organization or project logo or a headshot in the case of a human. + pub image: Data, +} + +/// Information concerning the identity of the controller of an account. +/// +/// NOTE: This is stored separately primarily to facilitate the addition of extra fields in a +/// backwards compatible way through a specialized `Decode` impl. +#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug)] +pub struct Registration< + Balance: Encode + Decode + Copy + Clone + Debug + Eq + PartialEq +> { + /// Judgements from the registrars on this identity. Stored ordered by `RegistrarIndex`. There + /// may be only a single judgement from each registrar. + pub judgements: Vec<(RegistrarIndex, Judgement)>, + + /// Amount held on deposit for this information. + pub deposit: Balance, + + /// Information on the identity. + pub info: IdentityInfo, +} + +impl < + Balance: Encode + Decode + Copy + Clone + Debug + Eq + PartialEq + Zero + Add, +> Registration { + fn total_deposit(&self) -> Balance { + self.deposit + self.judgements.iter() + .map(|(_, ref j)| if let Judgement::FeePaid(fee) = j { *fee } else { Zero::zero() }) + .fold(Zero::zero(), |a, i| a + i) + } +} + +/// Information concerning a registrar. +#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug)] +pub struct RegistrarInfo< + Balance: Encode + Decode + Clone + Debug + Eq + PartialEq, + AccountId: Encode + Decode + Clone + Debug + Eq + PartialEq +> { + /// The account of the registrar. + pub account: AccountId, + + /// Amount required to be given to the registrar for them to provide judgement. + pub fee: Balance, + + /// Relevant fields for this registrar. Registrar judgements are limited to attestations on + /// these fields. + pub fields: IdentityFields, +} + +decl_storage! { + trait Store for Module as Sudo { + /// Information that is pertinent to identify the entity behind an account. + pub IdentityOf get(fn identity): map T::AccountId => Option>>; + + /// The super-identity of an alternative "sub" identity together with its name, within that + /// context. If the account is not some other account's sub-identity, then just `None`. + pub SuperOf get(fn super_of): map T::AccountId => Option<(T::AccountId, Data)>; + + /// Alternative "sub" identities of this account. + /// + /// The first item is the deposit, the second is a vector of the accounts. + pub SubsOf get(fn subs): map T::AccountId => (BalanceOf, Vec); + + /// The set of registrars. Not expected to get very big as can only be added through a + /// special origin (likely a council motion). + /// + /// The index into this can be cast to `RegistrarIndex` to get a valid value. + pub Registrars get(fn registrars): Vec, T::AccountId>>>; + } +} + +decl_event!( + pub enum Event where AccountId = ::AccountId, Balance = BalanceOf { + /// A name was set or reset (which will remove all judgements). + IdentitySet(AccountId), + /// A name was cleared, and the given balance returned. + IdentityCleared(AccountId, Balance), + /// A name was removed and the given balance slashed. + IdentityKilled(AccountId, Balance), + /// A judgement was asked from a registrar. + JudgementRequested(AccountId, RegistrarIndex), + /// A judgement request was retracted. + JudgementUnrequested(AccountId, RegistrarIndex), + /// A judgement was given by a registrar. + JudgementGiven(AccountId, RegistrarIndex), + /// A registrar was added. + RegistrarAdded(RegistrarIndex), + } +); + +decl_module! { + // Simple declaration of the `Module` type. Lets the macro know what it's working on. + pub struct Module for enum Call where origin: T::Origin { + fn deposit_event() = default; + + /// Add a registrar to the system. + /// + /// The dispatch origin for this call must be `RegistrarOrigin` or `Root`. + /// + /// - `account`: the account of the registrar. + /// + /// Emits `RegistrarAdded` if successful. + /// + /// # + /// - `O(R)` where `R` registrar-count (governance-bounded). + /// - One storage mutation (codec `O(R)`). + /// - One event. + /// # + #[weight = SimpleDispatchInfo::FixedNormal(10_000)] + fn add_registrar(origin, account: T::AccountId) { + T::RegistrarOrigin::try_origin(origin) + .map(|_| ()) + .or_else(ensure_root)?; + + let i = >::mutate(|r| { + r.push(Some(RegistrarInfo { account, fee: Zero::zero(), fields: Default::default() })); + (r.len() - 1) as RegistrarIndex + }); + + Self::deposit_event(RawEvent::RegistrarAdded(i)); + } + + /// Set an account's identity information and reserve the appropriate deposit. + /// + /// If the account already has identity information, the deposit is taken as part payment + /// for the new deposit. + /// + /// The dispatch origin for this call must be _Signed_ and the sender must have a registered + /// identity. + /// + /// - `info`: The identity information. + /// + /// Emits `IdentitySet` if successful. + /// + /// # + /// - `O(X + R)` where `X` additional-field-count (deposit-bounded). + /// - At most two balance operations. + /// - One storage mutation (codec `O(X + R)`). + /// - One event. + /// # + #[weight = SimpleDispatchInfo::FixedNormal(50_000)] + fn set_identity(origin, info: IdentityInfo) { + let sender = ensure_signed(origin)?; + let fd = >::from(info.additional.len() as u32) * T::FieldDeposit::get(); + + let mut id = match >::get(&sender) { + Some(mut id) => { + // Only keep non-positive judgements. + id.judgements.retain(|j| j.1.is_sticky()); + id.info = info; + id + } + None => Registration { info, judgements: Vec::new(), deposit: Zero::zero() }, + }; + + let old_deposit = id.deposit; + id.deposit = T::BasicDeposit::get() + fd; + if id.deposit > old_deposit { + T::Currency::reserve(&sender, id.deposit - old_deposit)?; + } + if old_deposit > id.deposit { + let _ = T::Currency::unreserve(&sender, old_deposit - id.deposit); + } + + >::insert(&sender, id); + Self::deposit_event(RawEvent::IdentitySet(sender)); + } + + /// Set the sub-accounts of the sender. + /// + /// Payment: Any aggregate balance reserved by previous `set_subs` calls will be returned + /// and an amount `SubAccountDeposit` will be reserved for each item in `subs`. + /// + /// The dispatch origin for this call must be _Signed_ and the sender must have a registered + /// identity. + /// + /// - `subs`: The identity's sub-accounts. + /// + /// # + /// - `O(S)` where `S` subs-count (hard- and deposit-bounded). + /// - At most two balance operations. + /// - At most O(2 * S + 1) storage mutations; codec complexity `O(1 * S + S * 1)`); + /// one storage-exists. + /// # + fn set_subs(origin, subs: Vec<(T::AccountId, Data)>) { + let sender = ensure_signed(origin)?; + ensure!(>::exists(&sender), "not found"); + ensure!(subs.len() <= T::MaximumSubAccounts::get() as usize, "too many subs"); + + let (old_deposit, old_ids) = >::get(&sender); + let new_deposit = T::SubAccountDeposit::get() * >::from(subs.len() as u32); + + if old_deposit < new_deposit { + T::Currency::reserve(&sender, new_deposit - old_deposit)?; + } + // do nothing if they're equal. + if old_deposit > new_deposit { + let _ = T::Currency::unreserve(&sender, old_deposit - new_deposit); + } + + for s in old_ids.iter() { + >::remove(s); + } + let ids = subs.into_iter().map(|(id, name)| { + >::insert(&id, (sender.clone(), name)); + id + }).collect::>(); + + if ids.is_empty() { + >::remove(&sender); + } else { + >::insert(&sender, (new_deposit, ids)); + } + } + + /// Clear an account's identity info and all sub-account and return all deposits. + /// + /// Payment: All reserved balances on the account are returned. + /// + /// The dispatch origin for this call must be _Signed_ and the sender must have a registered + /// identity. + /// + /// Emits `IdentityCleared` if successful. + /// + /// # + /// - `O(R + S + X)`. + /// - One balance-reserve operation. + /// - `S + 2` storage deletions. + /// - One event. + /// # + fn clear_identity(origin) { + let sender = ensure_signed(origin)?; + + let (subs_deposit, sub_ids) = >::take(&sender); + let deposit = >::take(&sender).ok_or("not named")?.total_deposit() + + subs_deposit; + for sub in sub_ids.iter() { + >::remove(sub); + } + + let _ = T::Currency::unreserve(&sender, deposit.clone()); + + Self::deposit_event(RawEvent::IdentityCleared(sender, deposit)); + } + + /// Request a judgement from a registrar. + /// + /// Payment: At most `max_fee` will be reserved for payment to the registrar if judgement + /// given. + /// + /// The dispatch origin for this call must be _Signed_ and the sender must have a + /// registered identity. + /// + /// - `reg_index`: The index of the registrar whose judgement is requested. + /// - `max_fee`: The maximum fee that may be paid. This should just be auto-populated as: + /// + /// ```nocompile + /// Self::registrars(reg_index).uwnrap().fee + /// ``` + /// + /// Emits `JudgementRequested` if successful. + /// + /// # + /// - `O(R + X)`. + /// - One balance-reserve operation. + /// - Storage: 1 read `O(R)`, 1 mutate `O(X + R)`. + /// - One event. + /// # + #[weight = SimpleDispatchInfo::FixedNormal(50_000)] + fn request_judgement(origin, + #[compact] reg_index: RegistrarIndex, + #[compact] max_fee: BalanceOf, + ) { + let sender = ensure_signed(origin)?; + let registrars = >::get(); + let registrar = registrars.get(reg_index as usize).and_then(Option::as_ref) + .ok_or("empty index")?; + ensure!(max_fee >= registrar.fee, "fee changed"); + let mut id = >::get(&sender).ok_or("no identity")?; + + let item = (reg_index, Judgement::FeePaid(registrar.fee)); + match id.judgements.binary_search_by_key(®_index, |x| x.0) { + Ok(i) => if id.judgements[i].1.is_sticky() { + Err("sticky judgement")? + } else { + id.judgements[i] = item + }, + Err(i) => id.judgements.insert(i, item), + } + + T::Currency::reserve(&sender, registrar.fee)?; + + >::insert(&sender, id); + + Self::deposit_event(RawEvent::JudgementRequested(sender, reg_index)); + } + + /// Cancel a previous request. + /// + /// Payment: A previously reserved deposit is returned on success. + /// + /// The dispatch origin for this call must be _Signed_ and the sender must have a + /// registered identity. + /// + /// - `reg_index`: The index of the registrar whose judgement is no longer requested. + /// + /// Emits `JudgementUnrequested` if successful. + /// + /// # + /// - `O(R + X)`. + /// - One balance-reserve operation. + /// - One storage mutation `O(R + X)`. + /// - One event. + /// # + #[weight = SimpleDispatchInfo::FixedNormal(50_000)] + fn cancel_request(origin, reg_index: RegistrarIndex) { + let sender = ensure_signed(origin)?; + let mut id = >::get(&sender).ok_or("no identity")?; + + let pos = id.judgements.binary_search_by_key(®_index, |x| x.0) + .map_err(|_| "not found")?; + let fee = if let Judgement::FeePaid(fee) = id.judgements.remove(pos).1 { + fee + } else { + Err("judgement given")? + }; + + let _ = T::Currency::unreserve(&sender, fee); + >::insert(&sender, id); + + Self::deposit_event(RawEvent::JudgementUnrequested(sender, reg_index)); + } + + /// Set the fee required for a judgement to be requested from a registrar. + /// + /// The dispatch origin for this call must be _Signed_ and the sender must be the account + /// of the registrar whose index is `index`. + /// + /// - `index`: the index of the registrar whose fee is to be set. + /// - `fee`: the new fee. + /// + /// # + /// - `O(R)`. + /// - One storage mutation `O(R)`. + /// # + #[weight = SimpleDispatchInfo::FixedNormal(50_000)] + fn set_fee(origin, + #[compact] index: RegistrarIndex, + #[compact] fee: BalanceOf, + ) -> DispatchResult { + let who = ensure_signed(origin)?; + + >::mutate(|rs| + rs.get_mut(index as usize) + .and_then(|x| x.as_mut()) + .and_then(|r| if r.account == who { r.fee = fee; Some(()) } else { None }) + .ok_or_else(|| "invalid index".into()) + ) + } + + /// Change the account associated with a registrar. + /// + /// The dispatch origin for this call must be _Signed_ and the sender must be the account + /// of the registrar whose index is `index`. + /// + /// - `index`: the index of the registrar whose fee is to be set. + /// - `new`: the new account ID. + /// + /// # + /// - `O(R)`. + /// - One storage mutation `O(R)`. + /// # + #[weight = SimpleDispatchInfo::FixedNormal(50_000)] + fn set_account_id(origin, + #[compact] index: RegistrarIndex, + new: T::AccountId, + ) -> DispatchResult { + let who = ensure_signed(origin)?; + + >::mutate(|rs| + rs.get_mut(index as usize) + .and_then(|x| x.as_mut()) + .and_then(|r| if r.account == who { r.account = new; Some(()) } else { None }) + .ok_or_else(|| "invalid index".into()) + ) + } + + /// Set the field information for a registrar. + /// + /// The dispatch origin for this call must be _Signed_ and the sender must be the account + /// of the registrar whose index is `index`. + /// + /// - `index`: the index of the registrar whose fee is to be set. + /// - `fields`: the fields that the registrar concerns themselves with. + /// + /// # + /// - `O(R)`. + /// - One storage mutation `O(R)`. + /// # + #[weight = SimpleDispatchInfo::FixedNormal(50_000)] + fn set_fields(origin, + #[compact] index: RegistrarIndex, + fields: IdentityFields, + ) -> DispatchResult { + let who = ensure_signed(origin)?; + + >::mutate(|rs| + rs.get_mut(index as usize) + .and_then(|x| x.as_mut()) + .and_then(|r| if r.account == who { r.fields = fields; Some(()) } else { None }) + .ok_or_else(|| "invalid index".into()) + ) + } + + /// Provide a judgement for an account's identity. + /// + /// The dispatch origin for this call must be _Signed_ and the sender must be the account + /// of the registrar whose index is `reg_index`. + /// + /// - `reg_index`: the index of the registrar whose judgement is being made. + /// - `target`: the account whose identity the judgement is upon. This must be an account + /// with a registered identity. + /// - `judgement`: the judgement of the registrar of index `reg_index` about `target`. + /// + /// Emits `JudgementGiven` if successful. + /// + /// # + /// - `O(R + X)`. + /// - One balance-transfer operation. + /// - Up to one account-lookup operation. + /// - Storage: 1 read `O(R)`, 1 mutate `O(R + X)`. + /// - One event. + /// # + #[weight = SimpleDispatchInfo::FixedNormal(50_000)] + fn provide_judgement(origin, + #[compact] reg_index: RegistrarIndex, + target: ::Source, + judgement: Judgement>, + ) { + let sender = ensure_signed(origin)?; + let target = T::Lookup::lookup(target)?; + ensure!(!judgement.has_deposit(), "invalid judgement"); + >::get() + .get(reg_index as usize) + .and_then(Option::as_ref) + .and_then(|r| if r.account == sender { Some(r) } else { None }) + .ok_or("invalid index")?; + let mut id = >::get(&target).ok_or("invalid target")?; + + let item = (reg_index, judgement); + match id.judgements.binary_search_by_key(®_index, |x| x.0) { + Ok(position) => { + if let Judgement::FeePaid(fee) = id.judgements[position].1 { + let _ = T::Currency::repatriate_reserved(&target, &sender, fee); + } + id.judgements[position] = item + } + Err(position) => id.judgements.insert(position, item), + } + >::insert(&target, id); + Self::deposit_event(RawEvent::JudgementGiven(target, reg_index)); + } + + /// Remove an account's identity and sub-account information and slash the deposits. + /// + /// Payment: Reserved balances from `set_subs` and `set_identity` are slashed and handled by + /// `Slash`. Verification request deposits are not returned; they should be cancelled + /// manually using `cancel_request`. + /// + /// The dispatch origin for this call must be _Root_ or match `T::ForceOrigin`. + /// + /// - `target`: the account whose identity the judgement is upon. This must be an account + /// with a registered identity. + /// + /// Emits `IdentityKilled` if successful. + /// + /// # + /// - `O(R + S + X)`. + /// - One balance-reserve operation. + /// - `S + 2` storage mutations. + /// - One event. + /// # + #[weight = SimpleDispatchInfo::FreeOperational] + fn kill_identity(origin, target: ::Source) { + T::ForceOrigin::try_origin(origin) + .map(|_| ()) + .or_else(ensure_root)?; + + // Figure out who we're meant to be clearing. + let target = T::Lookup::lookup(target)?; + // Grab their deposit (and check that they have one). + let (subs_deposit, sub_ids) = >::take(&target); + let deposit = >::take(&target).ok_or("not named")?.total_deposit() + + subs_deposit; + for sub in sub_ids.iter() { + >::remove(sub); + } + // Slash their deposit from them. + T::Slashed::on_unbalanced(T::Currency::slash_reserved(&target, deposit).0); + + Self::deposit_event(RawEvent::IdentityKilled(target, deposit)); + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + use sp_runtime::traits::BadOrigin; + use frame_support::{assert_ok, assert_noop, impl_outer_origin, parameter_types, weights::Weight}; + use sp_core::H256; + use frame_system::EnsureSignedBy; + // The testing primitives are very useful for avoiding having to work with signatures + // or public keys. `u64` is used as the `AccountId` and no `Signature`s are required. + use sp_runtime::{ + Perbill, testing::Header, traits::{BlakeTwo256, IdentityLookup}, + }; + + impl_outer_origin! { + pub enum Origin for Test where system = frame_system {} + } + + // For testing the module, we construct most of a mock runtime. This means + // first constructing a configuration type (`Test`) which `impl`s each of the + // configuration traits of modules we want to use. + #[derive(Clone, Eq, PartialEq)] + pub struct Test; + parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: Weight = 1024; + pub const MaximumBlockLength: u32 = 2 * 1024; + pub const AvailableBlockRatio: Perbill = Perbill::one(); + } + impl frame_system::Trait for Test { + type Origin = Origin; + type Index = u64; + type BlockNumber = u64; + type Hash = H256; + type Call = (); + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Header = Header; + type Event = (); + type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; + type MaximumBlockLength = MaximumBlockLength; + type AvailableBlockRatio = AvailableBlockRatio; + type Version = (); + type ModuleToIndex = (); + } + parameter_types! { + pub const ExistentialDeposit: u64 = 0; + pub const TransferFee: u64 = 0; + pub const CreationFee: u64 = 0; + } + impl pallet_balances::Trait for Test { + type Balance = u64; + type OnFreeBalanceZero = (); + type OnNewAccount = (); + type Event = (); + type TransferPayment = (); + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type TransferFee = TransferFee; + type CreationFee = CreationFee; + } + parameter_types! { + pub const BasicDeposit: u64 = 10; + pub const FieldDeposit: u64 = 10; + pub const SubAccountDeposit: u64 = 10; + pub const MaximumSubAccounts: u32 = 2; + pub const One: u64 = 1; + pub const Two: u64 = 2; + } + impl Trait for Test { + type Event = (); + type Currency = Balances; + type Slashed = (); + type BasicDeposit = BasicDeposit; + type FieldDeposit = FieldDeposit; + type SubAccountDeposit = SubAccountDeposit; + type MaximumSubAccounts = MaximumSubAccounts; + type RegistrarOrigin = EnsureSignedBy; + type ForceOrigin = EnsureSignedBy; + } + type Balances = pallet_balances::Module; + type Identity = Module; + + // This function basically just builds a genesis storage key/value store according to + // our desired mockup. + fn new_test_ext() -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); + // We use default for brevity, but you can configure as desired if needed. + pallet_balances::GenesisConfig:: { + balances: vec![ + (1, 10), + (2, 10), + (3, 10), + (10, 100), + (20, 100), + (30, 100), + ], + vesting: vec![], + }.assimilate_storage(&mut t).unwrap(); + t.into() + } + + fn ten() -> IdentityInfo { + IdentityInfo { + display: Data::Raw(b"ten".to_vec()), + legal: Data::Raw(b"The Right Ordinal Ten, Esq.".to_vec()), + .. Default::default() + } + } + + #[test] + fn adding_registrar_should_work() { + new_test_ext().execute_with(|| { + assert_ok!(Identity::add_registrar(Origin::signed(1), 3)); + assert_ok!(Identity::set_fee(Origin::signed(3), 0, 10)); + let fields = IdentityFields(IdentityField::Display | IdentityField::Legal); + assert_ok!(Identity::set_fields(Origin::signed(3), 0, fields)); + assert_eq!(Identity::registrars(), vec![ + Some(RegistrarInfo { account: 3, fee: 10, fields }) + ]); + }); + } + + #[test] + fn registration_should_work() { + new_test_ext().execute_with(|| { + assert_ok!(Identity::add_registrar(Origin::signed(1), 3)); + assert_ok!(Identity::set_fee(Origin::signed(3), 0, 10)); + assert_ok!(Identity::set_identity(Origin::signed(10), ten())); + assert_eq!(Identity::identity(10).unwrap().info, ten()); + assert_eq!(Balances::free_balance(10), 90); + assert_ok!(Identity::clear_identity(Origin::signed(10))); + assert_eq!(Balances::free_balance(10), 100); + assert_noop!(Identity::clear_identity(Origin::signed(10)), "not named"); + }); + } + + #[test] + fn uninvited_judgement_should_work() { + new_test_ext().execute_with(|| { + assert_noop!( + Identity::provide_judgement(Origin::signed(3), 0, 10, Judgement::Reasonable), + "invalid index" + ); + + assert_ok!(Identity::add_registrar(Origin::signed(1), 3)); + assert_noop!( + Identity::provide_judgement(Origin::signed(3), 0, 10, Judgement::Reasonable), + "invalid target" + ); + + assert_ok!(Identity::set_identity(Origin::signed(10), ten())); + assert_noop!( + Identity::provide_judgement(Origin::signed(10), 0, 10, Judgement::Reasonable), + "invalid index" + ); + assert_noop!( + Identity::provide_judgement(Origin::signed(3), 0, 10, Judgement::FeePaid(1)), + "invalid judgement" + ); + + assert_ok!(Identity::provide_judgement(Origin::signed(3), 0, 10, Judgement::Reasonable)); + assert_eq!(Identity::identity(10).unwrap().judgements, vec![(0, Judgement::Reasonable)]); + }); + } + + #[test] + fn clearing_judgement_should_work() { + new_test_ext().execute_with(|| { + assert_ok!(Identity::add_registrar(Origin::signed(1), 3)); + assert_ok!(Identity::set_identity(Origin::signed(10), ten())); + assert_ok!(Identity::provide_judgement(Origin::signed(3), 0, 10, Judgement::Reasonable)); + assert_ok!(Identity::clear_identity(Origin::signed(10))); + assert_eq!(Identity::identity(10), None); + }); + } + + #[test] + fn killing_slashing_should_work() { + new_test_ext().execute_with(|| { + assert_ok!(Identity::set_identity(Origin::signed(10), ten())); + assert_noop!(Identity::kill_identity(Origin::signed(1), 10), BadOrigin); + assert_ok!(Identity::kill_identity(Origin::signed(2), 10)); + assert_eq!(Identity::identity(10), None); + assert_eq!(Balances::free_balance(10), 90); + assert_noop!(Identity::kill_identity(Origin::signed(2), 10), "not named"); + }); + } + + #[test] + fn setting_subaccounts_should_work() { + new_test_ext().execute_with(|| { + let mut subs = vec![(20, Data::Raw(vec![40; 1]))]; + assert_noop!(Identity::set_subs(Origin::signed(10), subs.clone()), "not found"); + + assert_ok!(Identity::set_identity(Origin::signed(10), ten())); + assert_ok!(Identity::set_subs(Origin::signed(10), subs.clone())); + assert_eq!(Balances::free_balance(10), 80); + assert_eq!(Identity::subs(10), (10, vec![20])); + assert_eq!(Identity::super_of(20), Some((10, Data::Raw(vec![40; 1])))); + + // push another item and re-set it. + subs.push((30, Data::Raw(vec![50; 1]))); + assert_ok!(Identity::set_subs(Origin::signed(10), subs.clone())); + assert_eq!(Balances::free_balance(10), 70); + assert_eq!(Identity::subs(10), (20, vec![20, 30])); + assert_eq!(Identity::super_of(20), Some((10, Data::Raw(vec![40; 1])))); + assert_eq!(Identity::super_of(30), Some((10, Data::Raw(vec![50; 1])))); + + // switch out one of the items and re-set. + subs[0] = (40, Data::Raw(vec![60; 1])); + assert_ok!(Identity::set_subs(Origin::signed(10), subs.clone())); + assert_eq!(Balances::free_balance(10), 70); // no change in the balance + assert_eq!(Identity::subs(10), (20, vec![40, 30])); + assert_eq!(Identity::super_of(20), None); + assert_eq!(Identity::super_of(30), Some((10, Data::Raw(vec![50; 1])))); + assert_eq!(Identity::super_of(40), Some((10, Data::Raw(vec![60; 1])))); + + // clear + assert_ok!(Identity::set_subs(Origin::signed(10), vec![])); + assert_eq!(Balances::free_balance(10), 90); + assert_eq!(Identity::subs(10), (0, vec![])); + assert_eq!(Identity::super_of(30), None); + assert_eq!(Identity::super_of(40), None); + + subs.push((20, Data::Raw(vec![40; 1]))); + assert_noop!(Identity::set_subs(Origin::signed(10), subs.clone()), "too many subs"); + }); + } + + #[test] + fn clearing_account_should_remove_subaccounts_and_refund() { + new_test_ext().execute_with(|| { + assert_ok!(Identity::set_identity(Origin::signed(10), ten())); + assert_ok!(Identity::set_subs(Origin::signed(10), vec![(20, Data::Raw(vec![40; 1]))])); + assert_ok!(Identity::clear_identity(Origin::signed(10))); + assert_eq!(Balances::free_balance(10), 100); + assert!(Identity::super_of(20).is_none()); + }); + } + + #[test] + fn killing_account_should_remove_subaccounts_and_not_refund() { + new_test_ext().execute_with(|| { + assert_ok!(Identity::set_identity(Origin::signed(10), ten())); + assert_ok!(Identity::set_subs(Origin::signed(10), vec![(20, Data::Raw(vec![40; 1]))])); + assert_ok!(Identity::kill_identity(Origin::ROOT, 10)); + assert_eq!(Balances::free_balance(10), 80); + assert!(Identity::super_of(20).is_none()); + }); + } + + #[test] + fn cancelling_requested_judgement_should_work() { + new_test_ext().execute_with(|| { + assert_ok!(Identity::add_registrar(Origin::signed(1), 3)); + assert_ok!(Identity::set_fee(Origin::signed(3), 0, 10)); + assert_noop!(Identity::cancel_request(Origin::signed(10), 0), "no identity"); + assert_ok!(Identity::set_identity(Origin::signed(10), ten())); + assert_ok!(Identity::request_judgement(Origin::signed(10), 0, 10)); + assert_ok!(Identity::cancel_request(Origin::signed(10), 0)); + assert_eq!(Balances::free_balance(10), 90); + assert_noop!(Identity::cancel_request(Origin::signed(10), 0), "not found"); + + assert_ok!(Identity::provide_judgement(Origin::signed(3), 0, 10, Judgement::Reasonable)); + assert_noop!(Identity::cancel_request(Origin::signed(10), 0), "judgement given"); + }); + } + + #[test] + fn requesting_judgement_should_work() { + new_test_ext().execute_with(|| { + assert_ok!(Identity::add_registrar(Origin::signed(1), 3)); + assert_ok!(Identity::set_fee(Origin::signed(3), 0, 10)); + assert_ok!(Identity::set_identity(Origin::signed(10), ten())); + assert_noop!(Identity::request_judgement(Origin::signed(10), 0, 9), "fee changed"); + assert_ok!(Identity::request_judgement(Origin::signed(10), 0, 10)); + // 10 for the judgement request, 10 for the identity. + assert_eq!(Balances::free_balance(10), 80); + + // Re-requesting won't work as we already paid. + assert_noop!(Identity::request_judgement(Origin::signed(10), 0, 10), "sticky judgement"); + assert_ok!(Identity::provide_judgement(Origin::signed(3), 0, 10, Judgement::Erroneous)); + // Registrar got their payment now. + assert_eq!(Balances::free_balance(3), 20); + + // Re-requesting still won't work as it's erroneous. + assert_noop!(Identity::request_judgement(Origin::signed(10), 0, 10), "sticky judgement"); + + // Requesting from a second registrar still works. + assert_ok!(Identity::add_registrar(Origin::signed(1), 4)); + assert_ok!(Identity::request_judgement(Origin::signed(10), 1, 10)); + + // Re-requesting after the judgement has been reduced works. + assert_ok!(Identity::provide_judgement(Origin::signed(3), 0, 10, Judgement::OutOfDate)); + assert_ok!(Identity::request_judgement(Origin::signed(10), 0, 10)); + }); + } + + #[test] + fn field_deposit_should_work() { + new_test_ext().execute_with(|| { + assert_ok!(Identity::add_registrar(Origin::signed(1), 3)); + assert_ok!(Identity::set_fee(Origin::signed(3), 0, 10)); + assert_ok!(Identity::set_identity(Origin::signed(10), IdentityInfo { + additional: vec![ + (Data::Raw(b"number".to_vec()), Data::Raw(10u32.encode())), + (Data::Raw(b"text".to_vec()), Data::Raw(b"10".to_vec())), + ], .. Default::default() + })); + assert_eq!(Balances::free_balance(10), 70); + }); + } + + #[test] + fn setting_account_id_should_work() { + new_test_ext().execute_with(|| { + assert_ok!(Identity::add_registrar(Origin::signed(1), 3)); + // account 4 cannot change the first registrar's identity since it's owned by 3. + assert_noop!(Identity::set_account_id(Origin::signed(4), 0, 3), "invalid index"); + // account 3 can, because that's the registrar's current account. + assert_ok!(Identity::set_account_id(Origin::signed(3), 0, 4)); + // account 4 can now, because that's their new ID. + assert_ok!(Identity::set_account_id(Origin::signed(4), 0, 3)); + }); + } +} diff --git a/frame/im-online/Cargo.toml b/frame/im-online/Cargo.toml index d0959da892205ebe5667be0b56342f52afc08ecd..5045509c7723aa52fb5a5ba2361ca1aaf54d8956 100644 --- a/frame/im-online/Cargo.toml +++ b/frame/im-online/Cargo.toml @@ -1,36 +1,36 @@ [package] name = "pallet-im-online" -version = "0.1.0" +version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" [dependencies] -app-crypto = { package = "substrate-application-crypto", path = "../../primitives/application-crypto", default-features = false } -authorship = { package = "pallet-authorship", path = "../authorship", default-features = false } +sp-application-crypto = { version = "2.0.0", default-features = false, path = "../../primitives/application-crypto" } +pallet-authorship = { version = "2.0.0", default-features = false, path = "../authorship" } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -primitives = { package="substrate-primitives", path = "../../primitives/core", default-features = false } -rstd = { package = "sr-std", path = "../../primitives/sr-std", default-features = false } +sp-core = { version = "2.0.0", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0", default-features = false, path = "../../primitives/std" } serde = { version = "1.0.101", optional = true } -session = { package = "pallet-session", path = "../session", default-features = false } -runtime-io = { package = "sr-io", path = "../../primitives/sr-io", default-features = false } -sr-primitives = { path = "../../primitives/sr-primitives", default-features = false } -sr-staking-primitives = { path = "../../primitives/sr-staking-primitives", default-features = false } -support = { package = "frame-support", path = "../support", default-features = false } -system = { package = "frame-system", path = "../system", default-features = false } +pallet-session = { version = "2.0.0", default-features = false, path = "../session" } +sp-io = { version = "2.0.0", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" } +sp-staking = { version = "2.0.0", default-features = false, path = "../../primitives/staking" } +frame-support = { version = "2.0.0", default-features = false, path = "../support" } +frame-system = { version = "2.0.0", default-features = false, path = "../system" } [features] -default = ["std", "session/historical"] +default = ["std", "pallet-session/historical"] std = [ - "app-crypto/std", - "authorship/std", + "sp-application-crypto/std", + "pallet-authorship/std", "codec/std", - "primitives/std", - "rstd/std", + "sp-core/std", + "sp-std/std", "serde", - "session/std", - "runtime-io/std", - "sr-primitives/std", - "sr-staking-primitives/std", - "support/std", - "system/std", + "pallet-session/std", + "sp-io/std", + "sp-runtime/std", + "sp-staking/std", + "frame-support/std", + "frame-system/std", ] diff --git a/frame/im-online/src/lib.rs b/frame/im-online/src/lib.rs index 467596233bc2ad760c069d8bd4986606e897381c..d7dfb1c67351988dfc6f08dabea1248e65363be5 100644 --- a/frame/im-online/src/lib.rs +++ b/frame/im-online/src/lib.rs @@ -42,15 +42,15 @@ //! ## Usage //! //! ``` -//! use support::{decl_module, dispatch::Result}; -//! use system::ensure_signed; +//! use frame_support::{decl_module, dispatch}; +//! use frame_system::{self as system, ensure_signed}; //! use pallet_im_online::{self as im_online}; //! //! pub trait Trait: im_online::Trait {} //! //! decl_module! { //! pub struct Module for enum Call where origin: T::Origin { -//! pub fn is_online(origin, authority_index: u32) -> Result { +//! pub fn is_online(origin, authority_index: u32) -> dispatch::DispatchResult { //! let _sender = ensure_signed(origin)?; //! let _is_online = >::is_online(authority_index); //! Ok(()) @@ -70,13 +70,13 @@ mod mock; mod tests; -use app_crypto::RuntimeAppPublic; +use sp_application_crypto::RuntimeAppPublic; use codec::{Encode, Decode}; -use primitives::offchain::{OpaqueNetworkState, StorageKind}; -use rstd::prelude::*; -use rstd::convert::TryInto; -use session::historical::IdentificationTuple; -use sr_primitives::{ +use sp_core::offchain::{OpaqueNetworkState, StorageKind}; +use sp_std::prelude::*; +use sp_std::convert::TryInto; +use pallet_session::historical::IdentificationTuple; +use sp_runtime::{ RuntimeDebug, traits::{Convert, Member, Printable, Saturating}, Perbill, transaction_validity::{ @@ -84,20 +84,20 @@ use sr_primitives::{ TransactionPriority, }, }; -use sr_staking_primitives::{ +use sp_staking::{ SessionIndex, offence::{ReportOffence, Offence, Kind}, }; -use support::{ +use frame_support::{ decl_module, decl_event, decl_storage, print, Parameter, debug, traits::Get, }; -use system::ensure_none; -use system::offchain::SubmitUnsignedTransaction; +use frame_system::{self as system, ensure_none}; +use frame_system::offchain::SubmitUnsignedTransaction; pub mod sr25519 { mod app_sr25519 { - use app_crypto::{app_crypto, key_types::IM_ONLINE, sr25519}; + use sp_application_crypto::{app_crypto, key_types::IM_ONLINE, sr25519}; app_crypto!(sr25519, IM_ONLINE); } @@ -114,7 +114,7 @@ pub mod sr25519 { pub mod ed25519 { mod app_ed25519 { - use app_crypto::{app_crypto, key_types::IM_ONLINE, ed25519}; + use sp_application_crypto::{app_crypto, key_types::IM_ONLINE, ed25519}; app_crypto!(ed25519, IM_ONLINE); } @@ -131,7 +131,7 @@ pub mod ed25519 { /// The local storage database key under which the worker progress status /// is tracked. -const DB_KEY: &[u8] = b"frame/im-online-worker-status"; +const DB_KEY: &[u8] = b"parity/im-online-worker-status"; /// It's important to persist the worker state, since e.g. the /// server could be restarted while starting the gossip process, but before @@ -177,12 +177,12 @@ pub struct Heartbeat authority_index: AuthIndex, } -pub trait Trait: system::Trait + session::historical::Trait { +pub trait Trait: frame_system::Trait + pallet_session::historical::Trait { /// The identifier type for an authority. type AuthorityId: Member + Parameter + RuntimeAppPublic + Default + Ord; /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// A dispatchable call type. type Call: From>; @@ -257,7 +257,7 @@ decl_module! { ) { ensure_none(origin)?; - let current_session = >::current_index(); + let current_session = >::current_index(); let exists = ::exists( ¤t_session, &heartbeat.authority_index @@ -285,7 +285,7 @@ decl_module! { debug::RuntimeLogger::init(); // Only send messages if we are a potential validator. - if runtime_io::offchain::is_validator() { + if sp_io::offchain::is_validator() { Self::offchain(now); } } @@ -294,7 +294,7 @@ decl_module! { /// Keep track of number of authored blocks per authority, uncles are counted as /// well since they're a valid proof of onlineness. -impl authorship::EventHandler for Module { +impl pallet_authorship::EventHandler for Module { fn note_author(author: T::ValidatorId) { Self::note_authorship(author); } @@ -310,7 +310,7 @@ impl Module { /// authored at least one block, during the current session. Otherwise /// `false`. pub fn is_online(authority_index: AuthIndex) -> bool { - let current_validators = >::validators(); + let current_validators = >::validators(); if authority_index >= current_validators.len() as u32 { return false; @@ -322,7 +322,7 @@ impl Module { } fn is_online_aux(authority_index: AuthIndex, authority: &T::ValidatorId) -> bool { - let current_session = >::current_index(); + let current_session = >::current_index(); ::exists(¤t_session, &authority_index) || >::get( @@ -334,13 +334,13 @@ impl Module { /// Returns `true` if a heartbeat has been received for the authority at `authority_index` in /// the authorities series, during the current session. Otherwise `false`. pub fn received_heartbeat_in_current_session(authority_index: AuthIndex) -> bool { - let current_session = >::current_index(); + let current_session = >::current_index(); ::exists(¤t_session, &authority_index) } /// Note that the given authority has authored a block in the current session. fn note_authorship(author: T::ValidatorId) { - let current_session = >::current_index(); + let current_session = >::current_index(); >::mutate( ¤t_session, @@ -408,12 +408,12 @@ impl Module { continue; } - let network_state = runtime_io::offchain::network_state() + let network_state = sp_io::offchain::network_state() .map_err(|_| OffchainErr::NetworkState)?; let heartbeat_data = Heartbeat { block_number, network_state, - session_index: >::current_index(), + session_index: >::current_index(), authority_index, }; @@ -453,7 +453,7 @@ impl Module { done, gossipping_at, }; - runtime_io::offchain::local_storage_compare_and_set( + sp_io::offchain::local_storage_compare_and_set( StorageKind::PERSISTENT, DB_KEY, curr_worker_status, @@ -469,7 +469,7 @@ impl Module { done, gossipping_at, }; - runtime_io::offchain::local_storage_set(StorageKind::PERSISTENT, DB_KEY, &enc.encode()); + sp_io::offchain::local_storage_set(StorageKind::PERSISTENT, DB_KEY, &enc.encode()); } // Checks if a heartbeat gossip already occurred at this block number. @@ -479,7 +479,7 @@ impl Module { now: T::BlockNumber, next_gossip: T::BlockNumber, ) -> Result<(Option>, bool), OffchainErr> { - let last_gossip = runtime_io::offchain::local_storage_get(StorageKind::PERSISTENT, DB_KEY); + let last_gossip = sp_io::offchain::local_storage_get(StorageKind::PERSISTENT, DB_KEY); match last_gossip { Some(last) => { let worker_status: WorkerStatus = Decode::decode(&mut &last[..]) @@ -509,11 +509,11 @@ impl Module { } } -impl sr_primitives::BoundToRuntimeAppPublic for Module { +impl sp_runtime::BoundToRuntimeAppPublic for Module { type Public = T::AuthorityId; } -impl session::OneSessionHandler for Module { +impl pallet_session::OneSessionHandler for Module { type Key = T::AuthorityId; fn on_genesis_session<'a, I: 'a>(validators: I) @@ -529,7 +529,7 @@ impl session::OneSessionHandler for Module { // Tell the offchain worker to start making the next session's heartbeats. // Since we consider producing blocks as being online, // the hearbeat is defered a bit to prevent spaming. - let block_number = >::block_number(); + let block_number = >::block_number(); let half_session = T::SessionDuration::get() / 2.into(); >::put(block_number + half_session); @@ -538,9 +538,9 @@ impl session::OneSessionHandler for Module { } fn on_before_session_ending() { - let session_index = >::current_index(); + let session_index = >::current_index(); let keys = Keys::::get(); - let current_validators = >::validators(); + let current_validators = >::validators(); let offenders = current_validators.into_iter().enumerate() .filter(|(index, id)| @@ -552,8 +552,8 @@ impl session::OneSessionHandler for Module { // Remove all received heartbeats and number of authored blocks from the // current session, they have already been processed and won't be needed // anymore. - ::remove_prefix(&>::current_index()); - >::remove_prefix(&>::current_index()); + ::remove_prefix(&>::current_index()); + >::remove_prefix(&>::current_index()); if offenders.is_empty() { Self::deposit_event(RawEvent::AllGood); @@ -572,7 +572,7 @@ impl session::OneSessionHandler for Module { } #[allow(deprecated)] -impl support::unsigned::ValidateUnsigned for Module { +impl frame_support::unsigned::ValidateUnsigned for Module { type Call = Call; fn validate_unsigned(call: &Self::Call) -> TransactionValidity { @@ -583,7 +583,7 @@ impl support::unsigned::ValidateUnsigned for Module { } // check if session index from heartbeat is recent - let current_session = >::current_index(); + let current_session = >::current_index(); if heartbeat.session_index != current_session { return InvalidTransaction::Stale.into(); } @@ -653,8 +653,14 @@ impl Offence for UnresponsivenessOffence { } fn slash_fraction(offenders: u32, validator_set_count: u32) -> Perbill { - // the formula is min((3 * (k - 1)) / n, 1) * 0.05 - let x = Perbill::from_rational_approximation(3 * (offenders - 1), validator_set_count); - x.saturating_mul(Perbill::from_percent(5)) + // the formula is min((3 * (k - (n / 10 + 1))) / n, 1) * 0.07 + // basically, 10% can be offline with no slash, but after that, it linearly climbs up to 7% + // when 13/30 are offline (around 5% when 1/3 are offline). + if let Some(threshold) = offenders.checked_sub(validator_set_count / 10 + 1) { + let x = Perbill::from_rational_approximation(3 * threshold, validator_set_count); + x.saturating_mul(Perbill::from_percent(7)) + } else { + Perbill::default() + } } } diff --git a/frame/im-online/src/mock.rs b/frame/im-online/src/mock.rs index 4be33c44ed59e61b4ca3a8299c5ce0e2d44879f9..7feed1eccaf65eb5d9417ce4179c08b5bd4f3349 100644 --- a/frame/im-online/src/mock.rs +++ b/frame/im-online/src/mock.rs @@ -21,14 +21,14 @@ use std::cell::RefCell; use crate::{Module, Trait}; -use sr_primitives::Perbill; -use sr_staking_primitives::{SessionIndex, offence::ReportOffence}; -use sr_primitives::testing::{Header, UintAuthorityId, TestXt}; -use sr_primitives::traits::{IdentityLookup, BlakeTwo256, ConvertInto}; -use primitives::H256; -use support::{impl_outer_origin, impl_outer_dispatch, parameter_types}; -use {runtime_io, system}; - +use sp_runtime::Perbill; +use sp_staking::{SessionIndex, offence::ReportOffence}; +use sp_runtime::testing::{Header, UintAuthorityId, TestXt}; +use sp_runtime::traits::{IdentityLookup, BlakeTwo256, ConvertInto}; +use sp_core::H256; +use frame_support::{impl_outer_origin, impl_outer_dispatch, parameter_types, weights::Weight}; + +use frame_system as system; impl_outer_origin!{ pub enum Origin for Runtime {} } @@ -44,7 +44,7 @@ thread_local! { } pub struct TestOnSessionEnding; -impl session::OnSessionEnding for TestOnSessionEnding { +impl pallet_session::OnSessionEnding for TestOnSessionEnding { fn on_session_ending(_ending_index: SessionIndex, _will_apply_at: SessionIndex) -> Option> { @@ -52,7 +52,7 @@ impl session::OnSessionEnding for TestOnSessionEnding { } } -impl session::historical::OnSessionEnding for TestOnSessionEnding { +impl pallet_session::historical::OnSessionEnding for TestOnSessionEnding { fn on_session_ending(_ending_index: SessionIndex, _will_apply_at: SessionIndex) -> Option<(Vec, Vec<(u64, u64)>)> { @@ -69,7 +69,7 @@ impl session::historical::OnSessionEnding for TestOnSessionEnding { /// An extrinsic type used for tests. pub type Extrinsic = TestXt; -type SubmitTransaction = system::offchain::TransactionSubmitter<(), Call, Extrinsic>; +type SubmitTransaction = frame_system::offchain::TransactionSubmitter<(), Call, Extrinsic>; type IdentificationTuple = (u64, u64); type Offence = crate::UnresponsivenessOffence; @@ -85,8 +85,8 @@ impl ReportOffence for OffenceHandler { } } -pub fn new_test_ext() -> runtime_io::TestExternalities { - let t = system::GenesisConfig::default().build_storage::().unwrap(); +pub fn new_test_ext() -> sp_io::TestExternalities { + let t = frame_system::GenesisConfig::default().build_storage::().unwrap(); t.into() } @@ -96,12 +96,12 @@ pub struct Runtime; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockWeight: Weight = 1024; pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } -impl system::Trait for Runtime { +impl frame_system::Trait for Runtime { type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -117,6 +117,7 @@ impl system::Trait for Runtime { type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); + type ModuleToIndex = (); } parameter_types! { @@ -128,9 +129,9 @@ parameter_types! { pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(33); } -impl session::Trait for Runtime { - type ShouldEndSession = session::PeriodicSessions; - type OnSessionEnding = session::historical::NoteHistoricalRoot; +impl pallet_session::Trait for Runtime { + type ShouldEndSession = pallet_session::PeriodicSessions; + type OnSessionEnding = pallet_session::historical::NoteHistoricalRoot; type SessionHandler = (ImOnline, ); type ValidatorId = u64; type ValidatorIdOf = ConvertInto; @@ -140,7 +141,7 @@ impl session::Trait for Runtime { type DisabledValidatorsThreshold = DisabledValidatorsThreshold; } -impl session::historical::Trait for Runtime { +impl pallet_session::historical::Trait for Runtime { type FullIdentification = u64; type FullIdentificationOf = ConvertInto; } @@ -149,7 +150,7 @@ parameter_types! { pub const UncleGenerations: u32 = 5; } -impl authorship::Trait for Runtime { +impl pallet_authorship::Trait for Runtime { type FindAuthor = (); type UncleGenerations = UncleGenerations; type FilterUncle = (); @@ -167,8 +168,8 @@ impl Trait for Runtime { /// Im Online module. pub type ImOnline = Module; -pub type System = system::Module; -pub type Session = session::Module; +pub type System = frame_system::Module; +pub type Session = pallet_session::Module; pub fn advance_session() { let now = System::block_number(); diff --git a/frame/im-online/src/tests.rs b/frame/im-online/src/tests.rs index edfdc34bc00d223a45e25a1dd48c7a19862028fa..1b4356aa49205057fc8f0ce4f336a8a171e401ba 100644 --- a/frame/im-online/src/tests.rs +++ b/frame/im-online/src/tests.rs @@ -20,14 +20,14 @@ use super::*; use crate::mock::*; -use primitives::offchain::{ +use sp_core::offchain::{ OpaquePeerId, OffchainExt, TransactionPoolExt, testing::{TestOffchainExt, TestTransactionPoolExt}, }; -use support::{dispatch, assert_noop}; -use sr_primitives::testing::UintAuthorityId; +use frame_support::{dispatch, assert_noop}; +use sp_runtime::testing::UintAuthorityId; #[test] fn test_unresponsiveness_slash_fraction() { @@ -38,14 +38,19 @@ fn test_unresponsiveness_slash_fraction() { ); assert_eq!( - UnresponsivenessOffence::<()>::slash_fraction(3, 50), - Perbill::from_parts(6000000), // 0.6% + UnresponsivenessOffence::<()>::slash_fraction(5, 50), + Perbill::zero(), // 0% + ); + + assert_eq!( + UnresponsivenessOffence::<()>::slash_fraction(7, 50), + Perbill::from_parts(4200000), // 0.42% ); // One third offline should be punished around 5%. assert_eq!( UnresponsivenessOffence::<()>::slash_fraction(17, 50), - Perbill::from_parts(48000000), // 4.8% + Perbill::from_parts(46200000), // 4.62% ); } @@ -106,9 +111,9 @@ fn heartbeat( session_index: u32, authority_index: u32, id: UintAuthorityId, -) -> dispatch::Result { +) -> dispatch::DispatchResult { #[allow(deprecated)] - use support::unsigned::ValidateUnsigned; + use frame_support::unsigned::ValidateUnsigned; let heartbeat = Heartbeat { block_number, @@ -122,9 +127,10 @@ fn heartbeat( let signature = id.sign(&heartbeat.encode()).unwrap(); #[allow(deprecated)] // Allow ValidateUnsigned - ImOnline::pre_dispatch(&crate::Call::heartbeat(heartbeat.clone(), signature.clone()))?; + ImOnline::pre_dispatch(&crate::Call::heartbeat(heartbeat.clone(), signature.clone())) + .map_err(|e| <&'static str>::from(e))?; ImOnline::heartbeat( - Origin::system(system::RawOrigin::None), + Origin::system(frame_system::RawOrigin::None), heartbeat, signature ) @@ -219,7 +225,7 @@ fn should_generate_heartbeats() { assert_eq!(heartbeat, Heartbeat { block_number: 2, - network_state: runtime_io::offchain::network_state().unwrap(), + network_state: sp_io::offchain::network_state().unwrap(), session_index: 2, authority_index: 2, }); @@ -257,7 +263,7 @@ fn should_cleanup_received_heartbeats_on_session_end() { #[test] fn should_mark_online_validator_when_block_is_authored() { - use authorship::EventHandler; + use pallet_authorship::EventHandler; new_test_ext().execute_with(|| { advance_session(); @@ -287,7 +293,7 @@ fn should_mark_online_validator_when_block_is_authored() { #[test] fn should_not_send_a_report_if_already_online() { - use authorship::EventHandler; + use pallet_authorship::EventHandler; let mut ext = new_test_ext(); let (offchain, _state) = TestOffchainExt::new(); @@ -308,7 +314,7 @@ fn should_not_send_a_report_if_already_online() { ImOnline::note_uncle(3, 0); // when - UintAuthorityId::set_all_keys(vec![0]); // all authorities use session key 0 + UintAuthorityId::set_all_keys(vec![0]); // all authorities use pallet_session key 0 ImOnline::offchain(4); // then @@ -324,7 +330,7 @@ fn should_not_send_a_report_if_already_online() { assert_eq!(heartbeat, Heartbeat { block_number: 4, - network_state: runtime_io::offchain::network_state().unwrap(), + network_state: sp_io::offchain::network_state().unwrap(), session_index: 2, authority_index: 0, }); diff --git a/frame/indices/Cargo.toml b/frame/indices/Cargo.toml index 17fe99ed928961e5503e355f43a29da077e36aaa..574c2d3eb6f3d7e5c9d6db6eee9db152b2235ae3 100644 --- a/frame/indices/Cargo.toml +++ b/frame/indices/Cargo.toml @@ -8,13 +8,13 @@ edition = "2018" serde = { version = "1.0.101", optional = true } safe-mix = { version = "1.0.0", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -substrate-keyring = { path = "../../primitives/keyring", optional = true } -rstd = { package = "sr-std", path = "../../primitives/sr-std", default-features = false } -runtime-io = { package = "sr-io", path = "../../primitives/sr-io", default-features = false } -sr-primitives = { path = "../../primitives/sr-primitives", default-features = false } -primitives = { package = "substrate-primitives", path = "../../primitives/core", default-features = false } -support = { package = "frame-support", path = "../support", default-features = false } -system = { package = "frame-system", path = "../system", default-features = false } +sp-keyring = { version = "2.0.0", optional = true, path = "../../primitives/keyring" } +sp-std = { version = "2.0.0", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" } +sp-core = { version = "2.0.0", default-features = false, path = "../../primitives/core" } +frame-support = { version = "2.0.0", default-features = false, path = "../support" } +frame-system = { version = "2.0.0", default-features = false, path = "../system" } [dev-dependencies] ref_thread_local = "0.0.0" @@ -24,12 +24,12 @@ default = ["std"] std = [ "serde", "safe-mix/std", - "substrate-keyring", + "sp-keyring", "codec/std", - "primitives/std", - "rstd/std", - "runtime-io/std", - "support/std", - "sr-primitives/std", - "system/std", + "sp-core/std", + "sp-std/std", + "sp-io/std", + "frame-support/std", + "sp-runtime/std", + "frame-system/std", ] diff --git a/frame/indices/src/address.rs b/frame/indices/src/address.rs index 21ee654cf2e3f362182a99f12bb8ca8f4cc60f10..2f0d34334526955d19d4c6d692e106701e107d61 100644 --- a/frame/indices/src/address.rs +++ b/frame/indices/src/address.rs @@ -18,13 +18,13 @@ #[cfg(feature = "std")] use std::fmt; -use rstd::convert::TryInto; +use sp_std::convert::TryInto; use crate::Member; use codec::{Encode, Decode, Input, Output, Error}; /// An indices-aware address, which can be either a direct `AccountId` or /// an index. -#[derive(PartialEq, Eq, Clone, sr_primitives::RuntimeDebug)] +#[derive(PartialEq, Eq, Clone, sp_runtime::RuntimeDebug)] #[cfg_attr(feature = "std", derive(Hash))] pub enum Address where AccountId: Member, diff --git a/frame/indices/src/lib.rs b/frame/indices/src/lib.rs index 31aa57276bde95444d9320a09639480b560da3ec..af30d5297ea9b440c936941274757bb94f341809 100644 --- a/frame/indices/src/lib.rs +++ b/frame/indices/src/lib.rs @@ -19,11 +19,11 @@ #![cfg_attr(not(feature = "std"), no_std)] -use rstd::{prelude::*, marker::PhantomData, convert::TryInto}; +use sp_std::{prelude::*, marker::PhantomData, convert::TryInto}; use codec::{Encode, Codec}; -use support::{Parameter, decl_module, decl_event, decl_storage}; -use sr_primitives::traits::{One, SimpleArithmetic, StaticLookup, Member, LookupError}; -use system::{IsDeadAccount, OnNewAccount}; +use frame_support::{Parameter, decl_module, decl_event, decl_storage}; +use sp_runtime::traits::{One, SimpleArithmetic, StaticLookup, Member, LookupError}; +use frame_system::{IsDeadAccount, OnNewAccount}; use self::address::Address as RawAddress; @@ -35,7 +35,7 @@ mod tests; /// Number of account IDs stored per enum set. const ENUM_SET_SIZE: u32 = 64; -pub type Address = RawAddress<::AccountId, ::AccountIndex>; +pub type Address = RawAddress<::AccountId, ::AccountIndex>; /// Turn an Id into an Index, or None for the purpose of getting /// a hint at a possibly desired index. @@ -56,7 +56,7 @@ impl> } /// The module's config trait. -pub trait Trait: system::Trait { +pub trait Trait: frame_system::Trait { /// Type used for storing an account's index; implies the maximum number of accounts the system /// can hold. type AccountIndex: Parameter + Member + Codec + Default + SimpleArithmetic + Copy; @@ -68,18 +68,18 @@ pub trait Trait: system::Trait { type ResolveHint: ResolveHint; /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; } decl_module! { - pub struct Module for enum Call where origin: T::Origin { + pub struct Module for enum Call where origin: T::Origin, system = frame_system { fn deposit_event() = default; } } decl_event!( pub enum Event where - ::AccountId, + ::AccountId, ::AccountIndex { /// A new account index was assigned. diff --git a/frame/indices/src/mock.rs b/frame/indices/src/mock.rs index 427fd87c47e7d14d9383e9708ea96f8869891649..2a1cb0746f816f7b84a385aba49d69cdd68c1335 100644 --- a/frame/indices/src/mock.rs +++ b/frame/indices/src/mock.rs @@ -20,15 +20,14 @@ use std::collections::HashSet; use ref_thread_local::{ref_thread_local, RefThreadLocal}; -use sr_primitives::testing::Header; -use sr_primitives::Perbill; -use primitives::H256; -use support::{impl_outer_origin, parameter_types}; -use {runtime_io, system}; +use sp_runtime::testing::Header; +use sp_runtime::Perbill; +use sp_core::H256; +use frame_support::{impl_outer_origin, parameter_types, weights::Weight}; use crate::{GenesisConfig, Module, Trait, IsDeadAccount, OnNewAccount, ResolveHint}; impl_outer_origin!{ - pub enum Origin for Runtime {} + pub enum Origin for Runtime where system = frame_system {} } ref_thread_local! { @@ -67,17 +66,17 @@ impl ResolveHint for TestResolveHint { pub struct Runtime; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockWeight: Weight = 1024; pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } -impl system::Trait for Runtime { +impl frame_system::Trait for Runtime { type Origin = Origin; type Index = u64; type BlockNumber = u64; type Call = (); type Hash = H256; - type Hashing = ::sr_primitives::traits::BlakeTwo256; + type Hashing = ::sp_runtime::traits::BlakeTwo256; type AccountId = u64; type Lookup = Indices; type Header = Header; @@ -87,6 +86,7 @@ impl system::Trait for Runtime { type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); + type ModuleToIndex = (); } impl Trait for Runtime { type AccountIndex = u64; @@ -95,14 +95,14 @@ impl Trait for Runtime { type Event = (); } -pub fn new_test_ext() -> runtime_io::TestExternalities { +pub fn new_test_ext() -> sp_io::TestExternalities { { let mut h = ALIVE.borrow_mut(); h.clear(); for i in 1..5 { h.insert(i); } } - let mut t = system::GenesisConfig::default().build_storage::().unwrap(); + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); GenesisConfig:: { ids: vec![1, 2, 3, 4] }.assimilate_storage(&mut t).unwrap(); diff --git a/frame/membership/Cargo.toml b/frame/membership/Cargo.toml index 12c81aa741f926a4c097203d19f05d0b4540ede9..cc45cfb94cb49dd1fd50d8707da00d722f1d86c1 100644 --- a/frame/membership/Cargo.toml +++ b/frame/membership/Cargo.toml @@ -7,23 +7,23 @@ edition = "2018" [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false } -rstd = { package = "sr-std", path = "../../primitives/sr-std", default-features = false } -runtime-io = { package = "sr-io", path = "../../primitives/sr-io", default-features = false } -support = { package = "frame-support", path = "../support", default-features = false } -system = { package = "frame-system", path = "../system", default-features = false } -sr-primitives = { path = "../../primitives/sr-primitives", default-features = false } +sp-std = { version = "2.0.0", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0", default-features = false, path = "../../primitives/io" } +frame-support = { version = "2.0.0", default-features = false, path = "../support" } +frame-system = { version = "2.0.0", default-features = false, path = "../system" } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" } [dev-dependencies] -primitives = { package = "substrate-primitives", path = "../../primitives/core" } +sp-core = { version = "2.0.0", path = "../../primitives/core" } [features] default = ["std"] std = [ "serde", "codec/std", - "sr-primitives/std", - "rstd/std", - "runtime-io/std", - "support/std", - "system/std", + "sp-runtime/std", + "sp-std/std", + "sp-io/std", + "frame-support/std", + "frame-system/std", ] diff --git a/frame/membership/src/lib.rs b/frame/membership/src/lib.rs index 472220cffdd51f1175b06a79b1b0c36f84d30a4c..0a7f8ec7fc9bd484a91d452ac65d0174bdc37b10 100644 --- a/frame/membership/src/lib.rs +++ b/frame/membership/src/lib.rs @@ -22,18 +22,18 @@ // Ensure we're `no_std` when compiling for Wasm. #![cfg_attr(not(feature = "std"), no_std)] -use rstd::prelude::*; -use support::{ +use sp_std::prelude::*; +use frame_support::{ decl_module, decl_storage, decl_event, traits::{ChangeMembers, InitializeMembers}, weights::SimpleDispatchInfo, }; -use system::ensure_root; -use sr_primitives::traits::EnsureOrigin; +use frame_system::{self as system, ensure_root, ensure_signed}; +use sp_runtime::traits::EnsureOrigin; -pub trait Trait: system::Trait { +pub trait Trait: frame_system::Trait { /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// Required origin for adding a member (though can always be Root). type AddOrigin: EnsureOrigin; @@ -63,7 +63,7 @@ decl_storage! { } add_extra_genesis { config(members): Vec; - config(phantom): rstd::marker::PhantomData; + config(phantom): sp_std::marker::PhantomData; build(|config: &Self| { let mut members = config.members.clone(); members.sort(); @@ -75,7 +75,7 @@ decl_storage! { decl_event!( pub enum Event where - ::AccountId, + ::AccountId, >::Event, { /// The given member was added; see the transaction for who. @@ -86,8 +86,10 @@ decl_event!( MembersSwapped, /// The membership was reset; see the transaction for who the new set is. MembersReset, + /// One of the members' keys changed. + KeyChanged, /// Phantom member, never used. - Dummy(rstd::marker::PhantomData<(AccountId, Event)>), + Dummy(sp_std::marker::PhantomData<(AccountId, Event)>), } ); @@ -152,8 +154,8 @@ decl_module! { let mut members = >::get(); let location = members.binary_search(&remove).ok().ok_or("not a member")?; + let _ = members.binary_search(&add).err().ok_or("already a member")?; members[location] = add.clone(); - let _location = members.binary_search(&add).err().ok_or("already a member")?; members.sort(); >::put(&members); @@ -186,6 +188,31 @@ decl_module! { Self::deposit_event(RawEvent::MembersReset); } + + /// Swap out the sending member for some other key `new`. + /// + /// May only be called from `Signed` origin of a current member. + #[weight = SimpleDispatchInfo::FixedNormal(50_000)] + fn change_key(origin, new: T::AccountId) { + let remove = ensure_signed(origin)?; + + if remove != new { + let mut members = >::get(); + let location = members.binary_search(&remove).ok().ok_or("not a member")?; + let _ = members.binary_search(&new).err().ok_or("already a member")?; + members[location] = new.clone(); + members.sort(); + >::put(&members); + + T::MembershipChanged::change_members_sorted( + &[new], + &[remove], + &members[..], + ); + } + + Self::deposit_event(RawEvent::KeyChanged); + } } } @@ -194,15 +221,15 @@ mod tests { use super::*; use std::cell::RefCell; - use support::{assert_ok, assert_noop, impl_outer_origin, parameter_types}; - use primitives::H256; + use frame_support::{assert_ok, assert_noop, impl_outer_origin, parameter_types, weights::Weight}; + use sp_core::H256; // The testing primitives are very useful for avoiding having to work with signatures // or public keys. `u64` is used as the `AccountId` and no `Signature`s are requried. - use sr_primitives::{Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header}; - use system::EnsureSignedBy; + use sp_runtime::{Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header}; + use frame_system::EnsureSignedBy; impl_outer_origin! { - pub enum Origin for Test {} + pub enum Origin for Test where system = frame_system {} } // For testing the module, we construct most of a mock runtime. This means @@ -212,11 +239,11 @@ mod tests { pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockWeight: Weight = 1024; pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } - impl system::Trait for Test { + impl frame_system::Trait for Test { type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -232,6 +259,7 @@ mod tests { type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); + type ModuleToIndex = (); } parameter_types! { pub const One: u64 = 1; @@ -279,8 +307,8 @@ mod tests { // This function basically just builds a genesis storage key/value store according to // our desired mockup. - fn new_test_ext() -> runtime_io::TestExternalities { - let mut t = system::GenesisConfig::default().build_storage::().unwrap(); + fn new_test_ext() -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); // We use default for brevity, but you can configure as desired if needed. GenesisConfig::{ members: vec![10, 20, 30], @@ -333,6 +361,35 @@ mod tests { }); } + #[test] + fn swap_member_works_that_does_not_change_order() { + new_test_ext().execute_with(|| { + assert_ok!(Membership::swap_member(Origin::signed(3), 10, 5)); + assert_eq!(Membership::members(), vec![5, 20, 30]); + assert_eq!(MEMBERS.with(|m| m.borrow().clone()), Membership::members()); + }); + } + + #[test] + fn change_key_works() { + new_test_ext().execute_with(|| { + assert_noop!(Membership::change_key(Origin::signed(3), 25), "not a member"); + assert_noop!(Membership::change_key(Origin::signed(10), 20), "already a member"); + assert_ok!(Membership::change_key(Origin::signed(10), 40)); + assert_eq!(Membership::members(), vec![20, 30, 40]); + assert_eq!(MEMBERS.with(|m| m.borrow().clone()), Membership::members()); + }); + } + + #[test] + fn change_key_works_that_does_not_change_order() { + new_test_ext().execute_with(|| { + assert_ok!(Membership::change_key(Origin::signed(10), 5)); + assert_eq!(Membership::members(), vec![5, 20, 30]); + assert_eq!(MEMBERS.with(|m| m.borrow().clone()), Membership::members()); + }); + } + #[test] fn reset_members_works() { new_test_ext().execute_with(|| { diff --git a/frame/metadata/Cargo.toml b/frame/metadata/Cargo.toml index 0fc604bea498c60ac84fc512bb663dc6f09cc51c..64cf326ff68dc9bd533c6a7b00a78996087fc344 100644 --- a/frame/metadata/Cargo.toml +++ b/frame/metadata/Cargo.toml @@ -7,14 +7,14 @@ edition = "2018" [dependencies] codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } serde = { version = "1.0.101", optional = true, features = ["derive"] } -rstd = { package = "sr-std", path = "../../primitives/sr-std", default-features = false } -primitives = { package = "substrate-primitives", path = "../../primitives/core", default-features = false } +sp-std = { version = "2.0.0", default-features = false, path = "../../primitives/std" } +sp-core = { version = "2.0.0", default-features = false, path = "../../primitives/core" } [features] default = ["std"] std = [ "codec/std", - "rstd/std", - "primitives/std", + "sp-std/std", + "sp-core/std", "serde", ] diff --git a/frame/metadata/src/lib.rs b/frame/metadata/src/lib.rs index d85a6837fc6e015d7d1c2068a685e1eaa9283fea..d47e0c75cfdb80fb7bcb4a8cf3088dabd81bb9ee 100644 --- a/frame/metadata/src/lib.rs +++ b/frame/metadata/src/lib.rs @@ -27,8 +27,8 @@ use serde::Serialize; #[cfg(feature = "std")] use codec::{Decode, Input, Error}; use codec::{Encode, Output}; -use rstd::vec::Vec; -use primitives::RuntimeDebug; +use sp_std::vec::Vec; +use sp_core::RuntimeDebug; #[cfg(feature = "std")] type StringBuf = String; @@ -85,12 +85,12 @@ impl Eq for DecodeDifferent where B: Encode + Eq + PartialEq + 'static, O: Encode + Eq + PartialEq + 'static {} -impl rstd::fmt::Debug for DecodeDifferent +impl sp_std::fmt::Debug for DecodeDifferent where - B: rstd::fmt::Debug + Eq + 'static, - O: rstd::fmt::Debug + Eq + 'static, + B: sp_std::fmt::Debug + Eq + 'static, + O: sp_std::fmt::Debug + Eq + 'static, { - fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { match self { DecodeDifferent::Encode(b) => b.fmt(f), DecodeDifferent::Decoded(o) => o.fmt(f), @@ -151,8 +151,8 @@ impl PartialEq for FnEncode { } } -impl rstd::fmt::Debug for FnEncode { - fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { +impl sp_std::fmt::Debug for FnEncode { + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { self.0().fmt(f) } } @@ -261,8 +261,8 @@ impl serde::Serialize for DefaultByteGetter { } } -impl rstd::fmt::Debug for DefaultByteGetter { - fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { +impl sp_std::fmt::Debug for DefaultByteGetter { + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { self.0.default_byte().fmt(f) } } @@ -342,8 +342,10 @@ pub enum RuntimeMetadata { V6(RuntimeMetadataDeprecated), /// Version 7 for runtime metadata. No longer used. V7(RuntimeMetadataDeprecated), - /// Version 8 for runtime metadata. - V8(RuntimeMetadataV8), + /// Version 8 for runtime metadata. No longer used. + V8(RuntimeMetadataDeprecated), + /// Version 9 for runtime metadata. + V9(RuntimeMetadataV9), } /// Enum that should fail. @@ -367,12 +369,12 @@ impl Decode for RuntimeMetadataDeprecated { /// The metadata of a runtime. #[derive(Eq, Encode, PartialEq, RuntimeDebug)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] -pub struct RuntimeMetadataV8 { +pub struct RuntimeMetadataV9 { pub modules: DecodeDifferentArray, } /// The latest version of the metadata. -pub type RuntimeMetadataLastVersion = RuntimeMetadataV8; +pub type RuntimeMetadataLastVersion = RuntimeMetadataV9; /// All metadata about an runtime module. #[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] @@ -389,14 +391,14 @@ pub struct ModuleMetadata { type ODFnA = Option>; type DFnA = DecodeDifferent, Vec>; -impl Into for RuntimeMetadataPrefixed { - fn into(self) -> primitives::OpaqueMetadata { - primitives::OpaqueMetadata::new(self.encode()) +impl Into for RuntimeMetadataPrefixed { + fn into(self) -> sp_core::OpaqueMetadata { + sp_core::OpaqueMetadata::new(self.encode()) } } impl Into for RuntimeMetadataLastVersion { fn into(self) -> RuntimeMetadataPrefixed { - RuntimeMetadataPrefixed(META_RESERVED, RuntimeMetadata::V8(self)) + RuntimeMetadataPrefixed(META_RESERVED, RuntimeMetadata::V9(self)) } } diff --git a/frame/nicks/Cargo.toml b/frame/nicks/Cargo.toml index aa2df57af514d157b16eae676966a2750bf48e6b..0dce684f0df2186fcb3845b25721f535d514fe1f 100644 --- a/frame/nicks/Cargo.toml +++ b/frame/nicks/Cargo.toml @@ -7,24 +7,24 @@ edition = "2018" [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -rstd = { package = "sr-std", path = "../../primitives/sr-std", default-features = false } -runtime-io = { package = "sr-io", path = "../../primitives/sr-io", default-features = false } -sr-primitives = { path = "../../primitives/sr-primitives", default-features = false } -support = { package = "frame-support", path = "../support", default-features = false } -system = { package = "frame-system", path = "../system", default-features = false } +sp-std = { version = "2.0.0", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0", default-features = false, path = "../support" } +frame-system = { version = "2.0.0", default-features = false, path = "../system" } [dev-dependencies] -primitives = { package = "substrate-primitives", path = "../../primitives/core" } -balances = { package = "pallet-balances", path = "../balances", default-features = false } +sp-core = { version = "2.0.0", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0", path = "../balances" } [features] default = ["std"] std = [ "serde", "codec/std", - "rstd/std", - "runtime-io/std", - "sr-primitives/std", - "support/std", - "system/std", + "sp-std/std", + "sp-io/std", + "sp-runtime/std", + "frame-support/std", + "frame-system/std", ] diff --git a/frame/nicks/src/lib.rs b/frame/nicks/src/lib.rs index 94b7043c17c94304032824d4d46776652a0c874d..d2f0b4d8c9827545b0288653249d75a549c882f3 100644 --- a/frame/nicks/src/lib.rs +++ b/frame/nicks/src/lib.rs @@ -38,23 +38,23 @@ #![cfg_attr(not(feature = "std"), no_std)] -use rstd::prelude::*; -use sr_primitives::{ +use sp_std::prelude::*; +use sp_runtime::{ traits::{StaticLookup, EnsureOrigin, Zero} }; -use support::{ +use frame_support::{ decl_module, decl_event, decl_storage, ensure, traits::{Currency, ReservableCurrency, OnUnbalanced, Get}, weights::SimpleDispatchInfo, }; -use system::{ensure_signed, ensure_root}; +use frame_system::{self as system, ensure_signed, ensure_root}; -type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; -type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; +type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; -pub trait Trait: system::Trait { +pub trait Trait: frame_system::Trait { /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// The currency trait. type Currency: ReservableCurrency; @@ -83,7 +83,7 @@ decl_storage! { } decl_event!( - pub enum Event where AccountId = ::AccountId, Balance = BalanceOf { + pub enum Event where AccountId = ::AccountId, Balance = BalanceOf { /// A name was set. NameSet(AccountId), /// A name was forcibly set. @@ -229,17 +229,17 @@ decl_module! { mod tests { use super::*; - use support::{assert_ok, assert_noop, impl_outer_origin, parameter_types}; - use primitives::H256; - use system::EnsureSignedBy; + use frame_support::{assert_ok, assert_noop, impl_outer_origin, parameter_types, weights::Weight}; + use sp_core::H256; + use frame_system::EnsureSignedBy; // The testing primitives are very useful for avoiding having to work with signatures // or public keys. `u64` is used as the `AccountId` and no `Signature`s are required. - use sr_primitives::{ + use sp_runtime::{ Perbill, testing::Header, traits::{BlakeTwo256, IdentityLookup}, }; impl_outer_origin! { - pub enum Origin for Test {} + pub enum Origin for Test where system = frame_system {} } // For testing the module, we construct most of a mock runtime. This means @@ -249,11 +249,11 @@ mod tests { pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockWeight: Weight = 1024; pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } - impl system::Trait for Test { + impl frame_system::Trait for Test { type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -269,13 +269,14 @@ mod tests { type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); + type ModuleToIndex = (); } parameter_types! { pub const ExistentialDeposit: u64 = 0; pub const TransferFee: u64 = 0; pub const CreationFee: u64 = 0; } - impl balances::Trait for Test { + impl pallet_balances::Trait for Test { type Balance = u64; type OnFreeBalanceZero = (); type OnNewAccount = (); @@ -301,15 +302,15 @@ mod tests { type MinLength = MinLength; type MaxLength = MaxLength; } - type Balances = balances::Module; + type Balances = pallet_balances::Module; type Nicks = Module; // This function basically just builds a genesis storage key/value store according to // our desired mockup. - fn new_test_ext() -> runtime_io::TestExternalities { - let mut t = system::GenesisConfig::default().build_storage::().unwrap(); + fn new_test_ext() -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); // We use default for brevity, but you can configure as desired if needed. - balances::GenesisConfig:: { + pallet_balances::GenesisConfig:: { balances: vec![ (1, 10), (2, 10), diff --git a/frame/offences/Cargo.toml b/frame/offences/Cargo.toml index 354de90e853c950f185439c74d968b5937614584..36d057f4e9fd9c892f1b07db501ad3cf79302b7b 100644 --- a/frame/offences/Cargo.toml +++ b/frame/offences/Cargo.toml @@ -1,32 +1,32 @@ [package] name = "pallet-offences" -version = "1.0.0" +version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" [dependencies] -balances = { package = "pallet-balances", path = "../balances", default-features = false } +pallet-balances = { version = "2.0.0", default-features = false, path = "../balances" } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -rstd = { package = "sr-std", path = "../../primitives/sr-std", default-features = false } +sp-std = { version = "2.0.0", default-features = false, path = "../../primitives/std" } serde = { version = "1.0.101", optional = true } -sr-primitives = { path = "../../primitives/sr-primitives", default-features = false } -sr-staking-primitives = { path = "../../primitives/sr-staking-primitives", default-features = false } -support = { package = "frame-support", path = "../support", default-features = false } -system = { package = "frame-system", path = "../system", default-features = false } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" } +sp-staking = { version = "2.0.0", default-features = false, path = "../../primitives/staking" } +frame-support = { version = "2.0.0", default-features = false, path = "../support" } +frame-system = { version = "2.0.0", default-features = false, path = "../system" } [dev-dependencies] -runtime-io = { package = "sr-io", path = "../../primitives/sr-io" } -substrate-primitives = { path = "../../primitives/core" } +sp-io = { version = "2.0.0", path = "../../primitives/io" } +sp-core = { version = "2.0.0", path = "../../primitives/core" } [features] default = ["std"] std = [ - "balances/std", + "pallet-balances/std", "codec/std", - "rstd/std", + "sp-std/std", "serde", - "sr-primitives/std", - "sr-staking-primitives/std", - "support/std", - "system/std", + "sp-runtime/std", + "sp-staking/std", + "frame-support/std", + "frame-system/std", ] diff --git a/frame/offences/src/lib.rs b/frame/offences/src/lib.rs index a6cf4d795646771e2dc424d2f5cd2190be6eef70..0dc66c72d40b5a50f43364d7b309f4fef96a4b0b 100644 --- a/frame/offences/src/lib.rs +++ b/frame/offences/src/lib.rs @@ -24,32 +24,27 @@ mod mock; mod tests; -use rstd::{ - vec::Vec, - collections::btree_set::BTreeSet, -}; -use support::{ +use sp_std::vec::Vec; +use frame_support::{ decl_module, decl_event, decl_storage, Parameter, }; -use sr_primitives::{ - Perbill, - traits::{Hash, Saturating}, -}; -use sr_staking_primitives::{ +use sp_runtime::traits::Hash; +use sp_staking::{ offence::{Offence, ReportOffence, Kind, OnOffenceHandler, OffenceDetails}, }; use codec::{Encode, Decode}; +use frame_system as system; /// A binary blob which represents a SCALE codec-encoded `O::TimeSlot`. type OpaqueTimeSlot = Vec; /// A type alias for a report identifier. -type ReportIdOf = ::Hash; +type ReportIdOf = ::Hash; /// Offences trait -pub trait Trait: system::Trait { +pub trait Trait: frame_system::Trait { /// The overarching event type. - type Event: From + Into<::Event>; + type Event: From + Into<::Event>; /// Full identification of the validator. type IdentificationTuple: Parameter + Ord; /// A handler called for every offence report. @@ -100,10 +95,11 @@ where // Go through all offenders in the offence report and find all offenders that was spotted // in unique reports. - let TriageOutcome { - new_offenders, - concurrent_offenders, - } = match Self::triage_offence_report::(reporters, &time_slot, offenders) { + let TriageOutcome { concurrent_offenders } = match Self::triage_offence_report::( + reporters, + &time_slot, + offenders, + ) { Some(triage) => triage, // The report contained only duplicates, so there is no need to slash again. None => return, @@ -113,44 +109,18 @@ where Self::deposit_event(Event::Offence(O::ID, time_slot.encode())); let offenders_count = concurrent_offenders.len() as u32; - let previous_offenders_count = offenders_count - new_offenders.len() as u32; // The amount new offenders are slashed let new_fraction = O::slash_fraction(offenders_count, validator_set_count); - // The amount previous offenders are slashed additionally. - // - // Since they were slashed in the past, we slash by: - // x = (new - prev) / (1 - prev) - // because: - // Y = X * (1 - prev) - // Z = Y * (1 - x) - // Z = X * (1 - new) - let old_fraction = if previous_offenders_count > 0 { - let previous_fraction = O::slash_fraction( - offenders_count.saturating_sub(previous_offenders_count), - validator_set_count, - ); - let numerator = new_fraction.saturating_sub(previous_fraction); - let denominator = Perbill::one().saturating_sub(previous_fraction); - denominator.saturating_mul(numerator) - } else { - new_fraction.clone() - }; + let slash_perbill: Vec<_> = (0..concurrent_offenders.len()) + .map(|_| new_fraction.clone()).collect(); - // calculate how much to slash - let slash_perbill = concurrent_offenders - .iter() - .map(|details| { - if previous_offenders_count > 0 && new_offenders.contains(&details.offender) { - new_fraction.clone() - } else { - old_fraction.clone() - } - }) - .collect::>(); - - T::OnOffenceHandler::on_offence(&concurrent_offenders, &slash_perbill); + T::OnOffenceHandler::on_offence( + &concurrent_offenders, + &slash_perbill, + offence.session_index(), + ); } } @@ -173,13 +143,13 @@ impl Module { offenders: Vec, ) -> Option> { let mut storage = ReportIndexStorage::::load(time_slot); - let mut new_offenders = BTreeSet::new(); + let mut any_new = false; for offender in offenders { let report_id = Self::report_id::(time_slot, &offender); if !>::exists(&report_id) { - new_offenders.insert(offender.clone()); + any_new = true; >::insert( &report_id, OffenceDetails { @@ -192,7 +162,7 @@ impl Module { } } - if !new_offenders.is_empty() { + if any_new { // Load report details for the all reports happened at the same time. let concurrent_offenders = storage.concurrent_reports .iter() @@ -202,7 +172,6 @@ impl Module { storage.save(); Some(TriageOutcome { - new_offenders, concurrent_offenders, }) } else { @@ -212,8 +181,6 @@ impl Module { } struct TriageOutcome { - /// Offenders that was spotted in the unique reports. - new_offenders: BTreeSet, /// Other reports for the same report kinds. concurrent_offenders: Vec>, } diff --git a/frame/offences/src/mock.rs b/frame/offences/src/mock.rs index e8e4c864d1f7a2bd7aa4a12909f5276294bcdccc..343fdc88fab85576845ec230f2be41daed40afef 100644 --- a/frame/offences/src/mock.rs +++ b/frame/offences/src/mock.rs @@ -21,16 +21,19 @@ use std::cell::RefCell; use crate::{Module, Trait}; use codec::Encode; -use sr_primitives::Perbill; -use sr_staking_primitives::{ +use sp_runtime::Perbill; +use sp_staking::{ SessionIndex, offence::{self, Kind, OffenceDetails}, }; -use sr_primitives::testing::Header; -use sr_primitives::traits::{IdentityLookup, BlakeTwo256}; -use substrate_primitives::H256; -use support::{impl_outer_origin, impl_outer_event, parameter_types, StorageMap, StorageDoubleMap}; -use {runtime_io, system}; +use sp_runtime::testing::Header; +use sp_runtime::traits::{IdentityLookup, BlakeTwo256}; +use sp_core::H256; +use frame_support::{ + impl_outer_origin, impl_outer_event, parameter_types, StorageMap, StorageDoubleMap, + weights::Weight, +}; +use frame_system as system; impl_outer_origin!{ pub enum Origin for Runtime {} @@ -46,6 +49,7 @@ impl offence::OnOffenceHandler for OnOff fn on_offence( _offenders: &[OffenceDetails], slash_fraction: &[Perbill], + _offence_session: SessionIndex, ) { ON_OFFENCE_PERBILL.with(|f| { *f.borrow_mut() = slash_fraction.to_vec(); @@ -64,11 +68,11 @@ pub fn with_on_offence_fractions) -> R>(f: F) -> pub struct Runtime; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockWeight: Weight = 1024; pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } -impl system::Trait for Runtime { +impl frame_system::Trait for Runtime { type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -84,6 +88,7 @@ impl system::Trait for Runtime { type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); + type ModuleToIndex = (); } impl Trait for Runtime { @@ -102,14 +107,14 @@ impl_outer_event! { } } -pub fn new_test_ext() -> runtime_io::TestExternalities { - let t = system::GenesisConfig::default().build_storage::().unwrap(); +pub fn new_test_ext() -> sp_io::TestExternalities { + let t = frame_system::GenesisConfig::default().build_storage::().unwrap(); t.into() } /// Offences module. pub type Offences = Module; -pub type System = system::Module; +pub type System = frame_system::Module; pub const KIND: [u8; 16] = *b"test_report_1234"; @@ -148,9 +153,7 @@ impl offence::Offence for Offence { } fn session_index(&self) -> SessionIndex { - // session index is not used by the pallet-offences directly, but rather it exists only for - // filtering historical reports. - unimplemented!() + 1 } fn slash_fraction( diff --git a/frame/offences/src/tests.rs b/frame/offences/src/tests.rs index 28e655d16bfdd2e93fa69ce211adca389f65bccb..2cbadf96b52c353561b10628c2d0007cf571a3cb 100644 --- a/frame/offences/src/tests.rs +++ b/frame/offences/src/tests.rs @@ -23,7 +23,8 @@ use crate::mock::{ Offences, System, Offence, TestEvent, KIND, new_test_ext, with_on_offence_fractions, offence_reports, }; -use system::{EventRecord, Phase}; +use sp_runtime::Perbill; +use frame_system::{EventRecord, Phase}; #[test] fn should_report_an_authority_and_trigger_on_offence() { @@ -48,38 +49,6 @@ fn should_report_an_authority_and_trigger_on_offence() { }); } -#[test] -fn should_calculate_the_fraction_correctly() { - new_test_ext().execute_with(|| { - // given - let time_slot = 42; - assert_eq!(offence_reports(KIND, time_slot), vec![]); - let offence1 = Offence { - validator_set_count: 5, - time_slot, - offenders: vec![5], - }; - let offence2 = Offence { - validator_set_count: 5, - time_slot, - offenders: vec![4], - }; - - // when - Offences::report_offence(vec![], offence1); - with_on_offence_fractions(|f| { - assert_eq!(f.clone(), vec![Perbill::from_percent(25)]); - }); - - Offences::report_offence(vec![], offence2); - - // then - with_on_offence_fractions(|f| { - assert_eq!(f.clone(), vec![Perbill::from_percent(15), Perbill::from_percent(45)]); - }); - }); -} - #[test] fn should_not_report_the_same_authority_twice_in_the_same_slot() { new_test_ext().execute_with(|| { diff --git a/frame/randomness-collective-flip/Cargo.toml b/frame/randomness-collective-flip/Cargo.toml index b76f908500197c1a82871cbc6c7cfbf1397d39c0..9e25ba4c5708285a56b49bdd9fdb0266173aa2b8 100644 --- a/frame/randomness-collective-flip/Cargo.toml +++ b/frame/randomness-collective-flip/Cargo.toml @@ -7,22 +7,22 @@ edition = "2018" [dependencies] safe-mix = { version = "1.0", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -sr-primitives = { path = "../../primitives/sr-primitives", default-features = false } -support = { package = "frame-support", path = "../support", default-features = false } -system = { package = "frame-system", path = "../system", default-features = false } -rstd = { package = "sr-std", path = "../../primitives/sr-std", default-features = false } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0", default-features = false, path = "../support" } +frame-system = { version = "2.0.0", default-features = false, path = "../system" } +sp-std = { version = "2.0.0", default-features = false, path = "../../primitives/std" } [dev-dependencies] -primitives = { package = "substrate-primitives", path = "../../primitives/core" } -runtime-io = { package = "sr-io", path = "../../primitives/sr-io" } +sp-core = { version = "2.0.0", path = "../../primitives/core" } +sp-io = { version = "2.0.0", path = "../../primitives/io" } [features] default = ["std"] std = [ "safe-mix/std", - "system/std", + "frame-system/std", "codec/std", - "support/std", - "sr-primitives/std", - "rstd/std", + "frame-support/std", + "sp-runtime/std", + "sp-std/std", ] diff --git a/frame/randomness-collective-flip/src/lib.rs b/frame/randomness-collective-flip/src/lib.rs index 595249b98606406911e01dcb9669f3c2b70644cb..8432a861980c71951b2eae485b2c7563b253580f 100644 --- a/frame/randomness-collective-flip/src/lib.rs +++ b/frame/randomness-collective-flip/src/lib.rs @@ -35,13 +35,13 @@ //! ### Example - Get random seed for the current block //! //! ``` -//! use support::{decl_module, dispatch::Result, traits::Randomness}; +//! use frame_support::{decl_module, dispatch, traits::Randomness}; //! -//! pub trait Trait: system::Trait {} +//! pub trait Trait: frame_system::Trait {} //! //! decl_module! { //! pub struct Module for enum Call where origin: T::Origin { -//! pub fn random_module_example(origin) -> Result { +//! pub fn random_module_example(origin) -> dispatch::DispatchResult { //! let _random_seed = >::random_seed(); //! Ok(()) //! } @@ -52,12 +52,12 @@ #![cfg_attr(not(feature = "std"), no_std)] -use rstd::{prelude::*, convert::TryInto}; -use sr_primitives::traits::Hash; -use support::{decl_module, decl_storage, traits::Randomness}; +use sp_std::{prelude::*, convert::TryInto}; +use sp_runtime::traits::Hash; +use frame_support::{decl_module, decl_storage, traits::Randomness}; use safe_mix::TripletMix; use codec::Encode; -use system::Trait; +use frame_system::Trait; const RANDOM_MATERIAL_LEN: u32 = 81; @@ -70,7 +70,7 @@ fn block_number_to_index(block_number: T::BlockNumber) -> usize { decl_module! { pub struct Module for enum Call where origin: T::Origin { fn on_initialize(block_number: T::BlockNumber) { - let parent_hash = >::parent_hash(); + let parent_hash = >::parent_hash(); >::mutate(|ref mut values| if values.len() < RANDOM_MATERIAL_LEN as usize { values.push(parent_hash) @@ -130,7 +130,7 @@ impl Randomness for Module { /// and mean that all bits of the resulting value are entirely manipulatable by the author of /// the parent block, who can determine the value of `parent_hash`. fn random(subject: &[u8]) -> T::Hash { - let block_number = >::block_number(); + let block_number = >::block_number(); let index = block_number_to_index::(block_number); let hash_series = >::get(); @@ -152,27 +152,27 @@ impl Randomness for Module { #[cfg(test)] mod tests { use super::*; - use primitives::H256; - use sr_primitives::{ + use sp_core::H256; + use sp_runtime::{ Perbill, traits::{BlakeTwo256, OnInitialize, Header as _, IdentityLookup}, testing::Header, }; - use support::{impl_outer_origin, parameter_types, traits::Randomness}; + use frame_support::{impl_outer_origin, parameter_types, weights::Weight, traits::Randomness}; #[derive(Clone, PartialEq, Eq)] pub struct Test; impl_outer_origin! { - pub enum Origin for Test {} + pub enum Origin for Test where system = frame_system {} } parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockWeight: Weight = 1024; pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } - impl system::Trait for Test { + impl frame_system::Trait for Test { type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -188,13 +188,14 @@ mod tests { type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; type Version = (); + type ModuleToIndex = (); } - type System = system::Module; + type System = frame_system::Module; type CollectiveFlip = Module; - fn new_test_ext() -> runtime_io::TestExternalities { - let t = system::GenesisConfig::default().build_storage::().unwrap(); + fn new_test_ext() -> sp_io::TestExternalities { + let t = frame_system::GenesisConfig::default().build_storage::().unwrap(); t.into() } diff --git a/frame/scored-pool/Cargo.toml b/frame/scored-pool/Cargo.toml index cebb0710032049473ce4924c8f54e5be0954ad43..0b4c2768dfcb553046c9767c057217393b43a89a 100644 --- a/frame/scored-pool/Cargo.toml +++ b/frame/scored-pool/Cargo.toml @@ -1,30 +1,30 @@ [package] name = "pallet-scored-pool" -version = "1.0.0" +version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" [dependencies] codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } serde = { version = "1.0.101", optional = true } -runtime-io = { package = "sr-io", path = "../../primitives/sr-io", default-features = false } -sr-primitives = { path = "../../primitives/sr-primitives", default-features = false } -rstd = { package = "sr-std", path = "../../primitives/sr-std", default-features = false } -support = { package = "frame-support", path = "../support", default-features = false } -system = { package = "frame-system", path = "../system", default-features = false } +sp-io = { version = "2.0.0", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0", default-features = false, path = "../../primitives/std" } +frame-support = { version = "2.0.0", default-features = false, path = "../support" } +frame-system = { version = "2.0.0", default-features = false, path = "../system" } [dev-dependencies] -balances = { package = "pallet-balances", path = "../balances" } -primitives = { package = "substrate-primitives", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0", path = "../balances" } +sp-core = { version = "2.0.0", path = "../../primitives/core" } [features] default = ["std"] std = [ "codec/std", "serde", - "runtime-io/std", - "sr-primitives/std", - "rstd/std", - "support/std", - "system/std", + "sp-io/std", + "sp-runtime/std", + "sp-std/std", + "frame-support/std", + "frame-system/std", ] diff --git a/frame/scored-pool/src/lib.rs b/frame/scored-pool/src/lib.rs index 39cffdb77f8e775fb69a310a80ad9791192aea5b..65a867df600e96b856ac10a363001947ebbc8b8c 100644 --- a/frame/scored-pool/src/lib.rs +++ b/frame/scored-pool/src/lib.rs @@ -53,15 +53,15 @@ //! ## Usage //! //! ``` -//! use support::{decl_module, dispatch::Result}; -//! use system::ensure_signed; +//! use frame_support::{decl_module, dispatch}; +//! use frame_system::{self as system, ensure_signed}; //! use pallet_scored_pool::{self as scored_pool}; //! //! pub trait Trait: scored_pool::Trait {} //! //! decl_module! { //! pub struct Module for enum Call where origin: T::Origin { -//! pub fn candidate(origin) -> Result { +//! pub fn candidate(origin) -> dispatch::DispatchResult { //! let who = ensure_signed(origin)?; //! //! let _ = >::submit_candidacy( @@ -89,21 +89,21 @@ mod mock; mod tests; use codec::FullCodec; -use rstd::{ +use sp_std::{ fmt::Debug, prelude::*, }; -use support::{ +use frame_support::{ decl_module, decl_storage, decl_event, ensure, traits::{ChangeMembers, InitializeMembers, Currency, Get, ReservableCurrency}, }; -use system::{self, ensure_root, ensure_signed}; -use sr_primitives::{ +use frame_system::{self as system, ensure_root, ensure_signed}; +use sp_runtime::{ traits::{EnsureOrigin, SimpleArithmetic, MaybeSerializeDeserialize, Zero, StaticLookup}, }; -type BalanceOf = <>::Currency as Currency<::AccountId>>::Balance; -type PoolT = Vec<(::AccountId, Option<>::Score>)>; +type BalanceOf = <>::Currency as Currency<::AccountId>>::Balance; +type PoolT = Vec<(::AccountId, Option<>::Score>)>; /// The enum is supplied when refreshing the members set. /// Depending on the enum variant the corresponding associated @@ -115,7 +115,7 @@ enum ChangeReceiver { MembershipChanged, } -pub trait Trait: system::Trait { +pub trait Trait: frame_system::Trait { /// The currency used for deposits. type Currency: Currency + ReservableCurrency; @@ -124,7 +124,7 @@ pub trait Trait: system::Trait { SimpleArithmetic + Clone + Copy + Default + FullCodec + MaybeSerializeDeserialize + Debug; /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; // The deposit which is reserved from candidates if they want to // start a candidacy. The deposit gets returned when the candidacy is @@ -175,7 +175,7 @@ decl_storage! { } add_extra_genesis { config(members): Vec; - config(phantom): rstd::marker::PhantomData; + config(phantom): sp_std::marker::PhantomData; build(|config| { let mut pool = config.pool.clone(); @@ -203,7 +203,7 @@ decl_storage! { decl_event!( pub enum Event where - ::AccountId, + ::AccountId, { /// The given member was removed. See the transaction for who. MemberRemoved, @@ -218,7 +218,7 @@ decl_event!( /// See the transaction for who. CandidateScored, /// Phantom member, never used. - Dummy(rstd::marker::PhantomData<(AccountId, I)>), + Dummy(sp_std::marker::PhantomData<(AccountId, I)>), } ); @@ -261,7 +261,7 @@ decl_module! { // `None` are always sorted to the end. if let Err(e) = >::append(&[(who.clone(), None)]) { T::Currency::unreserve(&who, deposit); - return Err(e); + Err(e)? } >::insert(&who, true); @@ -453,4 +453,3 @@ impl, I: Instance> Module { Ok(()) } } - diff --git a/frame/scored-pool/src/mock.rs b/frame/scored-pool/src/mock.rs index 394f486a8bec383bf28e52eef7a0a1c4c7a47aec..fe873da26a5901a4a6fe50fee9656478967d4956 100644 --- a/frame/scored-pool/src/mock.rs +++ b/frame/scored-pool/src/mock.rs @@ -19,17 +19,17 @@ use super::*; use std::cell::RefCell; -use support::{impl_outer_origin, parameter_types}; -use primitives::H256; +use frame_support::{impl_outer_origin, parameter_types, weights::Weight}; +use sp_core::H256; // The testing primitives are very useful for avoiding having to work with signatures // or public keys. `u64` is used as the `AccountId` and no `Signature`s are requried. -use sr_primitives::{ +use sp_runtime::{ Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header, }; -use system::EnsureSignedBy; +use frame_system::EnsureSignedBy; impl_outer_origin! { - pub enum Origin for Test {} + pub enum Origin for Test where system = frame_system {} } // For testing the module, we construct most of a mock runtime. This means @@ -45,7 +45,7 @@ parameter_types! { pub const ScoreOrigin: u64 = 3; pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockWeight: Weight = 1024; pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); @@ -54,7 +54,7 @@ parameter_types! { pub const CreationFee: u64 = 0; } -impl system::Trait for Test { +impl frame_system::Trait for Test { type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -70,9 +70,10 @@ impl system::Trait for Test { type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); + type ModuleToIndex = (); } -impl balances::Trait for Test { +impl pallet_balances::Trait for Test { type Balance = u64; type OnFreeBalanceZero = (); type OnNewAccount = (); @@ -116,7 +117,7 @@ impl Trait for Test { type KickOrigin = EnsureSignedBy; type MembershipInitialized = TestChangeMembers; type MembershipChanged = TestChangeMembers; - type Currency = balances::Module; + type Currency = pallet_balances::Module; type CandidateDeposit = CandidateDeposit; type Period = Period; type Score = u64; @@ -125,10 +126,10 @@ impl Trait for Test { // This function basically just builds a genesis storage key/value store according to // our desired mockup. -pub fn new_test_ext() -> runtime_io::TestExternalities { - let mut t = system::GenesisConfig::default().build_storage::().unwrap(); +pub fn new_test_ext() -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); // We use default for brevity, but you can configure as desired if needed. - balances::GenesisConfig:: { + pallet_balances::GenesisConfig:: { balances: vec![ (5, 500_000), (10, 500_000), diff --git a/frame/scored-pool/src/tests.rs b/frame/scored-pool/src/tests.rs index 2f47b5da6fe26c5a8c0443155b370fd38e2aa5b9..0b3ede9ee04eeb4944af492e5e8d6201ef1481da 100644 --- a/frame/scored-pool/src/tests.rs +++ b/frame/scored-pool/src/tests.rs @@ -19,12 +19,12 @@ use super::*; use mock::*; -use support::{assert_ok, assert_noop}; -use sr_primitives::traits::OnInitialize; +use frame_support::{assert_ok, assert_noop}; +use sp_runtime::traits::OnInitialize; type ScoredPool = Module; -type System = system::Module; -type Balances = balances::Module; +type System = frame_system::Module; +type Balances = pallet_balances::Module; const OOB_ERR: &str = "index out of bounds"; const INDEX_ERR: &str = "index does not match requested account"; diff --git a/frame/session/Cargo.toml b/frame/session/Cargo.toml index b93111d26266c0b0ee02c6d36793a77d17a4738d..82047dbd68336e9fe65a7fb53555d926cfdf654a 100644 --- a/frame/session/Cargo.toml +++ b/frame/session/Cargo.toml @@ -8,33 +8,33 @@ edition = "2018" serde = { version = "1.0.101", optional = true } safe-mix = { version = "1.0.0", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -rstd = { package = "sr-std", path = "../../primitives/sr-std", default-features = false } -sr-primitives = { path = "../../primitives/sr-primitives", default-features = false } -sr-staking-primitives = { path = "../../primitives/sr-staking-primitives", default-features = false } -support = { package = "frame-support", path = "../support", default-features = false } -system = { package = "frame-system", path = "../system", default-features = false } -timestamp = { package = "pallet-timestamp", path = "../timestamp", default-features = false } -substrate-trie = { path = "../../primitives/trie", default-features = false, optional = true } -runtime-io ={ package = "sr-io", path = "../../primitives/sr-io", default-features = false } +sp-std = { version = "2.0.0", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" } +sp-staking = { version = "2.0.0", default-features = false, path = "../../primitives/staking" } +frame-support = { version = "2.0.0", default-features = false, path = "../support" } +frame-system = { version = "2.0.0", default-features = false, path = "../system" } +pallet-timestamp = { version = "2.0.0", default-features = false, path = "../timestamp" } +sp-trie = { optional = true, path = "../../primitives/trie", default-features = false } +sp-io ={ path = "../../primitives/io", default-features = false } impl-trait-for-tuples = "0.1.3" [dev-dependencies] -primitives = { package = "substrate-primitives", path = "../../primitives/core" } -app-crypto = { package = "substrate-application-crypto", path = "../../primitives/application-crypto" } +sp-core = { version = "2.0.0", path = "../../primitives/core" } +sp-application-crypto = { version = "2.0.0", path = "../../primitives/application-crypto" } lazy_static = "1.4.0" [features] default = ["std", "historical"] -historical = ["substrate-trie"] +historical = ["sp-trie"] std = [ "serde", "safe-mix/std", "codec/std", - "rstd/std", - "support/std", - "sr-primitives/std", - "sr-staking-primitives/std", - "timestamp/std", - "substrate-trie/std", - "runtime-io/std", + "sp-std/std", + "frame-support/std", + "sp-runtime/std", + "sp-staking/std", + "pallet-timestamp/std", + "sp-trie/std", + "sp-io/std", ] diff --git a/frame/session/src/historical.rs b/frame/session/src/historical.rs index 7975da49983249041edc78b667cb249e4535527a..1298111e930c8ed34f3813ae22d3f858ff30b993 100644 --- a/frame/session/src/historical.rs +++ b/frame/session/src/historical.rs @@ -25,14 +25,14 @@ //! These roots and proofs of inclusion can be generated at any time during the current session. //! Afterwards, the proofs can be fed to a consensus module when reporting misbehavior. -use rstd::prelude::*; +use sp_std::prelude::*; use codec::{Encode, Decode}; -use sr_primitives::KeyTypeId; -use sr_primitives::traits::{Convert, OpaqueKeys, Hash as HashT}; -use support::{decl_module, decl_storage}; -use support::{Parameter, print}; -use substrate_trie::{MemoryDB, Trie, TrieMut, Recorder, EMPTY_PREFIX}; -use substrate_trie::trie_types::{TrieDBMut, TrieDB}; +use sp_runtime::KeyTypeId; +use sp_runtime::traits::{Convert, OpaqueKeys, Hash as HashT}; +use frame_support::{decl_module, decl_storage}; +use frame_support::{Parameter, print}; +use sp_trie::{MemoryDB, Trie, TrieMut, Recorder, EMPTY_PREFIX}; +use sp_trie::trie_types::{TrieDBMut, TrieDB}; use super::{SessionIndex, Module as SessionModule}; type ValidatorCount = u32; @@ -79,7 +79,7 @@ impl Module { None => return, // nothing to prune. }; - let up_to = rstd::cmp::min(up_to, end); + let up_to = sp_std::cmp::min(up_to, end); if up_to < start { return // out of bounds. harmless. @@ -108,7 +108,7 @@ pub trait OnSessionEnding: crate::OnSessionEndi /// An `OnSessionEnding` implementation that wraps an inner `I` and also /// sets the historical trie root of the ending session. -pub struct NoteHistoricalRoot(rstd::marker::PhantomData<(T, I)>); +pub struct NoteHistoricalRoot(sp_std::marker::PhantomData<(T, I)>); impl crate::OnSessionEnding for NoteHistoricalRoot where I: OnSessionEnding @@ -146,7 +146,7 @@ impl crate::OnSessionEnding for NoteHistoricalRoot< } } -type HasherOf = <::Hashing as HashT>::Hasher; +type HasherOf = <::Hashing as HashT>::Hasher; /// A tuple of the validator's ID and their full identification. pub type IdentificationTuple = (::ValidatorId, ::FullIdentification); @@ -214,7 +214,7 @@ impl ProvingTrie { } fn from_nodes(root: T::Hash, nodes: &[Vec]) -> Self { - use substrate_trie::HashDBT; + use sp_trie::HashDBT; let mut memory_db = MemoryDB::default(); for node in nodes { @@ -273,7 +273,7 @@ pub struct Proof { trie_nodes: Vec>, } -impl> support::traits::KeyOwnerProofSystem<(KeyTypeId, D)> +impl> frame_support::traits::KeyOwnerProofSystem<(KeyTypeId, D)> for Module { type Proof = Proof; @@ -310,24 +310,24 @@ impl> support::traits::KeyOwnerProofSystem<(KeyTypeId, #[cfg(test)] mod tests { use super::*; - use primitives::crypto::key_types::DUMMY; - use sr_primitives::{traits::OnInitialize, testing::UintAuthorityId}; + use sp_core::crypto::key_types::DUMMY; + use sp_runtime::{traits::OnInitialize, testing::UintAuthorityId}; use crate::mock::{ NEXT_VALIDATORS, force_new_session, set_next_validators, Test, System, Session, }; - use support::traits::KeyOwnerProofSystem; + use frame_support::traits::KeyOwnerProofSystem; type Historical = Module; - fn new_test_ext() -> runtime_io::TestExternalities { - let mut t = system::GenesisConfig::default().build_storage::().unwrap(); + fn new_test_ext() -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); crate::GenesisConfig:: { keys: NEXT_VALIDATORS.with(|l| l.borrow().iter().cloned().map(|i| (i, UintAuthorityId(i).into())).collect() ), }.assimilate_storage(&mut t).unwrap(); - runtime_io::TestExternalities::new(t) + sp_io::TestExternalities::new(t) } #[test] diff --git a/frame/session/src/lib.rs b/frame/session/src/lib.rs index 0e35ae45a6101eda506b13fd45d428cfe9204ef5..5b3e4e2aeeb2083635e142927338513f40a8ded9 100644 --- a/frame/session/src/lib.rs +++ b/frame/session/src/lib.rs @@ -119,15 +119,15 @@ #![cfg_attr(not(feature = "std"), no_std)] -use rstd::{prelude::*, marker::PhantomData, ops::{Sub, Rem}}; +use sp_std::{prelude::*, marker::PhantomData, ops::{Sub, Rem}}; use codec::Decode; -use sr_primitives::{KeyTypeId, Perbill, RuntimeAppPublic, BoundToRuntimeAppPublic}; -use support::weights::SimpleDispatchInfo; -use sr_primitives::traits::{Convert, Zero, Member, OpaqueKeys}; -use sr_staking_primitives::SessionIndex; -use support::{dispatch::Result, ConsensusEngineId, decl_module, decl_event, decl_storage}; -use support::{ensure, traits::{OnFreeBalanceZero, Get, FindAuthor}, Parameter}; -use system::{self, ensure_signed}; +use sp_runtime::{KeyTypeId, Perbill, RuntimeAppPublic, BoundToRuntimeAppPublic}; +use frame_support::weights::SimpleDispatchInfo; +use sp_runtime::traits::{Convert, Zero, Member, OpaqueKeys}; +use sp_staking::SessionIndex; +use frame_support::{dispatch, ConsensusEngineId, decl_module, decl_event, decl_storage}; +use frame_support::{ensure, traits::{OnFreeBalanceZero, Get, FindAuthor, ValidatorRegistration}, Parameter}; +use frame_system::{self as system, ensure_signed}; #[cfg(test)] mod mock; @@ -307,7 +307,7 @@ impl SessionHandler for Tuple { /// `SessionHandler` for tests that use `UintAuthorityId` as `Keys`. pub struct TestSessionHandler; impl SessionHandler for TestSessionHandler { - const KEY_TYPE_IDS: &'static [KeyTypeId] = &[sr_primitives::key_types::DUMMY]; + const KEY_TYPE_IDS: &'static [KeyTypeId] = &[sp_runtime::key_types::DUMMY]; fn on_genesis_session(_: &[(AId, Ks)]) {} @@ -333,9 +333,15 @@ impl SelectInitialValidators for () { } } -pub trait Trait: system::Trait { +impl ValidatorRegistration for Module { + fn is_registered(id: &T::ValidatorId) -> bool { + Self::load_keys(id).is_some() + } +} + +pub trait Trait: frame_system::Trait { /// The overarching event type. - type Event: From + Into<::Event>; + type Event: From + Into<::Event>; /// A stable ID for a validator. type ValidatorId: Member + Parameter; @@ -477,14 +483,14 @@ decl_module! { /// - One extra DB entry. /// # #[weight = SimpleDispatchInfo::FixedNormal(150_000)] - fn set_keys(origin, keys: T::Keys, proof: Vec) -> Result { + fn set_keys(origin, keys: T::Keys, proof: Vec) -> dispatch::DispatchResult { let who = ensure_signed(origin)?; ensure!(keys.ownership_proof_is_valid(&proof), "invalid ownership proof"); let who = match T::ValidatorIdOf::convert(who) { Some(val_id) => val_id, - None => return Err("no associated validator ID for account."), + None => Err("no associated validator ID for account.")?, }; Self::do_set_keys(&who, keys)?; @@ -619,13 +625,13 @@ impl Module { /// Returns `Ok(true)` if more than `DisabledValidatorsThreshold` validators in current /// session is already disabled. /// If used with the staking module it allows to force a new era in such case. - pub fn disable(c: &T::ValidatorId) -> rstd::result::Result { + pub fn disable(c: &T::ValidatorId) -> sp_std::result::Result { Self::validators().iter().position(|i| i == c).map(Self::disable_index).ok_or(()) } // perform the set_key operation, checking for duplicates. // does not set `Changed`. - fn do_set_keys(who: &T::ValidatorId, keys: T::Keys) -> Result { + fn do_set_keys(who: &T::ValidatorId, keys: T::Keys) -> dispatch::DispatchResult { let old_keys = Self::load_keys(&who); for id in T::Keys::key_ids() { @@ -696,7 +702,7 @@ impl OnFreeBalanceZero for Module { /// Wraps the author-scraping logic for consensus engines that can recover /// the canonical index of an author. This then transforms it into the /// registering account-ID of that session key index. -pub struct FindAccountFromAuthorIndex(rstd::marker::PhantomData<(T, Inner)>); +pub struct FindAccountFromAuthorIndex(sp_std::marker::PhantomData<(T, Inner)>); impl> FindAuthor for FindAccountFromAuthorIndex @@ -714,23 +720,23 @@ impl> FindAuthor #[cfg(test)] mod tests { use super::*; - use support::assert_ok; - use primitives::crypto::key_types::DUMMY; - use sr_primitives::{traits::OnInitialize, testing::UintAuthorityId}; + use frame_support::assert_ok; + use sp_core::crypto::key_types::DUMMY; + use sp_runtime::{traits::OnInitialize, testing::UintAuthorityId}; use mock::{ NEXT_VALIDATORS, SESSION_CHANGED, TEST_SESSION_CHANGED, authorities, force_new_session, set_next_validators, set_session_length, session_changed, Test, Origin, System, Session, reset_before_session_end_called, before_session_end_called, }; - fn new_test_ext() -> runtime_io::TestExternalities { - let mut t = system::GenesisConfig::default().build_storage::().unwrap(); + fn new_test_ext() -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); GenesisConfig:: { keys: NEXT_VALIDATORS.with(|l| l.borrow().iter().cloned().map(|i| (i, UintAuthorityId(i).into())).collect() ), }.assimilate_storage(&mut t).unwrap(); - runtime_io::TestExternalities::new(t) + sp_io::TestExternalities::new(t) } fn initialize_block(block: u64) { diff --git a/frame/session/src/mock.rs b/frame/session/src/mock.rs index cb95a35570bc1e37455446fff6404e825f83c32c..28c84d737447e34fc0a09235a9343b6d2444dbc7 100644 --- a/frame/session/src/mock.rs +++ b/frame/session/src/mock.rs @@ -18,13 +18,13 @@ use super::*; use std::cell::RefCell; -use support::{impl_outer_origin, parameter_types}; -use primitives::{crypto::key_types::DUMMY, H256}; -use sr_primitives::{ +use frame_support::{impl_outer_origin, parameter_types, weights::Weight}; +use sp_core::{crypto::key_types::DUMMY, H256}; +use sp_runtime::{ Perbill, impl_opaque_keys, traits::{BlakeTwo256, IdentityLookup, ConvertInto}, testing::{Header, UintAuthorityId} }; -use sr_staking_primitives::SessionIndex; +use sp_staking::SessionIndex; impl_opaque_keys! { pub struct MockSessionKeys { @@ -39,7 +39,7 @@ impl From for MockSessionKeys { } impl_outer_origin! { - pub enum Origin for Test {} + pub enum Origin for Test where system = frame_system {} } thread_local! { @@ -66,7 +66,7 @@ impl ShouldEndSession for TestShouldEndSession { pub struct TestSessionHandler; impl SessionHandler for TestSessionHandler { - const KEY_TYPE_IDS: &'static [sr_primitives::KeyTypeId] = &[UintAuthorityId::ID]; + const KEY_TYPE_IDS: &'static [sp_runtime::KeyTypeId] = &[UintAuthorityId::ID]; fn on_genesis_session(_validators: &[(u64, T)]) {} fn on_new_session( changed: bool, @@ -152,13 +152,13 @@ pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockWeight: Weight = 1024; pub const MaximumBlockLength: u32 = 2 * 1024; pub const MinimumPeriod: u64 = 5; pub const AvailableBlockRatio: Perbill = Perbill::one(); } -impl system::Trait for Test { +impl frame_system::Trait for Test { type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -174,9 +174,10 @@ impl system::Trait for Test { type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; type Version = (); + type ModuleToIndex = (); } -impl timestamp::Trait for Test { +impl pallet_timestamp::Trait for Test { type Moment = u64; type OnTimestampSet = (); type MinimumPeriod = MinimumPeriod; @@ -204,8 +205,8 @@ impl Trait for Test { #[cfg(feature = "historical")] impl crate::historical::Trait for Test { type FullIdentification = u64; - type FullIdentificationOf = sr_primitives::traits::ConvertInto; + type FullIdentificationOf = sp_runtime::traits::ConvertInto; } -pub type System = system::Module; +pub type System = frame_system::Module; pub type Session = Module; diff --git a/frame/staking/Cargo.toml b/frame/staking/Cargo.toml index 3ad4b68c834f67f6eacfb1ad863633b75932dce9..8cf6d9f80e81e1e147848b3cdc32cc8c5a0b10ac 100644 --- a/frame/staking/Cargo.toml +++ b/frame/staking/Cargo.toml @@ -8,38 +8,40 @@ edition = "2018" serde = { version = "1.0.101", optional = true } safe-mix = { version = "1.0.0", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -substrate-keyring = { path = "../../primitives/keyring", optional = true } -rstd = { package = "sr-std", path = "../../primitives/sr-std", default-features = false } -phragmen = { package = "substrate-phragmen", path = "../../primitives/phragmen", default-features = false } -runtime-io ={ package = "sr-io", path = "../../primitives/sr-io", default-features = false } -sr-primitives = { path = "../../primitives/sr-primitives", default-features = false } -sr-staking-primitives = { path = "../../primitives/sr-staking-primitives", default-features = false } -support = { package = "frame-support", path = "../support", default-features = false } -system = { package = "frame-system", path = "../system", default-features = false } -session = { package = "pallet-session", path = "../session", default-features = false, features = ["historical"] } -authorship = { package = "pallet-authorship", path = "../authorship", default-features = false } +sp-keyring = { version = "2.0.0", optional = true, path = "../../primitives/keyring" } +sp-std = { version = "2.0.0", default-features = false, path = "../../primitives/std" } +sp-phragmen = { version = "2.0.0", default-features = false, path = "../../primitives/phragmen" } +sp-io ={ path = "../../primitives/io", default-features = false } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" } +sp-staking = { version = "2.0.0", default-features = false, path = "../../primitives/staking" } +frame-support = { version = "2.0.0", default-features = false, path = "../support" } +frame-system = { version = "2.0.0", default-features = false, path = "../system" } +pallet-session = { version = "2.0.0", features = ["historical"], path = "../session", default-features = false } +pallet-authorship = { version = "2.0.0", default-features = false, path = "../authorship" } [dev-dependencies] -primitives = { package = "substrate-primitives", path = "../../primitives/core" } -balances = { package = "pallet-balances", path = "../balances" } -timestamp = { package = "pallet-timestamp", path = "../timestamp" } -pallet-staking-reward-curve = { path = "../staking/reward-curve"} +sp-core = { version = "2.0.0", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0", path = "../balances" } +pallet-timestamp = { version = "2.0.0", path = "../timestamp" } +pallet-staking-reward-curve = { version = "2.0.0", path = "../staking/reward-curve" } +substrate-test-utils = { version = "2.0.0", path = "../../test-utils" } [features] equalize = [] +migrate = [] default = ["std", "equalize"] std = [ "serde", "safe-mix/std", - "substrate-keyring", + "sp-keyring", "codec/std", - "rstd/std", - "phragmen/std", - "runtime-io/std", - "support/std", - "sr-primitives/std", - "sr-staking-primitives/std", - "session/std", - "system/std", - "authorship/std", + "sp-std/std", + "sp-phragmen/std", + "sp-io/std", + "frame-support/std", + "sp-runtime/std", + "sp-staking/std", + "pallet-session/std", + "frame-system/std", + "pallet-authorship/std", ] diff --git a/frame/staking/reward-curve/Cargo.toml b/frame/staking/reward-curve/Cargo.toml index 11ce7cefb4caa214da4032e582b86bbb5dbdcf91..0353476a955d1358a77ab4898287c49399661724 100644 --- a/frame/staking/reward-curve/Cargo.toml +++ b/frame/staking/reward-curve/Cargo.toml @@ -8,10 +8,10 @@ edition = "2018" proc-macro = true [dependencies] -syn = { version = "1.0.7", features = [ "full", "visit" ] } +syn = { version = "1.0.7", features = ["full", "visit"] } quote = "1.0" proc-macro2 = "1.0.6" proc-macro-crate = "0.1.4" [dev-dependencies] -sr-primitives = { path = "../../../primitives/sr-primitives" } +sp-runtime = { version = "2.0.0", path = "../../../primitives/runtime" } diff --git a/frame/staking/reward-curve/src/lib.rs b/frame/staking/reward-curve/src/lib.rs index 3bde53b55fe0689496ce4b1851a47f431646d9a5..89a1980d19fd92a72afd588f9a38f25e9d3dbc8d 100644 --- a/frame/staking/reward-curve/src/lib.rs +++ b/frame/staking/reward-curve/src/lib.rs @@ -42,7 +42,7 @@ use syn::parse::{Parse, ParseStream}; /// /// ``` /// # fn main() {} -/// use sr_primitives::curve::PiecewiseLinear; +/// use sp_runtime::curve::PiecewiseLinear; /// /// pallet_staking_reward_curve::build! { /// const I_NPOS: PiecewiseLinear<'static> = curve!( @@ -64,10 +64,10 @@ pub fn build(input: TokenStream) -> TokenStream { let declaration = generate_piecewise_linear(points); let test_module = generate_test_module(&input); - let imports = match crate_name("sr-primitives") { - Ok(sr_primitives) => { - let ident = syn::Ident::new(&sr_primitives, Span::call_site()); - quote!( extern crate #ident as _sr_primitives; ) + let imports = match crate_name("sp-runtime") { + Ok(sp_runtime) => { + let ident = syn::Ident::new(&sp_runtime, Span::call_site()); + quote!( extern crate #ident as _sp_runtime; ) }, Err(e) => syn::Error::new(Span::call_site(), &e).to_compile_error(), }; @@ -345,16 +345,16 @@ fn generate_piecewise_linear(points: Vec<(u32, u32)>) -> TokenStream2 { points_tokens.extend(quote!( ( - _sr_primitives::Perbill::from_parts(#x_perbill), - _sr_primitives::Perbill::from_parts(#y_perbill), + _sp_runtime::Perbill::from_parts(#x_perbill), + _sp_runtime::Perbill::from_parts(#y_perbill), ), )); } quote!( - _sr_primitives::curve::PiecewiseLinear::<'static> { + _sp_runtime::curve::PiecewiseLinear::<'static> { points: & [ #points_tokens ], - maximum: _sr_primitives::Perbill::from_parts(#max), + maximum: _sp_runtime::Perbill::from_parts(#max), } ) } diff --git a/frame/staking/reward-curve/tests/test.rs b/frame/staking/reward-curve/tests/test.rs index 4ed2def3fec8ebf1d07a1f3840ba0698723d2c67..399bf7b9a7f4e21dbfe62390858547d26c6dd05e 100644 --- a/frame/staking/reward-curve/tests/test.rs +++ b/frame/staking/reward-curve/tests/test.rs @@ -19,7 +19,7 @@ mod test_small_falloff { pallet_staking_reward_curve::build! { - const REWARD_CURVE: sr_primitives::curve::PiecewiseLinear<'static> = curve!( + const REWARD_CURVE: sp_runtime::curve::PiecewiseLinear<'static> = curve!( min_inflation: 0_020_000, max_inflation: 0_200_000, ideal_stake: 0_600_000, @@ -32,7 +32,7 @@ mod test_small_falloff { mod test_big_falloff { pallet_staking_reward_curve::build! { - const REWARD_CURVE: sr_primitives::curve::PiecewiseLinear<'static> = curve!( + const REWARD_CURVE: sp_runtime::curve::PiecewiseLinear<'static> = curve!( min_inflation: 0_100_000, max_inflation: 0_400_000, ideal_stake: 0_400_000, diff --git a/frame/staking/src/inflation.rs b/frame/staking/src/inflation.rs index 914d2ee93a4a43b3d54243d01db31f4e01dc1c4e..902cc0a271800fd0400f79b29780c0548bbec113 100644 --- a/frame/staking/src/inflation.rs +++ b/frame/staking/src/inflation.rs @@ -19,7 +19,7 @@ //! The staking rate in NPoS is the total amount of tokens staked by nominators and validators, //! divided by the total token supply. -use sr_primitives::{Perbill, traits::SimpleArithmetic, curve::PiecewiseLinear}; +use sp_runtime::{Perbill, traits::SimpleArithmetic, curve::PiecewiseLinear}; /// The total payout to all validators (and their nominators) per era. /// @@ -47,7 +47,7 @@ pub fn compute_total_payout( #[cfg(test)] mod test { - use sr_primitives::curve::PiecewiseLinear; + use sp_runtime::curve::PiecewiseLinear; pallet_staking_reward_curve::build! { const I_NPOS: PiecewiseLinear<'static> = curve!( diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index 29aeb7901c47b2efebe5fcc2975f50fbbce0cdda..387c2f53e3123a08f9fcbd0fde9ab42dd306db02 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -108,6 +108,8 @@ //! determined, a value is deducted from the balance of the validator and all the nominators who //! voted for this validator (values are deducted from the _stash_ account of the slashed entity). //! +//! Slashing logic is further described in the documentation of the `slashing` module. +//! //! Similar to slashing, rewards are also shared among a validator and its associated nominators. //! Yet, the reward funds are not always transferred to the stash account and can be configured. //! See [Reward Calculation](#reward-calculation) for more details. @@ -136,8 +138,8 @@ //! ### Example: Rewarding a validator by id. //! //! ``` -//! use support::{decl_module, dispatch::Result}; -//! use system::ensure_signed; +//! use frame_support::{decl_module, dispatch}; +//! use frame_system::{self as system, ensure_signed}; //! use pallet_staking::{self as staking}; //! //! pub trait Trait: staking::Trait {} @@ -145,7 +147,7 @@ //! decl_module! { //! pub struct Module for enum Call where origin: T::Origin { //! /// Reward a validator. -//! pub fn reward_myself(origin) -> Result { +//! pub fn reward_myself(origin) -> dispatch::DispatchResult { //! let reported = ensure_signed(origin)?; //! >::reward_by_ids(vec![(reported, 10)]); //! Ok(()) @@ -171,7 +173,7 @@ //! calculated using the era duration and the staking rate (the total amount of tokens staked by //! nominators and validators, divided by the total token supply). It aims to incentivise toward a //! defined staking rate. The full specification can be found -//! [here](https://research.web3.foundation/en/latest/polkadot/Token%20Economics/#inflation-model). +//! [here](https://research.web3.foundation/en/latest/polkadot/Token%20Economics.html#inflation-model). //! //! Total reward is split among validators and their nominators depending on the number of points //! they received during the era. Points are added to a validator using @@ -179,13 +181,13 @@ //! [`reward_by_indices`](./enum.Call.html#variant.reward_by_indices). //! //! [`Module`](./struct.Module.html) implements -//! [`authorship::EventHandler`](../pallet_authorship/trait.EventHandler.html) to add reward points +//! [`pallet_authorship::EventHandler`](../pallet_authorship/trait.EventHandler.html) to add reward points //! to block producer and block producer of referenced uncles. //! //! The validator and its nominator split their reward as following: //! //! The validator can declare an amount, named -//! [`validator_payment`](./struct.ValidatorPrefs.html#structfield.validator_payment), that does not +//! [`commission`](./struct.ValidatorPrefs.html#structfield.commission), that does not //! get shared with the nominators at each reward payout through its //! [`ValidatorPrefs`](./struct.ValidatorPrefs.html). This value gets deducted from the total reward //! that is paid to the validator and its nominators. The remaining portion is split among the @@ -248,37 +250,40 @@ mod mock; #[cfg(test)] mod tests; +mod migration; +mod slashing; pub mod inflation; -use rstd::{prelude::*, result}; +use sp_std::{prelude::*, result}; use codec::{HasCompact, Encode, Decode}; -use support::{ - decl_module, decl_event, decl_storage, ensure, +use frame_support::{ + decl_module, decl_event, decl_storage, ensure, decl_error, weights::SimpleDispatchInfo, traits::{ Currency, OnFreeBalanceZero, LockIdentifier, LockableCurrency, WithdrawReasons, OnUnbalanced, Imbalance, Get, Time } }; -use session::{historical::OnSessionEnding, SelectInitialValidators}; -use sr_primitives::{ +use pallet_session::{historical::OnSessionEnding, SelectInitialValidators}; +use sp_runtime::{ Perbill, RuntimeDebug, curve::PiecewiseLinear, traits::{ Convert, Zero, One, StaticLookup, CheckedSub, Saturating, Bounded, SaturatedConversion, + SimpleArithmetic, EnsureOrigin, } }; -use sr_staking_primitives::{ +use sp_staking::{ SessionIndex, offence::{OnOffenceHandler, OffenceDetails, Offence, ReportOffence}, }; #[cfg(feature = "std")] -use sr_primitives::{Serialize, Deserialize}; -use system::{ensure_signed, ensure_root}; +use sp_runtime::{Serialize, Deserialize}; +use frame_system::{self as system, ensure_signed, ensure_root}; -use phragmen::{elect, equalize, build_support_map, ExtendedBalance, PhragmenStakedAssignment}; +use sp_phragmen::{ExtendedBalance, PhragmenStakedAssignment}; const DEFAULT_MINIMUM_VALIDATOR_COUNT: u32 = 4; const MAX_NOMINATIONS: usize = 16; @@ -342,19 +347,19 @@ impl Default for RewardDestination { } } -/// Preference of what happens on a slash event. +/// Preference of what happens regarding validation. #[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] -pub struct ValidatorPrefs { +pub struct ValidatorPrefs { /// Reward that validator takes up-front; only the rest is split between themselves and /// nominators. #[codec(compact)] - pub validator_payment: Balance, + pub commission: Perbill, } -impl Default for ValidatorPrefs { +impl Default for ValidatorPrefs { fn default() -> Self { ValidatorPrefs { - validator_payment: Default::default(), + commission: Default::default(), } } } @@ -406,6 +411,74 @@ impl< .collect(); Self { total, active: self.active, stash: self.stash, unlocking } } + +} + +impl StakingLedger where + Balance: SimpleArithmetic + Saturating + Copy, +{ + /// Slash the validator for a given amount of balance. This can grow the value + /// of the slash in the case that the validator has less than `minimum_balance` + /// active funds. Returns the amount of funds actually slashed. + /// + /// Slashes from `active` funds first, and then `unlocking`, starting with the + /// chunks that are closest to unlocking. + fn slash( + &mut self, + mut value: Balance, + minimum_balance: Balance, + ) -> Balance { + let pre_total = self.total; + let total = &mut self.total; + let active = &mut self.active; + + let slash_out_of = | + total_remaining: &mut Balance, + target: &mut Balance, + value: &mut Balance, + | { + let mut slash_from_target = (*value).min(*target); + + if !slash_from_target.is_zero() { + *target -= slash_from_target; + + // don't leave a dust balance in the staking system. + if *target <= minimum_balance { + slash_from_target += *target; + *value += sp_std::mem::replace(target, Zero::zero()); + } + + *total_remaining = total_remaining.saturating_sub(slash_from_target); + *value -= slash_from_target; + } + }; + + slash_out_of(total, active, &mut value); + + let i = self.unlocking.iter_mut() + .map(|chunk| { + slash_out_of(total, &mut chunk.value, &mut value); + chunk.value + }) + .take_while(|value| value.is_zero()) // take all fully-consumed chunks out. + .count(); + + // kill all drained chunks. + let _ = self.unlocking.drain(..i); + + pre_total.saturating_sub(*total) + } +} + +/// A record of the nominations made by a specific account. +#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] +pub struct Nominations { + /// The targets of nomination. + pub targets: Vec, + /// The era the nominations were submitted. + pub submitted_in: EraIndex, + /// Whether the nominations have been suppressed. + pub suppressed: bool, } /// The amount of exposure (to slashing) than an individual nominator has. @@ -431,26 +504,34 @@ pub struct Exposure { pub others: Vec>, } -/// A slashing event occurred, slashing a validator for a given amount of balance. -#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Default, RuntimeDebug)] -pub struct SlashJournalEntry { - who: AccountId, - amount: Balance, - own_slash: Balance, // the amount of `who`'s own exposure that was slashed +/// A pending slash record. The value of the slash has been computed but not applied yet, +/// rather deferred for several eras. +#[derive(Encode, Decode, Default, RuntimeDebug)] +pub struct UnappliedSlash { + /// The stash ID of the offending validator. + validator: AccountId, + /// The validator's own slash. + own: Balance, + /// All other slashed stakers and amounts. + others: Vec<(AccountId, Balance)>, + /// Reporters of the offence; bounty payout recipients. + reporters: Vec, + /// The amount of payout. + payout: Balance, } pub type BalanceOf = - <::Currency as Currency<::AccountId>>::Balance; + <::Currency as Currency<::AccountId>>::Balance; type PositiveImbalanceOf = - <::Currency as Currency<::AccountId>>::PositiveImbalance; + <::Currency as Currency<::AccountId>>::PositiveImbalance; type NegativeImbalanceOf = - <::Currency as Currency<::AccountId>>::NegativeImbalance; -type MomentOf= <::Time as Time>::Moment; + <::Currency as Currency<::AccountId>>::NegativeImbalance; +type MomentOf = <::Time as Time>::Moment; /// Means for interacting with a specialized version of the `session` trait. /// -/// This is needed because `Staking` sets the `ValidatorIdOf` of the `session::Trait` -pub trait SessionInterface: system::Trait { +/// This is needed because `Staking` sets the `ValidatorIdOf` of the `pallet_session::Trait` +pub trait SessionInterface: frame_system::Trait { /// Disable a given validator by stash ID. /// /// Returns `true` if new era should be forced at the end of this session. @@ -463,31 +544,31 @@ pub trait SessionInterface: system::Trait { fn prune_historical_up_to(up_to: SessionIndex); } -impl SessionInterface<::AccountId> for T where - T: session::Trait::AccountId>, - T: session::historical::Trait< - FullIdentification = Exposure<::AccountId, BalanceOf>, +impl SessionInterface<::AccountId> for T where + T: pallet_session::Trait::AccountId>, + T: pallet_session::historical::Trait< + FullIdentification = Exposure<::AccountId, BalanceOf>, FullIdentificationOf = ExposureOf, >, - T::SessionHandler: session::SessionHandler<::AccountId>, - T::OnSessionEnding: session::OnSessionEnding<::AccountId>, - T::SelectInitialValidators: session::SelectInitialValidators<::AccountId>, - T::ValidatorIdOf: Convert<::AccountId, Option<::AccountId>> + T::SessionHandler: pallet_session::SessionHandler<::AccountId>, + T::OnSessionEnding: pallet_session::OnSessionEnding<::AccountId>, + T::SelectInitialValidators: pallet_session::SelectInitialValidators<::AccountId>, + T::ValidatorIdOf: Convert<::AccountId, Option<::AccountId>> { - fn disable_validator(validator: &::AccountId) -> Result { - >::disable(validator) + fn disable_validator(validator: &::AccountId) -> Result { + >::disable(validator) } - fn validators() -> Vec<::AccountId> { - >::validators() + fn validators() -> Vec<::AccountId> { + >::validators() } fn prune_historical_up_to(up_to: SessionIndex) { - >::prune_up_to(up_to); + >::prune_up_to(up_to); } } -pub trait Trait: system::Trait { +pub trait Trait: frame_system::Trait { /// The staking balance. type Currency: LockableCurrency; @@ -505,7 +586,7 @@ pub trait Trait: system::Trait { type RewardRemainder: OnUnbalanced>; /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// Handler for the unbalanced reduction when slashing a staker. type Slash: OnUnbalanced>; @@ -519,6 +600,14 @@ pub trait Trait: system::Trait { /// Number of eras that staked funds must remain bonded for. type BondingDuration: Get; + /// Number of eras that slashes are deferred by, after computation. This + /// should be less than the bonding duration. Set to 0 if slashes should be + /// applied immediately, without opportunity for intervention. + type SlashDeferDuration: Get; + + /// The origin which can cancel a deferred slash. Root can always do this. + type SlashCancelOrigin: EnsureOrigin; + /// Interface for interacting with a session module. type SessionInterface: self::SessionInterface; @@ -568,10 +657,13 @@ decl_storage! { pub Payee get(fn payee): map T::AccountId => RewardDestination; /// The map from (wannabe) validator stash key to the preferences of that validator. - pub Validators get(fn validators): linked_map T::AccountId => ValidatorPrefs>; + pub Validators get(fn validators): linked_map T::AccountId => ValidatorPrefs; /// The map from nominator stash key to the set of stash keys of all validators to nominate. - pub Nominators get(fn nominators): linked_map T::AccountId => Vec; + /// + /// NOTE: is private so that we can ensure upgraded before all typical accesses. + /// Direct storage APIs can still bypass this protection. + Nominators get(fn nominators): linked_map T::AccountId => Option>; /// Nominators for a particular account that is in action right now. You can't iterate /// through validators here, but you can find them in the Session module. @@ -609,12 +701,38 @@ decl_storage! { /// The rest of the slashed value is handled by the `Slash`. pub SlashRewardFraction get(fn slash_reward_fraction) config(): Perbill; + /// The amount of currency given to reporters of a slash event which was + /// canceled by extraordinary circumstances (e.g. governance). + pub CanceledSlashPayout get(fn canceled_payout) config(): BalanceOf; + + /// All unapplied slashes that are queued for later. + pub UnappliedSlashes: map EraIndex => Vec>>; + /// A mapping from still-bonded eras to the first session index of that era. BondedEras: Vec<(EraIndex, SessionIndex)>; - /// All slashes that have occurred in a given era. - EraSlashJournal get(fn era_slash_journal): - map EraIndex => Vec>>; + /// All slashing events on validators, mapped by era to the highest slash proportion + /// and slash value of the era. + ValidatorSlashInEra: + double_map EraIndex, twox_128(T::AccountId) => Option<(Perbill, BalanceOf)>; + + /// All slashing events on nominators, mapped by era to the highest slash value of the era. + NominatorSlashInEra: + double_map EraIndex, twox_128(T::AccountId) => Option>; + + /// Slashing spans for stash accounts. + SlashingSpans: map T::AccountId => Option; + + /// Records information about the maximum slash of a stash within a slashing span, + /// as well as how much reward has been paid out. + SpanSlash: + map (T::AccountId, slashing::SpanIndex) => slashing::SpanRecord>; + + /// The earliest era for which we have a pending, unapplied slash. + EarliestUnappliedSlash: Option; + + /// The version of storage for upgrade. + StorageVersion: u32; } add_extra_genesis { config(stakers): @@ -646,12 +764,14 @@ decl_storage! { }, _ => Ok(()) }; } + + StorageVersion::put(migration::CURRENT_VERSION); }); } } decl_event!( - pub enum Event where Balance = BalanceOf, ::AccountId { + pub enum Event where Balance = BalanceOf, ::AccountId { /// All validators have been rewarded by the first balance; the second is the remainder /// from the maximum amount of reward. Reward(Balance, Balance), @@ -663,6 +783,32 @@ decl_event!( } ); +decl_error! { + /// Error for the stacking module. + pub enum Error for Module { + /// Not a controller account. + NotController, + /// Not a stash account. + NotStash, + /// Stash is already bonded. + AlreadyBonded, + /// Controller is already paired. + AlreadyPaired, + /// Should be the root origin or the `T::SlashCancelOrigin`. + BadOrigin, + /// Targets cannot be empty. + EmptyTargets, + /// Duplicate index. + DuplicateIndex, + /// Slash record index out of bounds. + InvalidSlashIndex, + /// Can not bond with value less than minimum balance. + InsufficientValue, + /// Can not schedule more unlock chunks. + NoMoreChunks, + } +} + decl_module! { pub struct Module for enum Call where origin: T::Origin { /// Number of sessions per era. @@ -671,8 +817,14 @@ decl_module! { /// Number of eras that staked funds must remain bonded for. const BondingDuration: EraIndex = T::BondingDuration::get(); + type Error = Error; + fn deposit_event() = default; + fn on_initialize() { + Self::ensure_storage_upgraded(); + } + fn on_finalize() { // Set the start of the first era. if !>::exists() { @@ -704,18 +856,18 @@ decl_module! { let stash = ensure_signed(origin)?; if >::exists(&stash) { - return Err("stash already bonded") + Err(Error::::AlreadyBonded)? } let controller = T::Lookup::lookup(controller)?; if >::exists(&controller) { - return Err("controller already paired") + Err(Error::::AlreadyPaired)? } // reject a bond which is considered to be _dust_. if value < T::Currency::minimum_balance() { - return Err("can not bond with value less than minimum balance") + Err(Error::::InsufficientValue)? } // You're auto-bonded forever, here. We might improve this by only bonding when @@ -747,8 +899,8 @@ decl_module! { fn bond_extra(origin, #[compact] max_additional: BalanceOf) { let stash = ensure_signed(origin)?; - let controller = Self::bonded(&stash).ok_or("not a stash")?; - let mut ledger = Self::ledger(&controller).ok_or("not a controller")?; + let controller = Self::bonded(&stash).ok_or(Error::::NotStash)?; + let mut ledger = Self::ledger(&controller).ok_or(Error::::NotController)?; let stash_balance = T::Currency::free_balance(&stash); @@ -786,10 +938,10 @@ decl_module! { #[weight = SimpleDispatchInfo::FixedNormal(400_000)] fn unbond(origin, #[compact] value: BalanceOf) { let controller = ensure_signed(origin)?; - let mut ledger = Self::ledger(&controller).ok_or("not a controller")?; + let mut ledger = Self::ledger(&controller).ok_or(Error::::NotController)?; ensure!( ledger.unlocking.len() < MAX_UNLOCKING_CHUNKS, - "can not schedule more unlock chunks" + Error::::NoMoreChunks, ); let mut value = value.min(ledger.active); @@ -828,7 +980,7 @@ decl_module! { #[weight = SimpleDispatchInfo::FixedNormal(400_000)] fn withdraw_unbonded(origin) { let controller = ensure_signed(origin)?; - let ledger = Self::ledger(&controller).ok_or("not a controller")?; + let ledger = Self::ledger(&controller).ok_or(Error::::NotController)?; let ledger = ledger.consolidate_unlocked(Self::current_era()); if ledger.unlocking.is_empty() && ledger.active.is_zero() { @@ -858,9 +1010,11 @@ decl_module! { /// - Writes are limited to the `origin` account key. /// # #[weight = SimpleDispatchInfo::FixedNormal(750_000)] - fn validate(origin, prefs: ValidatorPrefs>) { + fn validate(origin, prefs: ValidatorPrefs) { + Self::ensure_storage_upgraded(); + let controller = ensure_signed(origin)?; - let ledger = Self::ledger(&controller).ok_or("not a controller")?; + let ledger = Self::ledger(&controller).ok_or(Error::::NotController)?; let stash = &ledger.stash; >::remove(stash); >::insert(stash, prefs); @@ -879,17 +1033,25 @@ decl_module! { /// # #[weight = SimpleDispatchInfo::FixedNormal(750_000)] fn nominate(origin, targets: Vec<::Source>) { + Self::ensure_storage_upgraded(); + let controller = ensure_signed(origin)?; - let ledger = Self::ledger(&controller).ok_or("not a controller")?; + let ledger = Self::ledger(&controller).ok_or(Error::::NotController)?; let stash = &ledger.stash; - ensure!(!targets.is_empty(), "targets cannot be empty"); + ensure!(!targets.is_empty(), Error::::EmptyTargets); let targets = targets.into_iter() .take(MAX_NOMINATIONS) .map(|t| T::Lookup::lookup(t)) .collect::, _>>()?; + let nominations = Nominations { + targets, + submitted_in: Self::current_era(), + suppressed: false, + }; + >::remove(stash); - >::insert(stash, targets); + >::insert(stash, &nominations); } /// Declare no desire to either validate or nominate. @@ -906,10 +1068,8 @@ decl_module! { #[weight = SimpleDispatchInfo::FixedNormal(500_000)] fn chill(origin) { let controller = ensure_signed(origin)?; - let ledger = Self::ledger(&controller).ok_or("not a controller")?; - let stash = &ledger.stash; - >::remove(stash); - >::remove(stash); + let ledger = Self::ledger(&controller).ok_or(Error::::NotController)?; + Self::chill_stash(&ledger.stash); } /// (Re-)set the payment target for a controller. @@ -926,7 +1086,7 @@ decl_module! { #[weight = SimpleDispatchInfo::FixedNormal(500_000)] fn set_payee(origin, payee: RewardDestination) { let controller = ensure_signed(origin)?; - let ledger = Self::ledger(&controller).ok_or("not a controller")?; + let ledger = Self::ledger(&controller).ok_or(Error::::NotController)?; let stash = &ledger.stash; >::insert(stash, payee); } @@ -945,10 +1105,10 @@ decl_module! { #[weight = SimpleDispatchInfo::FixedNormal(750_000)] fn set_controller(origin, controller: ::Source) { let stash = ensure_signed(origin)?; - let old_controller = Self::bonded(&stash).ok_or("not a stash")?; + let old_controller = Self::bonded(&stash).ok_or(Error::::NotStash)?; let controller = T::Lookup::lookup(controller)?; if >::exists(&controller) { - return Err("controller already paired") + Err(Error::::AlreadyPaired)? } if controller != old_controller { >::insert(&stash, &controller); @@ -1018,14 +1178,48 @@ decl_module! { ensure_root(origin)?; ForceEra::put(Forcing::ForceAlways); } + + /// Cancel enactment of a deferred slash. Can be called by either the root origin or + /// the `T::SlashCancelOrigin`. + /// passing the era and indices of the slashes for that era to kill. + /// + /// # + /// - One storage write. + /// # + #[weight = SimpleDispatchInfo::FreeOperational] + fn cancel_deferred_slash(origin, era: EraIndex, slash_indices: Vec) { + T::SlashCancelOrigin::try_origin(origin) + .map(|_| ()) + .or_else(ensure_root) + .map_err(|_| Error::::BadOrigin)?; + + let mut slash_indices = slash_indices; + slash_indices.sort_unstable(); + let mut unapplied = ::UnappliedSlashes::get(&era); + + for (removed, index) in slash_indices.into_iter().enumerate() { + let index = index as usize; + + // if `index` is not duplicate, `removed` must be <= index. + ensure!(removed <= index, Error::::DuplicateIndex); + + // all prior removals were from before this index, since the + // list is sorted. + let index = index - removed; + ensure!(index < unapplied.len(), Error::::InvalidSlashIndex); + + unapplied.remove(index); + } + + ::UnappliedSlashes::insert(&era, &unapplied); + } } } impl Module { // PUBLIC IMMUTABLES - /// The total balance that can be slashed from a validator controller account as of - /// right now. + /// The total balance that can be slashed from a stash account as of right now. pub fn slashable_balance_of(stash: &T::AccountId) -> BalanceOf { Self::bonded(stash).and_then(Self::ledger).map(|l| l.active).unwrap_or_default() } @@ -1048,67 +1242,15 @@ impl Module { >::insert(controller, ledger); } - /// Slash a given validator by a specific amount with given (historical) exposure. - /// - /// Removes the slash from the validator's balance by preference, - /// and reduces the nominators' balance if needed. - /// - /// Returns the resulting `NegativeImbalance` to allow distributing the slashed amount and - /// pushes an entry onto the slash journal. - fn slash_validator( - stash: &T::AccountId, - slash: BalanceOf, - exposure: &Exposure>, - journal: &mut Vec>>, - ) -> NegativeImbalanceOf { - // The amount we are actually going to slash (can't be bigger than the validator's total - // exposure) - let slash = slash.min(exposure.total); - - // limit what we'll slash of the stash's own to only what's in - // the exposure. - // - // note: this is fine only because we limit reports of the current era. - // otherwise, these funds may have already been slashed due to something - // reported from a prior era. - let already_slashed_own = journal.iter() - .filter(|entry| &entry.who == stash) - .map(|entry| entry.own_slash) - .fold(>::zero(), |a, c| a.saturating_add(c)); - - let own_remaining = exposure.own.saturating_sub(already_slashed_own); - - // The amount we'll slash from the validator's stash directly. - let own_slash = own_remaining.min(slash); - let (mut imbalance, missing) = T::Currency::slash(stash, own_slash); - let own_slash = own_slash - missing; - // The amount remaining that we can't slash from the validator, - // that must be taken from the nominators. - let rest_slash = slash - own_slash; - if !rest_slash.is_zero() { - // The total to be slashed from the nominators. - let total = exposure.total - exposure.own; - if !total.is_zero() { - for i in exposure.others.iter() { - let per_u64 = Perbill::from_rational_approximation(i.value, total); - // best effort - not much that can be done on fail. - imbalance.subsume(T::Currency::slash(&i.who, per_u64 * rest_slash).0) - } - } - } - - journal.push(SlashJournalEntry { - who: stash.clone(), - own_slash: own_slash.clone(), - amount: slash, - }); - - // trigger the event - Self::deposit_event( - RawEvent::Slash(stash.clone(), slash) - ); + /// Chill a stash account. + fn chill_stash(stash: &T::AccountId) { + >::remove(stash); + >::remove(stash); + } - imbalance + /// Ensures storage is upgraded to most recent necessary state. + fn ensure_storage_upgraded() { + migration::perform_migrations::(); } /// Actually make a payment to a staker. This uses the currency's reward function @@ -1138,8 +1280,8 @@ impl Module { /// nominators' balance, pro-rata based on their exposure, after having removed the validator's /// pre-payout cut. fn reward_validator(stash: &T::AccountId, reward: BalanceOf) -> PositiveImbalanceOf { - let off_the_table = reward.min(Self::validators(stash).validator_payment); - let reward = reward - off_the_table; + let off_the_table = Self::validators(stash).commission * reward; + let reward = reward.saturating_sub(off_the_table); let mut imbalance = >::zero(); let validator_cut = if reward.is_zero() { Zero::zero() @@ -1190,7 +1332,7 @@ impl Module { let points = CurrentEraPointsEarned::take(); let now = T::Time::now(); let previous_era_start = >::mutate(|v| { - rstd::mem::replace(v, now) + sp_std::mem::replace(v, now) }); let era_duration = now - previous_era_start; if !era_duration.is_zero() { @@ -1229,41 +1371,61 @@ impl Module { // Increment current era. let current_era = CurrentEra::mutate(|s| { *s += 1; *s }); - // prune journal for last era. - >::remove(current_era - 1); - CurrentEraStartSessionIndex::mutate(|v| { *v = start_session_index; }); let bonding_duration = T::BondingDuration::get(); - if current_era > bonding_duration { - let first_kept = current_era - bonding_duration; - BondedEras::mutate(|bonded| { - bonded.push((current_era, start_session_index)); + BondedEras::mutate(|bonded| { + bonded.push((current_era, start_session_index)); + + if current_era > bonding_duration { + let first_kept = current_era - bonding_duration; // prune out everything that's from before the first-kept index. let n_to_prune = bonded.iter() .take_while(|&&(era_idx, _)| era_idx < first_kept) .count(); - bonded.drain(..n_to_prune); + // kill slashing metadata. + for (pruned_era, _) in bonded.drain(..n_to_prune) { + slashing::clear_era_metadata::(pruned_era); + } if let Some(&(_, first_session)) = bonded.first() { T::SessionInterface::prune_historical_up_to(first_session); } - }) - } + } + }); // Reassign all Stakers. let (_slot_stake, maybe_new_validators) = Self::select_validators(); + Self::apply_unapplied_slashes(current_era); maybe_new_validators } + /// Apply previously-unapplied slashes on the beginning of a new era, after a delay. + fn apply_unapplied_slashes(current_era: EraIndex) { + let slash_defer_duration = T::SlashDeferDuration::get(); + ::EarliestUnappliedSlash::mutate(|earliest| if let Some(ref mut earliest) = earliest { + let keep_from = current_era.saturating_sub(slash_defer_duration); + for era in (*earliest)..keep_from { + let era_slashes = ::UnappliedSlashes::take(&era); + for slash in era_slashes { + slashing::apply_slash::(slash); + } + } + + *earliest = (*earliest).max(keep_from) + }) + } + /// Select a new validator set from the assembled stakers and their role preferences. /// /// Returns the new `SlotStake` value and a set of newly selected _stash_ IDs. + /// + /// Assumes storage is coherent with the declaration. fn select_validators() -> (BalanceOf, Option>) { let mut all_nominators: Vec<(T::AccountId, Vec)> = Vec::new(); let all_validator_candidates_iter = >::enumerate(); @@ -1272,9 +1434,24 @@ impl Module { all_nominators.push(self_vote); who }).collect::>(); - all_nominators.extend(>::enumerate()); - let maybe_phragmen_result = elect::<_, _, _, T::CurrencyToVote>( + let nominator_votes = >::enumerate().map(|(nominator, nominations)| { + let Nominations { submitted_in, mut targets, suppressed: _ } = nominations; + + // Filter out nomination targets which were nominated before the most recent + // slashing span. + targets.retain(|stash| { + ::SlashingSpans::get(&stash).map_or( + true, + |spans| submitted_in >= spans.last_start(), + ) + }); + + (nominator, targets) + }); + all_nominators.extend(nominator_votes); + + let maybe_phragmen_result = sp_phragmen::elect::<_, _, _, T::CurrencyToVote>( Self::validator_count() as usize, Self::minimum_validator_count().max(1) as usize, all_validators, @@ -1293,7 +1470,7 @@ impl Module { let to_balance = |e: ExtendedBalance| >>::convert(e); - let mut supports = build_support_map::<_, _, _, T::CurrencyToVote>( + let mut supports = sp_phragmen::build_support_map::<_, _, _, T::CurrencyToVote>( &elected_stashes, &assignments, Self::slashable_balance_of, @@ -1324,7 +1501,7 @@ impl Module { let tolerance = 0_u128; let iterations = 2_usize; - equalize::<_, _, T::CurrencyToVote, _>( + sp_phragmen::equalize::<_, _, T::CurrencyToVote, _>( staked_assignments, &mut supports, tolerance, @@ -1384,6 +1561,8 @@ impl Module { /// Remove all associated data of a stash account from the staking system. /// + /// Assumes storage is upgraded before calling. + /// /// This is called : /// - Immediately when an account's balance falls below existential deposit. /// - after a `withdraw_unbond()` call that frees all of a stash's bonded balance. @@ -1394,6 +1573,8 @@ impl Module { >::remove(stash); >::remove(stash); >::remove(stash); + + slashing::clear_stash_metadata::(stash); } /// Add reward points to validators using their stash account ID. @@ -1426,7 +1607,6 @@ impl Module { /// For each element in the iterator the given number of points in u32 is added to the /// validator, thus duplicates are handled. pub fn reward_by_indices(validators_points: impl IntoIterator) { - // TODO: This can be optimised once #3302 is implemented. let current_elected_len = >::current_elected().len() as u32; CurrentEraPointsEarned::mutate(|rewards| { @@ -1447,8 +1627,9 @@ impl Module { } } -impl session::OnSessionEnding for Module { +impl pallet_session::OnSessionEnding for Module { fn on_session_ending(_ending: SessionIndex, start_session: SessionIndex) -> Option> { + Self::ensure_storage_upgraded(); Self::new_session(start_session - 1).map(|(new, _old)| new) } } @@ -1457,12 +1638,14 @@ impl OnSessionEnding fn on_session_ending(_ending: SessionIndex, start_session: SessionIndex) -> Option<(Vec, Vec<(T::AccountId, Exposure>)>)> { + Self::ensure_storage_upgraded(); Self::new_session(start_session - 1) } } impl OnFreeBalanceZero for Module { fn on_free_balance_zero(stash: &T::AccountId) { + Self::ensure_storage_upgraded(); Self::kill_stash(stash); } } @@ -1471,13 +1654,13 @@ impl OnFreeBalanceZero for Module { /// * 20 points to the block producer for producing a (non-uncle) block in the relay chain, /// * 2 points to the block producer for each reference to a previously unreferenced uncle, and /// * 1 point to the producer of each referenced uncle block. -impl authorship::EventHandler for Module { +impl pallet_authorship::EventHandler for Module { fn note_author(author: T::AccountId) { Self::reward_by_ids(vec![(author, 20)]); } fn note_uncle(author: T::AccountId, _age: T::BlockNumber) { Self::reward_by_ids(vec![ - (>::author(), 2), + (>::author(), 2), (author, 1) ]) } @@ -1485,7 +1668,7 @@ impl authorship::EventHandler(rstd::marker::PhantomData); +pub struct StashOf(sp_std::marker::PhantomData); impl Convert> for StashOf { fn convert(controller: T::AccountId) -> Option { @@ -1495,7 +1678,7 @@ impl Convert> for StashOf { /// A typed conversion from stash account ID to the current exposure of nominators /// on that account. -pub struct ExposureOf(rstd::marker::PhantomData); +pub struct ExposureOf(sp_std::marker::PhantomData); impl Convert>>> for ExposureOf @@ -1512,26 +1695,51 @@ impl SelectInitialValidators for Module { } /// This is intended to be used with `FilterHistoricalOffences`. -impl OnOffenceHandler> for Module where - T: session::Trait::AccountId>, - T: session::historical::Trait< - FullIdentification = Exposure<::AccountId, BalanceOf>, +impl OnOffenceHandler> for Module where + T: pallet_session::Trait::AccountId>, + T: pallet_session::historical::Trait< + FullIdentification = Exposure<::AccountId, BalanceOf>, FullIdentificationOf = ExposureOf, >, - T::SessionHandler: session::SessionHandler<::AccountId>, - T::OnSessionEnding: session::OnSessionEnding<::AccountId>, - T::SelectInitialValidators: session::SelectInitialValidators<::AccountId>, - T::ValidatorIdOf: Convert<::AccountId, Option<::AccountId>> + T::SessionHandler: pallet_session::SessionHandler<::AccountId>, + T::OnSessionEnding: pallet_session::OnSessionEnding<::AccountId>, + T::SelectInitialValidators: pallet_session::SelectInitialValidators<::AccountId>, + T::ValidatorIdOf: Convert<::AccountId, Option<::AccountId>> { fn on_offence( - offenders: &[OffenceDetails>], + offenders: &[OffenceDetails>], slash_fraction: &[Perbill], + slash_session: SessionIndex, ) { - let mut remaining_imbalance = >::zero(); - let slash_reward_fraction = SlashRewardFraction::get(); + >::ensure_storage_upgraded(); + + let reward_proportion = SlashRewardFraction::get(); let era_now = Self::current_era(); - let mut journal = Self::era_slash_journal(era_now); + let window_start = era_now.saturating_sub(T::BondingDuration::get()); + let current_era_start_session = CurrentEraStartSessionIndex::get(); + + // fast path for current-era report - most likely. + let slash_era = if slash_session >= current_era_start_session { + era_now + } else { + let eras = BondedEras::get(); + + // reverse because it's more likely to find reports from recent eras. + match eras.iter().rev().filter(|&&(_, ref sesh)| sesh <= &slash_session).next() { + None => return, // before bonding period. defensive - should be filtered out. + Some(&(ref slash_era, _)) => *slash_era, + } + }; + + ::EarliestUnappliedSlash::mutate(|earliest| { + if earliest.is_none() { + *earliest = Some(era_now) + } + }); + + let slash_defer_duration = T::SlashDeferDuration::get(); + for (details, slash_fraction) in offenders.iter().zip(slash_fraction) { let stash = &details.offender.0; let exposure = &details.offender.1; @@ -1541,59 +1749,36 @@ impl OnOffenceHandler>::exists(stash) { - >::remove(stash); - Self::ensure_new_era(); - } - - // calculate the amount to slash - let slash_exposure = exposure.total; - let amount = *slash_fraction * slash_exposure; - // in some cases `slash_fraction` can be just `0`, - // which means we are not slashing this time. - if amount.is_zero() { - continue; - } - - // make sure to disable validator till the end of this session - if T::SessionInterface::disable_validator(stash).unwrap_or(false) { - // force a new era, to select a new validator set - Self::ensure_new_era(); - } - // actually slash the validator - let slashed_amount = Self::slash_validator(stash, amount, exposure, &mut journal); - - // distribute the rewards according to the slash - let slash_reward = slash_reward_fraction * slashed_amount.peek(); - if !slash_reward.is_zero() && !details.reporters.is_empty() { - let (mut reward, rest) = slashed_amount.split(slash_reward); - // split the reward between reporters equally. Division cannot fail because - // we guarded against it in the enclosing if. - let per_reporter = reward.peek() / (details.reporters.len() as u32).into(); - for reporter in &details.reporters { - let (reporter_reward, rest) = reward.split(per_reporter); - reward = rest; - T::Currency::resolve_creating(reporter, reporter_reward); + let unapplied = slashing::compute_slash::(slashing::SlashParams { + stash, + slash: *slash_fraction, + exposure, + slash_era, + window_start, + now: era_now, + reward_proportion, + }); + + if let Some(mut unapplied) = unapplied { + unapplied.reporters = details.reporters.clone(); + if slash_defer_duration == 0 { + // apply right away. + slashing::apply_slash::(unapplied); + } else { + // defer to end of some `slash_defer_duration` from now. + ::UnappliedSlashes::mutate( + era_now, + move |for_later| for_later.push(unapplied), + ); } - // The rest goes to the treasury. - remaining_imbalance.subsume(reward); - remaining_imbalance.subsume(rest); - } else { - remaining_imbalance.subsume(slashed_amount); } } - >::insert(era_now, journal); - - // Handle the rest of imbalances - T::Slash::on_unbalanced(remaining_imbalance); } } -/// Filter historical offences out and only allow those from the current era. +/// Filter historical offences out and only allow those from the bonding period. pub struct FilterHistoricalOffences { - _inner: rstd::marker::PhantomData<(T, R)>, + _inner: sp_std::marker::PhantomData<(T, R)>, } impl ReportOffence @@ -1603,9 +1788,13 @@ impl ReportOffence O: Offence, { fn report_offence(reporters: Vec, offence: O) { - // disallow any slashing from before the current era. + >::ensure_storage_upgraded(); + + // disallow any slashing from before the current bonding period. let offence_session = offence.session_index(); - if offence_session >= >::current_era_start_session_index() { + let bonded_eras = BondedEras::get(); + + if bonded_eras.first().filter(|(_, start)| offence_session >= *start).is_some() { R::report_offence(reporters, offence) } else { >::deposit_event( diff --git a/frame/staking/src/migration.rs b/frame/staking/src/migration.rs new file mode 100644 index 0000000000000000000000000000000000000000..0ee52dc337f9c1d1b1e0c47cb2d84ac7902d17cb --- /dev/null +++ b/frame/staking/src/migration.rs @@ -0,0 +1,88 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Storage migrations for srml-staking. + +/// Indicator of a version of a storage layout. +pub type VersionNumber = u32; + +// the current expected version of the storage +pub const CURRENT_VERSION: VersionNumber = 1; + +#[cfg(any(test, feature = "migrate"))] +mod inner { + use crate::{Store, Module, Trait}; + use frame_support::{StorageLinkedMap, StorageValue}; + use sp_std::vec::Vec; + use super::{CURRENT_VERSION, VersionNumber}; + + // the minimum supported version of the migration logic. + const MIN_SUPPORTED_VERSION: VersionNumber = 0; + + // migrate storage from v0 to v1. + // + // this upgrades the `Nominators` linked_map value type from `Vec` to + // `Option>` + pub fn to_v1(version: &mut VersionNumber) { + if *version != 0 { return } + *version += 1; + + let now = >::current_era(); + let res = as Store>::Nominators::translate::, _, _>( + |key| key, + |targets| crate::Nominations { + targets, + submitted_in: now, + suppressed: false, + }, + ); + + if let Err(e) = res { + frame_support::print("Encountered error in migration of Staking::Nominators map."); + if e.is_none() { + frame_support::print("Staking::Nominators map reinitialized"); + } + } + + frame_support::print("Finished migrating Staking storage to v1."); + } + + pub(super) fn perform_migrations() { + as Store>::StorageVersion::mutate(|version| { + if *version < MIN_SUPPORTED_VERSION { + frame_support::print("Cannot migrate staking storage because version is less than\ + minimum."); + frame_support::print(*version); + return + } + + if *version == CURRENT_VERSION { return } + + to_v1::(version); + }); + } +} + +#[cfg(not(any(test, feature = "migrate")))] +mod inner { + pub(super) fn perform_migrations() { } +} + +/// Perform all necessary storage migrations to get storage into the expected stsate for current +/// logic. No-op if fully upgraded. +pub(crate) fn perform_migrations() { + inner::perform_migrations::(); +} diff --git a/frame/staking/src/mock.rs b/frame/staking/src/mock.rs index c2a0745983754903cfe04a9a2ff91e6a0594896b..81066f9dd81a2b7db426727cb6b873141943c0ca 100644 --- a/frame/staking/src/mock.rs +++ b/frame/staking/src/mock.rs @@ -17,15 +17,18 @@ //! Test utilities use std::{collections::HashSet, cell::RefCell}; -use sr_primitives::{Perbill, KeyTypeId}; -use sr_primitives::curve::PiecewiseLinear; -use sr_primitives::traits::{IdentityLookup, Convert, OpaqueKeys, OnInitialize, SaturatedConversion}; -use sr_primitives::testing::{Header, UintAuthorityId}; -use sr_staking_primitives::SessionIndex; -use primitives::{H256, crypto::key_types}; -use runtime_io; -use support::{assert_ok, impl_outer_origin, parameter_types, StorageLinkedMap}; -use support::traits::{Currency, Get, FindAuthor}; +use sp_runtime::{Perbill, KeyTypeId}; +use sp_runtime::curve::PiecewiseLinear; +use sp_runtime::traits::{IdentityLookup, Convert, OpaqueKeys, OnInitialize, SaturatedConversion}; +use sp_runtime::testing::{Header, UintAuthorityId}; +use sp_staking::{SessionIndex, offence::{OffenceDetails, OnOffenceHandler}}; +use sp_core::{H256, crypto::key_types}; +use sp_io; +use frame_support::{ + assert_ok, impl_outer_origin, parameter_types, StorageLinkedMap, StorageValue, + traits::{Currency, Get, FindAuthor}, + weights::Weight, +}; use crate::{ EraIndex, GenesisConfig, Module, Trait, StakerStatus, ValidatorPrefs, RewardDestination, Nominators, inflation @@ -48,10 +51,11 @@ impl Convert for CurrencyToVoteHandler { thread_local! { static SESSION: RefCell<(Vec, HashSet)> = RefCell::new(Default::default()); static EXISTENTIAL_DEPOSIT: RefCell = RefCell::new(0); + static SLASH_DEFER_DURATION: RefCell = RefCell::new(0); } pub struct TestSessionHandler; -impl session::SessionHandler for TestSessionHandler { +impl pallet_session::SessionHandler for TestSessionHandler { const KEY_TYPE_IDS: &'static [KeyTypeId] = &[key_types::DUMMY]; fn on_genesis_session(_validators: &[(AccountId, Ks)]) {} @@ -87,15 +91,22 @@ impl Get for ExistentialDeposit { } } +pub struct SlashDeferDuration; +impl Get for SlashDeferDuration { + fn get() -> EraIndex { + SLASH_DEFER_DURATION.with(|v| *v.borrow()) + } +} + impl_outer_origin!{ - pub enum Origin for Test {} + pub enum Origin for Test where system = frame_system {} } /// Author of block is always 11 pub struct Author11; impl FindAuthor for Author11 { fn find_author<'a, I>(_digests: I) -> Option - where I: 'a + IntoIterator + where I: 'a + IntoIterator { Some(11) } @@ -106,17 +117,17 @@ impl FindAuthor for Author11 { pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockWeight: Weight = 1024; pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } -impl system::Trait for Test { +impl frame_system::Trait for Test { type Origin = Origin; type Index = u64; type BlockNumber = BlockNumber; type Call = (); type Hash = H256; - type Hashing = ::sr_primitives::traits::BlakeTwo256; + type Hashing = ::sp_runtime::traits::BlakeTwo256; type AccountId = AccountId; type Lookup = IdentityLookup; type Header = Header; @@ -126,12 +137,13 @@ impl system::Trait for Test { type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; type Version = (); + type ModuleToIndex = (); } parameter_types! { pub const TransferFee: Balance = 0; pub const CreationFee: Balance = 0; } -impl balances::Trait for Test { +impl pallet_balances::Trait for Test { type Balance = Balance; type OnFreeBalanceZero = Staking; type OnNewAccount = (); @@ -148,10 +160,10 @@ parameter_types! { pub const UncleGenerations: u64 = 0; pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(25); } -impl session::Trait for Test { - type OnSessionEnding = session::historical::NoteHistoricalRoot; +impl pallet_session::Trait for Test { + type OnSessionEnding = pallet_session::historical::NoteHistoricalRoot; type Keys = UintAuthorityId; - type ShouldEndSession = session::PeriodicSessions; + type ShouldEndSession = pallet_session::PeriodicSessions; type SessionHandler = TestSessionHandler; type Event = (); type ValidatorId = AccountId; @@ -160,11 +172,11 @@ impl session::Trait for Test { type DisabledValidatorsThreshold = DisabledValidatorsThreshold; } -impl session::historical::Trait for Test { +impl pallet_session::historical::Trait for Test { type FullIdentification = crate::Exposure; type FullIdentificationOf = crate::ExposureOf; } -impl authorship::Trait for Test { +impl pallet_authorship::Trait for Test { type FindAuthor = Author11; type UncleGenerations = UncleGenerations; type FilterUncle = (); @@ -173,7 +185,7 @@ impl authorship::Trait for Test { parameter_types! { pub const MinimumPeriod: u64 = 5; } -impl timestamp::Trait for Test { +impl pallet_timestamp::Trait for Test { type Moment = u64; type OnTimestampSet = (); type MinimumPeriod = MinimumPeriod; @@ -194,14 +206,16 @@ parameter_types! { pub const RewardCurve: &'static PiecewiseLinear<'static> = &I_NPOS; } impl Trait for Test { - type Currency = balances::Module; - type Time = timestamp::Module; + type Currency = pallet_balances::Module; + type Time = pallet_timestamp::Module; type CurrencyToVote = CurrencyToVoteHandler; type RewardRemainder = (); type Event = (); type Slash = (); type Reward = (); type SessionsPerEra = SessionsPerEra; + type SlashDeferDuration = SlashDeferDuration; + type SlashCancelOrigin = frame_system::EnsureRoot; type BondingDuration = BondingDuration; type SessionInterface = Self; type RewardCurve = RewardCurve; @@ -213,6 +227,7 @@ pub struct ExtBuilder { nominate: bool, validator_count: u32, minimum_validator_count: u32, + slash_defer_duration: EraIndex, fair: bool, num_validators: Option, invulnerables: Vec, @@ -226,6 +241,7 @@ impl Default for ExtBuilder { nominate: true, validator_count: 2, minimum_validator_count: 0, + slash_defer_duration: 0, fair: true, num_validators: None, invulnerables: vec![], @@ -254,6 +270,10 @@ impl ExtBuilder { self.minimum_validator_count = count; self } + pub fn slash_defer_duration(mut self, eras: EraIndex) -> Self { + self.slash_defer_duration = eras; + self + } pub fn fair(mut self, is_fair: bool) -> Self { self.fair = is_fair; self @@ -268,10 +288,11 @@ impl ExtBuilder { } pub fn set_associated_consts(&self) { EXISTENTIAL_DEPOSIT.with(|v| *v.borrow_mut() = self.existential_deposit); + SLASH_DEFER_DURATION.with(|v| *v.borrow_mut() = self.slash_defer_duration); } - pub fn build(self) -> runtime_io::TestExternalities { + pub fn build(self) -> sp_io::TestExternalities { self.set_associated_consts(); - let mut storage = system::GenesisConfig::default().build_storage::().unwrap(); + let mut storage = frame_system::GenesisConfig::default().build_storage::().unwrap(); let balance_factor = if self.existential_deposit > 0 { 256 } else { @@ -283,7 +304,7 @@ impl ExtBuilder { .map(|x| ((x + 1) * 10 + 1) as u64) .collect::>(); - let _ = balances::GenesisConfig::{ + let _ = pallet_balances::GenesisConfig::{ balances: vec![ (1, 10 * balance_factor), (2, 20 * balance_factor), @@ -331,11 +352,11 @@ impl ExtBuilder { ..Default::default() }.assimilate_storage(&mut storage); - let _ = session::GenesisConfig:: { + let _ = pallet_session::GenesisConfig:: { keys: validators.iter().map(|x| (*x, UintAuthorityId(*x))).collect(), }.assimilate_storage(&mut storage); - let mut ext = runtime_io::TestExternalities::from(storage); + let mut ext = sp_io::TestExternalities::from(storage); ext.execute_with(|| { let validators = Session::validators(); SESSION.with(|x| @@ -346,10 +367,10 @@ impl ExtBuilder { } } -pub type System = system::Module; -pub type Balances = balances::Module; -pub type Session = session::Module; -pub type Timestamp = timestamp::Module; +pub type System = frame_system::Module; +pub type Balances = pallet_balances::Module; +pub type Session = pallet_session::Module; +pub type Timestamp = pallet_timestamp::Module; pub type Staking = Module; pub fn check_exposure_all() { @@ -393,6 +414,14 @@ pub fn assert_is_stash(acc: u64) { assert!(Staking::bonded(&acc).is_some(), "Not a stash."); } +pub fn assert_ledger_consistent(stash: u64) { + assert_is_stash(stash); + let ledger = Staking::ledger(stash - 1).unwrap(); + + let real_total: Balance = ledger.unlocking.iter().fold(ledger.active, |a, c| a + c.value); + assert_eq!(real_total, ledger.total); +} + pub fn bond_validator(acc: u64, val: u64) { // a = controller // a + 1 = stash @@ -451,3 +480,33 @@ pub fn reward_all_elected() { pub fn validator_controllers() -> Vec { Session::validators().into_iter().map(|s| Staking::bonded(&s).expect("no controller for validator")).collect() } + +pub fn on_offence_in_era( + offenders: &[OffenceDetails>], + slash_fraction: &[Perbill], + era: EraIndex, +) { + let bonded_eras = crate::BondedEras::get(); + for &(bonded_era, start_session) in bonded_eras.iter() { + if bonded_era == era { + Staking::on_offence(offenders, slash_fraction, start_session); + return + } else if bonded_era > era { + break + } + } + + if Staking::current_era() == era { + Staking::on_offence(offenders, slash_fraction, Staking::current_era_start_session_index()); + } else { + panic!("cannot slash in era {}", era); + } +} + +pub fn on_offence_now( + offenders: &[OffenceDetails>], + slash_fraction: &[Perbill], +) { + let now = Staking::current_era(); + on_offence_in_era(offenders, slash_fraction, now) +} diff --git a/frame/staking/src/slashing.rs b/frame/staking/src/slashing.rs new file mode 100644 index 0000000000000000000000000000000000000000..bf4bde44be620a1b57f3d50ef16d989b785a9747 --- /dev/null +++ b/frame/staking/src/slashing.rs @@ -0,0 +1,821 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! A slashing implementation for NPoS systems. +//! +//! For the purposes of the economic model, it is easiest to think of each validator +//! of a nominator which nominates only its own identity. +//! +//! The act of nomination signals intent to unify economic identity with the validator - to take part in the +//! rewards of a job well done, and to take part in the punishment of a job done badly. +//! +//! There are 3 main difficulties to account for with slashing in NPoS: +//! - A nominator can nominate multiple validators and be slashed via any of them. +//! - Until slashed, stake is reused from era to era. Nominating with N coins for E eras in a row +//! does not mean you have N*E coins to be slashed - you've only ever had N. +//! - Slashable offences can be found after the fact and out of order. +//! +//! The algorithm implemented in this module tries to balance these 3 difficulties. +//! +//! First, we only slash participants for the _maximum_ slash they receive in some time period, +//! rather than the sum. This ensures a protection from overslashing. +//! +//! Second, we do not want the time period (or "span") that the maximum is computed +//! over to last indefinitely. That would allow participants to begin acting with +//! impunity after some point, fearing no further repercussions. For that reason, we +//! automatically "chill" validators and withdraw a nominator's nomination after a slashing event, +//! requiring them to re-enlist voluntarily (acknowledging the slash) and begin a new +//! slashing span. +//! +//! Typically, you will have a single slashing event per slashing span. Only in the case +//! where a validator releases many misbehaviors at once, or goes "back in time" to misbehave in +//! eras that have already passed, would you encounter situations where a slashing span +//! has multiple misbehaviors. However, accounting for such cases is necessary +//! to deter a class of "rage-quit" attacks. +//! +//! Based on research at https://research.web3.foundation/en/latest/polkadot/slashing/npos/ + +use super::{ + EraIndex, Trait, Module, Store, BalanceOf, Exposure, Perbill, SessionInterface, + NegativeImbalanceOf, UnappliedSlash, +}; +use sp_runtime::traits::{Zero, Saturating}; +use frame_support::{ + StorageMap, StorageDoubleMap, + traits::{Currency, OnUnbalanced, Imbalance}, +}; +use sp_std::vec::Vec; +use codec::{Encode, Decode}; + +/// The proportion of the slashing reward to be paid out on the first slashing detection. +/// This is f_1 in the paper. +const REWARD_F1: Perbill = Perbill::from_percent(50); + +/// The index of a slashing span - unique to each stash. +pub(crate) type SpanIndex = u32; + +// A range of start..end eras for a slashing span. +#[derive(Encode, Decode)] +#[cfg_attr(test, derive(Debug, PartialEq))] +pub(crate) struct SlashingSpan { + pub(crate) index: SpanIndex, + pub(crate) start: EraIndex, + pub(crate) length: Option, // the ongoing slashing span has indeterminate length. +} + +impl SlashingSpan { + fn contains_era(&self, era: EraIndex) -> bool { + self.start <= era && self.length.map_or(true, |l| self.start + l > era) + } +} + +/// An encoding of all of a nominator's slashing spans. +#[derive(Encode, Decode)] +pub struct SlashingSpans { + // the index of the current slashing span of the nominator. different for + // every stash, resets when the account hits free balance 0. + span_index: SpanIndex, + // the start era of the most recent (ongoing) slashing span. + last_start: EraIndex, + // all prior slashing spans start indices, in reverse order (most recent first) + // encoded as offsets relative to the slashing span after it. + prior: Vec, +} + +impl SlashingSpans { + // creates a new record of slashing spans for a stash, starting at the beginning + // of the bonding period, relative to now. + fn new(window_start: EraIndex) -> Self { + SlashingSpans { + span_index: 0, + last_start: window_start, + prior: Vec::new(), + } + } + + // update the slashing spans to reflect the start of a new span at the era after `now` + // returns `true` if a new span was started, `false` otherwise. `false` indicates + // that internal state is unchanged. + fn end_span(&mut self, now: EraIndex) -> bool { + let next_start = now + 1; + if next_start <= self.last_start { return false } + + let last_length = next_start - self.last_start; + self.prior.insert(0, last_length); + self.last_start = next_start; + self.span_index += 1; + true + } + + // an iterator over all slashing spans in _reverse_ order - most recent first. + pub(crate) fn iter(&'_ self) -> impl Iterator + '_ { + let mut last_start = self.last_start; + let mut index = self.span_index; + let last = SlashingSpan { index, start: last_start, length: None }; + let prior = self.prior.iter().cloned().map(move |length| { + let start = last_start - length; + last_start = start; + index -= 1; + + SlashingSpan { index, start, length: Some(length) } + }); + + sp_std::iter::once(last).chain(prior) + } + + /// Yields the era index where the last (current) slashing span started. + pub(crate) fn last_start(&self) -> EraIndex { + self.last_start + } + + // prune the slashing spans against a window, whose start era index is given. + // + // If this returns `Some`, then it includes a range start..end of all the span + // indices which were pruned. + fn prune(&mut self, window_start: EraIndex) -> Option<(SpanIndex, SpanIndex)> { + let old_idx = self.iter() + .skip(1) // skip ongoing span. + .position(|span| span.length.map_or(false, |len| span.start + len <= window_start)); + + let earliest_span_index = self.span_index - self.prior.len() as SpanIndex; + let pruned = match old_idx { + Some(o) => { + self.prior.truncate(o); + let new_earliest = self.span_index - self.prior.len() as SpanIndex; + Some((earliest_span_index, new_earliest)) + } + None => None, + }; + + // readjust the ongoing span, if it started before the beginning of the window. + self.last_start = sp_std::cmp::max(self.last_start, window_start); + pruned + } +} + +/// A slashing-span record for a particular stash. +#[derive(Encode, Decode, Default)] +pub(crate) struct SpanRecord { + slashed: Balance, + paid_out: Balance, +} + +impl SpanRecord { + /// The value of stash balance slashed in this span. + #[cfg(test)] + pub(crate) fn amount_slashed(&self) -> &Balance { + &self.slashed + } +} + +/// Parameters for performing a slash. +#[derive(Clone)] +pub(crate) struct SlashParams<'a, T: 'a + Trait> { + /// The stash account being slashed. + pub(crate) stash: &'a T::AccountId, + /// The proportion of the slash. + pub(crate) slash: Perbill, + /// The exposure of the stash and all nominators. + pub(crate) exposure: &'a Exposure>, + /// The era where the offence occurred. + pub(crate) slash_era: EraIndex, + /// The first era in the current bonding period. + pub(crate) window_start: EraIndex, + /// The current era. + pub(crate) now: EraIndex, + /// The maximum percentage of a slash that ever gets paid out. + /// This is f_inf in the paper. + pub(crate) reward_proportion: Perbill, +} + +/// Computes a slash of a validator and nominators. It returns an unapplied +/// record to be applied at some later point. Slashing metadata is updated in storage, +/// since unapplied records are only rarely intended to be dropped. +/// +/// The pending slash record returned does not have initialized reporters. Those have +/// to be set at a higher level, if any. +pub(crate) fn compute_slash(params: SlashParams) + -> Option>> +{ + let SlashParams { + stash, + slash, + exposure, + slash_era, + window_start, + now, + reward_proportion, + } = params.clone(); + + let mut reward_payout = Zero::zero(); + let mut val_slashed = Zero::zero(); + + // is the slash amount here a maximum for the era? + let own_slash = slash * exposure.own; + if slash * exposure.total == Zero::zero() { + // kick out the validator even if they won't be slashed, + // as long as the misbehavior is from their most recent slashing span. + kick_out_if_recent::(params); + return None; + } + + let (prior_slash_p, _era_slash) = as Store>::ValidatorSlashInEra::get( + &slash_era, + stash, + ).unwrap_or((Perbill::zero(), Zero::zero())); + + // compare slash proportions rather than slash values to avoid issues due to rounding + // error. + if slash.deconstruct() > prior_slash_p.deconstruct() { + as Store>::ValidatorSlashInEra::insert( + &slash_era, + stash, + &(slash, own_slash), + ); + } else { + // we slash based on the max in era - this new event is not the max, + // so neither the validator or any nominators will need an update. + // + // this does lead to a divergence of our system from the paper, which + // pays out some reward even if the latest report is not max-in-era. + // we opt to avoid the nominator lookups and edits and leave more rewards + // for more drastic misbehavior. + return None; + } + + // apply slash to validator. + { + let mut spans = fetch_spans::( + stash, + window_start, + &mut reward_payout, + &mut val_slashed, + reward_proportion, + ); + + let target_span = spans.compare_and_update_span_slash( + slash_era, + own_slash, + ); + + if target_span == Some(spans.span_index()) { + // misbehavior occurred within the current slashing span - take appropriate + // actions. + + // chill the validator - it misbehaved in the current span and should + // not continue in the next election. also end the slashing span. + spans.end_span(now); + >::chill_stash(stash); + + // make sure to disable validator till the end of this session + if T::SessionInterface::disable_validator(stash).unwrap_or(false) { + // force a new era, to select a new validator set + >::ensure_new_era() + } + } + } + + let mut nominators_slashed = Vec::new(); + reward_payout += slash_nominators::(params, prior_slash_p, &mut nominators_slashed); + + Some(UnappliedSlash { + validator: stash.clone(), + own: val_slashed, + others: nominators_slashed, + reporters: Vec::new(), + payout: reward_payout, + }) +} + +// doesn't apply any slash, but kicks out the validator if the misbehavior is from +// the most recent slashing span. +fn kick_out_if_recent( + params: SlashParams, +) { + // these are not updated by era-span or end-span. + let mut reward_payout = Zero::zero(); + let mut val_slashed = Zero::zero(); + let mut spans = fetch_spans::( + params.stash, + params.window_start, + &mut reward_payout, + &mut val_slashed, + params.reward_proportion, + ); + + if spans.era_span(params.slash_era).map(|s| s.index) == Some(spans.span_index()) { + spans.end_span(params.now); + >::chill_stash(params.stash); + + // make sure to disable validator till the end of this session + if T::SessionInterface::disable_validator(params.stash).unwrap_or(false) { + // force a new era, to select a new validator set + >::ensure_new_era() + } + } +} + +/// Slash nominators. Accepts general parameters and the prior slash percentage of the validator. +/// +/// Returns the amount of reward to pay out. +fn slash_nominators( + params: SlashParams, + prior_slash_p: Perbill, + nominators_slashed: &mut Vec<(T::AccountId, BalanceOf)>, +) -> BalanceOf { + let SlashParams { + stash: _, + slash, + exposure, + slash_era, + window_start, + now, + reward_proportion, + } = params; + + let mut reward_payout = Zero::zero(); + + nominators_slashed.reserve(exposure.others.len()); + for nominator in &exposure.others { + let stash = &nominator.who; + let mut nom_slashed = Zero::zero(); + + // the era slash of a nominator always grows, if the validator + // had a new max slash for the era. + let era_slash = { + let own_slash_prior = prior_slash_p * nominator.value; + let own_slash_by_validator = slash * nominator.value; + let own_slash_difference = own_slash_by_validator.saturating_sub(own_slash_prior); + + let mut era_slash = as Store>::NominatorSlashInEra::get( + &slash_era, + stash, + ).unwrap_or(Zero::zero()); + + era_slash += own_slash_difference; + + as Store>::NominatorSlashInEra::insert( + &slash_era, + stash, + &era_slash, + ); + + era_slash + }; + + // compare the era slash against other eras in the same span. + { + let mut spans = fetch_spans::( + stash, + window_start, + &mut reward_payout, + &mut nom_slashed, + reward_proportion, + ); + + let target_span = spans.compare_and_update_span_slash( + slash_era, + era_slash, + ); + + if target_span == Some(spans.span_index()) { + // Chill the nominator outright, ending the slashing span. + spans.end_span(now); + >::chill_stash(stash); + } + } + + nominators_slashed.push((stash.clone(), nom_slashed)); + } + + reward_payout +} + +// helper struct for managing a set of spans we are currently inspecting. +// writes alterations to disk on drop, but only if a slash has been carried out. +// +// NOTE: alterations to slashing metadata should not be done after this is dropped. +// dropping this struct applies any necessary slashes, which can lead to free balance +// being 0, and the account being garbage-collected -- a dead account should get no new +// metadata. +struct InspectingSpans<'a, T: Trait + 'a> { + dirty: bool, + window_start: EraIndex, + stash: &'a T::AccountId, + spans: SlashingSpans, + paid_out: &'a mut BalanceOf, + slash_of: &'a mut BalanceOf, + reward_proportion: Perbill, + _marker: sp_std::marker::PhantomData, +} + +// fetches the slashing spans record for a stash account, initializing it if necessary. +fn fetch_spans<'a, T: Trait + 'a>( + stash: &'a T::AccountId, + window_start: EraIndex, + paid_out: &'a mut BalanceOf, + slash_of: &'a mut BalanceOf, + reward_proportion: Perbill, +) -> InspectingSpans<'a, T> { + let spans = as Store>::SlashingSpans::get(stash).unwrap_or_else(|| { + let spans = SlashingSpans::new(window_start); + as Store>::SlashingSpans::insert(stash, &spans); + spans + }); + + InspectingSpans { + dirty: false, + window_start, + stash, + spans, + slash_of, + paid_out, + reward_proportion, + _marker: sp_std::marker::PhantomData, + } +} + +impl<'a, T: 'a + Trait> InspectingSpans<'a, T> { + fn span_index(&self) -> SpanIndex { + self.spans.span_index + } + + fn end_span(&mut self, now: EraIndex) { + self.dirty = self.spans.end_span(now) || self.dirty; + } + + fn add_slash(&mut self, amount: BalanceOf) { + *self.slash_of += amount; + } + + // find the span index of the given era, if covered. + fn era_span(&self, era: EraIndex) -> Option { + self.spans.iter().find(|span| span.contains_era(era)) + } + + // compares the slash in an era to the overall current span slash. + // if it's higher, applies the difference of the slashes and then updates the span on disk. + // + // returns the span index of the era where the slash occurred, if any. + fn compare_and_update_span_slash( + &mut self, + slash_era: EraIndex, + slash: BalanceOf, + ) -> Option { + let target_span = self.era_span(slash_era)?; + let span_slash_key = (self.stash.clone(), target_span.index); + let mut span_record = as Store>::SpanSlash::get(&span_slash_key); + let mut changed = false; + + let reward = if span_record.slashed < slash { + // new maximum span slash. apply the difference. + let difference = slash - span_record.slashed; + span_record.slashed = slash; + + // compute reward. + let reward = REWARD_F1 + * (self.reward_proportion * slash).saturating_sub(span_record.paid_out); + + self.add_slash(difference); + changed = true; + + reward + } else if span_record.slashed == slash { + // compute reward. no slash difference to apply. + REWARD_F1 * (self.reward_proportion * slash).saturating_sub(span_record.paid_out) + } else { + Zero::zero() + }; + + if !reward.is_zero() { + changed = true; + span_record.paid_out += reward; + *self.paid_out += reward; + } + + if changed { + self.dirty = true; + as Store>::SpanSlash::insert(&span_slash_key, &span_record); + } + + Some(target_span.index) + } +} + +impl<'a, T: 'a + Trait> Drop for InspectingSpans<'a, T> { + fn drop(&mut self) { + // only update on disk if we slashed this account. + if !self.dirty { return } + + if let Some((start, end)) = self.spans.prune(self.window_start) { + for span_index in start..end { + as Store>::SpanSlash::remove(&(self.stash.clone(), span_index)); + } + } + + as Store>::SlashingSpans::insert(self.stash, &self.spans); + } +} + +/// Clear slashing metadata for an obsolete era. +pub(crate) fn clear_era_metadata(obsolete_era: EraIndex) { + as Store>::ValidatorSlashInEra::remove_prefix(&obsolete_era); + as Store>::NominatorSlashInEra::remove_prefix(&obsolete_era); +} + +/// Clear slashing metadata for a dead account. +pub(crate) fn clear_stash_metadata(stash: &T::AccountId) { + let spans = match as Store>::SlashingSpans::take(stash) { + None => return, + Some(s) => s, + }; + + // kill slashing-span metadata for account. + // + // this can only happen while the account is staked _if_ they are completely slashed. + // in that case, they may re-bond, but it would count again as span 0. Further ancient + // slashes would slash into this new bond, since metadata has now been cleared. + for span in spans.iter() { + as Store>::SpanSlash::remove(&(stash.clone(), span.index)); + } +} + +// apply the slash to a stash account, deducting any missing funds from the reward +// payout, saturating at 0. this is mildly unfair but also an edge-case that +// can only occur when overlapping locked funds have been slashed. +fn do_slash( + stash: &T::AccountId, + value: BalanceOf, + reward_payout: &mut BalanceOf, + slashed_imbalance: &mut NegativeImbalanceOf, +) { + let controller = match >::bonded(stash) { + None => return, // defensive: should always exist. + Some(c) => c, + }; + + let mut ledger = match >::ledger(&controller) { + Some(ledger) => ledger, + None => return, // nothing to do. + }; + + let value = ledger.slash(value, T::Currency::minimum_balance()); + + if !value.is_zero() { + let (imbalance, missing) = T::Currency::slash(stash, value); + slashed_imbalance.subsume(imbalance); + + if !missing.is_zero() { + // deduct overslash from the reward payout + *reward_payout = reward_payout.saturating_sub(missing); + } + + >::update_ledger(&controller, &ledger); + + // trigger the event + >::deposit_event( + super::RawEvent::Slash(stash.clone(), value) + ); + } +} + +/// Apply a previously-unapplied slash. +pub(crate) fn apply_slash(unapplied_slash: UnappliedSlash>) { + let mut slashed_imbalance = NegativeImbalanceOf::::zero(); + let mut reward_payout = unapplied_slash.payout; + + do_slash::( + &unapplied_slash.validator, + unapplied_slash.own, + &mut reward_payout, + &mut slashed_imbalance, + ); + + for &(ref nominator, nominator_slash) in &unapplied_slash.others { + do_slash::( + &nominator, + nominator_slash, + &mut reward_payout, + &mut slashed_imbalance, + ); + } + + pay_reporters::(reward_payout, slashed_imbalance, &unapplied_slash.reporters); +} + + +/// Apply a reward payout to some reporters, paying the rewards out of the slashed imbalance. +fn pay_reporters( + reward_payout: BalanceOf, + slashed_imbalance: NegativeImbalanceOf, + reporters: &[T::AccountId], +) { + if reward_payout.is_zero() || reporters.is_empty() { + // nobody to pay out to or nothing to pay; + // just treat the whole value as slashed. + T::Slash::on_unbalanced(slashed_imbalance); + return + } + + // take rewards out of the slashed imbalance. + let reward_payout = reward_payout.min(slashed_imbalance.peek()); + let (mut reward_payout, mut value_slashed) = slashed_imbalance.split(reward_payout); + + let per_reporter = reward_payout.peek() / (reporters.len() as u32).into(); + for reporter in reporters { + let (reporter_reward, rest) = reward_payout.split(per_reporter); + reward_payout = rest; + + // this cancels out the reporter reward imbalance internally, leading + // to no change in total issuance. + T::Currency::resolve_creating(reporter, reporter_reward); + } + + // the rest goes to the on-slash imbalance handler (e.g. treasury) + value_slashed.subsume(reward_payout); // remainder of reward division remains. + T::Slash::on_unbalanced(value_slashed); +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn span_contains_era() { + // unbounded end + let span = SlashingSpan { index: 0, start: 1000, length: None }; + assert!(!span.contains_era(0)); + assert!(!span.contains_era(999)); + + assert!(span.contains_era(1000)); + assert!(span.contains_era(1001)); + assert!(span.contains_era(10000)); + + // bounded end - non-inclusive range. + let span = SlashingSpan { index: 0, start: 1000, length: Some(10) }; + assert!(!span.contains_era(0)); + assert!(!span.contains_era(999)); + + assert!(span.contains_era(1000)); + assert!(span.contains_era(1001)); + assert!(span.contains_era(1009)); + assert!(!span.contains_era(1010)); + assert!(!span.contains_era(1011)); + } + + #[test] + fn single_slashing_span() { + let spans = SlashingSpans { + span_index: 0, + last_start: 1000, + prior: Vec::new(), + }; + + assert_eq!( + spans.iter().collect::>(), + vec![SlashingSpan { index: 0, start: 1000, length: None }], + ); + } + + #[test] + fn many_prior_spans() { + let spans = SlashingSpans { + span_index: 10, + last_start: 1000, + prior: vec![10, 9, 8, 10], + }; + + assert_eq!( + spans.iter().collect::>(), + vec![ + SlashingSpan { index: 10, start: 1000, length: None }, + SlashingSpan { index: 9, start: 990, length: Some(10) }, + SlashingSpan { index: 8, start: 981, length: Some(9) }, + SlashingSpan { index: 7, start: 973, length: Some(8) }, + SlashingSpan { index: 6, start: 963, length: Some(10) }, + ], + ) + } + + #[test] + fn pruning_spans() { + let mut spans = SlashingSpans { + span_index: 10, + last_start: 1000, + prior: vec![10, 9, 8, 10], + }; + + assert_eq!(spans.prune(981), Some((6, 8))); + assert_eq!( + spans.iter().collect::>(), + vec![ + SlashingSpan { index: 10, start: 1000, length: None }, + SlashingSpan { index: 9, start: 990, length: Some(10) }, + SlashingSpan { index: 8, start: 981, length: Some(9) }, + ], + ); + + assert_eq!(spans.prune(982), None); + assert_eq!( + spans.iter().collect::>(), + vec![ + SlashingSpan { index: 10, start: 1000, length: None }, + SlashingSpan { index: 9, start: 990, length: Some(10) }, + SlashingSpan { index: 8, start: 981, length: Some(9) }, + ], + ); + + assert_eq!(spans.prune(989), None); + assert_eq!( + spans.iter().collect::>(), + vec![ + SlashingSpan { index: 10, start: 1000, length: None }, + SlashingSpan { index: 9, start: 990, length: Some(10) }, + SlashingSpan { index: 8, start: 981, length: Some(9) }, + ], + ); + + assert_eq!(spans.prune(1000), Some((8, 10))); + assert_eq!( + spans.iter().collect::>(), + vec![ + SlashingSpan { index: 10, start: 1000, length: None }, + ], + ); + + assert_eq!(spans.prune(2000), None); + assert_eq!( + spans.iter().collect::>(), + vec![ + SlashingSpan { index: 10, start: 2000, length: None }, + ], + ); + + // now all in one shot. + let mut spans = SlashingSpans { + span_index: 10, + last_start: 1000, + prior: vec![10, 9, 8, 10], + }; + assert_eq!(spans.prune(2000), Some((6, 10))); + assert_eq!( + spans.iter().collect::>(), + vec![ + SlashingSpan { index: 10, start: 2000, length: None }, + ], + ); + } + + #[test] + fn ending_span() { + let mut spans = SlashingSpans { + span_index: 1, + last_start: 10, + prior: Vec::new(), + }; + + assert!(spans.end_span(10)); + + assert_eq!( + spans.iter().collect::>(), + vec![ + SlashingSpan { index: 2, start: 11, length: None }, + SlashingSpan { index: 1, start: 10, length: Some(1) }, + ], + ); + + assert!(spans.end_span(15)); + assert_eq!( + spans.iter().collect::>(), + vec![ + SlashingSpan { index: 3, start: 16, length: None }, + SlashingSpan { index: 2, start: 11, length: Some(5) }, + SlashingSpan { index: 1, start: 10, length: Some(1) }, + ], + ); + + // does nothing if not a valid end. + assert!(!spans.end_span(15)); + assert_eq!( + spans.iter().collect::>(), + vec![ + SlashingSpan { index: 3, start: 16, length: None }, + SlashingSpan { index: 2, start: 11, length: Some(5) }, + SlashingSpan { index: 1, start: 10, length: Some(1) }, + ], + ); + } +} diff --git a/frame/staking/src/tests.rs b/frame/staking/src/tests.rs index aef5a26a04537828b4a0ed62fa855e107507d7de..109f2e086f65ff03855ea59ac1e9e28e6d504ac5 100644 --- a/frame/staking/src/tests.rs +++ b/frame/staking/src/tests.rs @@ -18,9 +18,10 @@ use super::*; use mock::*; -use sr_primitives::{assert_eq_error_rate, traits::OnInitialize}; -use sr_staking_primitives::offence::{OffenceDetails, OnOffenceHandler}; -use support::{assert_ok, assert_noop, assert_eq_uvec, traits::{Currency, ReservableCurrency}}; +use sp_runtime::{assert_eq_error_rate, traits::{OnInitialize, BadOrigin}}; +use sp_staking::offence::OffenceDetails; +use frame_support::{assert_ok, assert_noop, traits::{Currency, ReservableCurrency}}; +use substrate_test_utils::assert_eq_uvec; #[test] fn force_unstake_works() { @@ -34,7 +35,7 @@ fn force_unstake_works() { "account liquidity restrictions prevent withdrawal" ); // Force unstake requires root. - assert_noop!(Staking::force_unstake(Origin::signed(11), 11), "RequireRootOrigin"); + assert_noop!(Staking::force_unstake(Origin::signed(11), 11), BadOrigin); // We now force them to unstake assert_ok!(Staking::force_unstake(Origin::ROOT, 11)); // No longer bonded. @@ -79,7 +80,7 @@ fn basic_setup_works() { Staking::ledger(100), Some(StakingLedger { stash: 101, total: 500, active: 500, unlocking: vec![] }) ); - assert_eq!(Staking::nominators(101), vec![11, 21]); + assert_eq!(Staking::nominators(101).unwrap().targets, vec![11, 21]); if cfg!(feature = "equalize") { assert_eq!( @@ -141,7 +142,7 @@ fn change_controller_works() { assert_noop!( Staking::validate(Origin::signed(10), ValidatorPrefs::default()), - "not a controller" + Error::::NotController, ); assert_ok!(Staking::validate(Origin::signed(5), ValidatorPrefs::default())); }) @@ -637,7 +638,7 @@ fn nominators_also_get_slashed() { assert_eq!(Balances::total_balance(&2), initial_balance); // 10 goes offline - Staking::on_offence( + on_offence_now( &[OffenceDetails { offender: ( 11, @@ -679,10 +680,10 @@ fn double_staking_should_fail() { // 4 = not used so far, 1 stashed => not allowed. assert_noop!( Staking::bond(Origin::signed(1), 4, arbitrary_value, - RewardDestination::default()), "stash already bonded" + RewardDestination::default()), Error::::AlreadyBonded, ); // 1 = stashed => attempting to nominate should fail. - assert_noop!(Staking::nominate(Origin::signed(1), vec![1]), "not a controller"); + assert_noop!(Staking::nominate(Origin::signed(1), vec![1]), Error::::NotController); // 2 = controller => nominating should work. assert_ok!(Staking::nominate(Origin::signed(2), vec![1])); }); @@ -704,7 +705,7 @@ fn double_controlling_should_fail() { // 2 = controller, 3 stashed (Note that 2 is reused.) => no-op assert_noop!( Staking::bond(Origin::signed(3), 2, arbitrary_value, RewardDestination::default()), - "controller already paired", + Error::::AlreadyPaired, ); }); } @@ -964,7 +965,6 @@ fn validator_payment_prefs_work() { // This test will focus on validator payment. ExtBuilder::default().build().execute_with(|| { // Initial config - let validator_cut = 5; let stash_initial_balance = Balances::total_balance(&11); // check the balance of a validator accounts. @@ -982,7 +982,7 @@ fn validator_payment_prefs_work() { }); >::insert(&2, RewardDestination::Stash); >::insert(&11, ValidatorPrefs { - validator_payment: validator_cut + commission: Perbill::from_percent(50), }); // Compute total payout now for whole duration as other parameter won't change @@ -993,9 +993,9 @@ fn validator_payment_prefs_work() { start_era(1); // whats left to be shared is the sum of 3 rounds minus the validator's cut. - let shared_cut = total_payout_0 - validator_cut; + let shared_cut = total_payout_0 / 2; // Validator's payee is Staked account, 11, reward will be paid here. - assert_eq!(Balances::total_balance(&11), stash_initial_balance + shared_cut / 2 + validator_cut); + assert_eq!(Balances::total_balance(&11), stash_initial_balance + shared_cut / 2 + shared_cut); // Controller account will not get any reward. assert_eq!(Balances::total_balance(&10), 1); // Rest of the reward will be shared and paid to the nominator in stake. @@ -1152,11 +1152,11 @@ fn too_many_unbond_calls_should_not_work() { // locked at era 1 until 4 assert_ok!(Staking::unbond(Origin::signed(10), 1)); // can't do more. - assert_noop!(Staking::unbond(Origin::signed(10), 1), "can not schedule more unlock chunks"); + assert_noop!(Staking::unbond(Origin::signed(10), 1), Error::::NoMoreChunks); start_era(3); - assert_noop!(Staking::unbond(Origin::signed(10), 1), "can not schedule more unlock chunks"); + assert_noop!(Staking::unbond(Origin::signed(10), 1), Error::::NoMoreChunks); // free up. assert_ok!(Staking::withdraw_unbonded(Origin::signed(10))); @@ -1422,7 +1422,7 @@ fn bond_with_no_staked_value() { // Can't bond with 1 assert_noop!( Staking::bond(Origin::signed(1), 2, 1, RewardDestination::Controller), - "can not bond with value less than minimum balance", + Error::::InsufficientValue, ); // bonded with absolute minimum value possible. assert_ok!(Staking::bond(Origin::signed(1), 2, 5, RewardDestination::Controller)); @@ -1660,12 +1660,26 @@ fn reward_validator_slashing_validator_doesnt_overflow() { // Set staker let _ = Balances::make_free_balance_be(&11, stake); let _ = Balances::make_free_balance_be(&2, stake); + + // only slashes out of bonded stake are applied. without this line, + // it is 0. + Staking::bond(Origin::signed(2), 20000, stake - 1, RewardDestination::default()).unwrap(); >::insert(&11, Exposure { total: stake, own: 1, others: vec![ IndividualExposure { who: 2, value: stake - 1 } ]}); + // Check slashing - let _ = Staking::slash_validator(&11, reward_slash, &Staking::stakers(&11), &mut Vec::new()); + on_offence_now( + &[ + OffenceDetails { + offender: (11, Staking::stakers(&11)), + reporters: vec![], + }, + ], + &[Perbill::from_percent(100)], + ); + assert_eq!(Balances::total_balance(&11), stake - 1); assert_eq!(Balances::total_balance(&2), 1); }) @@ -1674,9 +1688,9 @@ fn reward_validator_slashing_validator_doesnt_overflow() { #[test] fn reward_from_authorship_event_handler_works() { ExtBuilder::default().build().execute_with(|| { - use authorship::EventHandler; + use pallet_authorship::EventHandler; - assert_eq!(>::author(), 11); + assert_eq!(>::author(), 11); >::note_author(11); >::note_uncle(21, 1); @@ -1760,7 +1774,7 @@ fn era_is_always_same_length() { #[test] fn offence_forces_new_era() { ExtBuilder::default().build().execute_with(|| { - Staking::on_offence( + on_offence_now( &[OffenceDetails { offender: ( 11, @@ -1780,7 +1794,7 @@ fn offence_ensures_new_era_without_clobbering() { ExtBuilder::default().build().execute_with(|| { assert_ok!(Staking::force_new_era_always(Origin::ROOT)); - Staking::on_offence( + on_offence_now( &[OffenceDetails { offender: ( 11, @@ -1799,7 +1813,7 @@ fn offence_ensures_new_era_without_clobbering() { fn offence_deselects_validator_when_slash_is_zero() { ExtBuilder::default().build().execute_with(|| { assert!(>::exists(11)); - Staking::on_offence( + on_offence_now( &[OffenceDetails { offender: ( 11, @@ -1822,7 +1836,7 @@ fn slashing_performed_according_exposure() { assert_eq!(Staking::stakers(&11).own, 1000); // Handle an offence with a historical exposure. - Staking::on_offence( + on_offence_now( &[OffenceDetails { offender: ( 11, @@ -1842,6 +1856,71 @@ fn slashing_performed_according_exposure() { }); } +#[test] +fn slash_in_old_span_does_not_deselect() { + ExtBuilder::default().build().execute_with(|| { + start_era(1); + + assert!(>::exists(11)); + on_offence_now( + &[OffenceDetails { + offender: ( + 11, + Staking::stakers(&11), + ), + reporters: vec![], + }], + &[Perbill::from_percent(0)], + ); + assert_eq!(Staking::force_era(), Forcing::ForceNew); + assert!(!>::exists(11)); + + start_era(2); + + Staking::validate(Origin::signed(10), Default::default()).unwrap(); + assert_eq!(Staking::force_era(), Forcing::NotForcing); + assert!(>::exists(11)); + + start_era(3); + + // this staker is in a new slashing span now, having re-registered after + // their prior slash. + + on_offence_in_era( + &[OffenceDetails { + offender: ( + 11, + Staking::stakers(&11), + ), + reporters: vec![], + }], + &[Perbill::from_percent(0)], + 1, + ); + + // not for zero-slash. + assert_eq!(Staking::force_era(), Forcing::NotForcing); + assert!(>::exists(11)); + + on_offence_in_era( + &[OffenceDetails { + offender: ( + 11, + Staking::stakers(&11), + ), + reporters: vec![], + }], + &[Perbill::from_percent(100)], + 1, + ); + + // or non-zero. + assert_eq!(Staking::force_era(), Forcing::NotForcing); + assert!(>::exists(11)); + assert_ledger_consistent(11); + }); +} + #[test] fn reporters_receive_their_slice() { // This test verifies that the reporters of the offence receive their slice from the slashed @@ -1855,7 +1934,7 @@ fn reporters_receive_their_slice() { assert_eq!(Staking::stakers(&11).total, initial_balance); - Staking::on_offence( + on_offence_now( &[OffenceDetails { offender: ( 11, @@ -1866,27 +1945,80 @@ fn reporters_receive_their_slice() { &[Perbill::from_percent(50)], ); - // initial_balance x 50% (slash fraction) x 10% (rewards slice) - let reward = initial_balance / 20 / 2; - assert_eq!(Balances::free_balance(&1), 10 + reward); - assert_eq!(Balances::free_balance(&2), 20 + reward); + // F1 * (reward_proportion * slash - 0) + // 50% * (10% * initial_balance / 2) + let reward = (initial_balance / 20) / 2; + let reward_each = reward / 2; // split into two pieces. + assert_eq!(Balances::free_balance(&1), 10 + reward_each); + assert_eq!(Balances::free_balance(&2), 20 + reward_each); + assert_ledger_consistent(11); }); } #[test] -fn invulnerables_are_not_slashed() { - // For invulnerable validators no slashing is performed. - ExtBuilder::default().invulnerables(vec![11]).build().execute_with(|| { +fn subsequent_reports_in_same_span_pay_out_less() { + // This test verifies that the reporters of the offence receive their slice from the slashed + // amount. + ExtBuilder::default().build().execute_with(|| { + // The reporters' reward is calculated from the total exposure. #[cfg(feature = "equalize")] let initial_balance = 1250; #[cfg(not(feature = "equalize"))] - let initial_balance = 1375; + let initial_balance = 1125; + + assert_eq!(Staking::stakers(&11).total, initial_balance); + on_offence_now( + &[OffenceDetails { + offender: ( + 11, + Staking::stakers(&11), + ), + reporters: vec![1], + }], + &[Perbill::from_percent(20)], + ); + + // F1 * (reward_proportion * slash - 0) + // 50% * (10% * initial_balance * 20%) + let reward = (initial_balance / 5) / 20; + assert_eq!(Balances::free_balance(&1), 10 + reward); + + on_offence_now( + &[OffenceDetails { + offender: ( + 11, + Staking::stakers(&11), + ), + reporters: vec![1], + }], + &[Perbill::from_percent(50)], + ); + + let prior_payout = reward; + + // F1 * (reward_proportion * slash - prior_payout) + // 50% * (10% * (initial_balance / 2) - prior_payout) + let reward = ((initial_balance / 20) - prior_payout) / 2; + assert_eq!(Balances::free_balance(&1), 10 + prior_payout + reward); + assert_ledger_consistent(11); + }); +} + +#[test] +fn invulnerables_are_not_slashed() { + // For invulnerable validators no slashing is performed. + ExtBuilder::default().invulnerables(vec![11]).build().execute_with(|| { assert_eq!(Balances::free_balance(&11), 1000); assert_eq!(Balances::free_balance(&21), 2000); - assert_eq!(Staking::stakers(&21).total, initial_balance); - Staking::on_offence( + let exposure = Staking::stakers(&21); + let initial_balance = Staking::slashable_balance_of(&21); + + let nominator_balances: Vec<_> = exposure.others + .iter().map(|o| Balances::free_balance(&o.who)).collect(); + + on_offence_now( &[ OffenceDetails { offender: (11, Staking::stakers(&11)), @@ -1904,6 +2036,16 @@ fn invulnerables_are_not_slashed() { assert_eq!(Balances::free_balance(&11), 1000); // 2000 - (0.2 * initial_balance) assert_eq!(Balances::free_balance(&21), 2000 - (2 * initial_balance / 10)); + + // ensure that nominators were slashed as well. + for (initial_balance, other) in nominator_balances.into_iter().zip(exposure.others) { + assert_eq!( + Balances::free_balance(&other.who), + initial_balance - (2 * other.value / 10), + ); + } + assert_ledger_consistent(11); + assert_ledger_consistent(21); }); } @@ -1913,7 +2055,7 @@ fn dont_slash_if_fraction_is_zero() { ExtBuilder::default().build().execute_with(|| { assert_eq!(Balances::free_balance(&11), 1000); - Staking::on_offence( + on_offence_now( &[OffenceDetails { offender: ( 11, @@ -1926,5 +2068,462 @@ fn dont_slash_if_fraction_is_zero() { // The validator hasn't been slashed. The new era is not forced. assert_eq!(Balances::free_balance(&11), 1000); + assert_ledger_consistent(11); + }); +} + +#[test] +fn only_slash_for_max_in_era() { + ExtBuilder::default().build().execute_with(|| { + assert_eq!(Balances::free_balance(&11), 1000); + + on_offence_now( + &[ + OffenceDetails { + offender: (11, Staking::stakers(&11)), + reporters: vec![], + }, + ], + &[Perbill::from_percent(50)], + ); + + // The validator has been slashed and has been force-chilled. + assert_eq!(Balances::free_balance(&11), 500); + assert_eq!(Staking::force_era(), Forcing::ForceNew); + + on_offence_now( + &[ + OffenceDetails { + offender: (11, Staking::stakers(&11)), + reporters: vec![], + }, + ], + &[Perbill::from_percent(25)], + ); + + // The validator has not been slashed additionally. + assert_eq!(Balances::free_balance(&11), 500); + + on_offence_now( + &[ + OffenceDetails { + offender: (11, Staking::stakers(&11)), + reporters: vec![], + }, + ], + &[Perbill::from_percent(60)], + ); + + // The validator got slashed 10% more. + assert_eq!(Balances::free_balance(&11), 400); + assert_ledger_consistent(11); + }) +} + +#[test] +fn garbage_collection_after_slashing() { + ExtBuilder::default().existential_deposit(1).build().execute_with(|| { + assert_eq!(Balances::free_balance(&11), 256_000); + + on_offence_now( + &[ + OffenceDetails { + offender: (11, Staking::stakers(&11)), + reporters: vec![], + }, + ], + &[Perbill::from_percent(10)], + ); + + assert_eq!(Balances::free_balance(&11), 256_000 - 25_600); + assert!(::SlashingSpans::get(&11).is_some()); + assert_eq!(::SpanSlash::get(&(11, 0)).amount_slashed(), &25_600); + + on_offence_now( + &[ + OffenceDetails { + offender: (11, Staking::stakers(&11)), + reporters: vec![], + }, + ], + &[Perbill::from_percent(100)], + ); + + // validator and nominator slash in era are garbage-collected by era change, + // so we don't test those here. + + assert_eq!(Balances::free_balance(&11), 0); + assert!(::SlashingSpans::get(&11).is_none()); + assert_eq!(::SpanSlash::get(&(11, 0)).amount_slashed(), &0); + }) +} + +#[test] +fn garbage_collection_on_window_pruning() { + ExtBuilder::default().build().execute_with(|| { + start_era(1); + + assert_eq!(Balances::free_balance(&11), 1000); + + let exposure = Staking::stakers(&11); + assert_eq!(Balances::free_balance(&101), 2000); + let nominated_value = exposure.others.iter().find(|o| o.who == 101).unwrap().value; + + on_offence_now( + &[ + OffenceDetails { + offender: (11, Staking::stakers(&11)), + reporters: vec![], + }, + ], + &[Perbill::from_percent(10)], + ); + + let now = Staking::current_era(); + + assert_eq!(Balances::free_balance(&11), 900); + assert_eq!(Balances::free_balance(&101), 2000 - (nominated_value / 10)); + + assert!(::ValidatorSlashInEra::get(&now, &11).is_some()); + assert!(::NominatorSlashInEra::get(&now, &101).is_some()); + + // + 1 because we have to exit the bonding window. + for era in (0..(BondingDuration::get() + 1)).map(|offset| offset + now + 1) { + assert!(::ValidatorSlashInEra::get(&now, &11).is_some()); + assert!(::NominatorSlashInEra::get(&now, &101).is_some()); + + start_era(era); + } + + assert!(::ValidatorSlashInEra::get(&now, &11).is_none()); + assert!(::NominatorSlashInEra::get(&now, &101).is_none()); + }) +} + +#[test] +fn slashing_nominators_by_span_max() { + ExtBuilder::default().build().execute_with(|| { + start_era(1); + start_era(2); + start_era(3); + + assert_eq!(Balances::free_balance(&11), 1000); + assert_eq!(Balances::free_balance(&21), 2000); + assert_eq!(Balances::free_balance(&101), 2000); + assert_eq!(Staking::slashable_balance_of(&21), 1000); + + + let exposure_11 = Staking::stakers(&11); + let exposure_21 = Staking::stakers(&21); + assert_eq!(Balances::free_balance(&101), 2000); + let nominated_value_11 = exposure_11.others.iter().find(|o| o.who == 101).unwrap().value; + let nominated_value_21 = exposure_21.others.iter().find(|o| o.who == 101).unwrap().value; + + on_offence_in_era( + &[ + OffenceDetails { + offender: (11, Staking::stakers(&11)), + reporters: vec![], + }, + ], + &[Perbill::from_percent(10)], + 2, + ); + + assert_eq!(Balances::free_balance(&11), 900); + + let slash_1_amount = Perbill::from_percent(10) * nominated_value_11; + assert_eq!(Balances::free_balance(&101), 2000 - slash_1_amount); + + let expected_spans = vec![ + slashing::SlashingSpan { index: 1, start: 4, length: None }, + slashing::SlashingSpan { index: 0, start: 0, length: Some(4) }, + ]; + + let get_span = |account| ::SlashingSpans::get(&account).unwrap(); + + assert_eq!( + get_span(11).iter().collect::>(), + expected_spans, + ); + + assert_eq!( + get_span(101).iter().collect::>(), + expected_spans, + ); + + // second slash: higher era, higher value, same span. + on_offence_in_era( + &[ + OffenceDetails { + offender: (21, Staking::stakers(&21)), + reporters: vec![], + }, + ], + &[Perbill::from_percent(30)], + 3, + ); + + // 11 was not further slashed, but 21 and 101 were. + assert_eq!(Balances::free_balance(&11), 900); + assert_eq!(Balances::free_balance(&21), 1700); + + let slash_2_amount = Perbill::from_percent(30) * nominated_value_21; + assert!(slash_2_amount > slash_1_amount); + + // only the maximum slash in a single span is taken. + assert_eq!(Balances::free_balance(&101), 2000 - slash_2_amount); + + // third slash: in same era and on same validator as first, higher + // in-era value, but lower slash value than slash 2. + on_offence_in_era( + &[ + OffenceDetails { + offender: (11, Staking::stakers(&11)), + reporters: vec![], + }, + ], + &[Perbill::from_percent(20)], + 2, + ); + + // 11 was further slashed, but 21 and 101 were not. + assert_eq!(Balances::free_balance(&11), 800); + assert_eq!(Balances::free_balance(&21), 1700); + + let slash_3_amount = Perbill::from_percent(20) * nominated_value_21; + assert!(slash_3_amount < slash_2_amount); + assert!(slash_3_amount > slash_1_amount); + + // only the maximum slash in a single span is taken. + assert_eq!(Balances::free_balance(&101), 2000 - slash_2_amount); + }); +} + +#[test] +fn slashes_are_summed_across_spans() { + ExtBuilder::default().build().execute_with(|| { + start_era(1); + start_era(2); + start_era(3); + + assert_eq!(Balances::free_balance(&21), 2000); + assert_eq!(Staking::slashable_balance_of(&21), 1000); + + let get_span = |account| ::SlashingSpans::get(&account).unwrap(); + + on_offence_now( + &[ + OffenceDetails { + offender: (21, Staking::stakers(&21)), + reporters: vec![], + }, + ], + &[Perbill::from_percent(10)], + ); + + let expected_spans = vec![ + slashing::SlashingSpan { index: 1, start: 4, length: None }, + slashing::SlashingSpan { index: 0, start: 0, length: Some(4) }, + ]; + + assert_eq!(get_span(21).iter().collect::>(), expected_spans); + assert_eq!(Balances::free_balance(&21), 1900); + + // 21 has been force-chilled. re-signal intent to validate. + Staking::validate(Origin::signed(20), Default::default()).unwrap(); + + start_era(4); + + assert_eq!(Staking::slashable_balance_of(&21), 900); + + on_offence_now( + &[ + OffenceDetails { + offender: (21, Staking::stakers(&21)), + reporters: vec![], + }, + ], + &[Perbill::from_percent(10)], + ); + + let expected_spans = vec![ + slashing::SlashingSpan { index: 2, start: 5, length: None }, + slashing::SlashingSpan { index: 1, start: 4, length: Some(1) }, + slashing::SlashingSpan { index: 0, start: 0, length: Some(4) }, + ]; + + assert_eq!(get_span(21).iter().collect::>(), expected_spans); + assert_eq!(Balances::free_balance(&21), 1810); + }); +} + +#[test] +fn deferred_slashes_are_deferred() { + ExtBuilder::default().slash_defer_duration(2).build().execute_with(|| { + start_era(1); + + assert_eq!(Balances::free_balance(&11), 1000); + + let exposure = Staking::stakers(&11); + assert_eq!(Balances::free_balance(&101), 2000); + let nominated_value = exposure.others.iter().find(|o| o.who == 101).unwrap().value; + + on_offence_now( + &[ + OffenceDetails { + offender: (11, Staking::stakers(&11)), + reporters: vec![], + }, + ], + &[Perbill::from_percent(10)], + ); + + assert_eq!(Balances::free_balance(&11), 1000); + assert_eq!(Balances::free_balance(&101), 2000); + + start_era(2); + + assert_eq!(Balances::free_balance(&11), 1000); + assert_eq!(Balances::free_balance(&101), 2000); + + start_era(3); + + assert_eq!(Balances::free_balance(&11), 1000); + assert_eq!(Balances::free_balance(&101), 2000); + + // at the start of era 4, slashes from era 1 are processed, + // after being deferred for at least 2 full eras. + start_era(4); + + assert_eq!(Balances::free_balance(&11), 900); + assert_eq!(Balances::free_balance(&101), 2000 - (nominated_value / 10)); + }) +} + +#[test] +fn remove_deferred() { + ExtBuilder::default().slash_defer_duration(2).build().execute_with(|| { + start_era(1); + + assert_eq!(Balances::free_balance(&11), 1000); + + let exposure = Staking::stakers(&11); + assert_eq!(Balances::free_balance(&101), 2000); + let nominated_value = exposure.others.iter().find(|o| o.who == 101).unwrap().value; + + on_offence_now( + &[ + OffenceDetails { + offender: (11, exposure.clone()), + reporters: vec![], + }, + ], + &[Perbill::from_percent(10)], + ); + + assert_eq!(Balances::free_balance(&11), 1000); + assert_eq!(Balances::free_balance(&101), 2000); + + start_era(2); + + on_offence_in_era( + &[ + OffenceDetails { + offender: (11, exposure.clone()), + reporters: vec![], + }, + ], + &[Perbill::from_percent(15)], + 1, + ); + + Staking::cancel_deferred_slash(Origin::ROOT, 1, vec![0]).unwrap(); + + assert_eq!(Balances::free_balance(&11), 1000); + assert_eq!(Balances::free_balance(&101), 2000); + + start_era(3); + + assert_eq!(Balances::free_balance(&11), 1000); + assert_eq!(Balances::free_balance(&101), 2000); + + // at the start of era 4, slashes from era 1 are processed, + // after being deferred for at least 2 full eras. + start_era(4); + + // the first slash for 10% was cancelled, so no effect. + assert_eq!(Balances::free_balance(&11), 1000); + assert_eq!(Balances::free_balance(&101), 2000); + + start_era(5); + + let slash_10 = Perbill::from_percent(10); + let slash_15 = Perbill::from_percent(15); + let initial_slash = slash_10 * nominated_value; + + let total_slash = slash_15 * nominated_value; + let actual_slash = total_slash - initial_slash; + + // 5% slash (15 - 10) processed now. + assert_eq!(Balances::free_balance(&11), 950); + assert_eq!(Balances::free_balance(&101), 2000 - actual_slash); + }) +} + +#[test] +fn remove_multi_deferred() { + ExtBuilder::default().slash_defer_duration(2).build().execute_with(|| { + start_era(1); + + assert_eq!(Balances::free_balance(&11), 1000); + + let exposure = Staking::stakers(&11); + assert_eq!(Balances::free_balance(&101), 2000); + + on_offence_now( + &[ + OffenceDetails { + offender: (11, exposure.clone()), + reporters: vec![], + }, + ], + &[Perbill::from_percent(10)], + ); + + on_offence_now( + &[ + OffenceDetails { + offender: (21, Staking::stakers(&21)), + reporters: vec![], + } + ], + &[Perbill::from_percent(10)], + ); + + + on_offence_now( + &[ + OffenceDetails { + offender: (11, exposure.clone()), + reporters: vec![], + }, + ], + &[Perbill::from_percent(25)], + ); + + assert_eq!(::UnappliedSlashes::get(&1).len(), 3); + Staking::cancel_deferred_slash(Origin::ROOT, 1, vec![0, 2]).unwrap(); + + let slashes = ::UnappliedSlashes::get(&1); + assert_eq!(slashes.len(), 1); + assert_eq!(slashes[0].validator, 21); + }) +} + +#[test] +fn version_initialized() { + ExtBuilder::default().build().execute_with(|| { + assert_eq!(::StorageVersion::get(), crate::migration::CURRENT_VERSION); }); } diff --git a/frame/sudo/Cargo.toml b/frame/sudo/Cargo.toml index dc158c2b80d7587f7fdbd4696dd3e625ee26b266..c97d04f9c7ce1f64685c4a74c0ea6604bf4a8e47 100644 --- a/frame/sudo/Cargo.toml +++ b/frame/sudo/Cargo.toml @@ -7,23 +7,23 @@ edition = "2018" [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -rstd = { package = "sr-std", path = "../../primitives/sr-std", default-features = false } -runtime-io = { package = "sr-io", path = "../../primitives/sr-io", default-features = false } -sr-primitives = { path = "../../primitives/sr-primitives", default-features = false } -support = { package = "frame-support", path = "../support", default-features = false } -system = { package = "frame-system", path = "../system", default-features = false } +sp-std = { version = "2.0.0", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0", default-features = false, path = "../support" } +frame-system = { version = "2.0.0", default-features = false, path = "../system" } [dev-dependencies] -primitives = { package = "substrate-primitives", path = "../../primitives/core" } +sp-core = { version = "2.0.0", path = "../../primitives/core" } [features] default = ["std"] std = [ "serde", "codec/std", - "rstd/std", - "runtime-io/std", - "sr-primitives/std", - "support/std", - "system/std", + "sp-std/std", + "sp-io/std", + "sp-runtime/std", + "frame-support/std", + "frame-system/std", ] diff --git a/frame/sudo/src/lib.rs b/frame/sudo/src/lib.rs index 082d1f673703e2dfaf505cb7026618297ee8376d..00a1b72a86ecd9ed6715e83fd4f5668ab238f96d 100644 --- a/frame/sudo/src/lib.rs +++ b/frame/sudo/src/lib.rs @@ -51,14 +51,14 @@ //! This is an example of a module that exposes a privileged function: //! //! ``` -//! use support::{decl_module, dispatch::Result}; -//! use system::ensure_root; +//! use frame_support::{decl_module, dispatch}; +//! use frame_system::{self as system, ensure_root}; //! -//! pub trait Trait: system::Trait {} +//! pub trait Trait: frame_system::Trait {} //! //! decl_module! { //! pub struct Module for enum Call where origin: T::Origin { -//! pub fn privileged_function(origin) -> Result { +//! pub fn privileged_function(origin) -> dispatch::DispatchResult { //! ensure_root(origin)?; //! //! // do something... @@ -86,19 +86,18 @@ #![cfg_attr(not(feature = "std"), no_std)] -use rstd::prelude::*; -use sr_primitives::{ - traits::{StaticLookup, Dispatchable}, DispatchError, -}; -use support::{ - Parameter, decl_module, decl_event, decl_storage, ensure, +use sp_std::prelude::*; +use sp_runtime::{traits::{StaticLookup, Dispatchable}, DispatchError}; + +use frame_support::{ + Parameter, decl_module, decl_event, decl_storage, decl_error, ensure, weights::SimpleDispatchInfo, }; -use system::ensure_signed; +use frame_system::{self as system, ensure_signed}; -pub trait Trait: system::Trait { +pub trait Trait: frame_system::Trait { /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// A sudo-able call. type Proposal: Parameter + Dispatchable; @@ -107,6 +106,8 @@ pub trait Trait: system::Trait { decl_module! { // Simple declaration of the `Module` type. Lets the macro know what it's working on. pub struct Module for enum Call where origin: T::Origin { + type Error = Error; + fn deposit_event() = default; /// Authenticates the sudo key and dispatches a function call with `Root` origin. @@ -123,13 +124,13 @@ decl_module! { fn sudo(origin, proposal: Box) { // This is a public call, so we ensure that the origin is some signed account. let sender = ensure_signed(origin)?; - ensure!(sender == Self::key(), "only the current sudo key can sudo"); + ensure!(sender == Self::key(), Error::::RequireSudo); - let res = match proposal.dispatch(system::RawOrigin::Root.into()) { + let res = match proposal.dispatch(frame_system::RawOrigin::Root.into()) { Ok(_) => true, Err(e) => { let e: DispatchError = e.into(); - sr_primitives::print(e); + sp_runtime::print(e); false } }; @@ -149,7 +150,7 @@ decl_module! { fn set_key(origin, new: ::Source) { // This is a public call, so we ensure that the origin is some signed account. let sender = ensure_signed(origin)?; - ensure!(sender == Self::key(), "only the current sudo key can change the sudo key"); + ensure!(sender == Self::key(), Error::::RequireSudo); let new = T::Lookup::lookup(new)?; Self::deposit_event(RawEvent::KeyChanged(Self::key())); @@ -171,15 +172,15 @@ decl_module! { fn sudo_as(origin, who: ::Source, proposal: Box) { // This is a public call, so we ensure that the origin is some signed account. let sender = ensure_signed(origin)?; - ensure!(sender == Self::key(), "only the current sudo key can sudo"); + ensure!(sender == Self::key(), Error::::RequireSudo); let who = T::Lookup::lookup(who)?; - let res = match proposal.dispatch(system::RawOrigin::Signed(who).into()) { + let res = match proposal.dispatch(frame_system::RawOrigin::Signed(who).into()) { Ok(_) => true, Err(e) => { let e: DispatchError = e.into(); - sr_primitives::print(e); + sp_runtime::print(e); false } }; @@ -190,7 +191,7 @@ decl_module! { } decl_event!( - pub enum Event where AccountId = ::AccountId { + pub enum Event where AccountId = ::AccountId { /// A sudo just took place. Sudid(bool), /// The sudoer just switched identity; the old key is supplied. @@ -206,3 +207,11 @@ decl_storage! { Key get(fn key) config(): T::AccountId; } } + +decl_error! { + /// Error for the Sudo module + pub enum Error for Module { + /// Sender must be the Sudo account + RequireSudo, + } +} diff --git a/frame/support/Cargo.toml b/frame/support/Cargo.toml index fea24fd6d65ba6e6bcf95a7af7aee1c1ca9bd153..1695375d36832f06b9191124394344271db6c88b 100644 --- a/frame/support/Cargo.toml +++ b/frame/support/Cargo.toml @@ -8,24 +8,24 @@ edition = "2018" log = "0.4" serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.0.6", default-features = false, features = ["derive"] } -frame-metadata = { path = "../metadata", default-features = false } -rstd = { package = "sr-std", path = "../../primitives/sr-std", default-features = false } -runtime-io ={ package = "sr-io", path = "../../primitives/sr-io", default-features = false } -sr-primitives = { path = "../../primitives/sr-primitives", default-features = false } -primitives = { package = "substrate-primitives", path = "../../primitives/core", default-features = false } -sr-arithmetic = { path = "../../primitives/sr-arithmetic", default-features = false } -inherents = { package = "substrate-inherents", path = "../../primitives/inherents", default-features = false } -frame-support-procedural = { package = "frame-support-procedural", path = "./procedural" } +frame-metadata = { version = "2.0.0", default-features = false, path = "../metadata" } +sp-std = { version = "2.0.0", default-features = false, path = "../../primitives/std" } +sp-io ={ path = "../../primitives/io", default-features = false } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" } +sp-core = { version = "2.0.0", default-features = false, path = "../../primitives/core" } +sp-arithmetic = { version = "2.0.0", default-features = false, path = "../../primitives/arithmetic" } +sp-inherents = { version = "2.0.0", default-features = false, path = "../../primitives/inherents" } +frame-support-procedural = { version = "2.0.0", path = "./procedural" } paste = "0.1.6" once_cell = { version = "0.2.4", default-features = false, optional = true } -state-machine = { package = "substrate-state-machine", path = "../../primitives/state-machine", optional = true } +sp-state-machine = { version = "2.0.0", optional = true, path = "../../primitives/state-machine" } bitmask = { version = "0.5.0", default-features = false } impl-trait-for-tuples = "0.1.3" tracing = { version = "0.1.10", optional = true } [dev-dependencies] pretty_assertions = "0.6.1" -frame-system = { path = "../system" } +frame-system = { version = "2.0.0", path = "../system" } [features] default = ["std"] @@ -34,14 +34,14 @@ std = [ "once_cell", "bitmask/std", "serde", - "runtime-io/std", + "sp-io/std", "codec/std", - "rstd/std", - "sr-primitives/std", - "sr-arithmetic/std", + "sp-std/std", + "sp-runtime/std", + "sp-arithmetic/std", "frame-metadata/std", - "inherents/std", - "state-machine", + "sp-inherents/std", + "sp-state-machine", ] nightly = [] strict = [] diff --git a/frame/support/procedural/Cargo.toml b/frame/support/procedural/Cargo.toml index 2231cf67db8070f8d755a42280982e94a8302bc2..9280289028a5afb87cb6d50dd8569aa1f5016721 100644 --- a/frame/support/procedural/Cargo.toml +++ b/frame/support/procedural/Cargo.toml @@ -8,7 +8,7 @@ edition = "2018" proc-macro = true [dependencies] -frame-support-procedural-tools = { package = "frame-support-procedural-tools", path = "./tools" } +frame-support-procedural-tools = { version = "2.0.0", path = "./tools" } proc-macro2 = "1.0.6" quote = "1.0.2" diff --git a/frame/support/procedural/src/construct_runtime/mod.rs b/frame/support/procedural/src/construct_runtime/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..8472542d16d97b5e2dfbd6b3e2368f1428b23a57 --- /dev/null +++ b/frame/support/procedural/src/construct_runtime/mod.rs @@ -0,0 +1,383 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +mod parse; + +use frame_support_procedural_tools::syn_ext as ext; +use frame_support_procedural_tools::{generate_crate_access, generate_hidden_includes}; +use parse::{ModuleDeclaration, RuntimeDefinition, WhereSection}; +use proc_macro::TokenStream; +use proc_macro2::{Span, TokenStream as TokenStream2}; +use quote::quote; +use syn::{Ident, Result}; + +/// The fixed name of the system module. +const SYSTEM_MODULE_NAME: &str = "System"; + +pub fn construct_runtime(input: TokenStream) -> TokenStream { + let definition = syn::parse_macro_input!(input as RuntimeDefinition); + construct_runtime_parsed(definition) + .unwrap_or_else(|e| e.to_compile_error()) + .into() +} + +fn construct_runtime_parsed(definition: RuntimeDefinition) -> Result { + let RuntimeDefinition { + name, + where_section: WhereSection { + block, + node_block, + unchecked_extrinsic, + .. + }, + modules: + ext::Braces { + content: ext::Punctuated { inner: modules, .. }, + token: modules_token, + }, + .. + } = definition; + + // Assert we have system module declared + let system_module = match find_system_module(modules.iter()) { + Some(sm) => sm, + None => { + return Err(syn::Error::new( + modules_token.span, + "`System` module declaration is missing. \ + Please add this line: `System: system::{Module, Call, Storage, Config, Event},`", + )) + } + }; + let hidden_crate_name = "construct_runtime"; + let scrate = generate_crate_access(&hidden_crate_name, "frame-support"); + let scrate_decl = generate_hidden_includes(&hidden_crate_name, "frame-support"); + + let all_but_system_modules = modules.iter().filter(|module| module.name != SYSTEM_MODULE_NAME); + + let outer_event = decl_outer_event_or_origin( + &name, + all_but_system_modules.clone(), + &system_module, + &scrate, + DeclOuterKind::Event, + )?; + let outer_origin = decl_outer_event_or_origin( + &name, + all_but_system_modules.clone(), + &system_module, + &scrate, + DeclOuterKind::Origin, + )?; + let all_modules = decl_all_modules(&name, modules.iter()); + let module_to_index = decl_module_to_index(modules.iter(), modules.len(), &scrate); + + let dispatch = decl_outer_dispatch(&name, modules.iter(), &scrate); + let metadata = decl_runtime_metadata(&name, modules.iter(), &scrate); + let outer_config = decl_outer_config(&name, modules.iter(), &scrate); + let inherent = decl_outer_inherent(&block, &unchecked_extrinsic, modules.iter(), &scrate); + let validate_unsigned = decl_validate_unsigned(&name, modules.iter(), &scrate); + + Ok(quote!( + #scrate_decl + + #[derive(Clone, Copy, PartialEq, Eq)] + #[cfg_attr(feature = "std", derive(Debug))] + pub struct #name; + impl #scrate::sp_runtime::traits::GetNodeBlockType for #name { + type NodeBlock = #node_block; + } + impl #scrate::sp_runtime::traits::GetRuntimeBlockType for #name { + type RuntimeBlock = #block; + } + + #outer_event + + #outer_origin + + #all_modules + + #module_to_index + + #dispatch + + #metadata + + #outer_config + + #inherent + + #validate_unsigned + ) + .into()) +} + +fn decl_validate_unsigned<'a>( + runtime: &'a Ident, + module_declarations: impl Iterator, + scrate: &'a TokenStream2, +) -> TokenStream2 { + let modules_tokens = module_declarations + .filter(|module_declaration| module_declaration.exists_part("ValidateUnsigned")) + .map(|module_declaration| &module_declaration.name); + quote!( + #scrate::impl_outer_validate_unsigned!( + impl ValidateUnsigned for #runtime { + #( #modules_tokens )* + } + ); + ) +} + +fn decl_outer_inherent<'a>( + block: &'a syn::TypePath, + unchecked_extrinsic: &'a syn::TypePath, + module_declarations: impl Iterator, + scrate: &'a TokenStream2, +) -> TokenStream2 { + let modules_tokens = module_declarations.filter_map(|module_declaration| { + let maybe_config_part = module_declaration.find_part("Inherent"); + maybe_config_part.map(|config_part| { + let arg = config_part + .args + .as_ref() + .and_then(|parens| parens.content.inner.iter().next()) + .unwrap_or(&module_declaration.name); + let name = &module_declaration.name; + quote!(#name : #arg,) + }) + }); + quote!( + #scrate::impl_outer_inherent!( + impl Inherents where Block = #block, UncheckedExtrinsic = #unchecked_extrinsic { + #(#modules_tokens)* + } + ); + ) +} + +fn decl_outer_config<'a>( + runtime: &'a Ident, + module_declarations: impl Iterator, + scrate: &'a TokenStream2, +) -> TokenStream2 { + let modules_tokens = module_declarations + .filter_map(|module_declaration| { + module_declaration.find_part("Config").map(|part| { + let transformed_generics: Vec<_> = part + .generics + .params + .iter() + .map(|param| quote!(<#param>)) + .collect(); + (module_declaration, transformed_generics) + }) + }) + .map(|(module_declaration, generics)| { + let module = &module_declaration.module; + let name = Ident::new( + &format!("{}Config", module_declaration.name), + module_declaration.name.span(), + ); + let instance = module_declaration.instance.as_ref().into_iter(); + quote!( + #name => + #module #(#instance)* #(#generics)*, + ) + }); + quote!( + #scrate::sp_runtime::impl_outer_config! { + pub struct GenesisConfig for #runtime { + #(#modules_tokens)* + } + } + ) +} + +fn decl_runtime_metadata<'a>( + runtime: &'a Ident, + module_declarations: impl Iterator, + scrate: &'a TokenStream2, +) -> TokenStream2 { + let modules_tokens = module_declarations + .filter_map(|module_declaration| { + module_declaration.find_part("Module").map(|_| { + let filtered_names: Vec<_> = module_declaration + .module_parts() + .into_iter() + .filter(|part| part.name != "Module") + .map(|part| part.name.clone()) + .collect(); + (module_declaration, filtered_names) + }) + }) + .map(|(module_declaration, filtered_names)| { + let module = &module_declaration.module; + let name = &module_declaration.name; + let instance = module_declaration + .instance + .as_ref() + .map(|name| quote!(<#name>)) + .into_iter(); + quote!(#module::Module #(#instance)* as #name with #(#filtered_names)* ,) + }); + quote!( + #scrate::impl_runtime_metadata!{ + for #runtime with modules + #(#modules_tokens)* + } + ) +} + +fn decl_outer_dispatch<'a>( + runtime: &'a Ident, + module_declarations: impl Iterator, + scrate: &'a TokenStream2, +) -> TokenStream2 { + let modules_tokens = module_declarations + .filter(|module_declaration| module_declaration.exists_part("Call")) + .map(|module_declaration| { + let module = &module_declaration.module; + let name = &module_declaration.name; + quote!(#module::#name) + }); + quote!( + #scrate::impl_outer_dispatch! { + pub enum Call for #runtime where origin: Origin { + #(#modules_tokens,)* + } + } + ) +} + +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +enum DeclOuterKind { + Event, + Origin, +} + +fn decl_outer_event_or_origin<'a>( + runtime_name: &'a Ident, + module_declarations: impl Iterator, + system_name: &'a Ident, + scrate: &'a TokenStream2, + kind: DeclOuterKind, +) -> syn::Result { + let mut modules_tokens = TokenStream2::new(); + let kind_str = format!("{:?}", kind); + for module_declaration in module_declarations { + match module_declaration.find_part(&kind_str) { + Some(module_entry) => { + let module = &module_declaration.module; + let instance = module_declaration.instance.as_ref(); + let generics = &module_entry.generics; + if instance.is_some() && generics.params.len() == 0 { + let msg = format!( + "Instantiable module with no generic `{}` cannot \ + be constructed: module `{}` must have generic `{}`", + kind_str, module_declaration.name, kind_str + ); + return Err(syn::Error::new(module_declaration.name.span(), msg)); + } + let tokens = quote!(#module #instance #generics ,); + modules_tokens.extend(tokens); + } + None => {} + } + } + let macro_call = match kind { + DeclOuterKind::Event => quote!(#scrate::impl_outer_event!), + DeclOuterKind::Origin => quote!(#scrate::impl_outer_origin!), + }; + let enum_name = Ident::new(kind_str.as_str(), Span::call_site()); + Ok(quote!( + #macro_call { + pub enum #enum_name for #runtime_name where system = #system_name { + #modules_tokens + } + } + )) +} + +fn decl_all_modules<'a>( + runtime: &'a Ident, + module_declarations: impl Iterator, +) -> TokenStream2 { + let mut types = TokenStream2::new(); + let mut names = Vec::new(); + for module_declaration in module_declarations { + let type_name = &module_declaration.name; + let module = &module_declaration.module; + let mut generics = vec![quote!(#runtime)]; + generics.extend( + module_declaration + .instance + .iter() + .map(|name| quote!(#module::#name)), + ); + let type_decl = quote!( + pub type #type_name = #module::Module <#(#generics),*>; + ); + types.extend(type_decl); + names.push(&module_declaration.name); + } + // Make nested tuple structure like (((Babe, Consensus), Grandpa), ...) + // But ignore the system module. + let all_modules = names.iter() + .filter(|n| **n != SYSTEM_MODULE_NAME) + .fold(TokenStream2::default(), |combined, name| quote!((#name, #combined))); + + quote!( + #types + type AllModules = ( #all_modules ); + ) +} + +fn decl_module_to_index<'a>( + module_declarations: impl Iterator, + num_modules: usize, + scrate: &TokenStream2, +) -> TokenStream2 { + let names = module_declarations.map(|d| &d.name); + let indices = 0..num_modules; + + quote!( + /// Provides an implementation of `ModuleToIndex` to map a module + /// to its index in the runtime. + pub struct ModuleToIndex; + + impl #scrate::traits::ModuleToIndex for ModuleToIndex { + fn module_to_index() -> Option { + let type_id = #scrate::sp_std::any::TypeId::of::(); + #( + if type_id == #scrate::sp_std::any::TypeId::of::<#names>() { + return Some(#indices) + } + )* + + None + } + } + ) +} + +fn find_system_module<'a>( + mut module_declarations: impl Iterator, +) -> Option<&'a Ident> { + module_declarations + .find(|decl| decl.name == SYSTEM_MODULE_NAME) + .map(|decl| &decl.module) +} diff --git a/frame/support/procedural/src/construct_runtime/parse.rs b/frame/support/procedural/src/construct_runtime/parse.rs new file mode 100644 index 0000000000000000000000000000000000000000..84ac6573c6379374c8a13443e168bc5603489ed1 --- /dev/null +++ b/frame/support/procedural/src/construct_runtime/parse.rs @@ -0,0 +1,401 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +use frame_support_procedural_tools::syn_ext as ext; +use proc_macro2::Span; +use std::collections::HashSet; +use syn::{ + parse::{Parse, ParseStream}, + spanned::Spanned, + token, Error, Ident, Result, Token, +}; + +mod keyword { + syn::custom_keyword!(Block); + syn::custom_keyword!(NodeBlock); + syn::custom_keyword!(UncheckedExtrinsic); +} + +#[derive(Debug)] +pub struct RuntimeDefinition { + pub visibility_token: Token![pub], + pub enum_token: Token![enum], + pub name: Ident, + pub where_section: WhereSection, + pub modules: ext::Braces>, +} + +impl Parse for RuntimeDefinition { + fn parse(input: ParseStream) -> Result { + Ok(Self { + visibility_token: input.parse()?, + enum_token: input.parse()?, + name: input.parse()?, + where_section: input.parse()?, + modules: input.parse()?, + }) + } +} + +#[derive(Debug)] +pub struct WhereSection { + pub block: syn::TypePath, + pub node_block: syn::TypePath, + pub unchecked_extrinsic: syn::TypePath, +} + +impl Parse for WhereSection { + fn parse(input: ParseStream) -> Result { + input.parse::()?; + let mut definitions = Vec::new(); + while !input.peek(token::Brace) { + let definition: WhereDefinition = input.parse()?; + definitions.push(definition); + if !input.peek(Token![,]) { + if !input.peek(token::Brace) { + return Err(input.error("Expected `,` or `{`")); + } + break; + } + input.parse::()?; + } + let block = remove_kind(input, WhereKind::Block, &mut definitions)?.value; + let node_block = remove_kind(input, WhereKind::NodeBlock, &mut definitions)?.value; + let unchecked_extrinsic = + remove_kind(input, WhereKind::UncheckedExtrinsic, &mut definitions)?.value; + if let Some(WhereDefinition { + ref kind_span, + ref kind, + .. + }) = definitions.first() + { + let msg = format!( + "`{:?}` was declared above. Please use exactly one delcataion for `{:?}`.", + kind, kind + ); + return Err(Error::new(*kind_span, msg)); + } + Ok(Self { + block, + node_block, + unchecked_extrinsic, + }) + } +} + +#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)] +pub enum WhereKind { + Block, + NodeBlock, + UncheckedExtrinsic, +} + +#[derive(Debug)] +pub struct WhereDefinition { + pub kind_span: Span, + pub kind: WhereKind, + pub value: syn::TypePath, +} + +impl Parse for WhereDefinition { + fn parse(input: ParseStream) -> Result { + let lookahead = input.lookahead1(); + let (kind_span, kind) = if lookahead.peek(keyword::Block) { + (input.parse::()?.span(), WhereKind::Block) + } else if lookahead.peek(keyword::NodeBlock) { + ( + input.parse::()?.span(), + WhereKind::NodeBlock, + ) + } else if lookahead.peek(keyword::UncheckedExtrinsic) { + ( + input.parse::()?.span(), + WhereKind::UncheckedExtrinsic, + ) + } else { + return Err(lookahead.error()); + }; + + Ok(Self { + kind_span, + kind, + value: { + let _: Token![=] = input.parse()?; + input.parse()? + }, + }) + } +} + +#[derive(Debug)] +pub struct ModuleDeclaration { + pub name: Ident, + pub module: Ident, + pub instance: Option, + pub details: Option>>, +} + +impl Parse for ModuleDeclaration { + fn parse(input: ParseStream) -> Result { + let name = input.parse()?; + let _: Token![:] = input.parse()?; + let module = input.parse()?; + let instance = if input.peek(Token![::]) && input.peek3(Token![<]) { + let _: Token![::] = input.parse()?; + let _: Token![<] = input.parse()?; + let res = Some(input.parse()?); + let _: Token![>] = input.parse()?; + res + } else { + None + }; + let details = if input.peek(Token![::]) { + let _: Token![::] = input.parse()?; + Some(input.parse()?) + } else { + None + }; + let parsed = Self { + name, + module, + instance, + details, + }; + if let Some(ref details) = parsed.details { + let parts = &details.content.inner; + let mut resolved = HashSet::new(); + let has_default = parts.into_iter().any(|m| m.is_default()); + for entry in parts { + match entry { + ModuleEntry::Part(part) if has_default => { + if part.is_included_in_default() { + let msg = format!( + "`{}` is already included in `default`. Either remove `default` or remove `{}`", + part.name, + part.name + ); + return Err(Error::new(part.name.span(), msg)); + } + } + ModuleEntry::Part(part) => { + if !resolved.insert(part.name.clone()) { + let msg = format!( + "`{}` was already declared before. Please remove the duplicate declaration", + part.name + ); + return Err(Error::new(part.name.span(), msg)); + } + } + _ => {} + } + } + } + Ok(parsed) + } +} + +impl ModuleDeclaration { + /// Get resolved module parts, i.e. after expanding `default` keyword + /// or empty declaration + pub fn module_parts(&self) -> Vec { + if let Some(ref details) = self.details { + details + .content + .inner + .iter() + .flat_map(|entry| match entry { + ModuleEntry::Default(ref token) => Self::default_modules(token.span()), + ModuleEntry::Part(ref part) => vec![part.clone()], + }) + .collect() + } else { + Self::default_modules(self.module.span()) + } + } + + pub fn find_part(&self, name: &str) -> Option { + self.module_parts() + .into_iter() + .find(|part| part.name == name) + } + + pub fn exists_part(&self, name: &str) -> bool { + self.find_part(name).is_some() + } + + fn default_modules(span: Span) -> Vec { + let mut res: Vec<_> = ["Module", "Call", "Storage"] + .iter() + .map(|name| ModulePart::with_name(name, span)) + .collect(); + res.extend( + ["Event", "Config"] + .iter() + .map(|name| ModulePart::with_generics(name, span)), + ); + res + } +} + +#[derive(Debug)] +pub enum ModuleEntry { + Default(Token![default]), + Part(ModulePart), +} + +impl Parse for ModuleEntry { + fn parse(input: ParseStream) -> Result { + let lookahead = input.lookahead1(); + if lookahead.peek(Token![default]) { + Ok(ModuleEntry::Default(input.parse()?)) + } else if lookahead.peek(Ident) { + Ok(ModuleEntry::Part(input.parse()?)) + } else { + Err(lookahead.error()) + } + } +} + +impl ModuleEntry { + pub fn is_default(&self) -> bool { + match self { + ModuleEntry::Default(_) => true, + _ => false, + } + } +} + +#[derive(Debug, Clone)] +pub struct ModulePart { + pub name: Ident, + pub generics: syn::Generics, + pub args: Option>>, +} + +impl Parse for ModulePart { + fn parse(input: ParseStream) -> Result { + let name = input.parse()?; + let generics: syn::Generics = input.parse()?; + if !generics.params.is_empty() && !Self::is_allowed_generic(&name) { + let valid_generics = ModulePart::format_names(ModulePart::allowed_generics()); + let msg = format!( + "`{}` is not allowed to have generics. \ + Only the following modules are allowed to have generics: {}.", + name, valid_generics + ); + return Err(syn::Error::new(name.span(), msg)); + } + let args = if input.peek(token::Paren) { + if !Self::is_allowed_arg(&name) { + let syn::group::Parens { token: parens, .. } = syn::group::parse_parens(input)?; + let valid_names = ModulePart::format_names(ModulePart::allowed_args()); + let msg = format!( + "`{}` is not allowed to have arguments in parens. \ + Only the following modules are allowed to have arguments in parens: {}.", + name, valid_names + ); + return Err(syn::Error::new(parens.span, msg)); + } + Some(input.parse()?) + } else { + None + }; + Ok(Self { + name, + generics, + args, + }) + } +} + +impl ModulePart { + pub fn is_allowed_generic(ident: &Ident) -> bool { + Self::allowed_generics().into_iter().any(|n| ident == n) + } + + pub fn is_allowed_arg(ident: &Ident) -> bool { + Self::allowed_args().into_iter().any(|n| ident == n) + } + + pub fn allowed_generics() -> Vec<&'static str> { + vec!["Event", "Origin", "Config"] + } + + pub fn allowed_args() -> Vec<&'static str> { + vec!["Inherent"] + } + + pub fn format_names(names: Vec<&'static str>) -> String { + let res: Vec<_> = names.into_iter().map(|s| format!("`{}`", s)).collect(); + res.join(", ") + } + + pub fn is_included_in_default(&self) -> bool { + ["Module", "Call", "Storage", "Event", "Config"] + .iter() + .any(|name| self.name == name) + } + + /// Plain module name like `Event` or `Call`, etc. + pub fn with_name(name: &str, span: Span) -> Self { + let name = Ident::new(name, span); + Self { + name, + generics: syn::Generics { + lt_token: None, + gt_token: None, + where_clause: None, + ..Default::default() + }, + args: None, + } + } + + /// Module name with generic like `Event` or `Call`, etc. + pub fn with_generics(name: &str, span: Span) -> Self { + let name = Ident::new(name, span); + let typ = Ident::new("T", span); + let generic_param = syn::GenericParam::Type(typ.into()); + let generic_params = vec![generic_param].into_iter().collect(); + let generics = syn::Generics { + lt_token: Some(syn::token::Lt { spans: [span] }), + params: generic_params, + gt_token: Some(syn::token::Gt { spans: [span] }), + where_clause: None, + }; + Self { + name, + generics, + args: None, + } + } +} + +fn remove_kind( + input: ParseStream, + kind: WhereKind, + definitions: &mut Vec, +) -> Result { + if let Some(pos) = definitions.iter().position(|d| d.kind == kind) { + Ok(definitions.remove(pos)) + } else { + let msg = format!( + "Missing associated type for `{:?}`. Add `{:?}` = ... to where section.", + kind, kind + ); + Err(input.error(msg)) + } +} diff --git a/frame/support/procedural/src/lib.rs b/frame/support/procedural/src/lib.rs index 1832e870a3593277a688da9ee457d7fdec557161..d9c2fe03c9bf51e4621afef816d7d855c082f901 100644 --- a/frame/support/procedural/src/lib.rs +++ b/frame/support/procedural/src/lib.rs @@ -23,6 +23,7 @@ extern crate proc_macro; mod storage; +mod construct_runtime; use proc_macro::TokenStream; @@ -55,11 +56,20 @@ use proc_macro::TokenStream; /// * Value: `Foo: type`: Implements the /// [`StorageValue`](../frame_support/storage/trait.StorageValue.html) trait using the /// [`StorageValue generator`](../frame_support/storage/generator/trait.StorageValue.html). -/// The generator `unhashed_key` is `$module_prefix ++ " " ++ $storage_name` +/// +/// The generator is implemented with: +/// * `module_prefix`: module_prefix +/// * `storage_prefix`: storage_name +/// +/// Thus the storage value is finally stored at: +/// ```nocompile +/// Twox128(module_prefix) ++ Twox128(storage_prefix) +/// ``` /// /// * Map: `Foo: map hasher($hash) type => type`: Implements the /// [`StorageMap`](../frame_support/storage/trait.StorageMap.html) trait using the /// [`StorageMap generator`](../frame_support/storage/generator/trait.StorageMap.html). +/// And [`StoragePrefixedMap`](../frame_support/storage/trait.StoragePrefixedMap.html). /// /// `$hash` representing a choice of hashing algorithms available in the /// [`Hashable`](../frame_support/trait.Hashable.html) trait. @@ -68,12 +78,19 @@ use proc_macro::TokenStream; /// with care, see generator documentation. /// /// The generator is implemented with: -/// * `prefix`: `$module_prefix ++ " " ++ $storage_name` +/// * `module_prefix`: $module_prefix +/// * `storage_prefix`: storage_name /// * `Hasher`: $hash /// +/// Thus the keys are stored at: +/// ```nocompile +/// twox128(module_prefix) ++ twox128(storage_prefix) ++ hasher(encode(key)) +/// ``` +/// /// * Linked map: `Foo: linked_map hasher($hash) type => type`: Implements the /// [`StorageLinkedMap`](../frame_support/storage/trait.StorageLinkedMap.html) trait using the /// [`StorageLinkedMap generator`](../frame_support/storage/generator/trait.StorageLinkedMap.html). +/// And [`StoragePrefixedMap`](../frame_support/storage/trait.StoragePrefixedMap.html). /// /// `$hash` representing a choice of hashing algorithms available in the /// [`Hashable`](../frame_support/trait.Hashable.html) trait. @@ -81,18 +98,29 @@ use proc_macro::TokenStream; /// `hasher($hash)` is optional and its default is `blake2_256`. One should use another hasher /// with care, see generator documentation. /// -/// The generator is implemented with: -/// * `prefix`: `$module_prefix ++ " " ++ $storage_name` -/// * `head_key`: `"head of " ++ $module_prefix ++ " " ++ $storage_name` -/// * `Hasher`: $hash -/// /// All key formatting logic can be accessed in a type-agnostic format via the /// [`KeyFormat`](../srml_support/storage/generator/trait.KeyFormat.html) trait, which /// is implemented for the storage linked map type as well. /// +/// The generator key format is implemented with: +/// * `module_prefix`: $module_prefix +/// * `storage_prefix`: storage_name +/// * `head_prefix`: `"HeadOf" ++ storage_name` +/// * `Hasher`: $hash +/// +/// Thus the keys are stored at: +/// ```nocompile +/// Twox128(module_prefix) ++ Twox128(storage_prefix) ++ Hasher(encode(key)) +/// ``` +/// and head is stored at: +/// ```nocompile +/// Twox128(module_prefix) ++ Twox128(head_prefix) +/// ``` +/// /// * Double map: `Foo: double_map hasher($hash1) u32, $hash2(u32) => u32`: Implements the /// [`StorageDoubleMap`](../frame_support/storage/trait.StorageDoubleMap.html) trait using the /// [`StorageDoubleMap generator`](../frame_support/storage/generator/trait.StorageDoubleMap.html). +/// And [`StoragePrefixedMap`](../frame_support/storage/trait.StoragePrefixedMap.html). /// /// `$hash1` and `$hash2` representing choices of hashing algorithms available in the /// [`Hashable`](../frame_support/trait.Hashable.html) trait. They must be choosen with care, see @@ -110,10 +138,16 @@ use proc_macro::TokenStream; /// Otherwise, other items in storage with the same first key can be compromised. /// /// The generator is implemented with: -/// * `key1_prefix`: `$module_prefix ++ " " ++ $storage_name` +/// * `module_prefix`: $module_prefix +/// * `storage_prefix`: storage_name /// * `Hasher1`: $hash1 /// * `Hasher2`: $hash2 /// +/// Thus keys are stored at: +/// ```nocompile +/// Twox128(module_prefix) ++ Twox128(storage_prefix) ++ Hasher1(encode(key1)) ++ Hasher2(encode(key2)) +/// ``` +/// /// Supported hashers (ordered from least to best security): /// /// * `twox_64_concat` - TwoX with 64bit + key concatenated. @@ -219,3 +253,63 @@ use proc_macro::TokenStream; pub fn decl_storage(input: TokenStream) -> TokenStream { storage::decl_storage_impl(input) } + +/// Construct a runtime, with the given name and the given modules. +/// +/// The parameters here are specific types for `Block`, `NodeBlock`, and `UncheckedExtrinsic` +/// and the modules that are used by the runtime. +/// `Block` is the block type that is used in the runtime and `NodeBlock` is the block type +/// that is used in the node. For instance they can differ in the extrinsics type. +/// +/// # Example: +/// +/// ```nocompile +/// construct_runtime!( +/// pub enum Runtime where +/// Block = Block, +/// NodeBlock = runtime::Block, +/// UncheckedExtrinsic = UncheckedExtrinsic +/// { +/// System: system, +/// Test: test::{default}, +/// Test2: test_with_long_module::{Module}, +/// +/// // Module with instances +/// Test3_Instance1: test3::::{Module, Call, Storage, Event, Config, Origin}, +/// Test3_DefaultInstance: test3::{Module, Call, Storage, Event, Config, Origin}, +/// } +/// ) +/// ``` +/// +/// The module `System: system` will expand to `System: system::{Module, Call, Storage, Event, Config}`. +/// The identifier `System` is the name of the module and the lower case identifier `system` is the +/// name of the Rust module/crate for this Substrate module. +/// +/// The module `Test: test::{default}` will expand to +/// `Test: test::{Module, Call, Storage, Event, Config}`. +/// +/// The module `Test2: test_with_long_module::{Module}` will expand to +/// `Test2: test_with_long_module::{Module}`. +/// +/// We provide support for the following types in a module: +/// +/// - `Module` +/// - `Call` +/// - `Storage` +/// - `Event` or `Event` (if the event is generic) +/// - `Origin` or `Origin` (if the origin is generic) +/// - `Config` or `Config` (if the config is generic) +/// - `Inherent ( $(CALL),* )` - If the module provides/can check inherents. The optional parameter +/// is for modules that use a `Call` from a different module as +/// inherent. +/// - `ValidateUnsigned` - If the module validates unsigned extrinsics. +/// +/// # Note +/// +/// The population of the genesis storage depends on the order of modules. So, if one of your +/// modules depends on another module, the module that is depended upon needs to come before +/// the module depending on it. +#[proc_macro] +pub fn construct_runtime(input: TokenStream) -> TokenStream { + construct_runtime::construct_runtime(input) +} diff --git a/frame/support/procedural/src/storage/genesis_config/builder_def.rs b/frame/support/procedural/src/storage/genesis_config/builder_def.rs index fbab6819492906f7a242ccc8fb6ad7541d305f00..7edee59de8c3b8ec0e25df115d97856f44c24377 100644 --- a/frame/support/procedural/src/storage/genesis_config/builder_def.rs +++ b/frame/support/procedural/src/storage/genesis_config/builder_def.rs @@ -44,32 +44,55 @@ impl BuilderDef { let storage_trait = &line.storage_trait; let value_type = &line.value_type; - // Contains the data to inset at genesis either from build or config. + // Defines the data variable to use for insert at genesis either from build or config. let mut data = None; if let Some(builder) = &line.build { is_generic |= ext::expr_contains_ident(&builder, &def.module_runtime_generic); is_generic |= line.is_generic; - data = Some(quote_spanned!(builder.span() => &(#builder)(self))); + data = Some(match &line.storage_type { + StorageLineTypeDef::Simple(_) if line.is_option => + quote_spanned!(builder.span() => + let data = (#builder)(self); + let data = Option::as_ref(&data); + ), + _ => quote_spanned!(builder.span() => let data = &(#builder)(self); ), + }); } else if let Some(config) = &line.config { is_generic |= line.is_generic; - data = Some(quote!(&self.#config;)); + data = Some(match &line.storage_type { + StorageLineTypeDef::Simple(_) if line.is_option => + quote!( let data = Some(&self.#config); ), + _ => quote!( let data = &self.#config; ), + }); }; if let Some(data) = data { blocks.push(match &line.storage_type { - StorageLineTypeDef::Simple(_) => { + StorageLineTypeDef::Simple(_) if line.is_option => { + quote!{{ + #data + let v: Option<&#value_type>= data; + if let Some(v) = v { + <#storage_struct as #scrate::#storage_trait>::put::<&#value_type>(v); + } + }} + }, + StorageLineTypeDef::Simple(_) if !line.is_option => { quote!{{ - let v: &#value_type = #data; + #data + let v: &#value_type = data; <#storage_struct as #scrate::#storage_trait>::put::<&#value_type>(v); }} }, + StorageLineTypeDef::Simple(_) => unreachable!(), StorageLineTypeDef::Map(map) | StorageLineTypeDef::LinkedMap(map) => { let key = &map.key; quote!{{ - let data: &#scrate::rstd::vec::Vec<(#key, #value_type)> = #data; + #data + let data: &#scrate::sp_std::vec::Vec<(#key, #value_type)> = data; data.iter().for_each(|(k, v)| { <#storage_struct as #scrate::#storage_trait>::insert::< &#key, &#value_type @@ -81,7 +104,8 @@ impl BuilderDef { let key1 = &map.key1; let key2 = &map.key2; quote!{{ - let data: &#scrate::rstd::vec::Vec<(#key1, #key2, #value_type)> = #data; + #data + let data: &#scrate::sp_std::vec::Vec<(#key1, #key2, #value_type)> = data; data.iter().for_each(|(k1, k2, v)| { <#storage_struct as #scrate::#storage_trait>::insert::< &#key1, &#key2, &#value_type diff --git a/frame/support/procedural/src/storage/genesis_config/mod.rs b/frame/support/procedural/src/storage/genesis_config/mod.rs index c222644f78ae3c32d564f1505b69fec9d6a617ab..4e91ccd1df13e9cecee0c3d875968e71b5506a17 100644 --- a/frame/support/procedural/src/storage/genesis_config/mod.rs +++ b/frame/support/procedural/src/storage/genesis_config/mod.rs @@ -132,20 +132,17 @@ fn impl_build_storage( let builder_blocks = &builders.blocks; let build_storage_impl_trait = quote!( - #scrate::sr_primitives::BuildModuleGenesisStorage<#runtime_generic, #inherent_instance> + #scrate::sp_runtime::BuildModuleGenesisStorage<#runtime_generic, #inherent_instance> ); quote!{ #[cfg(feature = "std")] impl#genesis_impl GenesisConfig#genesis_struct #genesis_where_clause { pub fn build_storage #fn_generic (&self) -> std::result::Result< - ( - #scrate::sr_primitives::StorageOverlay, - #scrate::sr_primitives::ChildrenStorageOverlay, - ), + #scrate::sp_runtime::Storage, String > #fn_where_clause { - let mut storage = (Default::default(), Default::default()); + let mut storage = Default::default(); self.assimilate_storage::<#fn_traitinstance>(&mut storage)?; Ok(storage) } @@ -153,12 +150,9 @@ fn impl_build_storage( /// Assimilate the storage for this module into pre-existing overlays. pub fn assimilate_storage #fn_generic ( &self, - tuple_storage: &mut ( - #scrate::sr_primitives::StorageOverlay, - #scrate::sr_primitives::ChildrenStorageOverlay, - ), + storage: &mut #scrate::sp_runtime::Storage, ) -> std::result::Result<(), String> #fn_where_clause { - #scrate::BasicExternalities::execute_with_storage(tuple_storage, || { + #scrate::BasicExternalities::execute_with_storage(storage, || { #( #builder_blocks )* Ok(()) }) @@ -171,10 +165,7 @@ fn impl_build_storage( { fn build_module_genesis_storage( &self, - storage: &mut ( - #scrate::sr_primitives::StorageOverlay, - #scrate::sr_primitives::ChildrenStorageOverlay, - ), + storage: &mut #scrate::sp_runtime::Storage, ) -> std::result::Result<(), String> { self.assimilate_storage::<#fn_traitinstance> (storage) } diff --git a/frame/support/procedural/src/storage/instance_trait.rs b/frame/support/procedural/src/storage/instance_trait.rs index 1a7add89a4b80024f35f512176db7eba61655fd2..abc56092e31e4b784fd584e2fbbb535e8d473d28 100644 --- a/frame/support/procedural/src/storage/instance_trait.rs +++ b/frame/support/procedural/src/storage/instance_trait.rs @@ -19,24 +19,12 @@ use proc_macro2::{TokenStream, Span}; use quote::quote; -use super::{DeclStorageDefExt, StorageLineTypeDef}; +use super::DeclStorageDefExt; const NUMBER_OF_INSTANCE: usize = 16; -const INHERENT_INSTANCE_NAME: &str = "__InherentHiddenInstance"; +pub(crate) const INHERENT_INSTANCE_NAME: &str = "__InherentHiddenInstance"; pub(crate) const DEFAULT_INSTANTIABLE_TRAIT_NAME: &str = "__GeneratedInstantiable"; -// prefix for consts in trait Instance -pub(crate) const PREFIX_FOR: &str = "PREFIX_FOR_"; -pub(crate) const HEAD_KEY_FOR: &str = "HEAD_KEY_FOR_"; - -// Used to generate the const: -// `const $name: &'static str = $value_prefix ++ instance_prefix ++ $value_suffix` -struct InstanceConstDef { - name: syn::Ident, - value_prefix: String, - value_suffix: String, -} - // Used to generate an instance implementation. struct InstanceDef { prefix: String, @@ -47,33 +35,7 @@ struct InstanceDef { pub fn decl_and_impl(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStream { let mut impls = TokenStream::new(); - let mut const_defs = vec![]; - - for line in def.storage_lines.iter() { - let storage_prefix = format!("{} {}", def.crate_name, line.name); - - let const_name = syn::Ident::new( - &format!("{}{}", PREFIX_FOR, line.name.to_string()), proc_macro2::Span::call_site() - ); - const_defs.push(InstanceConstDef { - name: const_name, - value_prefix: String::new(), - value_suffix: storage_prefix.clone(), - }); - - if let StorageLineTypeDef::LinkedMap(_) = line.storage_type { - let const_name = syn::Ident::new( - &format!("{}{}", HEAD_KEY_FOR, line.name.to_string()), proc_macro2::Span::call_site() - ); - const_defs.push(InstanceConstDef { - name: const_name, - value_prefix: "head of ".into(), - value_suffix: storage_prefix, - }); - } - } - - impls.extend(create_instance_trait(&const_defs, def)); + impls.extend(create_instance_trait(def)); // Implementation of instances. if let Some(module_instance) = &def.module_instance { @@ -95,7 +57,7 @@ pub fn decl_and_impl(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStre ); for instance_def in instance_defs { - impls.extend(create_and_impl_instance_struct(scrate, &instance_def, &const_defs, def)); + impls.extend(create_and_impl_instance_struct(scrate, &instance_def, def)); } } @@ -116,27 +78,18 @@ pub fn decl_and_impl(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStre instance_struct: inherent_instance, doc: quote!(#[doc(hidden)]), }; - impls.extend(create_and_impl_instance_struct(scrate, &instance_def, &const_defs, def)); + impls.extend(create_and_impl_instance_struct(scrate, &instance_def, def)); } impls } fn create_instance_trait( - const_defs: &[InstanceConstDef], def: &DeclStorageDefExt, ) -> TokenStream { let instance_trait = def.module_instance.as_ref().map(|i| i.instance_trait.clone()) .unwrap_or_else(|| syn::Ident::new(DEFAULT_INSTANTIABLE_TRAIT_NAME, Span::call_site())); - let mut const_impls = TokenStream::new(); - for const_def in const_defs { - let const_name = &const_def.name; - const_impls.extend(quote! { - const #const_name: &'static str; - }); - } - let optional_hide = if def.module_instance.is_some() { quote!() } else { @@ -151,7 +104,6 @@ fn create_instance_trait( pub trait #instance_trait: 'static { /// The prefix used by any storage entry of an instance. const PREFIX: &'static str; - #const_impls } } } @@ -159,22 +111,8 @@ fn create_instance_trait( fn create_and_impl_instance_struct( scrate: &TokenStream, instance_def: &InstanceDef, - const_defs: &[InstanceConstDef], def: &DeclStorageDefExt, ) -> TokenStream { - let mut const_impls = TokenStream::new(); - - for const_def in const_defs { - let const_value = format!( - "{}{}{}", const_def.value_prefix, instance_def.prefix, const_def.value_suffix - ); - let const_name = &const_def.name; - - const_impls.extend(quote! { - const #const_name: &'static str = #const_value; - }); - } - let instance_trait = def.module_instance.as_ref().map(|i| i.instance_trait.clone()) .unwrap_or_else(|| syn::Ident::new(DEFAULT_INSTANTIABLE_TRAIT_NAME, Span::call_site())); @@ -194,7 +132,6 @@ fn create_and_impl_instance_struct( pub struct #instance_struct; impl #instance_trait for #instance_struct { const PREFIX: &'static str = #prefix; - #const_impls } } } diff --git a/frame/support/procedural/src/storage/metadata.rs b/frame/support/procedural/src/storage/metadata.rs index b5ccb8a07ab904862b0c5b3526a4be1a38537245..17ad250f66cb3cd5c269fd23b392baa1e0e09c2f 100644 --- a/frame/support/procedural/src/storage/metadata.rs +++ b/frame/support/procedural/src/storage/metadata.rs @@ -104,11 +104,11 @@ fn default_byte_getter( #[doc(hidden)] pub struct #struct_name< #runtime_generic, #optional_instance_bound_optional_default - >(pub #scrate::rstd::marker::PhantomData<(#runtime_generic #optional_comma_instance)>); + >(pub #scrate::sp_std::marker::PhantomData<(#runtime_generic #optional_comma_instance)>); #[cfg(feature = "std")] #[allow(non_upper_case_globals)] - static #cache_name: #scrate::once_cell::sync::OnceCell<#scrate::rstd::vec::Vec> = + static #cache_name: #scrate::once_cell::sync::OnceCell<#scrate::sp_std::vec::Vec> = #scrate::once_cell::sync::OnceCell::new(); #[cfg(feature = "std")] @@ -117,7 +117,7 @@ fn default_byte_getter( for #struct_name<#runtime_generic, #optional_instance> #where_clause { - fn default_byte(&self) -> #scrate::rstd::vec::Vec { + fn default_byte(&self) -> #scrate::sp_std::vec::Vec { use #scrate::codec::Encode; #cache_name.get_or_init(|| { let def_val: #query_type = #default; @@ -138,7 +138,7 @@ fn default_byte_getter( for #struct_name<#runtime_generic, #optional_instance> #where_clause { - fn default_byte(&self) -> #scrate::rstd::vec::Vec { + fn default_byte(&self) -> #scrate::sp_std::vec::Vec { use #scrate::codec::Encode; let def_val: #query_type = #default; <#query_type as Encode>::encode(&def_val) @@ -146,7 +146,7 @@ fn default_byte_getter( } }; let struct_instance = quote!( - #struct_name::<#runtime_generic, #optional_instance>(#scrate::rstd::marker::PhantomData) + #struct_name::<#runtime_generic, #optional_instance>(#scrate::sp_std::marker::PhantomData) ); (struct_def, struct_instance) diff --git a/frame/support/procedural/src/storage/mod.rs b/frame/support/procedural/src/storage/mod.rs index 0ec266a8a0c54a5e69c9665944481fd383e92231..8fbb97d916ba9e7435d89732c0947e5d2601530a 100644 --- a/frame/support/procedural/src/storage/mod.rs +++ b/frame/support/procedural/src/storage/mod.rs @@ -418,7 +418,8 @@ pub fn decl_storage_impl(input: proc_macro::TokenStream) -> proc_macro::TokenStr StorageValue as _, StorageMap as _, StorageLinkedMap as _, - StorageDoubleMap as _ + StorageDoubleMap as _, + StoragePrefixedMap as _, }; #scrate_decl diff --git a/frame/support/procedural/src/storage/storage_struct.rs b/frame/support/procedural/src/storage/storage_struct.rs index 5267876a4416ca68cb7e3bc9b312973943281bf7..fdb1dbb16192a45876668d829900d77edca5a6b9 100644 --- a/frame/support/procedural/src/storage/storage_struct.rs +++ b/frame/support/procedural/src/storage/storage_struct.rs @@ -16,11 +16,11 @@ //! Implementation of storage structures and implementation of storage traits on them. -use proc_macro2::TokenStream; +use proc_macro2::{TokenStream, Ident, Span}; use quote::quote; use super::{ DeclStorageDefExt, StorageLineTypeDef, - instance_trait::{PREFIX_FOR, HEAD_KEY_FOR}, + instance_trait::INHERENT_INSTANCE_NAME, }; fn from_optional_value_to_query(is_option: bool, default: &Option) -> TokenStream { @@ -68,7 +68,7 @@ pub fn decl_and_impl(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStre #visibility struct #name< #optional_storage_runtime_bound_comma #optional_instance_bound_optional_default >( - #scrate::rstd::marker::PhantomData< + #scrate::sp_std::marker::PhantomData< (#optional_storage_runtime_comma #optional_instance) > ) #optional_storage_where_clause; @@ -78,17 +78,14 @@ pub fn decl_and_impl(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStre let from_optional_value_to_query = from_optional_value_to_query(line.is_option, &line.default_value); - let final_prefix = if let Some(instance) = def.module_instance.as_ref() { - let instance = &instance.instance_generic; - let const_name = syn::Ident::new( - &format!("{}{}", PREFIX_FOR, line.name.to_string()), proc_macro2::Span::call_site() - ); - quote!( #instance::#const_name.as_bytes() ) + // Contains accessor to instance, used to get prefixes + let instance_or_inherent = if let Some(instance) = def.module_instance.as_ref() { + instance.instance_generic.clone() } else { - let prefix = format!("{} {}", def.crate_name, line.name); - quote!( #prefix.as_bytes() ) + Ident::new(INHERENT_INSTANCE_NAME, Span::call_site()) }; + let storage_name_str = syn::LitStr::new(&line.name.to_string(), line.name.span()); let storage_generator_trait = &line.storage_generator_trait; let storage_struct = &line.storage_struct; @@ -104,8 +101,12 @@ pub fn decl_and_impl(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStre { type Query = #query_type; - fn unhashed_key() -> &'static [u8] { - #final_prefix + fn module_prefix() -> &'static [u8] { + #instance_or_inherent::PREFIX.as_bytes() + } + + fn storage_prefix() -> &'static [u8] { + #storage_name_str.as_bytes() } fn from_optional_value_to_query(v: Option<#value_type>) -> Self::Query { @@ -121,14 +122,30 @@ pub fn decl_and_impl(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStre StorageLineTypeDef::Map(map) => { let hasher = map.hasher.to_storage_hasher_struct(); quote!( + impl<#impl_trait> #scrate::storage::StoragePrefixedMap<#value_type> + for #storage_struct #optional_storage_where_clause + { + fn module_prefix() -> &'static [u8] { + #instance_or_inherent::PREFIX.as_bytes() + } + + fn storage_prefix() -> &'static [u8] { + #storage_name_str.as_bytes() + } + } + impl<#impl_trait> #scrate::#storage_generator_trait for #storage_struct #optional_storage_where_clause { type Query = #query_type; type Hasher = #scrate::#hasher; - fn prefix() -> &'static [u8] { - #final_prefix + fn module_prefix() -> &'static [u8] { + #instance_or_inherent::PREFIX.as_bytes() + } + + fn storage_prefix() -> &'static [u8] { + #storage_name_str.as_bytes() } fn from_optional_value_to_query(v: Option<#value_type>) -> Self::Query { @@ -144,30 +161,30 @@ pub fn decl_and_impl(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStre StorageLineTypeDef::LinkedMap(map) => { let hasher = map.hasher.to_storage_hasher_struct(); - // make sure to use different prefix for head and elements. - let head_key = if let Some(instance) = def.module_instance.as_ref() { - let instance = &instance.instance_generic; - let const_name = syn::Ident::new( - &format!("{}{}", HEAD_KEY_FOR, line.name.to_string()), proc_macro2::Span::call_site() - ); - quote!( #instance::#const_name.as_bytes() ) - } else { - let prefix = format!("head of {} {}", def.crate_name, line.name); - quote!( #prefix.as_bytes() ) - }; + let head_prefix_str = syn::LitStr::new( + &format!("HeadOf{}", line.name.to_string()), + line.name.span(), + ); quote!( + impl<#impl_trait> #scrate::storage::StoragePrefixedMap<#value_type> + for #storage_struct #optional_storage_where_clause + { + fn module_prefix() -> &'static [u8] { + #instance_or_inherent::PREFIX.as_bytes() + } + + fn storage_prefix() -> &'static [u8] { + #storage_name_str.as_bytes() + } + } + impl<#impl_trait> #scrate::#storage_generator_trait for #storage_struct #optional_storage_where_clause { type Query = #query_type; - type Hasher = #scrate::#hasher; type KeyFormat = Self; - fn prefix() -> &'static [u8] { - #final_prefix - } - fn from_optional_value_to_query(v: Option<#value_type>) -> Self::Query { #from_optional_value_to_query } @@ -180,8 +197,16 @@ pub fn decl_and_impl(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStre impl<#impl_trait> #scrate::storage::generator::LinkedMapKeyFormat for #storage_struct { type Hasher = #scrate::#hasher; - fn head_key() -> &'static [u8] { - #head_key + fn module_prefix() -> &'static [u8] { + #instance_or_inherent::PREFIX.as_bytes() + } + + fn storage_prefix() -> &'static [u8] { + #storage_name_str.as_bytes() + } + + fn head_prefix() -> &'static [u8] { + #head_prefix_str.as_bytes() } } ) @@ -190,6 +215,18 @@ pub fn decl_and_impl(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStre let hasher1 = map.hasher1.to_storage_hasher_struct(); let hasher2 = map.hasher2.to_storage_hasher_struct(); quote!( + impl<#impl_trait> #scrate::storage::StoragePrefixedMap<#value_type> + for #storage_struct #optional_storage_where_clause + { + fn module_prefix() -> &'static [u8] { + #instance_or_inherent::PREFIX.as_bytes() + } + + fn storage_prefix() -> &'static [u8] { + #storage_name_str.as_bytes() + } + } + impl<#impl_trait> #scrate::#storage_generator_trait for #storage_struct #optional_storage_where_clause { @@ -199,8 +236,12 @@ pub fn decl_and_impl(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStre type Hasher2 = #scrate::#hasher2; - fn key1_prefix() -> &'static [u8] { - #final_prefix + fn module_prefix() -> &'static [u8] { + #instance_or_inherent::PREFIX.as_bytes() + } + + fn storage_prefix() -> &'static [u8] { + #storage_name_str.as_bytes() } fn from_optional_value_to_query(v: Option<#value_type>) -> Self::Query { diff --git a/frame/support/procedural/tools/Cargo.toml b/frame/support/procedural/tools/Cargo.toml index 740a6985fea878bed9dc249acc54d2fbb1a794de..a9b8f6d4bfafd27efc81c1822759b68080ac2af5 100644 --- a/frame/support/procedural/tools/Cargo.toml +++ b/frame/support/procedural/tools/Cargo.toml @@ -5,8 +5,8 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -frame-support-procedural-tools-derive = { package = "frame-support-procedural-tools-derive", path = "./derive" } +frame-support-procedural-tools-derive = { version = "2.0.0", path = "./derive" } proc-macro2 = "1.0.6" quote = "1.0.2" -syn = { version = "1.0.7", features = ["full"] } +syn = { version = "1.0.7", features = ["full", "visit"] } proc-macro-crate = "0.1.4" diff --git a/frame/support/procedural/tools/src/lib.rs b/frame/support/procedural/tools/src/lib.rs index 5340bdbe59d239a7d9d7cfc34383ebc1c65aa6ee..e1e73af10411a020d995427d0b96efa58cd215de 100644 --- a/frame/support/procedural/tools/src/lib.rs +++ b/frame/support/procedural/tools/src/lib.rs @@ -27,12 +27,12 @@ use quote::quote; pub mod syn_ext; -// FIXME #1569, remove the following functions, which are copied from sr-api-macros +// FIXME #1569, remove the following functions, which are copied from sp-api-macros use proc_macro2::{TokenStream, Span}; use syn::Ident; fn generate_hidden_includes_mod_name(unique_id: &str) -> Ident { - Ident::new(&format!("sr_api_hidden_includes_{}", unique_id), Span::call_site()) + Ident::new(&format!("sp_api_hidden_includes_{}", unique_id), Span::call_site()) } /// Generates the access to the `frame-support` crate. @@ -47,7 +47,7 @@ pub fn generate_crate_access(unique_id: &str, def_crate: &str) -> TokenStream { /// Generates the hidden includes that are required to make the macro independent from its scope. pub fn generate_hidden_includes(unique_id: &str, def_crate: &str) -> TokenStream { - if ::std::env::var("CARGO_PKG_NAME").unwrap() == def_crate { + if std::env::var("CARGO_PKG_NAME").unwrap() == def_crate { TokenStream::new() } else { let mod_name = generate_hidden_includes_mod_name(unique_id); diff --git a/frame/support/procedural/tools/src/syn_ext.rs b/frame/support/procedural/tools/src/syn_ext.rs index 18c1cd43ce742744dc0b5ea420164b83c0d2ff95..afcda4eebff8316b893bd78374e2e8b6643d6816 100644 --- a/frame/support/procedural/tools/src/syn_ext.rs +++ b/frame/support/procedural/tools/src/syn_ext.rs @@ -59,6 +59,11 @@ macro_rules! groups_impl { } } + impl Clone for $name

{ + fn clone(&self) -> Self { + Self { token: self.token.clone(), content: self.content.clone() } + } + } } } @@ -72,11 +77,11 @@ pub struct PunctuatedInner { pub variant: V, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct NoTrailing; -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct Trailing; pub type Punctuated = PunctuatedInner; @@ -107,6 +112,12 @@ impl ToTokens for PunctuatedInner { } } +impl Clone for PunctuatedInner { + fn clone(&self) -> Self { + Self { inner: self.inner.clone(), variant: self.variant.clone() } + } +} + /// Note that syn Meta is almost fine for use case (lacks only `ToToken`) #[derive(Debug, Clone)] pub struct Meta { @@ -178,6 +189,14 @@ impl ToTokens for Opt

{ } } +impl Clone for Opt

=

::Hash; +/// Block hash type for a pool. +pub type BlockHash

= <

::Block as BlockT>::Hash; +/// Transaction type for a pool. +pub type TransactionFor

= <

::Block as BlockT>::Extrinsic; +/// Type of transactions event stream for a pool. +pub type TransactionStatusStreamFor

= TransactionStatusStream, BlockHash

>; + +/// In-pool transaction interface. +/// +/// The pool is container of transactions that are implementing this trait. +/// See `sp_runtime::ValidTransaction` for details about every field. +pub trait InPoolTransaction { + /// Transaction type. + type Transaction; + /// Transaction hash type. + type Hash; + + /// Get the reference to the transaction data. + fn data(&self) -> &Self::Transaction; + /// Get hash of the transaction. + fn hash(&self) -> &Self::Hash; + /// Get priority of the transaction. + fn priority(&self) -> &TransactionPriority; + /// Get longevity of the transaction. + fn longevity(&self) ->&TransactionLongevity; + /// Get transaction dependencies. + fn requires(&self) -> &[TransactionTag]; + /// Get tags that transaction provides. + fn provides(&self) -> &[TransactionTag]; + /// Return a flag indicating if the transaction should be propagated to other peers. + fn is_propagateable(&self) -> bool; +} + +/// Transaction pool interface. +pub trait TransactionPool: Send + Sync { + /// Block type. + type Block: BlockT; + /// Transaction hash type. + type Hash: Hash + Eq + Member + Serialize; + /// In-pool transaction type. + type InPoolTransaction: InPoolTransaction< + Transaction = TransactionFor, + Hash = TxHash + >; + /// Error type. + type Error: From + crate::error::IntoPoolError; + + /// Returns a future that imports a bunch of unverified transactions to the pool. + fn submit_at( + &self, + at: &BlockId, + xts: impl IntoIterator> + 'static, + ) -> Box, Self::Error>>, + Self::Error + >> + Send + Unpin>; + + /// Returns a future that imports one unverified transaction to the pool. + fn submit_one( + &self, + at: &BlockId, + xt: TransactionFor, + ) -> Box, + Self::Error + >> + Send + Unpin>; + + /// Returns a future that import a single transaction and starts to watch their progress in the pool. + fn submit_and_watch( + &self, + at: &BlockId, + xt: TransactionFor, + ) -> Box>, Self::Error>> + Send + Unpin>; + + /// Remove transactions identified by given hashes (and dependent transactions) from the pool. + fn remove_invalid(&self, hashes: &[TxHash]) -> Vec>; + + /// Returns pool status. + fn status(&self) -> PoolStatus; + + /// Get an iterator for ready transactions ordered by priority + fn ready(&self) -> Box>>; + + /// Return an event stream of transactions imported to the pool. + fn import_notification_stream(&self) -> ImportNotificationStream; + + /// Returns transaction hash + fn hash_of(&self, xt: &TransactionFor) -> TxHash; + + /// Notify the pool about transactions broadcast. + fn on_broadcasted(&self, propagations: HashMap, Vec>); +} + +/// An abstraction for transaction pool. +/// +/// This trait is used by offchain calls to be able to submit transactions. +/// The main use case is for offchain workers, to feed back the results of computations, +/// but since the transaction pool access is a separate `ExternalitiesExtension` it can +/// be also used in context of other offchain calls. For one may generate and submit +/// a transaction for some misbehavior reports (say equivocation). +pub trait OffchainSubmitTransaction: Send + Sync { + /// Submit transaction. + /// + /// The transaction will end up in the pool and be propagated to others. + fn submit_at( + &self, + at: &BlockId, + extrinsic: Block::Extrinsic, + ) -> Result<(), ()>; +} + +impl OffchainSubmitTransaction for TPool { + fn submit_at( + &self, + at: &BlockId, + extrinsic: ::Extrinsic, + ) -> Result<(), ()> { + log::debug!( + target: "txpool", + "(offchain call) Submitting a transaction to the pool: {:?}", + extrinsic + ); + + let result = futures::executor::block_on(self.submit_one(&at, extrinsic)); + + result.map(|_| ()) + .map_err(|e| log::warn!( + target: "txpool", + "(offchain call) Error submitting a transaction to the pool: {:?}", + e + )) + } +} + +/// Transaction pool maintainer interface. +pub trait TransactionPoolMaintainer: Send + Sync { + /// Block type. + type Block: BlockT; + /// Transaction Hash type. + type Hash: Hash + Eq + Member + Serialize; + + /// Returns a future that performs maintenance procedures on the pool when + /// with given hash is imported. + fn maintain( + &self, + id: &BlockId, + retracted: &[Self::Hash], + ) -> Box + Send + Unpin>; +} + +/// Maintainable pool implementation. +pub struct MaintainableTransactionPool { + pool: Pool, + maintainer: Maintainer, +} + +impl MaintainableTransactionPool { + /// Create new maintainable pool using underlying pool and maintainer. + pub fn new(pool: Pool, maintainer: Maintainer) -> Self { + MaintainableTransactionPool { pool, maintainer } + } +} + +impl TransactionPool for MaintainableTransactionPool + where + Pool: TransactionPool, + Maintainer: Send + Sync, +{ + type Block = Pool::Block; + type Hash = Pool::Hash; + type InPoolTransaction = Pool::InPoolTransaction; + type Error = Pool::Error; + + fn submit_at( + &self, + at: &BlockId, + xts: impl IntoIterator> + 'static, + ) -> Box, Self::Error>>, Self::Error>> + Send + Unpin> { + self.pool.submit_at(at, xts) + } + + fn submit_one( + &self, + at: &BlockId, + xt: TransactionFor, + ) -> Box, Self::Error>> + Send + Unpin> { + self.pool.submit_one(at, xt) + } + + fn submit_and_watch( + &self, + at: &BlockId, + xt: TransactionFor, + ) -> Box>, Self::Error>> + Send + Unpin> { + self.pool.submit_and_watch(at, xt) + } + + fn remove_invalid(&self, hashes: &[TxHash]) -> Vec> { + self.pool.remove_invalid(hashes) + } + + fn status(&self) -> PoolStatus { + self.pool.status() + } + + fn ready(&self) -> Box>> { + self.pool.ready() + } + + fn import_notification_stream(&self) -> ImportNotificationStream { + self.pool.import_notification_stream() + } + + fn hash_of(&self, xt: &TransactionFor) -> TxHash { + self.pool.hash_of(xt) + } + + fn on_broadcasted(&self, propagations: HashMap, Vec>) { + self.pool.on_broadcasted(propagations) + } +} + +impl TransactionPoolMaintainer for MaintainableTransactionPool + where + Pool: Send + Sync, + Maintainer: TransactionPoolMaintainer +{ + type Block = Maintainer::Block; + type Hash = Maintainer::Hash; + + fn maintain( + &self, + id: &BlockId, + retracted: &[Self::Hash], + ) -> Box + Send + Unpin> { + self.maintainer.maintain(id, retracted) + } +} diff --git a/primitives/transaction-pool/runtime-api/src/lib.rs b/primitives/transaction-pool/src/runtime_api.rs similarity index 77% rename from primitives/transaction-pool/runtime-api/src/lib.rs rename to primitives/transaction-pool/src/runtime_api.rs index 48d0f8a85dd31c461b5985fb8e1ec44de2bc17a3..4ca47805b92d36fb2ba0ef75c72e5def14a40d6e 100644 --- a/primitives/transaction-pool/runtime-api/src/lib.rs +++ b/primitives/transaction-pool/src/runtime_api.rs @@ -1,4 +1,4 @@ -// Copyright 2018-2019 Parity Technologies (UK) Ltd. +// Copyright 2019 Parity Technologies (UK) Ltd. // This file is part of Substrate. // Substrate is free software: you can redistribute it and/or modify @@ -14,13 +14,12 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! Substrate runtime api for the transaction queue. +//! Tagged Transaction Queue Runtime API. -#![cfg_attr(not(feature = "std"), no_std)] +use sp_runtime::transaction_validity::TransactionValidity; +use sp_runtime::traits::Block as BlockT; -use sr_primitives::{transaction_validity::TransactionValidity, traits::Block as BlockT}; - -sr_api::decl_runtime_apis! { +sp_api::decl_runtime_apis! { /// The `TaggedTransactionQueue` api trait for interfering with the transaction queue. pub trait TaggedTransactionQueue { /// Validate the given transaction. diff --git a/primitives/trie/Cargo.toml b/primitives/trie/Cargo.toml index a8e98bee0e700b3b3cf98337d18222a306a1b0d3..a4ec92395072207398f1bcfd5b4afe23187170dc 100644 --- a/primitives/trie/Cargo.toml +++ b/primitives/trie/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "substrate-trie" +name = "sp-trie" version = "2.0.0" authors = ["Parity Technologies "] description = "Patricia trie stuff using a parity-scale-codec node format" @@ -13,15 +13,15 @@ harness = false [dependencies] codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false } -rstd = { package = "sr-std", path = "../sr-std", default-features = false } +sp-std = { version = "2.0.0", default-features = false, path = "../std" } hash-db = { version = "0.15.2", default-features = false } trie-db = { version = "0.16.0", default-features = false } trie-root = { version = "0.15.2", default-features = false } memory-db = { version = "0.15.2", default-features = false } -primitives = { package = "substrate-primitives", path = "../core", default-features = false } +sp-core = { version = "2.0.0", default-features = false, path = "../core" } [dev-dependencies] -trie-bench = "0.16.3" +trie-bench = "0.17.0" trie-standardmap = "0.15.2" criterion = "0.2.11" hex-literal = "0.2.1" @@ -29,11 +29,11 @@ hex-literal = "0.2.1" [features] default = ["std"] std = [ - "rstd/std", + "sp-std/std", "codec/std", "hash-db/std", "memory-db/std", "trie-db/std", "trie-root/std", - "primitives/std", + "sp-core/std", ] diff --git a/primitives/trie/benches/bench.rs b/primitives/trie/benches/bench.rs index a8a473222285d78ff92775468f4cefa28a146191..353644ee1efc64a8e0162f49aa49472482fe3ae1 100644 --- a/primitives/trie/benches/bench.rs +++ b/primitives/trie/benches/bench.rs @@ -20,11 +20,11 @@ criterion_main!(benches); fn benchmark(c: &mut Criterion) { trie_bench::standard_benchmark::< - substrate_trie::Layout, - substrate_trie::TrieStream, + sp_trie::Layout, + sp_trie::TrieStream, >(c, "substrate-blake2"); trie_bench::standard_benchmark::< - substrate_trie::Layout, - substrate_trie::TrieStream, + sp_trie::Layout, + sp_trie::TrieStream, >(c, "substrate-keccak"); } diff --git a/primitives/trie/src/lib.rs b/primitives/trie/src/lib.rs index de056cace1b7e39162a1457c6ad938e57cd838e6..08f26e00639ff3972037d73461571a39830a0988 100644 --- a/primitives/trie/src/lib.rs +++ b/primitives/trie/src/lib.rs @@ -23,9 +23,10 @@ mod node_header; mod node_codec; mod trie_stream; -use rstd::boxed::Box; -use rstd::vec::Vec; -use hash_db::Hasher; +use sp_std::boxed::Box; +use sp_std::marker::PhantomData; +use sp_std::vec::Vec; +use hash_db::{Hasher, Prefix}; /// Our `NodeCodec`-specific error. pub use error::Error; /// The Substrate format implementation of `TrieStream`. @@ -44,7 +45,7 @@ pub use hash_db::{HashDB as HashDBT, EMPTY_PREFIX}; #[derive(Default)] /// substrate trie layout -pub struct Layout(rstd::marker::PhantomData); +pub struct Layout(sp_std::marker::PhantomData); impl TrieLayout for Layout { const USE_EXTENSION: bool = false; @@ -167,42 +168,50 @@ pub fn read_trie_value_with< } /// Determine the default child trie root. -pub fn default_child_trie_root(_storage_key: &[u8]) -> Vec { - L::trie_root::<_, Vec, Vec>(core::iter::empty()).as_ref().iter().cloned().collect() +pub fn default_child_trie_root( + _storage_key: &[u8], +) -> ::Out { + L::trie_root::<_, Vec, Vec>(core::iter::empty()) } /// Determine a child trie root given its ordered contents, closed form. H is the default hasher, /// but a generic implementation may ignore this type parameter and use other hashers. -pub fn child_trie_root(_storage_key: &[u8], input: I) -> Vec +pub fn child_trie_root( + _storage_key: &[u8], + input: I, +) -> ::Out where I: IntoIterator, A: AsRef<[u8]> + Ord, B: AsRef<[u8]>, { - L::trie_root(input).as_ref().iter().cloned().collect() + L::trie_root(input) } /// Determine a child trie root given a hash DB and delta values. H is the default hasher, /// but a generic implementation may ignore this type parameter and use other hashers. -pub fn child_delta_trie_root( +pub fn child_delta_trie_root( _storage_key: &[u8], + keyspace: &[u8], db: &mut DB, - root_vec: Vec, - delta: I -) -> Result, Box>> + root_data: RD, + delta: I, +) -> Result<::Out, Box>> where I: IntoIterator)>, A: AsRef<[u8]> + Ord, B: AsRef<[u8]>, + RD: AsRef<[u8]>, DB: hash_db::HashDB + hash_db::PlainDB, trie_db::DBValue>, { let mut root = TrieHash::::default(); // root is fetched from DB, not writable by runtime, so it's always valid. - root.as_mut().copy_from_slice(&root_vec); + root.as_mut().copy_from_slice(root_data.as_ref()); { - let mut trie = TrieDBMut::::from_existing(&mut *db, &mut root)?; + let mut db = KeySpacedDBMut::new(&mut *db, keyspace); + let mut trie = TrieDBMut::::from_existing(&mut db, &mut root)?; for (key, change) in delta { match change { @@ -212,12 +221,13 @@ pub fn child_delta_trie_root( } } - Ok(root.as_ref().to_vec()) + Ok(root) } /// Call `f` for all keys in a child trie. pub fn for_keys_in_child_trie( _storage_key: &[u8], + keyspace: &[u8], db: &DB, root_slice: &[u8], mut f: F @@ -230,7 +240,8 @@ pub fn for_keys_in_child_trie( // root is fetched from DB, not writable by runtime, so it's always valid. root.as_mut().copy_from_slice(root_slice); - let trie = TrieDB::::new(&*db, &root)?; + let db = KeySpacedDB::new(&*db, keyspace); + let trie = TrieDB::::new(&db, &root)?; let iter = trie.iter()?; for x in iter { @@ -267,6 +278,7 @@ pub fn record_all_keys( /// Read a value from the child trie. pub fn read_child_trie_value( _storage_key: &[u8], + keyspace: &[u8], db: &DB, root_slice: &[u8], key: &[u8] @@ -279,12 +291,14 @@ pub fn read_child_trie_value( // root is fetched from DB, not writable by runtime, so it's always valid. root.as_mut().copy_from_slice(root_slice); - Ok(TrieDB::::new(&*db, &root)?.get(key).map(|x| x.map(|val| val.to_vec()))?) + let db = KeySpacedDB::new(&*db, keyspace); + Ok(TrieDB::::new(&db, &root)?.get(key).map(|x| x.map(|val| val.to_vec()))?) } /// Read a value from the child trie with given query. pub fn read_child_trie_value_with, DB>( _storage_key: &[u8], + keyspace: &[u8], db: &DB, root_slice: &[u8], key: &[u8], @@ -298,7 +312,104 @@ pub fn read_child_trie_value_with::new(&*db, &root)?.get_with(key, query).map(|x| x.map(|val| val.to_vec()))?) + let db = KeySpacedDB::new(&*db, keyspace); + Ok(TrieDB::::new(&db, &root)?.get_with(key, query).map(|x| x.map(|val| val.to_vec()))?) +} + +/// `HashDB` implementation that append a encoded prefix (unique id bytes) in addition to the +/// prefix of every key value. +pub struct KeySpacedDB<'a, DB, H>(&'a DB, &'a [u8], PhantomData); + +/// `HashDBMut` implementation that append a encoded prefix (unique id bytes) in addition to the +/// prefix of every key value. +/// +/// Mutable variant of `KeySpacedDB`, see [`KeySpacedDB`]. +pub struct KeySpacedDBMut<'a, DB, H>(&'a mut DB, &'a [u8], PhantomData); + +/// Utility function used to merge some byte data (keyspace) and `prefix` data +/// before calling key value database primitives. +fn keyspace_as_prefix_alloc(ks: &[u8], prefix: Prefix) -> (Vec, Option) { + let mut result = sp_std::vec![0; ks.len() + prefix.0.len()]; + result[..ks.len()].copy_from_slice(ks); + result[ks.len()..].copy_from_slice(prefix.0); + (result, prefix.1) +} + +impl<'a, DB, H> KeySpacedDB<'a, DB, H> where + H: Hasher, +{ + /// instantiate new keyspaced db + pub fn new(db: &'a DB, ks: &'a [u8]) -> Self { + KeySpacedDB(db, ks, PhantomData) + } +} + +impl<'a, DB, H> KeySpacedDBMut<'a, DB, H> where + H: Hasher, +{ + /// instantiate new keyspaced db + pub fn new(db: &'a mut DB, ks: &'a [u8]) -> Self { + KeySpacedDBMut(db, ks, PhantomData) + } +} + +impl<'a, DB, H, T> hash_db::HashDBRef for KeySpacedDB<'a, DB, H> where + DB: hash_db::HashDBRef, + H: Hasher, + T: From<&'static [u8]>, +{ + fn get(&self, key: &H::Out, prefix: Prefix) -> Option { + let derived_prefix = keyspace_as_prefix_alloc(self.1, prefix); + self.0.get(key, (&derived_prefix.0, derived_prefix.1)) + } + + fn contains(&self, key: &H::Out, prefix: Prefix) -> bool { + let derived_prefix = keyspace_as_prefix_alloc(self.1, prefix); + self.0.contains(key, (&derived_prefix.0, derived_prefix.1)) + } +} + +impl<'a, DB, H, T> hash_db::HashDB for KeySpacedDBMut<'a, DB, H> where + DB: hash_db::HashDB, + H: Hasher, + T: Default + PartialEq + for<'b> From<&'b [u8]> + Clone + Send + Sync, +{ + fn get(&self, key: &H::Out, prefix: Prefix) -> Option { + let derived_prefix = keyspace_as_prefix_alloc(self.1, prefix); + self.0.get(key, (&derived_prefix.0, derived_prefix.1)) + } + + fn contains(&self, key: &H::Out, prefix: Prefix) -> bool { + let derived_prefix = keyspace_as_prefix_alloc(self.1, prefix); + self.0.contains(key, (&derived_prefix.0, derived_prefix.1)) + } + + fn insert(&mut self, prefix: Prefix, value: &[u8]) -> H::Out { + let derived_prefix = keyspace_as_prefix_alloc(self.1, prefix); + self.0.insert((&derived_prefix.0, derived_prefix.1), value) + } + + fn emplace(&mut self, key: H::Out, prefix: Prefix, value: T) { + let derived_prefix = keyspace_as_prefix_alloc(self.1, prefix); + self.0.emplace(key, (&derived_prefix.0, derived_prefix.1), value) + } + + fn remove(&mut self, key: &H::Out, prefix: Prefix) { + let derived_prefix = keyspace_as_prefix_alloc(self.1, prefix); + self.0.remove(key, (&derived_prefix.0, derived_prefix.1)) + } +} + +impl<'a, DB, H, T> hash_db::AsHashDB for KeySpacedDBMut<'a, DB, H> where + DB: hash_db::HashDB, + H: Hasher, + T: Default + PartialEq + for<'b> From<&'b [u8]> + Clone + Send + Sync, +{ + fn as_hash_db(&self) -> &dyn hash_db::HashDB { &*self } + + fn as_hash_db_mut<'b>(&'b mut self) -> &'b mut (dyn hash_db::HashDB + 'b) { + &mut *self + } } /// Constants used into trie simplification codec. @@ -314,7 +425,7 @@ mod trie_constants { mod tests { use super::*; use codec::{Encode, Compact}; - use primitives::Blake2Hasher; + use sp_core::Blake2Hasher; use hash_db::{HashDB, Hasher}; use trie_db::{DBValue, TrieMut, Trie, NodeCodec as NodeCodecT}; use trie_standardmap::{Alphabet, ValueMode, StandardMap}; diff --git a/primitives/trie/src/node_codec.rs b/primitives/trie/src/node_codec.rs index e31ce8cc912456d95c0772fbb01b67454cc84596..0b48941ca65ab4e1097f63fc0c4d05a46249f34c 100644 --- a/primitives/trie/src/node_codec.rs +++ b/primitives/trie/src/node_codec.rs @@ -16,10 +16,10 @@ //! `NodeCodec` implementation for Substrate's trie format. -use rstd::marker::PhantomData; -use rstd::ops::Range; -use rstd::vec::Vec; -use rstd::borrow::Borrow; +use sp_std::marker::PhantomData; +use sp_std::ops::Range; +use sp_std::vec::Vec; +use sp_std::borrow::Borrow; use codec::{Encode, Decode, Input, Compact}; use hash_db::Hasher; use trie_db::{self, node::{NibbleSlicePlan, NodePlan, NodeHandlePlan}, ChildReference, @@ -30,7 +30,7 @@ use super::{node_header::{NodeHeader, NodeKind}}; /// Helper struct for trie node decoder. This implements `codec::Input` on a byte slice, while /// tracking the absolute position. This is similar to `std::io::Cursor` but does not implement -/// `Read` and `io` is not in `rstd`. +/// `Read` and `io` is not in `sp-std`. struct ByteSliceInput<'a> { data: &'a [u8], offset: usize, @@ -94,7 +94,7 @@ impl NodeCodecT for NodeCodec { H::hash(::empty_node()) } - fn decode_plan(data: &[u8]) -> rstd::result::Result { + fn decode_plan(data: &[u8]) -> sp_std::result::Result { let mut input = ByteSliceInput::new(data); match NodeHeader::decode(&mut input)? { NodeHeader::Null => Ok(NodePlan::Empty), @@ -229,7 +229,7 @@ fn partial_from_iterator_encode>( nibble_count: usize, node_kind: NodeKind, ) -> Vec { - let nibble_count = rstd::cmp::min(trie_constants::NIBBLE_SIZE_BOUND, nibble_count); + let nibble_count = sp_std::cmp::min(trie_constants::NIBBLE_SIZE_BOUND, nibble_count); let mut output = Vec::with_capacity(3 + (nibble_count / nibble_ops::NIBBLE_PER_BYTE)); match node_kind { @@ -247,7 +247,7 @@ fn partial_encode(partial: Partial, node_kind: NodeKind) -> Vec { let number_nibble_encoded = (partial.0).0 as usize; let nibble_count = partial.1.len() * nibble_ops::NIBBLE_PER_BYTE + number_nibble_encoded; - let nibble_count = rstd::cmp::min(trie_constants::NIBBLE_SIZE_BOUND, nibble_count); + let nibble_count = sp_std::cmp::min(trie_constants::NIBBLE_SIZE_BOUND, nibble_count); let mut output = Vec::with_capacity(3 + partial.1.len()); match node_kind { @@ -290,4 +290,3 @@ impl Bitmap { dest[1] = (bitmap / 256) as u8; } } - diff --git a/primitives/trie/src/node_header.rs b/primitives/trie/src/node_header.rs index 616273e574d6007106a495965d384bb0238c20fd..43d71e33b3fef06888d5e5e6269a33b98e3b1d83 100644 --- a/primitives/trie/src/node_header.rs +++ b/primitives/trie/src/node_header.rs @@ -18,11 +18,11 @@ use crate::trie_constants; use codec::{Encode, Decode, Input, Output}; -use rstd::iter::once; +use sp_std::iter::once; /// A node header #[derive(Copy, Clone, PartialEq, Eq)] -#[derive(primitives::RuntimeDebug)] +#[derive(sp_core::RuntimeDebug)] pub(crate) enum NodeHeader { Null, Branch(bool, usize), @@ -72,9 +72,9 @@ impl Decode for NodeHeader { /// Size encoding allows unlimited, length unefficient, representation, but /// is bounded to 16 bit maximum value to avoid possible DOS. pub(crate) fn size_and_prefix_iterator(size: usize, prefix: u8) -> impl Iterator { - let size = rstd::cmp::min(trie_constants::NIBBLE_SIZE_BOUND, size); + let size = sp_std::cmp::min(trie_constants::NIBBLE_SIZE_BOUND, size); - let l1 = rstd::cmp::min(62, size); + let l1 = sp_std::cmp::min(62, size); let (first_byte, mut rem) = if size == l1 { (once(prefix + l1 as u8), 0) } else { @@ -94,7 +94,7 @@ pub(crate) fn size_and_prefix_iterator(size: usize, prefix: u8) -> impl Iterator None } }; - first_byte.chain(rstd::iter::from_fn(next_bytes)) + first_byte.chain(sp_std::iter::from_fn(next_bytes)) } /// Encodes size and prefix to a stream output. diff --git a/primitives/trie/src/trie_stream.rs b/primitives/trie/src/trie_stream.rs index 2629cefac8c5ea2019e8263b7bf79a2bc84c55f2..926397346fea00481d5564b6e931bf334ce31ecd 100644 --- a/primitives/trie/src/trie_stream.rs +++ b/primitives/trie/src/trie_stream.rs @@ -19,7 +19,7 @@ use hash_db::Hasher; use trie_root; use codec::Encode; -use rstd::vec::Vec; +use sp_std::vec::Vec; use crate::trie_constants; use crate::node_header::{NodeKind, size_and_prefix_iterator}; use crate::node_codec::Bitmap; @@ -51,7 +51,7 @@ fn branch_node_bit_mask(has_children: impl Iterator) -> (u8, u8) { /// Create a leaf/branch node, encoding a number of nibbles. fn fuse_nibbles_node<'a>(nibbles: &'a [u8], kind: NodeKind) -> impl Iterator + 'a { - let size = rstd::cmp::min(trie_constants::NIBBLE_SIZE_BOUND, nibbles.len()); + let size = sp_std::cmp::min(trie_constants::NIBBLE_SIZE_BOUND, nibbles.len()); let iter_start = match kind { NodeKind::Leaf => size_and_prefix_iterator(size, trie_constants::LEAF_PREFIX_MASK), @@ -125,7 +125,7 @@ fn branch_node(has_value: bool, has_children: impl Iterator) -> [u8 result } -fn branch_node_buffered(has_value: bool, has_children: I, output: &mut[u8]) +fn branch_node_buffered(has_value: bool, has_children: I, output: &mut[u8]) where I: Iterator, { diff --git a/primitives/sr-version/Cargo.toml b/primitives/version/Cargo.toml similarity index 67% rename from primitives/sr-version/Cargo.toml rename to primitives/version/Cargo.toml index 5be3048f827b4351d7fbc1b091d0851aef7d7ac2..fbbf0cfa9460703e6350c7450eb88cf95b12b285 100644 --- a/primitives/sr-version/Cargo.toml +++ b/primitives/version/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "sr-version" +name = "sp-version" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" @@ -8,8 +8,8 @@ edition = "2018" impl-serde = { version = "0.2.3", optional = true } serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.0.5", default-features = false, features = ["derive"] } -rstd = { package = "sr-std", path = "../sr-std", default-features = false } -sr-primitives = { path = "../sr-primitives", default-features = false } +sp-std = { version = "2.0.0", default-features = false, path = "../std" } +sp-runtime = { version = "2.0.0", default-features = false, path = "../runtime" } [features] default = ["std"] @@ -17,6 +17,6 @@ std = [ "impl-serde", "serde", "codec/std", - "rstd/std", - "sr-primitives/std", + "sp-std/std", + "sp-runtime/std", ] diff --git a/primitives/sr-version/src/lib.rs b/primitives/version/src/lib.rs similarity index 79% rename from primitives/sr-version/src/lib.rs rename to primitives/version/src/lib.rs index f342c2521792661f45c4ea5e40dccda256cfbb7c..edb4aa851e7e888d38acec01790e30c51b9a2ad1 100644 --- a/primitives/sr-version/src/lib.rs +++ b/primitives/version/src/lib.rs @@ -25,13 +25,16 @@ use std::fmt; #[cfg(feature = "std")] use std::collections::HashSet; #[cfg(feature = "std")] -use sr_primitives::traits::RuntimeApiInfo; +use sp_runtime::traits::RuntimeApiInfo; use codec::Encode; #[cfg(feature = "std")] use codec::Decode; -use sr_primitives::RuntimeString; -pub use sr_primitives::create_runtime_str; +use sp_runtime::RuntimeString; +pub use sp_runtime::create_runtime_str; + +#[cfg(feature = "std")] +use sp_runtime::{traits::Block as BlockT, generic::BlockId}; /// The identity of a particular API interface that the runtime might provide. pub type ApiId = [u8; 8]; @@ -62,7 +65,7 @@ macro_rules! create_apis_vec { /// This triplet have different semantics and mis-interpretation could cause problems. /// In particular: bug fixes should result in an increment of `spec_version` and possibly `authoring_version`, /// absolutely not `impl_version` since they change the semantics of the runtime. -#[derive(Clone, PartialEq, Eq, Encode, Default, sr_primitives::RuntimeDebug)] +#[derive(Clone, PartialEq, Eq, Encode, Default, sp_runtime::RuntimeDebug)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize, Decode))] #[cfg_attr(feature = "std", serde(rename_all = "camelCase"))] pub struct RuntimeVersion { @@ -158,10 +161,51 @@ pub struct NativeVersion { #[cfg(feature = "std")] impl NativeVersion { /// Check if this version matches other version for authoring blocks. - pub fn can_author_with(&self, other: &RuntimeVersion) -> bool { - self.runtime_version.spec_name == other.spec_name && - (self.runtime_version.authoring_version == other.authoring_version || - self.can_author_with.contains(&other.authoring_version)) + /// + /// # Return + /// + /// - Returns `Ok(())` when authoring is supported. + /// - Returns `Err(_)` with a detailed error when authoring is not supported. + pub fn can_author_with(&self, other: &RuntimeVersion) -> Result<(), String> { + if self.runtime_version.spec_name != other.spec_name { + Err(format!( + "`spec_name` does not match `{}` vs `{}`", + self.runtime_version.spec_name, + other.spec_name, + )) + } else if self.runtime_version.authoring_version != other.authoring_version + && !self.can_author_with.contains(&other.authoring_version) + { + Err(format!( + "`authoring_version` does not match `{version}` vs `{other_version}` and \ + `can_author_with` not contains `{other_version}`", + version = self.runtime_version.authoring_version, + other_version = other.authoring_version, + )) + } else { + Ok(()) + } + } +} + +/// Something that can provide the runtime version at a given block and the native runtime version. +#[cfg(feature = "std")] +pub trait GetRuntimeVersion { + /// Returns the version of the native runtime. + fn native_version(&self) -> &NativeVersion; + + /// Returns the version of runtime at the given block. + fn runtime_version(&self, at: &BlockId) -> Result; +} + +#[cfg(feature = "std")] +impl, Block: BlockT> GetRuntimeVersion for std::sync::Arc { + fn native_version(&self) -> &NativeVersion { + (&**self).native_version() + } + + fn runtime_version(&self, at: &BlockId) -> Result { + (&**self).runtime_version(at) } } diff --git a/primitives/wasm-interface/Cargo.toml b/primitives/wasm-interface/Cargo.toml index 90dc7b812d9f90970c35740881d99cc71861c187..8f44c8895cfa7a45d98e57cec2ba92effdb04e13 100644 --- a/primitives/wasm-interface/Cargo.toml +++ b/primitives/wasm-interface/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "substrate-wasm-interface" +name = "sp-wasm-interface" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" diff --git a/test-utils/Cargo.toml b/test-utils/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..ac4c9954192dc99f9aa7caa6586874acd5856927 --- /dev/null +++ b/test-utils/Cargo.toml @@ -0,0 +1,5 @@ +[package] +name = "substrate-test-utils" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" diff --git a/test-utils/client/Cargo.toml b/test-utils/client/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..05dc41b2233a18b1c75637b0af50a60ce6cfddab --- /dev/null +++ b/test-utils/client/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "substrate-test-client" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +sc-client-api = { version = "2.0.0", path = "../../client/api" } +sc-client = { version = "2.0.0", path = "../../client/" } +sc-client-db = { version = "2.0.0", features = ["test-helpers"], path = "../../client/db" } +sp-consensus = { version = "0.8", path = "../../primitives/consensus/common" } +sc-executor = { version = "2.0.0", path = "../../client/executor" } +futures = "0.3.1" +hash-db = "0.15.2" +sp-keyring = { version = "2.0.0", path = "../../primitives/keyring" } +codec = { package = "parity-scale-codec", version = "1.0.0" } +sp-core = { version = "2.0.0", path = "../../primitives/core" } +sp-runtime = { version = "2.0.0", path = "../../primitives/runtime" } +sp-blockchain = { version = "2.0.0", path = "../../primitives/blockchain" } +sp-state-machine = { version = "2.0.0", path = "../../primitives/state-machine" } diff --git a/test/utils/client/src/client_ext.rs b/test-utils/client/src/client_ext.rs similarity index 89% rename from test/utils/client/src/client_ext.rs rename to test-utils/client/src/client_ext.rs index d7ae5097a3196628ca94bed996ff6c8481c9cdc8..f560d0f97b0ae5f463a94e03cfa42f649f166cd5 100644 --- a/test/utils/client/src/client_ext.rs +++ b/test-utils/client/src/client_ext.rs @@ -16,17 +16,17 @@ //! Client extension for tests. -use client::{self, Client}; -use client_api::backend::Finalizer; -use consensus::{ +use sc_client::{self, Client}; +use sc_client_api::backend::Finalizer; +use sp_consensus::{ BlockImportParams, BlockImport, BlockOrigin, Error as ConsensusError, ForkChoiceStrategy, }; use hash_db::Hasher; -use sr_primitives::Justification; -use sr_primitives::traits::{Block as BlockT}; -use sr_primitives::generic::BlockId; -use primitives::Blake2Hasher; +use sp_runtime::Justification; +use sp_runtime::traits::{Block as BlockT}; +use sp_runtime::generic::BlockId; +use sp_core::Blake2Hasher; use codec::alloc::collections::hash_map::HashMap; /// Extension trait for a test client. @@ -56,7 +56,7 @@ pub trait ClientExt: Sized { &self, id: BlockId, justification: Option, - ) -> client::error::Result<()>; + ) -> sp_blockchain::Result<()>; /// Returns hash of the genesis block. fn genesis_hash(&self) -> ::Hash; @@ -64,8 +64,8 @@ pub trait ClientExt: Sized { impl ClientExt for Client where - B: client_api::backend::Backend, - E: client::CallExecutor, + B: sc_client_api::backend::Backend, + E: sc_client::CallExecutor, for<'r> &'r Self: BlockImport, Block: BlockT::Out>, { @@ -83,6 +83,7 @@ impl ClientExt for Client auxiliary: Vec::new(), fork_choice: ForkChoiceStrategy::LongestChain, allow_missing_state: false, + import_existing: false, }; BlockImport::import_block(&mut (&*self), import, HashMap::new()).map(|_| ()) @@ -102,6 +103,7 @@ impl ClientExt for Client auxiliary: Vec::new(), fork_choice: ForkChoiceStrategy::Custom(true), allow_missing_state: false, + import_existing: false, }; BlockImport::import_block(&mut (&*self), import, HashMap::new()).map(|_| ()) @@ -121,6 +123,7 @@ impl ClientExt for Client auxiliary: Vec::new(), fork_choice: ForkChoiceStrategy::Custom(true), allow_missing_state: false, + import_existing: false, }; BlockImport::import_block(&mut (&*self), import, HashMap::new()).map(|_| ()) @@ -143,6 +146,7 @@ impl ClientExt for Client auxiliary: Vec::new(), fork_choice: ForkChoiceStrategy::LongestChain, allow_missing_state: false, + import_existing: false, }; BlockImport::import_block(&mut (&*self), import, HashMap::new()).map(|_| ()) @@ -152,7 +156,7 @@ impl ClientExt for Client &self, id: BlockId, justification: Option, - ) -> client::error::Result<()> { + ) -> sp_blockchain::Result<()> { Finalizer::finalize_block(self, id, justification, true) } diff --git a/test/utils/client/src/lib.rs b/test-utils/client/src/lib.rs similarity index 73% rename from test/utils/client/src/lib.rs rename to test-utils/client/src/lib.rs index c4f97aec1daad5ee2d05b519c44abb5c566fd884..2496409f8718a0cd1933176aefde1978311b22c6 100644 --- a/test/utils/client/src/lib.rs +++ b/test-utils/client/src/lib.rs @@ -20,42 +20,43 @@ pub mod client_ext; -pub use client::{blockchain, self}; -pub use client_api::execution_extensions::{ExecutionStrategies, ExecutionExtensions}; -pub use client_db::{Backend, self}; -pub use client_ext::ClientExt; -pub use consensus; -pub use executor::{NativeExecutor, WasmExecutionMethod, self}; -pub use keyring::{ +pub use sc_client::{blockchain, self}; +pub use sc_client_api::execution_extensions::{ExecutionStrategies, ExecutionExtensions}; +pub use sc_client_db::{Backend, self}; +pub use sp_consensus; +pub use sc_executor::{NativeExecutor, WasmExecutionMethod, self}; +pub use sp_keyring::{ AccountKeyring, ed25519::Keyring as Ed25519Keyring, sr25519::Keyring as Sr25519Keyring, }; -pub use primitives::{Blake2Hasher, traits::BareCryptoStorePtr}; -pub use sr_primitives::{StorageOverlay, ChildrenStorageOverlay}; -pub use state_machine::ExecutionStrategy; +pub use sp_core::{Blake2Hasher, traits::BareCryptoStorePtr}; +pub use sp_runtime::{Storage, StorageChild}; +pub use sp_state_machine::ExecutionStrategy; + +pub use self::client_ext::ClientExt; use std::sync::Arc; use std::collections::HashMap; use hash_db::Hasher; -use primitives::storage::well_known_keys; -use sr_primitives::traits::Block as BlockT; -use client::LocalCallExecutor; +use sp_core::storage::{well_known_keys, ChildInfo}; +use sp_runtime::traits::Block as BlockT; +use sc_client::LocalCallExecutor; /// Test client light database backend. -pub type LightBackend = client::light::backend::Backend< - client_db::light::LightStorage, +pub type LightBackend = sc_client::light::backend::Backend< + sc_client_db::light::LightStorage, Blake2Hasher, >; /// A genesis storage initialisation trait. pub trait GenesisInit: Default { /// Construct genesis storage. - fn genesis_storage(&self) -> (StorageOverlay, ChildrenStorageOverlay); + fn genesis_storage(&self) -> Storage; } impl GenesisInit for () { - fn genesis_storage(&self) -> (StorageOverlay, ChildrenStorageOverlay) { + fn genesis_storage(&self) -> Storage { Default::default() } } @@ -64,7 +65,7 @@ impl GenesisInit for () { pub struct TestClientBuilder { execution_strategies: ExecutionStrategies, genesis_init: G, - child_storage_extension: HashMap, Vec<(Vec, Vec)>>, + child_storage_extension: HashMap, StorageChild>, backend: Arc, _executor: std::marker::PhantomData, keystore: Option, @@ -136,10 +137,15 @@ impl TestClientBuilder mut self, key: impl AsRef<[u8]>, child_key: impl AsRef<[u8]>, + child_info: ChildInfo, value: impl AsRef<[u8]>, ) -> Self { - let entry = self.child_storage_extension.entry(key.as_ref().to_vec()).or_insert_with(Vec::new); - entry.push((child_key.as_ref().to_vec(), value.as_ref().to_vec())); + let entry = self.child_storage_extension.entry(key.as_ref().to_vec()) + .or_insert_with(|| StorageChild { + data: Default::default(), + child_info: child_info.to_owned(), + }); + entry.data.insert(child_key.as_ref().to_vec(), value.as_ref().to_vec()); self } @@ -163,16 +169,16 @@ impl TestClientBuilder self, executor: Executor, ) -> ( - client::Client< + sc_client::Client< Backend, Executor, Block, RuntimeApi, >, - client::LongestChain, + sc_client::LongestChain, ) where - Executor: client::CallExecutor, - Backend: client_api::backend::Backend, + Executor: sc_client::CallExecutor, + Backend: sc_client_api::backend::Backend, Block: BlockT::Out>, { @@ -180,17 +186,20 @@ impl TestClientBuilder let mut storage = self.genesis_init.genesis_storage(); // Add some child storage keys. - for (key, value) in self.child_storage_extension { - storage.1.insert( + for (key, child_content) in self.child_storage_extension { + storage.children.insert( well_known_keys::CHILD_STORAGE_KEY_PREFIX.iter().cloned().chain(key).collect(), - value.into_iter().collect(), + StorageChild { + data: child_content.data.into_iter().collect(), + child_info: child_content.child_info, + }, ); } storage }; - let client = client::Client::new( + let client = sc_client::Client::new( self.backend.clone(), executor, storage, @@ -201,14 +210,14 @@ impl TestClientBuilder ) ).expect("Creates new client"); - let longest_chain = client::LongestChain::new(self.backend); + let longest_chain = sc_client::LongestChain::new(self.backend); (client, longest_chain) } } impl TestClientBuilder< - client::LocalCallExecutor>, + sc_client::LocalCallExecutor>, Backend, G, > { @@ -217,17 +226,17 @@ impl TestClientBuilder< self, executor: I, ) -> ( - client::Client< + sc_client::Client< Backend, - client::LocalCallExecutor>, + sc_client::LocalCallExecutor>, Block, RuntimeApi >, - client::LongestChain, + sc_client::LongestChain, ) where I: Into>>, - E: executor::NativeExecutionDispatch, - Backend: client_api::backend::Backend, + E: sc_executor::NativeExecutionDispatch, + Backend: sc_client_api::backend::Backend, Block: BlockT::Out>, { let executor = executor.into().unwrap_or_else(|| diff --git a/test-utils/runtime/Cargo.toml b/test-utils/runtime/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..7d58fe1637bd6244d588b9cb85ad4fcdffdda105 --- /dev/null +++ b/test-utils/runtime/Cargo.toml @@ -0,0 +1,83 @@ +[package] +name = "substrate-test-runtime" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" +build = "build.rs" + +[dependencies] +sp-application-crypto = { version = "2.0.0", default-features = false, path = "../../primitives/application-crypto" } +sp-consensus-aura = { version = "0.8", default-features = false, path = "../../primitives/consensus/aura" } +sp-consensus-babe = { version = "0.8", default-features = false, path = "../../primitives/consensus/babe" } +sp-block-builder = { version = "2.0.0", default-features = false, path = "../../primitives/block-builder" } +cfg-if = "0.1.10" +codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } +frame-executive = { version = "2.0.0", default-features = false, path = "../../frame/executive" } +sp-inherents = { version = "2.0.0", default-features = false, path = "../../primitives/inherents" } +sp-keyring = { version = "2.0.0", optional = true, path = "../../primitives/keyring" } +log = { version = "0.4.8", optional = true } +memory-db = { version = "0.15.2", default-features = false } +sp-offchain = { path = "../../primitives/offchain", default-features = false} +sp-core = { version = "2.0.0", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0", default-features = false, path = "../../primitives/std" } +sp-runtime-interface = { path = "../../primitives/runtime-interface", default-features = false} +sp-io = { version = "2.0.0", default-features = false, path = "../../primitives/io" } +frame-support = { version = "2.0.0", default-features = false, path = "../../frame/support" } +sp-version = { version = "2.0.0", default-features = false, path = "../../primitives/version" } +serde = { version = "1.0.101", optional = true, features = ["derive"] } +sp-session = { version = "2.0.0", default-features = false, path = "../../primitives/session" } +sp-api = { version = "2.0.0", default-features = false, path = "../../primitives/api" } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" } +pallet-babe = { version = "2.0.0", default-features = false, path = "../../frame/babe" } +frame-system = { version = "2.0.0", default-features = false, path = "../../frame/system" } +frame-system-rpc-runtime-api = { version = "2.0.0", default-features = false, path = "../../frame/system/rpc/runtime-api" } +pallet-timestamp = { version = "2.0.0", default-features = false, path = "../../frame/timestamp" } +sc-client = { version = "2.0.0", optional = true, path = "../../client" } +sp-trie = { version = "2.0.0", default-features = false, path = "../../primitives/trie" } +sp-transaction-pool = { version = "2.0.0", default-features = false, path = "../../primitives/transaction-pool" } +trie-db = { version = "0.16.0", default-features = false } + +[dev-dependencies] +sc-executor = { version = "2.0.0", path = "../../client/executor" } +substrate-test-runtime-client = { version = "2.0.0", path = "./client" } +sp-state-machine = { version = "2.0.0", path = "../../primitives/state-machine" } + +[build-dependencies] +wasm-builder-runner = { version = "1.0.4", package = "substrate-wasm-builder-runner", path = "../../utils/wasm-builder-runner" } + +[features] +default = [ + "std", +] +std = [ + "sp-application-crypto/std", + "sp-consensus-aura/std", + "sp-consensus-babe/std", + "sp-block-builder/std", + "codec/std", + "frame-executive/std", + "sp-inherents/std", + "sp-keyring", + "log", + "memory-db/std", + "sp-offchain/std", + "sp-core/std", + "sp-core/std", + "sp-std/std", + "sp-runtime-interface/std", + "sp-io/std", + "frame-support/std", + "sp-version/std", + "serde", + "sp-session/std", + "sp-api/std", + "sp-runtime/std", + "pallet-babe/std", + "frame-system-rpc-runtime-api/std", + "frame-system/std", + "pallet-timestamp/std", + "sc-client", + "sp-trie/std", + "sp-transaction-pool/std", + "trie-db/std", +] diff --git a/test/utils/runtime/build.rs b/test-utils/runtime/build.rs similarity index 97% rename from test/utils/runtime/build.rs rename to test-utils/runtime/build.rs index cd2c502e78c45b1c72bb7cf60d349709b2887181..3197a406f2a099b4f6dc049bc51b6c413189fdc2 100644 --- a/test/utils/runtime/build.rs +++ b/test-utils/runtime/build.rs @@ -20,7 +20,7 @@ fn main() { build_current_project_with_rustflags( "wasm_binary.rs", WasmBuilderSource::CratesOrPath { - path: "../../../utils/wasm-builder", + path: "../../utils/wasm-builder", version: "1.0.8", }, // Note that we set the stack-size to 1MB explicitly even though it is set diff --git a/test-utils/runtime/client/Cargo.toml b/test-utils/runtime/client/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..760aa44379d34dec1659c50a5613200e0769c178 --- /dev/null +++ b/test-utils/runtime/client/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "substrate-test-runtime-client" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +sc-block-builder = { version = "2.0.0", path = "../../../client/block-builder" } +substrate-test-client = { version = "2.0.0", path = "../../client" } +sp-core = { version = "2.0.0", path = "../../../primitives/core" } +substrate-test-runtime = { version = "2.0.0", path = "../../runtime" } +sp-runtime = { version = "2.0.0", path = "../../../primitives/runtime" } +sp-blockchain = { version = "2.0.0", path = "../../../primitives/blockchain" } +codec = { package = "parity-scale-codec", version = "1.0.0" } +sc-client-api = { version = "2.0.0", path = "../../../client/api" } +sc-client = { version = "2.0.0", path = "../../../client/" } +futures = "0.3.1" diff --git a/test/utils/runtime/client/src/block_builder_ext.rs b/test-utils/runtime/client/src/block_builder_ext.rs similarity index 63% rename from test/utils/runtime/client/src/block_builder_ext.rs rename to test-utils/runtime/client/src/block_builder_ext.rs index 6bd3ed18ebeb6936cb3417b70d075b5a517e16a2..5b98b1deb36d3efbd9f7e6d2a708d9199526b547 100644 --- a/test/utils/runtime/client/src/block_builder_ext.rs +++ b/test-utils/runtime/client/src/block_builder_ext.rs @@ -16,29 +16,28 @@ //! Block Builder extensions for tests. -use runtime; -use sr_primitives::traits::ProvideRuntimeApi; -use generic_test_client::client; +use substrate_test_runtime; +use sp_runtime::traits::ProvideRuntimeApi; -use block_builder::BlockBuilderApi; +use sc_block_builder::BlockBuilderApi; /// Extension trait for test block builder. pub trait BlockBuilderExt { /// Add transfer extrinsic to the block. - fn push_transfer(&mut self, transfer: runtime::Transfer) -> Result<(), client::error::Error>; + fn push_transfer(&mut self, transfer: substrate_test_runtime::Transfer) -> Result<(), sp_blockchain::Error>; /// Add storage change extrinsic to the block. fn push_storage_change( &mut self, key: Vec, value: Option>, - ) -> Result<(), client::error::Error>; + ) -> Result<(), sp_blockchain::Error>; } -impl<'a, A> BlockBuilderExt for block_builder::BlockBuilder<'a, runtime::Block, A> where +impl<'a, A> BlockBuilderExt for sc_block_builder::BlockBuilder<'a, substrate_test_runtime::Block, A> where A: ProvideRuntimeApi + 'a, - A::Api: BlockBuilderApi, + A::Api: BlockBuilderApi, { - fn push_transfer(&mut self, transfer: runtime::Transfer) -> Result<(), client::error::Error> { + fn push_transfer(&mut self, transfer: substrate_test_runtime::Transfer) -> Result<(), sp_blockchain::Error> { self.push(transfer.into_signed_tx()) } @@ -46,7 +45,7 @@ impl<'a, A> BlockBuilderExt for block_builder::BlockBuilder<'a, runtime::Block, &mut self, key: Vec, value: Option>, - ) -> Result<(), client::error::Error> { - self.push(runtime::Extrinsic::StorageChange(key, value)) + ) -> Result<(), sp_blockchain::Error> { + self.push(substrate_test_runtime::Extrinsic::StorageChange(key, value)) } } diff --git a/test/utils/runtime/client/src/lib.rs b/test-utils/runtime/client/src/lib.rs similarity index 50% rename from test/utils/runtime/client/src/lib.rs rename to test-utils/runtime/client/src/lib.rs index d56bcfa770b5d72fcfb94edf7ce7fb762cb4b6a8..988fa5667818b19968a138dfd48c8dc1b91917fc 100644 --- a/test/utils/runtime/client/src/lib.rs +++ b/test-utils/runtime/client/src/lib.rs @@ -24,13 +24,23 @@ mod block_builder_ext; use std::sync::Arc; use std::collections::HashMap; -pub use block_builder_ext::BlockBuilderExt; -pub use generic_test_client::*; -pub use runtime; +pub use substrate_test_client::*; +pub use substrate_test_runtime as runtime; + +pub use self::block_builder_ext::BlockBuilderExt; + +use sp_core::sr25519; +use sp_core::storage::{ChildInfo, Storage, StorageChild}; +use substrate_test_runtime::genesismap::{GenesisConfig, additional_storage_with_genesis}; +use sp_runtime::traits::{Block as BlockT, Header as HeaderT, Hash as HashT, NumberFor}; +use sc_client::{ + light::fetcher::{ + Fetcher, + RemoteHeaderRequest, RemoteReadRequest, RemoteReadChildRequest, + RemoteCallRequest, RemoteChangesRequest, RemoteBodyRequest, + }, +}; -use primitives::sr25519; -use runtime::genesismap::{GenesisConfig, additional_storage_with_genesis}; -use sr_primitives::traits::{Block as BlockT, Header as HeaderT, Hash as HashT}; /// A prelude to import in tests. pub mod prelude { @@ -47,37 +57,37 @@ pub mod prelude { mod local_executor { #![allow(missing_docs)] - use runtime; - use crate::executor::native_executor_instance; + use substrate_test_runtime; + use crate::sc_executor::native_executor_instance; // FIXME #1576 change the macro and pass in the `BlakeHasher` that dispatch needs from here instead native_executor_instance!( pub LocalExecutor, - runtime::api::dispatch, - runtime::native_version + substrate_test_runtime::api::dispatch, + substrate_test_runtime::native_version ); } /// Native executor used for tests. -pub use local_executor::LocalExecutor; +pub use self::local_executor::LocalExecutor; /// Test client database backend. -pub type Backend = generic_test_client::Backend; +pub type Backend = substrate_test_client::Backend; /// Test client executor. -pub type Executor = client::LocalCallExecutor< +pub type Executor = sc_client::LocalCallExecutor< Backend, NativeExecutor, >; /// Test client light database backend. -pub type LightBackend = generic_test_client::LightBackend; +pub type LightBackend = substrate_test_client::LightBackend; /// Test client light executor. -pub type LightExecutor = client::light::call_executor::GenesisCallExecutor< +pub type LightExecutor = sc_client::light::call_executor::GenesisCallExecutor< LightBackend, - client::LocalCallExecutor< - client::light::backend::Backend< - client_db::light::LightStorage, + sc_client::LocalCallExecutor< + sc_client::light::backend::Backend< + sc_client_db::light::LightStorage, Blake2Hasher, >, NativeExecutor @@ -89,8 +99,7 @@ pub type LightExecutor = client::light::call_executor::GenesisCallExecutor< pub struct GenesisParameters { support_changes_trie: bool, heap_pages_override: Option, - extra_storage: HashMap, Vec>, - child_extra_storage: HashMap, HashMap, Vec>>, + extra_storage: Storage, } impl GenesisParameters { @@ -110,41 +119,41 @@ impl GenesisParameters { 1000, self.heap_pages_override, self.extra_storage.clone(), - self.child_extra_storage.clone(), ) } } -impl generic_test_client::GenesisInit for GenesisParameters { - fn genesis_storage(&self) -> (StorageOverlay, ChildrenStorageOverlay) { +impl substrate_test_client::GenesisInit for GenesisParameters { + fn genesis_storage(&self) -> Storage { use codec::Encode; + let mut storage = self.genesis_config().genesis_map(); - let child_roots = storage.1.iter().map(|(sk, child_map)| { + let child_roots = storage.children.iter().map(|(sk, child_content)| { let state_root = <<::Header as HeaderT>::Hashing as HashT>::trie_root( - child_map.clone().into_iter().collect() + child_content.data.clone().into_iter().collect() ); (sk.clone(), state_root.encode()) }); let state_root = <<::Header as HeaderT>::Hashing as HashT>::trie_root( - storage.0.clone().into_iter().chain(child_roots).collect() + storage.top.clone().into_iter().chain(child_roots).collect() ); - let block: runtime::Block = client::genesis::construct_genesis_block(state_root); - storage.0.extend(additional_storage_with_genesis(&block)); + let block: runtime::Block = sc_client::genesis::construct_genesis_block(state_root); + storage.top.extend(additional_storage_with_genesis(&block)); storage } } /// A `TestClient` with `test-runtime` builder. -pub type TestClientBuilder = generic_test_client::TestClientBuilder; +pub type TestClientBuilder = substrate_test_client::TestClientBuilder; /// Test client type with `LocalExecutor` and generic Backend. -pub type Client = client::Client< +pub type Client = sc_client::Client< B, - client::LocalCallExecutor>, - runtime::Block, - runtime::RuntimeApi, + sc_client::LocalCallExecutor>, + substrate_test_runtime::Block, + substrate_test_runtime::RuntimeApi, >; /// A test client with default backend. @@ -181,6 +190,7 @@ pub trait TestClientBuilderExt: Sized { fn add_extra_child_storage>, K: Into>, V: Into>>( self, storage_key: SK, + child_info: ChildInfo, key: K, value: V, ) -> Self; @@ -198,14 +208,14 @@ pub trait TestClientBuilderExt: Sized { } /// Build the test client and longest chain selector. - fn build_with_longest_chain(self) -> (Client, client::LongestChain); + fn build_with_longest_chain(self) -> (Client, sc_client::LongestChain); } impl TestClientBuilderExt for TestClientBuilder< - client::LocalCallExecutor>, + sc_client::LocalCallExecutor>, B > where - B: client_api::backend::Backend, + B: sc_client_api::backend::Backend, { fn set_heap_pages(mut self, heap_pages: u64) -> Self { self.genesis_init_mut().heap_pages_override = Some(heap_pages); @@ -220,13 +230,14 @@ impl TestClientBuilderExt for TestClientBuilder< fn add_extra_storage>, V: Into>>(mut self, key: K, value: V) -> Self { let key = key.into(); assert!(!key.is_empty()); - self.genesis_init_mut().extra_storage.insert(key, value.into()); + self.genesis_init_mut().extra_storage.top.insert(key, value.into()); self } fn add_extra_child_storage>, K: Into>, V: Into>>( mut self, storage_key: SK, + child_info: ChildInfo, key: K, value: V, ) -> Self { @@ -234,19 +245,96 @@ impl TestClientBuilderExt for TestClientBuilder< let key = key.into(); assert!(!storage_key.is_empty()); assert!(!key.is_empty()); - self.genesis_init_mut().child_extra_storage + self.genesis_init_mut().extra_storage.children .entry(storage_key) - .or_insert_with(Default::default) - .insert(key, value.into()); + .or_insert_with(|| StorageChild { + data: Default::default(), + child_info: child_info.to_owned(), + }).data.insert(key, value.into()); self } - fn build_with_longest_chain(self) -> (Client, client::LongestChain) { + fn build_with_longest_chain(self) -> (Client, sc_client::LongestChain) { self.build_with_native_executor(None) } } +/// Type of optional fetch callback. +type MaybeFetcherCallback = Option Result + Send + Sync>>; + +/// Type of fetcher future result. +type FetcherFutureResult = futures::future::Ready>; + +/// Implementation of light client fetcher used in tests. +#[derive(Default)] +pub struct LightFetcher { + call: MaybeFetcherCallback, Vec>, + body: MaybeFetcherCallback, Vec>, +} + +impl LightFetcher { + /// Sets remote call callback. + pub fn with_remote_call( + self, + call: MaybeFetcherCallback, Vec>, + ) -> Self { + LightFetcher { + call, + body: self.body, + } + } + + /// Sets remote body callback. + pub fn with_remote_body( + self, + body: MaybeFetcherCallback, Vec>, + ) -> Self { + LightFetcher { + call: self.call, + body, + } + } +} + +impl Fetcher for LightFetcher { + type RemoteHeaderResult = FetcherFutureResult; + type RemoteReadResult = FetcherFutureResult, Option>>>; + type RemoteCallResult = FetcherFutureResult>; + type RemoteChangesResult = FetcherFutureResult, u32)>>; + type RemoteBodyResult = FetcherFutureResult>; + + fn remote_header(&self, _: RemoteHeaderRequest) -> Self::RemoteHeaderResult { + unimplemented!() + } + + fn remote_read(&self, _: RemoteReadRequest) -> Self::RemoteReadResult { + unimplemented!() + } + + fn remote_read_child(&self, _: RemoteReadChildRequest) -> Self::RemoteReadResult { + unimplemented!() + } + + fn remote_call(&self, req: RemoteCallRequest) -> Self::RemoteCallResult { + match self.call { + Some(ref call) => futures::future::ready(call(req)), + None => unimplemented!(), + } + } + + fn remote_changes(&self, _: RemoteChangesRequest) -> Self::RemoteChangesResult { + unimplemented!() + } + + fn remote_body(&self, req: RemoteBodyRequest) -> Self::RemoteBodyResult { + match self.body { + Some(ref body) => futures::future::ready(body(req)), + None => unimplemented!(), + } + } +} + /// Creates new client instance used for tests. pub fn new() -> Client { TestClientBuilder::new().build() @@ -254,15 +342,15 @@ pub fn new() -> Client { /// Creates new light client instance used for tests. pub fn new_light() -> ( - client::Client, + sc_client::Client, Arc, ) { - let storage = client_db::light::LightStorage::new_test(); - let blockchain = Arc::new(client::light::blockchain::Blockchain::new(storage)); + let storage = sc_client_db::light::LightStorage::new_test(); + let blockchain = Arc::new(sc_client::light::blockchain::Blockchain::new(storage)); let backend = Arc::new(LightBackend::new(blockchain.clone())); let executor = NativeExecutor::new(WasmExecutionMethod::Interpreted, None); - let local_call_executor = client::LocalCallExecutor::new(backend.clone(), executor); + let local_call_executor = sc_client::LocalCallExecutor::new(backend.clone(), executor); let call_executor = LightExecutor::new( backend.clone(), local_call_executor, @@ -275,3 +363,8 @@ pub fn new_light() -> ( backend, ) } + +/// Creates new light client fetcher used for tests. +pub fn new_light_fetcher() -> LightFetcher { + LightFetcher::default() +} diff --git a/test/utils/runtime/client/src/trait_tests.rs b/test-utils/runtime/client/src/trait_tests.rs similarity index 95% rename from test/utils/runtime/client/src/trait_tests.rs rename to test-utils/runtime/client/src/trait_tests.rs index bfdab4d942ed24a1277aa2ceb160e495fcaa7f08..9217cff801c4b1eaea2596bba68f3197d2c41690 100644 --- a/test/utils/runtime/client/src/trait_tests.rs +++ b/test-utils/runtime/client/src/trait_tests.rs @@ -21,19 +21,19 @@ use std::sync::Arc; -use client_api::backend::LocalBackend; +use sc_client_api::backend::LocalBackend; use crate::block_builder_ext::BlockBuilderExt; -use client_api::blockchain::{Backend as BlockChainBackendT, HeaderBackend}; +use sc_client_api::blockchain::{Backend as BlockChainBackendT, HeaderBackend}; use crate::{AccountKeyring, ClientExt, TestClientBuilder, TestClientBuilderExt}; -use generic_test_client::consensus::BlockOrigin; -use primitives::Blake2Hasher; -use runtime::{self, Transfer}; -use sr_primitives::generic::BlockId; -use sr_primitives::traits::Block as BlockT; +use substrate_test_client::sp_consensus::BlockOrigin; +use sp_core::Blake2Hasher; +use substrate_test_runtime::{self, Transfer}; +use sp_runtime::generic::BlockId; +use sp_runtime::traits::Block as BlockT; /// helper to test the `leaves` implementation for various backends pub fn test_leaves_for_backend(backend: Arc) where - B: LocalBackend, + B: LocalBackend, { // block tree: // G -> A1 -> A2 -> A3 -> A4 -> A5 @@ -149,7 +149,7 @@ pub fn test_leaves_for_backend(backend: Arc) where /// helper to test the `children` implementation for various backends pub fn test_children_for_backend(backend: Arc) where - B: LocalBackend, + B: LocalBackend, { // block tree: // G -> A1 -> A2 -> A3 -> A4 -> A5 @@ -240,7 +240,7 @@ pub fn test_children_for_backend(backend: Arc) where } pub fn test_blockchain_query_by_number_gets_canonical(backend: Arc) where - B: LocalBackend, + B: LocalBackend, { // block tree: // G -> A1 -> A2 -> A3 -> A4 -> A5 diff --git a/test/utils/runtime/src/genesismap.rs b/test-utils/runtime/src/genesismap.rs similarity index 71% rename from test/utils/runtime/src/genesismap.rs rename to test-utils/runtime/src/genesismap.rs index 79cba52323e58866e79f534a5147a3e5bae85f24..62d9b160b9e33806e5bca07c379560ce32297fcd 100644 --- a/test/utils/runtime/src/genesismap.rs +++ b/test-utils/runtime/src/genesismap.rs @@ -16,12 +16,13 @@ //! Tool for creating the genesis block. -use std::collections::HashMap; -use runtime_io::hashing::{blake2_256, twox_128}; +use std::collections::BTreeMap; +use sp_io::hashing::{blake2_256, twox_128}; use super::{AuthorityId, AccountId, WASM_BINARY, system}; use codec::{Encode, KeyedVec, Joiner}; -use primitives::{ChangesTrieConfiguration, map, storage::well_known_keys}; -use sr_primitives::traits::{Block as BlockT, Hash as HashT, Header as HeaderT}; +use sp_core::{ChangesTrieConfiguration, map}; +use sp_core::storage::{well_known_keys, Storage}; +use sp_runtime::traits::{Block as BlockT, Hash as HashT, Header as HeaderT}; /// Configuration of a general Substrate test genesis block. pub struct GenesisConfig { @@ -30,8 +31,7 @@ pub struct GenesisConfig { balances: Vec<(AccountId, u64)>, heap_pages_override: Option, /// Additional storage key pairs that will be added to the genesis map. - extra_storage: HashMap, Vec>, - child_extra_storage: HashMap, HashMap, Vec>>, + extra_storage: Storage, } impl GenesisConfig { @@ -41,8 +41,7 @@ impl GenesisConfig { endowed_accounts: Vec, balance: u64, heap_pages_override: Option, - extra_storage: HashMap, Vec>, - child_extra_storage: HashMap, HashMap, Vec>>, + extra_storage: Storage, ) -> Self { GenesisConfig { changes_trie_config: match support_changes_trie { @@ -53,16 +52,12 @@ impl GenesisConfig { balances: endowed_accounts.into_iter().map(|a| (a, balance)).collect(), heap_pages_override, extra_storage, - child_extra_storage, } } - pub fn genesis_map(&self) -> ( - HashMap, Vec>, - HashMap, HashMap, Vec>>, - ) { + pub fn genesis_map(&self) -> Storage { let wasm_runtime = WASM_BINARY.to_vec(); - let mut map: HashMap, Vec> = self.balances.iter() + let mut map: BTreeMap, Vec> = self.balances.iter() .map(|&(ref account, balance)| (account.to_keyed_vec(b"balance:"), vec![].and(&balance))) .map(|(k, v)| (blake2_256(&k[..])[..].to_vec(), v.to_vec())) .chain(vec![ @@ -78,10 +73,10 @@ impl GenesisConfig { } map.insert(twox_128(&b"sys:auth"[..])[..].to_vec(), self.authorities.encode()); // Add the extra storage entries. - map.extend(self.extra_storage.clone().into_iter()); + map.extend(self.extra_storage.top.clone().into_iter()); // Assimilate the system genesis config. - let mut storage = (map, self.child_extra_storage.clone()); + let mut storage = Storage { top: map, children: self.extra_storage.children.clone()}; let mut config = system::GenesisConfig::default(); config.authorities = self.authorities.clone(); config.assimilate_storage(&mut storage).expect("Adding `system::GensisConfig` to the genesis"); @@ -91,27 +86,26 @@ impl GenesisConfig { } pub fn insert_genesis_block( - storage: &mut ( - HashMap, Vec>, - HashMap, HashMap, Vec>>, - ) -) -> primitives::hash::H256 { - let child_roots = storage.1.iter().map(|(sk, child_map)| { + storage: &mut Storage, +) -> sp_core::hash::H256 { + let child_roots = storage.children.iter().map(|(sk, child_content)| { let state_root = <<::Header as HeaderT>::Hashing as HashT>::trie_root( - child_map.clone().into_iter().collect(), + child_content.data.clone().into_iter().collect(), ); (sk.clone(), state_root.encode()) }); + // add child roots to storage + storage.top.extend(child_roots); let state_root = <<::Header as HeaderT>::Hashing as HashT>::trie_root( - storage.0.clone().into_iter().chain(child_roots).collect() + storage.top.clone().into_iter().collect() ); - let block: crate::Block = substrate_client::genesis::construct_genesis_block(state_root); + let block: crate::Block = sc_client::genesis::construct_genesis_block(state_root); let genesis_hash = block.header.hash(); - storage.0.extend(additional_storage_with_genesis(&block)); + storage.top.extend(additional_storage_with_genesis(&block)); genesis_hash } -pub fn additional_storage_with_genesis(genesis_block: &crate::Block) -> HashMap, Vec> { +pub fn additional_storage_with_genesis(genesis_block: &crate::Block) -> BTreeMap, Vec> { map![ twox_128(&b"latest"[..]).to_vec() => genesis_block.hash().as_fixed_bytes().to_vec() ] diff --git a/test/utils/runtime/src/lib.rs b/test-utils/runtime/src/lib.rs similarity index 88% rename from test/utils/runtime/src/lib.rs rename to test-utils/runtime/src/lib.rs index 58caae2098d0714f2f96457844038fff5fbd48c8..e3b34881c34a6e386d8a924babe56f0223c42c00 100644 --- a/test/utils/runtime/src/lib.rs +++ b/test-utils/runtime/src/lib.rs @@ -22,18 +22,17 @@ pub mod genesismap; pub mod system; -use rstd::{prelude::*, marker::PhantomData}; +use sp_std::{prelude::*, marker::PhantomData}; use codec::{Encode, Decode, Input, Error}; -use primitives::{Blake2Hasher, OpaqueMetadata, RuntimeDebug}; -use app_crypto::{ed25519, sr25519, RuntimeAppPublic}; -pub use app_crypto; +use sp_core::{Blake2Hasher, OpaqueMetadata, RuntimeDebug}; +use sp_application_crypto::{ed25519, sr25519, RuntimeAppPublic}; use trie_db::{TrieMut, Trie}; -use substrate_trie::PrefixedMemoryDB; -use substrate_trie::trie_types::{TrieDB, TrieDBMut}; +use sp_trie::PrefixedMemoryDB; +use sp_trie::trie_types::{TrieDB, TrieDBMut}; -use sr_api::{decl_runtime_apis, impl_runtime_apis}; -use sr_primitives::{ +use sp_api::{decl_runtime_apis, impl_runtime_apis}; +use sp_runtime::{ ApplyExtrinsicResult, create_runtime_str, Perbill, impl_opaque_keys, transaction_validity::{ TransactionValidity, ValidTransaction, TransactionValidityError, InvalidTransaction, @@ -43,17 +42,18 @@ use sr_primitives::{ GetNodeBlockType, GetRuntimeBlockType, Verify, IdentityLookup, }, }; -use runtime_version::RuntimeVersion; -pub use primitives::{hash::H256}; +use sp_version::RuntimeVersion; +pub use sp_core::{hash::H256}; #[cfg(any(feature = "std", test))] -use runtime_version::NativeVersion; -use runtime_support::{impl_outer_origin, parameter_types}; -use inherents::{CheckInherentsResult, InherentData}; +use sp_version::NativeVersion; +use frame_support::{impl_outer_origin, parameter_types, weights::Weight}; +use sp_inherents::{CheckInherentsResult, InherentData}; use cfg_if::cfg_if; +use sp_core::storage::ChildType; // Ensure Babe and Aura use the same crypto to simplify things a bit. -pub use babe_primitives::AuthorityId; -pub type AuraId = aura_primitives::sr25519::AuthorityId; +pub use sp_consensus_babe::AuthorityId; +pub type AuraId = sp_consensus_aura::sr25519::AuthorityId; // Inlucde the WASM binary #[cfg(feature = "std")] @@ -95,7 +95,7 @@ impl Transfer { /// Convert into a signed extrinsic. #[cfg(feature = "std")] pub fn into_signed_tx(self) -> Extrinsic { - let signature = keyring::AccountKeyring::from_public(&self.from) + let signature = sp_keyring::AccountKeyring::from_public(&self.from) .expect("Creates keyring from public key.").sign(&self.encode()).into(); Extrinsic::Transfer(self, signature) } @@ -124,7 +124,7 @@ impl BlindCheckable for Extrinsic { match self { Extrinsic::AuthoritiesChange(new_auth) => Ok(Extrinsic::AuthoritiesChange(new_auth)), Extrinsic::Transfer(transfer, signature) => { - if sr_primitives::verify_encoded_lazy(&signature, &transfer, &transfer.from) { + if sp_runtime::verify_encoded_lazy(&signature, &transfer, &transfer.from) { Ok(Extrinsic::Transfer(transfer, signature)) } else { Err(InvalidTransaction::BadProof.into()) @@ -173,17 +173,17 @@ pub type BlockNumber = u64; /// Index of a transaction. pub type Index = u64; /// The item of a block digest. -pub type DigestItem = sr_primitives::generic::DigestItem; +pub type DigestItem = sp_runtime::generic::DigestItem; /// The digest of a block. -pub type Digest = sr_primitives::generic::Digest; +pub type Digest = sp_runtime::generic::Digest; /// A test block. -pub type Block = sr_primitives::generic::Block; +pub type Block = sp_runtime::generic::Block; /// A test block's header. -pub type Header = sr_primitives::generic::Header; +pub type Header = sp_runtime::generic::Header; /// Run whatever tests we have. pub fn run_tests(mut input: &[u8]) -> Vec { - use sr_primitives::print; + use sp_runtime::print; print("run_tests..."); let block = Block::decode(&mut input).unwrap(); @@ -194,8 +194,8 @@ pub fn run_tests(mut input: &[u8]) -> Vec { } /// Changes trie configuration (optionally) used in tests. -pub fn changes_trie_config() -> primitives::ChangesTrieConfiguration { - primitives::ChangesTrieConfiguration { +pub fn changes_trie_config() -> sp_core::ChangesTrieConfiguration { + sp_core::ChangesTrieConfiguration { digest_interval: 4, digest_levels: 2, } @@ -353,7 +353,7 @@ impl From for Event { parameter_types! { pub const BlockHashCount: BlockNumber = 250; pub const MinimumPeriod: u64 = 5; - pub const MaximumBlockWeight: u32 = 4 * 1024 * 1024; + pub const MaximumBlockWeight: Weight = 4 * 1024 * 1024; pub const MaximumBlockLength: u32 = 4 * 1024 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); } @@ -374,6 +374,7 @@ impl frame_system::Trait for Runtime { type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); + type ModuleToIndex = (); } impl pallet_timestamp::Trait for Runtime { @@ -405,8 +406,8 @@ fn benchmark_add_one(i: u64) -> u64 { /// The `benchmark_add_one` function as function pointer. #[cfg(not(feature = "std"))] -static BENCHMARK_ADD_ONE: runtime_interface::wasm::ExchangeableFunction u64> = - runtime_interface::wasm::ExchangeableFunction::new(benchmark_add_one); +static BENCHMARK_ADD_ONE: sp_runtime_interface::wasm::ExchangeableFunction u64> = + sp_runtime_interface::wasm::ExchangeableFunction::new(benchmark_add_one); fn code_using_trie() -> u64 { let pairs = [ @@ -415,7 +416,7 @@ fn code_using_trie() -> u64 { ].to_vec(); let mut mdb = PrefixedMemoryDB::default(); - let mut root = rstd::default::Default::default(); + let mut root = sp_std::default::Default::default(); let _ = { let v = &pairs; let mut t = TrieDBMut::::new(&mut mdb, &mut root); @@ -457,7 +458,7 @@ static mut MUTABLE_STATIC: u64 = 32; cfg_if! { if #[cfg(feature = "std")] { impl_runtime_apis! { - impl sr_api::Core for Runtime { + impl sp_api::Core for Runtime { fn version() -> RuntimeVersion { version() } @@ -471,13 +472,13 @@ cfg_if! { } } - impl sr_api::Metadata for Runtime { + impl sp_api::Metadata for Runtime { fn metadata() -> OpaqueMetadata { unimplemented!() } } - impl transaction_pool_api::TaggedTransactionQueue for Runtime { + impl sp_transaction_pool::runtime_api::TaggedTransactionQueue for Runtime { fn validate_transaction(utx: ::Extrinsic) -> TransactionValidity { if let Extrinsic::IncludeData(data) = utx { return Ok(ValidTransaction { @@ -493,7 +494,7 @@ cfg_if! { } } - impl block_builder_api::BlockBuilder for Runtime { + impl sp_block_builder::BlockBuilder for Runtime { fn apply_extrinsic(extrinsic: ::Extrinsic) -> ApplyExtrinsicResult { system::execute_transaction(extrinsic) } @@ -597,7 +598,7 @@ cfg_if! { } } - impl aura_primitives::AuraApi for Runtime { + impl sp_consensus_aura::AuraApi for Runtime { fn slot_duration() -> u64 { 1000 } fn authorities() -> Vec { system::authorities().into_iter().map(|a| { @@ -607,9 +608,9 @@ cfg_if! { } } - impl babe_primitives::BabeApi for Runtime { - fn configuration() -> babe_primitives::BabeConfiguration { - babe_primitives::BabeConfiguration { + impl sp_consensus_babe::BabeApi for Runtime { + fn configuration() -> sp_consensus_babe::BabeConfiguration { + sp_consensus_babe::BabeConfiguration { slot_duration: 1000, epoch_length: EpochDuration::get(), c: (3, 10), @@ -621,14 +622,14 @@ cfg_if! { } } - impl offchain_primitives::OffchainWorkerApi for Runtime { + impl sp_offchain::OffchainWorkerApi for Runtime { fn offchain_worker(block: u64) { let ex = Extrinsic::IncludeData(block.encode()); - runtime_io::offchain::submit_transaction(ex.encode()).unwrap(); + sp_io::offchain::submit_transaction(ex.encode()).unwrap(); } } - impl session::SessionKeys for Runtime { + impl sp_session::SessionKeys for Runtime { fn generate_session_keys(_: Option>) -> Vec { SessionKeys::generate(None) } @@ -642,7 +643,7 @@ cfg_if! { } } else { impl_runtime_apis! { - impl sr_api::Core for Runtime { + impl sp_api::Core for Runtime { fn version() -> RuntimeVersion { version() } @@ -656,13 +657,13 @@ cfg_if! { } } - impl sr_api::Metadata for Runtime { + impl sp_api::Metadata for Runtime { fn metadata() -> OpaqueMetadata { unimplemented!() } } - impl transaction_pool_api::TaggedTransactionQueue for Runtime { + impl sp_transaction_pool::runtime_api::TaggedTransactionQueue for Runtime { fn validate_transaction(utx: ::Extrinsic) -> TransactionValidity { if let Extrinsic::IncludeData(data) = utx { return Ok(ValidTransaction{ @@ -678,7 +679,7 @@ cfg_if! { } } - impl block_builder_api::BlockBuilder for Runtime { + impl sp_block_builder::BlockBuilder for Runtime { fn apply_extrinsic(extrinsic: ::Extrinsic) -> ApplyExtrinsicResult { system::execute_transaction(extrinsic) } @@ -813,7 +814,7 @@ cfg_if! { } } - impl aura_primitives::AuraApi for Runtime { + impl sp_consensus_aura::AuraApi for Runtime { fn slot_duration() -> u64 { 1000 } fn authorities() -> Vec { system::authorities().into_iter().map(|a| { @@ -823,9 +824,9 @@ cfg_if! { } } - impl babe_primitives::BabeApi for Runtime { - fn configuration() -> babe_primitives::BabeConfiguration { - babe_primitives::BabeConfiguration { + impl sp_consensus_babe::BabeApi for Runtime { + fn configuration() -> sp_consensus_babe::BabeConfiguration { + sp_consensus_babe::BabeConfiguration { slot_duration: 1000, epoch_length: EpochDuration::get(), c: (3, 10), @@ -837,14 +838,14 @@ cfg_if! { } } - impl offchain_primitives::OffchainWorkerApi for Runtime { + impl sp_offchain::OffchainWorkerApi for Runtime { fn offchain_worker(block: u64) { let ex = Extrinsic::IncludeData(block.encode()); - runtime_io::offchain::submit_transaction(ex.encode()).unwrap() + sp_io::offchain::submit_transaction(ex.encode()).unwrap() } } - impl session::SessionKeys for Runtime { + impl sp_session::SessionKeys for Runtime { fn generate_session_keys(_: Option>) -> Vec { SessionKeys::generate(None) } @@ -891,10 +892,10 @@ fn test_sr25519_crypto() -> (sr25519::AppSignature, sr25519::AppPublic) { fn test_read_storage() { const KEY: &[u8] = b":read_storage"; - runtime_io::storage::set(KEY, b"test"); + sp_io::storage::set(KEY, b"test"); let mut v = [0u8; 4]; - let r = runtime_io::storage::read( + let r = sp_io::storage::read( KEY, &mut v, 0 @@ -903,28 +904,44 @@ fn test_read_storage() { assert_eq!(&v, b"test"); let mut v = [0u8; 4]; - let r = runtime_io::storage::read(KEY, &mut v, 8); + let r = sp_io::storage::read(KEY, &mut v, 8); assert_eq!(r, Some(4)); assert_eq!(&v, &[0, 0, 0, 0]); } fn test_read_child_storage() { const CHILD_KEY: &[u8] = b":child_storage:default:read_child_storage"; + const UNIQUE_ID: &[u8] = b":unique_id"; const KEY: &[u8] = b":read_child_storage"; - runtime_io::storage::child_set(CHILD_KEY, KEY, b"test"); + sp_io::storage::child_set( + CHILD_KEY, + UNIQUE_ID, + ChildType::CryptoUniqueId as u32, + KEY, + b"test", + ); let mut v = [0u8; 4]; - let r = runtime_io::storage::child_read( + let r = sp_io::storage::child_read( CHILD_KEY, + UNIQUE_ID, + ChildType::CryptoUniqueId as u32, KEY, &mut v, - 0 + 0, ); assert_eq!(r, Some(4)); assert_eq!(&v, b"test"); let mut v = [0u8; 4]; - let r = runtime_io::storage::child_read(CHILD_KEY, KEY, &mut v, 8); + let r = sp_io::storage::child_read( + CHILD_KEY, + UNIQUE_ID, + ChildType::CryptoUniqueId as u32, + KEY, + &mut v, + 8, + ); assert_eq!(r, Some(4)); assert_eq!(&v, &[0, 0, 0, 0]); } @@ -933,16 +950,16 @@ fn test_read_child_storage() { mod tests { use substrate_test_runtime_client::{ prelude::*, - consensus::BlockOrigin, + sp_consensus::BlockOrigin, DefaultTestClientBuilderExt, TestClientBuilder, runtime::TestAPI, }; - use sr_primitives::{ + use sp_runtime::{ generic::BlockId, traits::ProvideRuntimeApi, }; - use primitives::storage::well_known_keys::HEAP_PAGES; - use state_machine::ExecutionStrategy; + use sp_core::storage::well_known_keys::HEAP_PAGES; + use sp_state_machine::ExecutionStrategy; use codec::Encode; #[test] diff --git a/test/utils/runtime/src/system.rs b/test-utils/runtime/src/system.rs similarity index 90% rename from test/utils/runtime/src/system.rs rename to test-utils/runtime/src/system.rs index 1ac318c417c27c0f91bcf701718e0dd76f4554cc..162f9a8ad6277296b89538de293c0c46ae0ac9bb 100644 --- a/test/utils/runtime/src/system.rs +++ b/test-utils/runtime/src/system.rs @@ -17,25 +17,25 @@ //! System manager: Handles all of the top-level stuff; executing block/transaction, setting code //! and depositing logs. -use rstd::prelude::*; -use runtime_io::{ +use sp_std::prelude::*; +use sp_io::{ storage::root as storage_root, storage::changes_root as storage_changes_root, hashing::blake2_256, }; -use runtime_support::storage; -use runtime_support::{decl_storage, decl_module}; -use sr_primitives::{ +use frame_support::storage; +use frame_support::{decl_storage, decl_module}; +use sp_runtime::{ traits::{Hash as HashT, BlakeTwo256, Header as _}, generic, ApplyExtrinsicResult, transaction_validity::{ TransactionValidity, ValidTransaction, InvalidTransaction, TransactionValidityError, }, }; -use codec::{KeyedVec, Encode}; +use codec::{KeyedVec, Encode, Decode}; use frame_system::Trait; use crate::{ AccountId, BlockNumber, Extrinsic, Transfer, H256 as Hash, Block, Header, Digest, AuthorityId }; -use primitives::storage::well_known_keys; +use sp_core::storage::well_known_keys; const NONCE_OF: &[u8] = b"nonce:"; const BALANCE_OF: &[u8] = b"balance:"; @@ -139,20 +139,26 @@ fn execute_block_with_state_root_handler( }); let o_new_authorities = ::take(); + let storage_root = Hash::decode(&mut &storage_root()[..]) + .expect("`storage_root` is a valid hash"); if let Mode::Overwrite = mode { - header.state_root = storage_root().into(); + header.state_root = storage_root; } else { // check storage root. - let storage_root = storage_root().into(); info_expect_equal_hash(&storage_root, &header.state_root); assert!(storage_root == header.state_root, "Storage root must match that calculated."); } // check digest let digest = &mut header.digest; - if let Some(storage_changes_root) = storage_changes_root(header.parent_hash.into()) { - digest.push(generic::DigestItem::ChangesTrieRoot(storage_changes_root.into())); + if let Some(storage_changes_root) = storage_changes_root(&header.parent_hash.encode()) { + digest.push( + generic::DigestItem::ChangesTrieRoot( + Hash::decode(&mut &storage_changes_root[..]) + .expect("`storage_changes_root` is a valid hash") + ) + ); } if let Some(new_authorities) = o_new_authorities { digest.push(generic::DigestItem::Consensus(*b"aura", new_authorities.encode())); @@ -163,7 +169,7 @@ fn execute_block_with_state_root_handler( /// The block executor. pub struct BlockExecutor; -impl executive::ExecuteBlock for BlockExecutor { +impl frame_executive::ExecuteBlock for BlockExecutor { fn execute_block(block: Block) { execute_block(block); } @@ -226,8 +232,10 @@ pub fn finalize_block() -> Header { let o_new_authorities = ::take(); // This MUST come after all changes to storage are done. Otherwise we will fail the // “Storage root does not match that calculated” assertion. - let storage_root = BlakeTwo256::storage_root(); - let storage_changes_root = BlakeTwo256::storage_changes_root(parent_hash); + let storage_root = Hash::decode(&mut &storage_root()[..]) + .expect("`storage_root` is a valid hash"); + let storage_changes_root = storage_changes_root(&parent_hash.encode()) + .map(|r| Hash::decode(&mut &r[..]).expect("`storage_changes_root` is a valid hash")); if let Some(storage_changes_root) = storage_changes_root { digest.push(generic::DigestItem::ChangesTrieRoot(storage_changes_root)); @@ -249,7 +257,7 @@ pub fn finalize_block() -> Header { #[inline(always)] fn check_signature(utx: &Extrinsic) -> Result<(), TransactionValidityError> { - use sr_primitives::traits::BlindCheckable; + use sp_runtime::traits::BlindCheckable; utx.clone().check().map_err(|_| InvalidTransaction::BadProof.into()).map(|_| ()) } @@ -304,7 +312,7 @@ fn execute_storage_change(key: &[u8], value: Option<&[u8]>) -> ApplyExtrinsicRes #[cfg(feature = "std")] fn info_expect_equal_hash(given: &Hash, expected: &Hash) { - use primitives::hexdisplay::HexDisplay; + use sp_core::hexdisplay::HexDisplay; if given != expected { println!( "Hash: given={}, expected={}", @@ -317,9 +325,9 @@ fn info_expect_equal_hash(given: &Hash, expected: &Hash) { #[cfg(not(feature = "std"))] fn info_expect_equal_hash(given: &Hash, expected: &Hash) { if given != expected { - sr_primitives::print("Hash not equal"); - sr_primitives::print(given.as_bytes()); - sr_primitives::print(expected.as_bytes()); + sp_runtime::print("Hash not equal"); + sp_runtime::print(given.as_bytes()); + sp_runtime::print(expected.as_bytes()); } } @@ -327,12 +335,12 @@ fn info_expect_equal_hash(given: &Hash, expected: &Hash) { mod tests { use super::*; - use runtime_io::TestExternalities; + use sp_io::TestExternalities; use substrate_test_runtime_client::{AccountKeyring, Sr25519Keyring}; use crate::{Header, Transfer, WASM_BINARY}; - use primitives::{NeverNativeValue, map, traits::CodeExecutor}; - use substrate_executor::{NativeExecutor, WasmExecutionMethod, native_executor_instance}; - use runtime_io::hashing::twox_128; + use sp_core::{NeverNativeValue, map, traits::CodeExecutor}; + use sc_executor::{NativeExecutor, WasmExecutionMethod, native_executor_instance}; + use sp_io::hashing::twox_128; // Declare an instance of the native executor dispatch for the test runtime. native_executor_instance!( @@ -353,16 +361,16 @@ mod tests { ]; TestExternalities::new_with_code( WASM_BINARY, - ( - map![ + sp_core::storage::Storage { + top: map![ twox_128(b"latest").to_vec() => vec![69u8; 32], twox_128(b"sys:auth").to_vec() => authorities.encode(), blake2_256(&AccountKeyring::Alice.to_raw_public().to_keyed_vec(b"balance:")).to_vec() => { vec![111u8, 0, 0, 0, 0, 0, 0, 0] } ], - map![], - ) + children: map![], + }, ) } diff --git a/test-utils/src/lib.rs b/test-utils/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..f79a5da5c63e50bcbb0ec4bd53011c6e0450c94c --- /dev/null +++ b/test-utils/src/lib.rs @@ -0,0 +1,54 @@ +// Copyright 2017-2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Test utils + +/// Panic when the vectors are different, without taking the order into account. +/// +/// # Examples +/// +/// ```rust +/// #[macro_use] +/// # use substrate_test_utils::{assert_eq_uvec}; +/// # fn main() { +/// assert_eq_uvec!(vec![1,2], vec![2,1]); +/// # } +/// ``` +/// +/// ```rust,should_panic +/// #[macro_use] +/// # use substrate_test_utils::{assert_eq_uvec}; +/// # fn main() { +/// assert_eq_uvec!(vec![1,2,3], vec![2,1]); +/// # } +/// ``` +#[macro_export] +macro_rules! assert_eq_uvec { + ( $x:expr, $y:expr ) => { + $crate::__assert_eq_uvec!($x, $y); + $crate::__assert_eq_uvec!($y, $x); + } +} + +#[macro_export] +#[doc(hidden)] +macro_rules! __assert_eq_uvec { + ( $x:expr, $y:expr ) => { + $x.iter().for_each(|e| { + if !$y.contains(e) { panic!(format!("vectors not equal: {:?} != {:?}", $x, $y)); } + }); + } +} diff --git a/test/utils/client/Cargo.toml b/test/utils/client/Cargo.toml deleted file mode 100644 index d0ba0eca7ca1959235c1e48772e8930dfb12b493..0000000000000000000000000000000000000000 --- a/test/utils/client/Cargo.toml +++ /dev/null @@ -1,19 +0,0 @@ -[package] -name = "substrate-test-client" -version = "2.0.0" -authors = ["Parity Technologies "] -edition = "2018" - -[dependencies] -client-api = { package = "substrate-client-api", path = "../../../client/api" } -client = { package = "substrate-client", path = "../../../client/" } -client-db = { package = "substrate-client-db", path = "../../../client//db", features = ["test-helpers"] } -consensus = { package = "substrate-consensus-common", path = "../../../primitives/consensus/common" } -executor = { package = "substrate-executor", path = "../../../client/executor" } -futures = "0.3.1" -hash-db = "0.15.2" -keyring = { package = "substrate-keyring", path = "../../../primitives/keyring" } -codec = { package = "parity-scale-codec", version = "1.0.0" } -primitives = { package = "substrate-primitives", path = "../../../primitives/core" } -sr-primitives = { path = "../../../primitives/sr-primitives" } -state_machine = { package = "substrate-state-machine", path = "../../../primitives/state-machine" } diff --git a/test/utils/primitives/Cargo.toml b/test/utils/primitives/Cargo.toml deleted file mode 100644 index d82226d347aa1bc4a98273e795f046c1bcb4232f..0000000000000000000000000000000000000000 --- a/test/utils/primitives/Cargo.toml +++ /dev/null @@ -1,71 +0,0 @@ -[package] -name = "substrate-test-primitives" -version = "2.0.0" -authors = ["Parity Technologies "] -edition = "2018" - -[dependencies] -app-crypto = { package = "substrate-application-crypto", path = "../../../primitives/application-crypto", default-features = false } -codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -# aura-primitives = { package = "substrate-consensus-aura-primitives", path = "../../../primitives/consensus/aura", default-features = false } -# babe-primitives = { package = "substrate-consensus-babe-primitives", path = "../../../primitives/consensus/babe", default-features = false } -# block-builder-api = { package = "substrate-block-builder-runtime-api", path = "../../../primitives/block-builder/runtime-api", default-features = false } -# inherents = { package = "substrate-inherents", path = "../../../primitives/inherents", default-features = false } -# log = { version = "0.4.8", optional = true } -# memory-db = { version = "0.15.2", default-features = false } -# offchain-primitives = { package = "substrate-offchain-primitives", path = "../../../primitives/offchain", default-features = false} -primitives = { package = "substrate-primitives", path = "../../../primitives/core", default-features = false } -# rstd = { package = "sr-std", path = "../../../primitives/sr-std", default-features = false } -# runtime-interface = { package = "substrate-runtime-interface", path = "../../../primitives/runtime-interface", default-features = false} -# runtime_io = { package = "sr-io", path = "../../../primitives/sr-io", default-features = false } -# runtime_support = { package = "frame-support", path = "../../../frame/support", default-features = false } -# runtime_version = { package = "sr-version", path = "../../../primitives/sr-version", default-features = false } -serde = { version = "1.0.101", optional = true, features = ["derive"] } -# session = { package = "substrate-session", path = "../../../primitives/session", default-features = false } -# sr-api = { path = "../../../primitives/sr-api", default-features = false } -sr-primitives = { path = "../../../primitives/sr-primitives", default-features = false } -# pallet-babe = { path = "../../../frame/babe", default-features = false } -# frame-system = { path = "../../../frame/system", default-features = false } -# frame-system-rpc-runtime-api = { path = "../../../frame/system/rpc/runtime-api", default-features = false } -# pallet-timestamp = { path = "../../../frame/timestamp", default-features = false } -# substrate-client = { path = "../../../client", optional = true } -# substrate-trie = { path = "../../../primitives/trie", default-features = false } -# transaction-pool-api = { package = "substrate-transaction-pool-runtime-api", path = "../../../primitives/transaction-pool/runtime-api", default-features = false } -# trie-db = { version = "0.15.2", default-features = false } - -[features] -default = [ - "std", -] -std = [ - "app-crypto/std", - # "aura-primitives/std", - # "babe-primitives/std", - # "block-builder-api/std", - # "codec/std", - # "executive/std", - # "inherents/std", - # "keyring", - # "log", - # "memory-db/std", - # "offchain-primitives/std", - # "primitives/std", - # "primitives/std", - # "rstd/std", - # "runtime-interface/std", - # "runtime_io/std", - # "runtime_support/std", - # "runtime_version/std", - "serde", - # "session/std", - # "sr-api/std", - # "sr-primitives/std", - # "pallet-babe/std", - # "frame-system-rpc-runtime-api/std", - # "frame-system/std", - # "pallet-timestamp/std", - # "substrate-client", - # "substrate-trie/std", - # "transaction-pool-api/std", - # "trie-db/std", -] diff --git a/test/utils/runtime/Cargo.toml b/test/utils/runtime/Cargo.toml deleted file mode 100644 index f89524d2846cd8b856285326c6ae835659bfa7e8..0000000000000000000000000000000000000000 --- a/test/utils/runtime/Cargo.toml +++ /dev/null @@ -1,83 +0,0 @@ -[package] -name = "substrate-test-runtime" -version = "2.0.0" -authors = ["Parity Technologies "] -edition = "2018" -build = "build.rs" - -[dependencies] -app-crypto = { package = "substrate-application-crypto", path = "../../../primitives/application-crypto", default-features = false } -aura-primitives = { package = "substrate-consensus-aura-primitives", path = "../../../primitives/consensus/aura", default-features = false } -babe-primitives = { package = "substrate-consensus-babe-primitives", path = "../../../primitives/consensus/babe", default-features = false } -block-builder-api = { package = "substrate-block-builder-runtime-api", path = "../../../primitives/block-builder/runtime-api", default-features = false } -cfg-if = "0.1.10" -codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -executive = { package = "frame-executive", path = "../../../frame/executive", default-features = false } -inherents = { package = "substrate-inherents", path = "../../../primitives/inherents", default-features = false } -keyring = { package = "substrate-keyring", path = "../../../primitives/keyring", optional = true } -log = { version = "0.4.8", optional = true } -memory-db = { version = "0.15.2", default-features = false } -offchain-primitives = { package = "substrate-offchain-primitives", path = "../../../primitives/offchain", default-features = false} -primitives = { package = "substrate-primitives", path = "../../../primitives/core", default-features = false } -rstd = { package = "sr-std", path = "../../../primitives/sr-std", default-features = false } -runtime-interface = { package = "substrate-runtime-interface", path = "../../../primitives/runtime-interface", default-features = false} -runtime_io = { package = "sr-io", path = "../../../primitives/sr-io", default-features = false } -runtime_support = { package = "frame-support", path = "../../../frame/support", default-features = false } -runtime_version = { package = "sr-version", path = "../../../primitives/sr-version", default-features = false } -serde = { version = "1.0.101", optional = true, features = ["derive"] } -session = { package = "substrate-session", path = "../../../primitives/session", default-features = false } -sr-api = { path = "../../../primitives/sr-api", default-features = false } -sr-primitives = { path = "../../../primitives/sr-primitives", default-features = false } -pallet-babe = { path = "../../../frame/babe", default-features = false } -frame-system = { path = "../../../frame/system", default-features = false } -frame-system-rpc-runtime-api = { path = "../../../frame/system/rpc/runtime-api", default-features = false } -pallet-timestamp = { path = "../../../frame/timestamp", default-features = false } -substrate-client = { path = "../../../client", optional = true } -substrate-trie = { path = "../../../primitives/trie", default-features = false } -transaction-pool-api = { package = "substrate-transaction-pool-runtime-api", path = "../../../primitives/transaction-pool/runtime-api", default-features = false } -trie-db = { version = "0.16.0", default-features = false } - -[dev-dependencies] -substrate-executor = { path = "../../../client/executor" } -substrate-test-runtime-client = { path = "./client" } -state_machine = { package = "substrate-state-machine", path = "../../../primitives/state-machine" } - -[build-dependencies] -wasm-builder-runner = { package = "substrate-wasm-builder-runner", path = "../../../client/utils/wasm-builder-runner", version = "1.0.4" } - -[features] -default = [ - "std", -] -std = [ - "app-crypto/std", - "aura-primitives/std", - "babe-primitives/std", - "block-builder-api/std", - "codec/std", - "executive/std", - "inherents/std", - "keyring", - "log", - "memory-db/std", - "offchain-primitives/std", - "primitives/std", - "primitives/std", - "rstd/std", - "runtime-interface/std", - "runtime_io/std", - "runtime_support/std", - "runtime_version/std", - "serde", - "session/std", - "sr-api/std", - "sr-primitives/std", - "pallet-babe/std", - "frame-system-rpc-runtime-api/std", - "frame-system/std", - "pallet-timestamp/std", - "substrate-client", - "substrate-trie/std", - "transaction-pool-api/std", - "trie-db/std", -] diff --git a/test/utils/runtime/client/Cargo.toml b/test/utils/runtime/client/Cargo.toml deleted file mode 100644 index 68f58200621004195db3d8dd2f4023205109d055..0000000000000000000000000000000000000000 --- a/test/utils/runtime/client/Cargo.toml +++ /dev/null @@ -1,15 +0,0 @@ -[package] -name = "substrate-test-runtime-client" -version = "2.0.0" -authors = ["Parity Technologies "] -edition = "2018" - -[dependencies] -block-builder = { package = "substrate-block-builder", path = "../../../../client/block-builder" } -generic-test-client = { package = "substrate-test-client", path = "../../client" } -primitives = { package = "substrate-primitives", path = "../../../../primitives/core" } -runtime = { package = "substrate-test-runtime", path = "../../runtime" } -sr-primitives = { path = "../../../../primitives/sr-primitives" } -codec = { package = "parity-scale-codec", version = "1.0.0" } -client-api = { package = "substrate-client-api", path = "../../../../client/api" } -client = { package = "substrate-client", path = "../../../../client/" } diff --git a/test/utils/transaction-factory/Cargo.toml b/test/utils/transaction-factory/Cargo.toml deleted file mode 100644 index fdd948a6f2d29bb6ac30cd4e926366e4ad32a2c8..0000000000000000000000000000000000000000 --- a/test/utils/transaction-factory/Cargo.toml +++ /dev/null @@ -1,19 +0,0 @@ -[package] -name = "transaction-factory" -version = "0.0.1" -authors = ["Parity Technologies "] -edition = "2018" - -[dependencies] -block-builder-api = { package = "substrate-block-builder-runtime-api", path = "../../../primitives/block-builder/runtime-api" } -cli = { package = "substrate-cli", path = "../../../client/cli" } -client-api = { package = "substrate-client-api", path = "../../../client/api" } -client = { package = "substrate-client", path = "../../../client" } -codec = { package = "parity-scale-codec", version = "1.0.0", features = ["derive"] } -consensus_common = { package = "substrate-consensus-common", path = "../../../primitives/consensus/common" } -log = "0.4.8" -primitives = { package = "substrate-primitives", path = "../../../primitives/core" } -sr-api = { path = "../../../primitives/sr-api" } -sr-primitives = { path = "../../../primitives/sr-primitives" } -substrate-service = { path = "../../../client/service" } - diff --git a/utils/frame/rpc/support/Cargo.toml b/utils/frame/rpc/support/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..f26a69cc5fa0cdad9743908593787b43b028f35a --- /dev/null +++ b/utils/frame/rpc/support/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "substrate-frame-rpc-support" +version = "2.0.0" +authors = ["Parity Technologies ", "Andrew Dirksen "] +edition = "2018" + +[dependencies] +futures = { version = "0.3.0", features = ["compat"] } +jsonrpc-client-transports = "14" +jsonrpc-core = "14" +codec = { package = "parity-scale-codec", version = "1" } +serde = "1" +frame-support = { version = "2.0.0", path = "../../../../frame/support" } +sp-storage = { version = "2.0.0", path = "../../../../primitives/storage" } +sc-rpc-api = { version = "2.0.0", path = "../../../../client/rpc-api" } + +[dev-dependencies] +frame-system = { version = "2.0.0", path = "../../../../frame/system" } +tokio = "0.1" diff --git a/frame/support/rpc/src/lib.rs b/utils/frame/rpc/support/src/lib.rs similarity index 89% rename from frame/support/rpc/src/lib.rs rename to utils/frame/rpc/support/src/lib.rs index e248e0c9fed799705879758ecd8c9f3b4946df0e..80c0658086df6639f7d82eca1424070f8c1b6003 100644 --- a/frame/support/rpc/src/lib.rs +++ b/utils/frame/rpc/support/src/lib.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! Combines [substrate_rpc_api::state::StateClient] with [frame_support::storage::generator] traits +//! Combines [sc_rpc_api::state::StateClient] with [frame_support::storage::generator] traits //! to provide strongly typed chain state queries over rpc. #![warn(missing_docs)] @@ -22,13 +22,13 @@ use core::marker::PhantomData; use futures::compat::Future01CompatExt; use jsonrpc_client_transports::RpcError; -use parity_scale_codec::{DecodeAll, FullCodec, FullEncode}; +use codec::{DecodeAll, FullCodec, FullEncode}; use serde::{de::DeserializeOwned, Serialize}; use frame_support::storage::generator::{ StorageDoubleMap, StorageLinkedMap, StorageMap, StorageValue }; -use substrate_primitives_storage::{StorageData, StorageKey}; -use substrate_rpc_api::state::StateClient; +use sp_storage::{StorageData, StorageKey}; +use sc_rpc_api::state::StateClient; /// A typed query on chain state usable from an RPC client. /// @@ -38,11 +38,11 @@ use substrate_rpc_api::state::StateClient; /// # use futures::future::FutureExt; /// # use jsonrpc_client_transports::RpcError; /// # use jsonrpc_client_transports::transports::http; -/// # use parity_scale_codec::Encode; +/// # use codec::Encode; /// # use frame_support::{decl_storage, decl_module}; -/// # use frame_support_rpc::StorageQuery; +/// # use substrate_frame_rpc_support::StorageQuery; /// # use frame_system::Trait; -/// # use substrate_rpc_api::state::StateClient; +/// # use sc_rpc_api::state::StateClient; /// # /// # // Hash would normally be ::Hash, but we don't have /// # // frame_system::Trait implemented for TestRuntime. Here we just pretend. @@ -108,7 +108,7 @@ impl StorageQuery { /// Create a storage query for a value in a StorageMap. pub fn map, K: FullEncode>(key: K) -> Self { Self { - key: StorageKey(St::storage_map_final_key(key).as_ref().to_vec()), + key: StorageKey(St::storage_map_final_key(key)), _spook: PhantomData, } } @@ -116,7 +116,7 @@ impl StorageQuery { /// Create a storage query for a value in a StorageLinkedMap. pub fn linked_map, K: FullCodec>(key: K) -> Self { Self { - key: StorageKey(St::storage_linked_map_final_key(key).as_ref().to_vec()), + key: StorageKey(St::storage_linked_map_final_key(key)), _spook: PhantomData, } } diff --git a/utils/frame/rpc/system/Cargo.toml b/utils/frame/rpc/system/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..45e1af6f76bdf37d5ee6ccd9d069b165c598b7c1 --- /dev/null +++ b/utils/frame/rpc/system/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "substrate-frame-rpc-system" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +sc-client = { version = "2.0.0", path = "../../../../client/" } +codec = { package = "parity-scale-codec", version = "1.0.0" } +futures = "0.3.1" +jsonrpc-core = "14.0.3" +jsonrpc-core-client = "14.0.3" +jsonrpc-derive = "14.0.3" +log = "0.4.8" +serde = { version = "1.0.101", features = ["derive"] } +sp-runtime = { version = "2.0.0", path = "../../../../primitives/runtime" } +frame-system-rpc-runtime-api = { version = "2.0.0", path = "../../../../frame/system/rpc/runtime-api" } +sp-core = { version = "2.0.0", path = "../../../../primitives/core" } +sp-blockchain = { version = "2.0.0", path = "../../../../primitives/blockchain" } +sp-transaction-pool = { version = "2.0.0", path = "../../../../primitives/transaction-pool" } + +[dev-dependencies] +substrate-test-runtime-client = { version = "2.0.0", path = "../../../../test-utils/runtime/client" } +env_logger = "0.7.0" +sc-transaction-pool = { version = "2.0.0", path = "../../../../client/transaction-pool" } diff --git a/utils/frame/rpc/system/src/lib.rs b/utils/frame/rpc/system/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..c1d9b1f4f628e57ed8d3616fee7ddca9bb608f01 --- /dev/null +++ b/utils/frame/rpc/system/src/lib.rs @@ -0,0 +1,263 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! System SRML specific RPC methods. + +use std::sync::Arc; + +use codec::{self, Codec, Decode, Encode}; +use sc_client::{ + light::blockchain::{future_header, RemoteBlockchain}, + light::fetcher::{Fetcher, RemoteCallRequest}, +}; +use jsonrpc_core::{ + Error, ErrorCode, + futures::future::{result, Future}, +}; +use jsonrpc_derive::rpc; +use futures::future::{ready, TryFutureExt}; +use sp_blockchain::{ + HeaderBackend, + Error as ClientError +}; +use sp_runtime::{ + generic::BlockId, + traits, +}; +use sp_core::hexdisplay::HexDisplay; +use sp_transaction_pool::{TransactionPool, InPoolTransaction}; + +pub use frame_system_rpc_runtime_api::AccountNonceApi; +pub use self::gen_client::Client as SystemClient; + +/// Future that resolves to account nonce. +pub type FutureResult = Box + Send>; + +/// System RPC methods. +#[rpc] +pub trait SystemApi { + /// Returns the next valid index (aka nonce) for given account. + /// + /// This method takes into consideration all pending transactions + /// currently in the pool and if no transactions are found in the pool + /// it fallbacks to query the index from the runtime (aka. state nonce). + #[rpc(name = "system_accountNextIndex", alias("account_nextIndex"))] + fn nonce(&self, account: AccountId) -> FutureResult; +} + +const RUNTIME_ERROR: i64 = 1; + +/// An implementation of System-specific RPC methods on full client. +pub struct FullSystem { + client: Arc, + pool: Arc

, + _marker: std::marker::PhantomData, +} + +impl FullSystem { + /// Create new `FullSystem` given client and transaction pool. + pub fn new(client: Arc, pool: Arc

) -> Self { + FullSystem { + client, + pool, + _marker: Default::default(), + } + } +} + +impl SystemApi for FullSystem +where + C: traits::ProvideRuntimeApi, + C: HeaderBackend, + C: Send + Sync + 'static, + C::Api: AccountNonceApi, + P: TransactionPool + 'static, + Block: traits::Block, + AccountId: Clone + std::fmt::Display + Codec, + Index: Clone + std::fmt::Display + Codec + Send + traits::SimpleArithmetic + 'static, +{ + fn nonce(&self, account: AccountId) -> FutureResult { + let get_nonce = || { + let api = self.client.runtime_api(); + let best = self.client.info().best_hash; + let at = BlockId::hash(best); + + let nonce = api.account_nonce(&at, account.clone()).map_err(|e| Error { + code: ErrorCode::ServerError(RUNTIME_ERROR), + message: "Unable to query nonce.".into(), + data: Some(format!("{:?}", e).into()), + })?; + + Ok(adjust_nonce(&*self.pool, account, nonce)) + }; + + Box::new(result(get_nonce())) + } +} + +/// An implementation of System-specific RPC methods on light client. +pub struct LightSystem { + client: Arc, + remote_blockchain: Arc>, + fetcher: Arc, + pool: Arc

, +} + +impl LightSystem { + /// Create new `LightSystem`. + pub fn new( + client: Arc, + remote_blockchain: Arc>, + fetcher: Arc, + pool: Arc

, + ) -> Self { + LightSystem { + client, + remote_blockchain, + fetcher, + pool, + } + } +} + +impl SystemApi for LightSystem +where + P: TransactionPool + 'static, + C: HeaderBackend, + C: Send + Sync + 'static, + F: Fetcher + 'static, + Block: traits::Block, + AccountId: Clone + std::fmt::Display + Codec + Send + 'static, + Index: Clone + std::fmt::Display + Codec + Send + traits::SimpleArithmetic + 'static, +{ + fn nonce(&self, account: AccountId) -> FutureResult { + let best_hash = self.client.info().best_hash; + let best_id = BlockId::hash(best_hash); + let future_best_header = future_header(&*self.remote_blockchain, &*self.fetcher, best_id); + let fetcher = self.fetcher.clone(); + let call_data = account.encode(); + let future_best_header = future_best_header + .and_then(move |maybe_best_header| ready( + match maybe_best_header { + Some(best_header) => Ok(best_header), + None => Err(ClientError::UnknownBlock(format!("{}", best_hash))), + } + )); + let future_nonce = future_best_header.and_then(move |best_header| + fetcher.remote_call(RemoteCallRequest { + block: best_hash, + header: best_header, + method: "AccountNonceApi_account_nonce".into(), + call_data, + retry_count: None, + }) + ).compat(); + let future_nonce = future_nonce.and_then(|nonce| Decode::decode(&mut &nonce[..]) + .map_err(|e| ClientError::CallResultDecode("Cannot decode account nonce", e))); + let future_nonce = future_nonce.map_err(|e| Error { + code: ErrorCode::ServerError(RUNTIME_ERROR), + message: "Unable to query nonce.".into(), + data: Some(format!("{:?}", e).into()), + }); + + let pool = self.pool.clone(); + let future_nonce = future_nonce.map(move |nonce| adjust_nonce(&*pool, account, nonce)); + + Box::new(future_nonce) + } +} + +/// Adjust account nonce from state, so that tx with the nonce will be +/// placed after all ready txpool transactions. +fn adjust_nonce( + pool: &P, + account: AccountId, + nonce: Index, +) -> Index where + P: TransactionPool, + AccountId: Clone + std::fmt::Display + Encode, + Index: Clone + std::fmt::Display + Encode + traits::SimpleArithmetic + 'static, +{ + log::debug!(target: "rpc", "State nonce for {}: {}", account, nonce); + // Now we need to query the transaction pool + // and find transactions originating from the same sender. + // + // Since extrinsics are opaque to us, we look for them using + // `provides` tag. And increment the nonce if we find a transaction + // that matches the current one. + let mut current_nonce = nonce.clone(); + let mut current_tag = (account.clone(), nonce.clone()).encode(); + for tx in pool.ready() { + log::debug!( + target: "rpc", + "Current nonce to {}, checking {} vs {:?}", + current_nonce, + HexDisplay::from(¤t_tag), + tx.provides().iter().map(|x| format!("{}", HexDisplay::from(x))).collect::>(), + ); + // since transactions in `ready()` need to be ordered by nonce + // it's fine to continue with current iterator. + if tx.provides().get(0) == Some(¤t_tag) { + current_nonce += traits::One::one(); + current_tag = (account.clone(), current_nonce.clone()).encode(); + } + } + + current_nonce +} + +#[cfg(test)] +mod tests { + use super::*; + + use futures::executor::block_on; + use substrate_test_runtime_client::{ + runtime::Transfer, + AccountKeyring, + }; + use sc_transaction_pool::{BasicPool, FullChainApi}; + + #[test] + fn should_return_next_nonce_for_some_account() { + // given + let _ = env_logger::try_init(); + let client = Arc::new(substrate_test_runtime_client::new()); + let pool = Arc::new(BasicPool::new(Default::default(), FullChainApi::new(client.clone()))); + + let new_transaction = |nonce: u64| { + let t = Transfer { + from: AccountKeyring::Alice.into(), + to: AccountKeyring::Bob.into(), + amount: 5, + nonce, + }; + t.into_signed_tx() + }; + // Populate the pool + let ext0 = new_transaction(0); + block_on(pool.submit_one(&BlockId::number(0), ext0)).unwrap(); + let ext1 = new_transaction(1); + block_on(pool.submit_one(&BlockId::number(0), ext1)).unwrap(); + + let accounts = FullSystem::new(client, pool); + + // when + let nonce = accounts.nonce(AccountKeyring::Alice.into()); + + // then + assert_eq!(nonce.wait().unwrap(), 2); + } +} diff --git a/client/grafana-data-source/Cargo.toml b/utils/grafana-data-source/Cargo.toml similarity index 66% rename from client/grafana-data-source/Cargo.toml rename to utils/grafana-data-source/Cargo.toml index 597d036c58ae334e0bd22c0d976f8b3f7c543c84..76bf7d5988d9ab0f10b290738b416c6432aa3cf0 100644 --- a/client/grafana-data-source/Cargo.toml +++ b/utils/grafana-data-source/Cargo.toml @@ -7,18 +7,17 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -hyper = { version = "0.13.0-alpha.4", default-features = false, features = ["unstable-stream"] } -tokio-io = "0.2.0-alpha.6" -tokio-executor = "0.2.0-alpha.6" +log = "0.4.8" +hyper = { version = "0.13.1", default-features = false, features = ["stream"] } +tokio = "0.2" futures-util = { version = "0.3.1", default-features = false, features = ["io"] } -futures-util-alpha = { package = "futures-util-preview", default-features = false, version = "0.3.0-alpha.19" } serde_json = "1" serde = { version = "1", features = ["derive"] } chrono = { version = "0.4", features = ["serde"] } lazy_static = "1.4" parking_lot = "0.9" futures-timer = "2.0" -derive_more = "0.15" +derive_more = "0.99" [target.'cfg(not(target_os = "unknown"))'.dependencies] async-std = { version = "1.0.1", features = ["unstable"] } diff --git a/utils/grafana-data-source/src/database.rs b/utils/grafana-data-source/src/database.rs new file mode 100644 index 0000000000000000000000000000000000000000..55b48123fa38f8acb1b53c21f9f1f38ae4f8b029 --- /dev/null +++ b/utils/grafana-data-source/src/database.rs @@ -0,0 +1,170 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +use std::collections::HashMap; +use std::convert::TryFrom; +use crate::Error; + +pub struct Database { + base_timestamp: i64, + storage: HashMap> +} + +impl Database { + /// Create a new Database. + pub fn new() -> Self { + Self { + base_timestamp: now_millis(), + storage: HashMap::new() + } + } + + /// Produce an iterator for keys starting with a base string. + pub fn keys_starting_with<'a>(&'a self, base: &'a str) -> impl Iterator + 'a { + self.storage.keys() + .filter(move |key| key.starts_with(base)) + .cloned() + } + + /// Select `max_datapoints` datapoints that have been added between `from` and `to`. + pub fn datapoints_between(&self, key: &str, from: i64, to: i64, max_datapoints: usize) -> Option> { + self.storage.get(key) + .map(|vec| { + let from = find_index(vec, self.base_timestamp, from); + let to = find_index(vec, self.base_timestamp, to); + let slice = &vec[from .. to]; + + if max_datapoints == 0 { + Vec::new() + } else if max_datapoints >= slice.len() { + // Just convert the slice as-is + slice.iter() + .map(|dp| dp.make_absolute(self.base_timestamp)) + .collect() + } else { + // We have more datapoints than we need, so we need to skip some + (0 .. max_datapoints - 1) + .map(|i| &slice[i * slice.len() / (max_datapoints - 1)]) + .chain(slice.last()) + .map(|dp| dp.make_absolute(self.base_timestamp)) + .collect() + } + }) + } + + /// Push a new datapoint. Will error if the base timestamp hasn't been updated in `2^32` + /// milliseconds (49 days). + pub fn push(&mut self, key: &str, value: f32) -> Result<(), Error> { + self.storage.entry(key.into()) + .or_insert_with(Vec::new) + .push(Datapoint::new(self.base_timestamp, value)?); + + Ok(()) + } + + /// Set a new base timestamp, and remove metrics older than this new timestamp. Errors if the + /// difference between timestamps is greater than `2^32` milliseconds (49 days). + pub fn truncate(&mut self, new_base_timestamp: i64) -> Result<(), Error> { + // Ensure that the new base is older. + if self.base_timestamp >= new_base_timestamp { + return Ok(()); + } + + // If the old base timestamp was too long ago, the + let delta = u32::try_from(new_base_timestamp - self.base_timestamp) + .map_err(Error::Timestamp)?; + + for metric in self.storage.values_mut() { + // Find the index of the oldest allowed timestamp and cut out all those before it. + let index = find_index(&metric, self.base_timestamp, new_base_timestamp); + + *metric = metric.iter_mut() + .skip(index) + .map(|dp| { + dp.delta_timestamp -= delta; + *dp + }) + .collect(); + } + + self.base_timestamp = new_base_timestamp; + + Ok(()) + } +} + +#[derive(Clone, Copy)] +struct Datapoint { + delta_timestamp: u32, + value: f32 +} + +impl Datapoint { + fn new(base_timestamp: i64, value: f32) -> Result { + Ok(Self { + delta_timestamp: u32::try_from(now_millis() - base_timestamp) + .map_err(Error::Timestamp)?, + value + }) + } + + fn make_absolute(self, base_timestamp: i64) -> (f32, i64) { + (self.value, base_timestamp + self.delta_timestamp as i64) + } +} + +fn find_index(slice: &[Datapoint], base_timestamp: i64, timestamp: i64) -> usize { + slice.binary_search_by_key(×tamp, |datapoint| { + base_timestamp + datapoint.delta_timestamp as i64 + }).unwrap_or_else(|index| index) +} + +/// Get the current unix timestamp in milliseconds. +fn now_millis() -> i64 { + chrono::Utc::now().timestamp_millis() +} + +#[test] +fn test() { + let mut database = Database::new(); + let start = now_millis(); + + database.push("test", 1.0).unwrap(); + database.push("test", 2.5).unwrap(); + database.push("test", 2.0).unwrap(); + database.push("test 2", 1.0).unwrap(); + + let mut keys: Vec<_> = database.keys_starting_with("test").collect(); + keys.sort(); + + assert_eq!(keys, ["test", "test 2"]); + assert_eq!(database.keys_starting_with("test ").collect::>(), ["test 2"]); + + assert_eq!( + database.datapoints_between("test", start - 1000, start + 1000, 4), + Some(vec![(1.0, start), (2.5, start), (2.0, start)]) + ); + + assert_eq!( + database.datapoints_between("test", start - 1000, start + 1000, 3), + Some(vec![(1.0, start), (2.5, start), (2.0, start)]) + ); + + assert_eq!( + database.datapoints_between("test", start - 1000, start + 1000, 2), + Some(vec![(1.0, start), (2.0, start)]) + ); +} diff --git a/client/grafana-data-source/src/lib.rs b/utils/grafana-data-source/src/lib.rs similarity index 52% rename from client/grafana-data-source/src/lib.rs rename to utils/grafana-data-source/src/lib.rs index 7373f62705606029a1fa3d468d7f1c0bfea0e10e..229400066a1e97c755a2cc772fdddb5dcfe98b45 100644 --- a/client/grafana-data-source/src/lib.rs +++ b/utils/grafana-data-source/src/lib.rs @@ -23,36 +23,69 @@ //! [Grafana]: https://grafana.com/ //! [`grafana-json-data-source`]: https://github.com/simPod/grafana-json-datasource +#![warn(missing_docs)] + use lazy_static::lazy_static; -use std::collections::HashMap; use parking_lot::RwLock; mod types; mod server; -mod util; #[cfg(not(target_os = "unknown"))] mod networking; +mod database; +use database::Database; pub use server::run_server; -pub use util::now_millis; - -type Metrics = HashMap<&'static str, Vec<(f32, i64)>>; +use std::num::TryFromIntError; lazy_static! { - /// The `RwLock` wrapping the metrics. Not intended to be used directly. - #[doc(hidden)] - pub static ref METRICS: RwLock = RwLock::new(Metrics::new()); + // The `RwLock` wrapping the metrics database. + static ref DATABASE: RwLock = RwLock::new(Database::new()); } /// Write metrics to `METRICS`. #[macro_export] macro_rules! record_metrics( - ($($key:expr => $value:expr),*) => { - use $crate::{METRICS, now_millis}; - let mut metrics = METRICS.write(); - let now = now_millis(); - $( - metrics.entry($key).or_insert_with(Vec::new).push(($value as f32, now)); - )* + ($($key:expr => $value:expr,)*) => { + if cfg!(not(target_os = "unknown")) { + $crate::record_metrics_slice(&[ + $( ($key, $value as f32), )* + ]) + } else { + Ok(()) + } } ); + +/// Write metrics to `METRICS` as a slice. Intended to be only used via `record_metrics!`. +pub fn record_metrics_slice(metrics: &[(&str, f32)]) -> Result<(), Error> { + let mut database = crate::DATABASE.write(); + + for &(key, value) in metrics.iter() { + database.push(key, value)?; + } + + Ok(()) +} + +/// Error type that can be returned by either `record_metrics` or `run_server`. +#[derive(Debug, derive_more::Display, derive_more::From)] +pub enum Error { + Hyper(hyper::Error), + Serde(serde_json::Error), + Http(hyper::http::Error), + Timestamp(TryFromIntError), + Io(std::io::Error) +} + +impl std::error::Error for Error { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + match self { + Error::Hyper(error) => Some(error), + Error::Serde(error) => Some(error), + Error::Http(error) => Some(error), + Error::Timestamp(error) => Some(error), + Error::Io(error) => Some(error) + } + } +} diff --git a/client/grafana-data-source/src/networking.rs b/utils/grafana-data-source/src/networking.rs similarity index 95% rename from client/grafana-data-source/src/networking.rs rename to utils/grafana-data-source/src/networking.rs index 66362e4e68145b23046d6ab7f23e13a275e3c573..f5bbd21d57a86ac56f7ec98eb33dae30469b9c9c 100644 --- a/client/grafana-data-source/src/networking.rs +++ b/utils/grafana-data-source/src/networking.rs @@ -33,7 +33,7 @@ impl hyper::server::accept::Accept for Incoming<'_> { pub struct TcpStream(pub async_std::net::TcpStream); -impl tokio_io::AsyncRead for TcpStream { +impl tokio::io::AsyncRead for TcpStream { fn poll_read( self: Pin<&mut Self>, cx: &mut Context, @@ -44,7 +44,7 @@ impl tokio_io::AsyncRead for TcpStream { } } -impl tokio_io::AsyncWrite for TcpStream { +impl tokio::io::AsyncWrite for TcpStream { fn poll_write( self: Pin<&mut Self>, cx: &mut Context, diff --git a/client/grafana-data-source/src/server.rs b/utils/grafana-data-source/src/server.rs similarity index 62% rename from client/grafana-data-source/src/server.rs rename to utils/grafana-data-source/src/server.rs index 0213e9ff25514c6af295b24dce8ebdfa5f78345e..6553a7b9e0d15eacfba3573e552e5530e6e933e1 100644 --- a/client/grafana-data-source/src/server.rs +++ b/utils/grafana-data-source/src/server.rs @@ -17,47 +17,33 @@ use serde::{Serialize, de::DeserializeOwned}; use hyper::{Body, Request, Response, header, service::{service_fn, make_service_fn}, Server}; use chrono::{Duration, Utc}; -use futures_util::{FutureExt, future::{Future, select, Either}}; +use futures_util::{FutureExt, TryStreamExt, future::{Future, select, Either}}; use futures_timer::Delay; -use crate::{METRICS, util, types::{Target, Query, TimeseriesData}}; - -#[derive(Debug, derive_more::Display)] -enum Error { - Hyper(hyper::Error), - Serde(serde_json::Error), - Http(hyper::http::Error) -} - -impl std::error::Error for Error {} +use crate::{DATABASE, Error, types::{Target, Query, TimeseriesData, Range}}; async fn api_response(req: Request) -> Result, Error> { match req.uri().path() { "/search" => { map_request_to_response(req, |target: Target| { // Filter and return metrics relating to the target - METRICS.read() - .keys() - .filter(|key| key.starts_with(&target.target)) - .cloned() + DATABASE.read() + .keys_starting_with(&target.target) .collect::>() }).await }, "/query" => { map_request_to_response(req, |query: Query| { - let metrics = METRICS.read(); + let metrics = DATABASE.read(); + + let Query { + range: Range { from, to }, + max_datapoints, .. + } = query; // Return timeseries data related to the specified metrics query.targets.iter() .map(|target| { - let datapoints = metrics.get(target.target.as_str()) - .map(|metric| { - let from = util::find_index(&metric, query.range.from); - let to = util::find_index(&metric, query.range.to); - - // Avoid returning more than `max_datapoints` (mostly to stop - // the web browser from having to do a ton of work) - util::select_points(&metric[from .. to], query.max_datapoints) - }) + let datapoints = metrics.datapoints_between(&target.target, from, to, max_datapoints) .unwrap_or_else(Vec::new); TimeseriesData { @@ -77,9 +63,8 @@ async fn map_request_to_response(req: Request, transformation Res: Serialize, T: Fn(Req) -> Res + Send + Sync + 'static { - use futures_util_alpha::TryStreamExt; - let body = req.into_body() + .map_ok(|bytes| bytes.to_vec()) .try_concat() .await .map_err(Error::Hyper)?; @@ -99,23 +84,42 @@ async fn map_request_to_response(req: Request, transformation pub struct Executor; #[cfg(not(target_os = "unknown"))] -impl tokio_executor::TypedExecutor for Executor +impl hyper::rt::Executor for Executor where T: Future + Send + 'static, T::Output: Send + 'static, { - fn spawn(&mut self, future: T) -> Result<(), tokio_executor::SpawnError> { + fn execute(&self, future: T) { async_std::task::spawn(future); - Ok(()) } } /// Start the data source server. #[cfg(not(target_os = "unknown"))] -pub async fn run_server(address: std::net::SocketAddr) -> Result<(), hyper::Error> { +pub async fn run_server(mut address: std::net::SocketAddr) -> Result<(), Error> { + use async_std::{net, io}; use crate::networking::Incoming; - let listener = async_std::net::TcpListener::bind(&address).await.unwrap(); + let listener = loop { + let listener = net::TcpListener::bind(&address).await; + match listener { + Ok(listener) => { + log::info!("Grafana data source server started at {}", address); + break listener + }, + Err(err) => match err.kind() { + io::ErrorKind::AddrInUse | io::ErrorKind::PermissionDenied if address.port() != 0 => { + log::warn!( + "Unable to bind grafana data source server to {}. Trying random port.", + address + ); + address.set_port(0); + continue; + }, + _ => return Err(err.into()), + } + } + }; let service = make_service_fn(|_| { async { @@ -128,38 +132,29 @@ pub async fn run_server(address: std::net::SocketAddr) -> Result<(), hyper::Erro .serve(service) .boxed(); - let clean = clean_up(Duration::days(1), Duration::weeks(1)) + let every = std::time::Duration::from_secs(24 * 3600); + let clean = clean_up(every, Duration::weeks(1)) .boxed(); let result = match select(server, clean).await { - Either::Left((result, _)) => result, - Either::Right(_) => Ok(()) + Either::Left((result, _)) => result.map_err(Into::into), + Either::Right((result, _)) => result }; result } #[cfg(target_os = "unknown")] -pub async fn run_server(_: std::net::SocketAddr) -> Result<(), hyper::Error> { +pub async fn run_server(_: std::net::SocketAddr) -> Result<(), Error> { Ok(()) } /// Periodically remove old metrics. -async fn clean_up(every: Duration, before: Duration) { +async fn clean_up(every: std::time::Duration, before: Duration) -> Result<(), Error> { loop { - Delay::new(every.to_std().unwrap()).await; + Delay::new(every).await; let oldest_allowed = (Utc::now() - before).timestamp_millis(); - - let mut metrics = METRICS.write(); - - for metric in metrics.values_mut() { - // Find the index of the oldest allowed timestamp and cut out all those before it. - let index = util::find_index(&metric, oldest_allowed); - - if index > 0 { - *metric = metric[index..].to_vec(); - } - } + DATABASE.write().truncate(oldest_allowed)?; } } diff --git a/client/grafana-data-source/src/types.rs b/utils/grafana-data-source/src/types.rs similarity index 100% rename from client/grafana-data-source/src/types.rs rename to utils/grafana-data-source/src/types.rs diff --git a/client/grafana-data-source/test/Cargo.toml b/utils/grafana-data-source/test/Cargo.toml similarity index 82% rename from client/grafana-data-source/test/Cargo.toml rename to utils/grafana-data-source/test/Cargo.toml index 2ee376be8d212e68639ab69015591f6572bb7305..079b49dc8608a517ffe50cfef1553ab0a536c33c 100644 --- a/client/grafana-data-source/test/Cargo.toml +++ b/utils/grafana-data-source/test/Cargo.toml @@ -7,7 +7,7 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -grafana-data-source = { path = ".." } +grafana-data-source = { version = "2.0.0", path = ".." } futures = "0.3" futures-timer = "2.0" rand = "0.7" diff --git a/client/grafana-data-source/test/src/main.rs b/utils/grafana-data-source/test/src/main.rs similarity index 90% rename from client/grafana-data-source/test/src/main.rs rename to utils/grafana-data-source/test/src/main.rs index bb2b317a6c41cfd716eb98496883d2de8fc48ff9..a723e7e476168c0f4212c043aea87d33d1e9cc53 100644 --- a/client/grafana-data-source/test/src/main.rs +++ b/utils/grafana-data-source/test/src/main.rs @@ -25,10 +25,14 @@ async fn randomness() { let random = rand::thread_rng().gen_range(0.0, 1000.0); - record_metrics!( + let result = record_metrics!( "random data" => random, - "random^2" => random * random + "random^2" => random * random, ); + + if let Err(error) = result { + eprintln!("{}", error); + } } } diff --git a/client/utils/wasm-builder-runner/Cargo.toml b/utils/wasm-builder-runner/Cargo.toml similarity index 100% rename from client/utils/wasm-builder-runner/Cargo.toml rename to utils/wasm-builder-runner/Cargo.toml diff --git a/client/utils/wasm-builder-runner/README.md b/utils/wasm-builder-runner/README.md similarity index 100% rename from client/utils/wasm-builder-runner/README.md rename to utils/wasm-builder-runner/README.md diff --git a/client/utils/wasm-builder-runner/src/lib.rs b/utils/wasm-builder-runner/src/lib.rs similarity index 100% rename from client/utils/wasm-builder-runner/src/lib.rs rename to utils/wasm-builder-runner/src/lib.rs diff --git a/utils/wasm-builder/src/wasm_project.rs b/utils/wasm-builder/src/wasm_project.rs index 701a50fe1c9c77849b971301b2febde70b4665b9..bb32d622187420eb37c475b827b1261cd20af3c9 100644 --- a/utils/wasm-builder/src/wasm_project.rs +++ b/utils/wasm-builder/src/wasm_project.rs @@ -181,6 +181,7 @@ fn create_wasm_workspace_project(wasm_workspace: &Path, cargo_manifest: &Path) { .map(|d| d.into_path()) .filter(|p| p.is_dir() && !p.ends_with("target")) .filter_map(|p| p.file_name().map(|f| f.to_owned()).and_then(|s| s.into_string().ok())) + .filter(|f| !f.starts_with(".")) .collect::>(); let crate_metadata = MetadataCommand::new()

{ + fn clone(&self) -> Self { + Self { + inner: self.inner.clone() + } + } +} + pub fn extract_type_option(typ: &syn::Type) -> Option { if let syn::Type::Path(ref path) = typ { let v = path.path.segments.last()?; diff --git a/frame/support/rpc/Cargo.toml b/frame/support/rpc/Cargo.toml deleted file mode 100644 index 15e9fee7f0c4cc160bfb4c9d6471ed32a6b5a279..0000000000000000000000000000000000000000 --- a/frame/support/rpc/Cargo.toml +++ /dev/null @@ -1,19 +0,0 @@ -[package] -name = "frame-support-rpc" -version = "2.0.0" -authors = ["Parity Technologies ", "Andrew Dirksen "] -edition = "2018" - -[dependencies] -futures = { version = "0.3.0", features = ["compat"] } -jsonrpc-client-transports = "14" -jsonrpc-core = "14" -parity-scale-codec = "1" -serde = "1" -frame-support = { path = "../" } -substrate-primitives-storage = { path = "../../../primitives/core/storage" } -substrate-rpc-api = { path = "../../../client/rpc/api" } - -[dev-dependencies] -frame-system = { path = "../../system" } -tokio = "0.1" diff --git a/frame/support/src/debug.rs b/frame/support/src/debug.rs index feb8e6d873e6c5b3d7e004aa8eb9a8c34e13a4fe..2e64b67c1b8e0a2f12e1016ff0147524bada396b 100644 --- a/frame/support/src/debug.rs +++ b/frame/support/src/debug.rs @@ -25,7 +25,7 @@ //! this that are described below. //! //! First component to utilize debug-printing and loggin is actually -//! located in `primitives` crate: `primitives::RuntimeDebug`. +//! located in `primitives` crate: `sp_core::RuntimeDebug`. //! This custom-derive generates `core::fmt::Debug` implementation, //! just like regular `derive(Debug)`, however it does not generate //! any code when the code is compiled to WASM. This means that @@ -37,7 +37,7 @@ //! ```rust,no_run //! use frame_support::debug; //! -//! #[derive(primitives::RuntimeDebug)] +//! #[derive(sp_core::RuntimeDebug)] //! struct MyStruct { //! a: u64, //! } @@ -68,7 +68,7 @@ //! ```rust,no_run //! use frame_support::debug::native; //! -//! #[derive(primitives::RuntimeDebug)] +//! #[derive(sp_core::RuntimeDebug)] //! struct MyStruct { //! a: u64, //! } @@ -86,8 +86,8 @@ //! native::print!("My struct: {:?}", x); //! ``` -use rstd::vec::Vec; -use rstd::fmt::{self, Debug}; +use sp_std::vec::Vec; +use sp_std::fmt::{self, Debug}; pub use log::{info, debug, error, trace, warn}; pub use crate::runtime_print as print; @@ -155,7 +155,7 @@ impl fmt::Write for Writer { impl Writer { /// Print the content of this `Writer` out. pub fn print(&self) { - runtime_io::misc::print_utf8(&self.0) + sp_io::misc::print_utf8(&self.0) } } @@ -204,7 +204,7 @@ impl log::Log for RuntimeLogger { let mut w = Writer::default(); let _ = core::write!(&mut w, "{}", record.args()); - runtime_io::logging::log( + sp_io::logging::log( record.level().into(), record.target(), &w.0, diff --git a/frame/support/src/dispatch.rs b/frame/support/src/dispatch.rs index 025ee67dd145b7b522fbbb2940312fe3b9078d55..6683aaea31dd9bb330ea42a1dea3db6eb4ce05d4 100644 --- a/frame/support/src/dispatch.rs +++ b/frame/support/src/dispatch.rs @@ -17,7 +17,7 @@ //! Dispatch system. Contains a macro for defining runtime modules and //! generating values representing lazy module function calls. -pub use crate::rstd::{result, fmt, prelude::{Vec, Clone, Eq, PartialEq}, marker}; +pub use crate::sp_std::{result, fmt, prelude::{Vec, Clone, Eq, PartialEq}, marker}; pub use crate::codec::{Codec, EncodeLike, Decode, Encode, Input, Output, HasCompact, EncodeAsRef}; pub use frame_metadata::{ FunctionMetadata, DecodeDifferent, DecodeDifferentArray, FunctionArgumentMetadata, @@ -25,19 +25,13 @@ pub use frame_metadata::{ }; pub use crate::weights::{ SimpleDispatchInfo, GetDispatchInfo, DispatchInfo, WeighData, ClassifyDispatch, - TransactionPriority, Weight, WeighBlock, -}; -pub use sr_primitives::{ - traits::{Dispatchable, DispatchResult, ModuleDispatchError}, - DispatchError, + TransactionPriority, Weight, WeighBlock, PaysFee, }; +pub use sp_runtime::{traits::Dispatchable, DispatchError, DispatchResult}; /// A type that cannot be instantiated. pub enum Never {} -/// Result with string error message. This exists for backward compatibility purpose. -pub type Result = DispatchResult<&'static str>; - /// Serializable version of Dispatchable. /// This value can be used as a "function" in an extrinsic. pub trait Callable { @@ -48,6 +42,9 @@ pub trait Callable { // https://github.com/rust-lang/rust/issues/51331 pub type CallableCallFor = >::Call; +/// A type that can be used as a parameter in a dispatchable function. +/// +/// When using `decl_module` all arguments for call functions must implement this trait. pub trait Parameter: Codec + EncodeLike + Clone + Eq + fmt::Debug {} impl Parameter for T where T: Codec + EncodeLike + Clone + Eq + fmt::Debug {} @@ -58,21 +55,21 @@ impl Parameter for T where T: Codec + EncodeLike + Clone + Eq + fmt::Debug {} /// ``` /// # #[macro_use] /// # extern crate frame_support; -/// # use frame_support::dispatch::Result; +/// # use frame_support::dispatch; /// # use frame_system::{self as system, Trait, ensure_signed}; /// decl_module! { /// pub struct Module for enum Call where origin: T::Origin { /// /// // Private functions are dispatchable, but not available to other /// // SRML modules. -/// fn my_function(origin, var: u64) -> Result { +/// fn my_function(origin, var: u64) -> dispatch::DispatchResult { /// // Your implementation /// Ok(()) /// } /// /// // Public functions are both dispatchable and available to other /// // SRML modules. -/// pub fn my_public_function(origin) -> Result { +/// pub fn my_public_function(origin) -> dispatch::DispatchResult { /// // Your implementation /// Ok(()) /// } @@ -92,18 +89,18 @@ impl Parameter for T where T: Codec + EncodeLike + Clone + Eq + fmt::Debug {} /// /// ### Shorthand Example /// -/// The macro automatically expands a shorthand function declaration to return the `Result` type. -/// These functions are the same: +/// The macro automatically expands a shorthand function declaration to return the +/// [`DispatchResult`] type. These functions are the same: /// /// ``` /// # #[macro_use] /// # extern crate frame_support; -/// # use frame_support::dispatch::Result; +/// # use frame_support::dispatch; /// # use frame_system::{self as system, Trait, ensure_signed}; /// decl_module! { /// pub struct Module for enum Call where origin: T::Origin { /// -/// fn my_long_function(origin) -> Result { +/// fn my_long_function(origin) -> dispatch::DispatchResult { /// // Your implementation /// Ok(()) /// } @@ -123,11 +120,11 @@ impl Parameter for T where T: Codec + EncodeLike + Clone + Eq + fmt::Debug {} /// ``` /// # #[macro_use] /// # extern crate frame_support; -/// # use frame_support::dispatch::Result; +/// # use frame_support::dispatch; /// # use frame_system::{self as system, Trait, ensure_signed, ensure_root}; /// decl_module! { /// pub struct Module for enum Call where origin: T::Origin { -/// fn my_privileged_function(origin) -> Result { +/// fn my_privileged_function(origin) -> dispatch::DispatchResult { /// ensure_root(origin)?; /// // Your implementation /// Ok(()) @@ -147,7 +144,7 @@ impl Parameter for T where T: Codec + EncodeLike + Clone + Eq + fmt::Debug {} /// ``` /// # #[macro_use] /// # extern crate frame_support; -/// # use frame_support::dispatch::Result; +/// # use frame_support::dispatch; /// # use frame_system::{self as system, ensure_signed}; /// # pub struct DefaultInstance; /// # pub trait Instance {} @@ -175,7 +172,7 @@ impl Parameter for T where T: Codec + EncodeLike + Clone + Eq + fmt::Debug {} /// ``` /// # #[macro_use] /// # extern crate frame_support; -/// # use frame_support::dispatch::Result; +/// # use frame_support::dispatch; /// # use frame_system::{self as system, ensure_signed}; /// pub trait Trait: system::Trait where Self::AccountId: From {} /// @@ -199,12 +196,12 @@ impl Parameter for T where T: Codec + EncodeLike + Clone + Eq + fmt::Debug {} /// The following reserved functions also take the block number (with type `T::BlockNumber`) as an optional input: /// /// * `on_initialize`: Executes at the beginning of a block. Using this function will -/// implement the [`OnInitialize`](../sr_primitives/traits/trait.OnInitialize.html) trait. +/// implement the [`OnInitialize`](../sp_runtime/traits/trait.OnInitialize.html) trait. /// * `on_finalize`: Executes at the end of a block. Using this function will -/// implement the [`OnFinalize`](../sr_primitives/traits/trait.OnFinalize.html) trait. +/// implement the [`OnFinalize`](../sp_runtime/traits/trait.OnFinalize.html) trait. /// * `offchain_worker`: Executes at the beginning of a block and produces extrinsics for a future block /// upon completion. Using this function will implement the -/// [`OffchainWorker`](../sr_primitives/traits/trait.OffchainWorker.html) trait. +/// [`OffchainWorker`](../sp_runtime/traits/trait.OffchainWorker.html) trait. #[macro_export] macro_rules! decl_module { // Entry point #1. @@ -858,14 +855,14 @@ macro_rules! decl_module { fn on_initialize() { $( $impl:tt )* } ) => { impl<$trait_instance: $trait_name$(, $instance: $instantiable)?> - $crate::sr_primitives::traits::OnInitialize<$trait_instance::BlockNumber> + $crate::sp_runtime::traits::OnInitialize<$trait_instance::BlockNumber> for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )* { fn on_initialize(_block_number_not_used: $trait_instance::BlockNumber) { - use $crate::rstd::if_std; + use $crate::sp_std::if_std; if_std! { use $crate::tracing; - let span = tracing::span!(tracing::Level::INFO, "on_initialize"); + let span = tracing::span!(tracing::Level::DEBUG, "on_initialize"); let _enter = span.enter(); } { $( $impl )* } @@ -880,14 +877,14 @@ macro_rules! decl_module { fn on_initialize($param:ident : $param_ty:ty) { $( $impl:tt )* } ) => { impl<$trait_instance: $trait_name$(, $instance: $instantiable)?> - $crate::sr_primitives::traits::OnInitialize<$trait_instance::BlockNumber> + $crate::sp_runtime::traits::OnInitialize<$trait_instance::BlockNumber> for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )* { fn on_initialize($param: $param_ty) { - use $crate::rstd::if_std; + use $crate::sp_std::if_std; if_std! { use $crate::tracing; - let span = tracing::span!(tracing::Level::INFO, "on_initialize"); + let span = tracing::span!(tracing::Level::DEBUG, "on_initialize"); let _enter = span.enter(); } { $( $impl )* } @@ -900,7 +897,7 @@ macro_rules! decl_module { { $( $other_where_bounds:tt )* } ) => { impl<$trait_instance: $trait_name$(, $instance: $instantiable)?> - $crate::sr_primitives::traits::OnInitialize<$trait_instance::BlockNumber> + $crate::sp_runtime::traits::OnInitialize<$trait_instance::BlockNumber> for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )* {} }; @@ -912,14 +909,14 @@ macro_rules! decl_module { fn on_finalize() { $( $impl:tt )* } ) => { impl<$trait_instance: $trait_name$(, $instance: $instantiable)?> - $crate::sr_primitives::traits::OnFinalize<$trait_instance::BlockNumber> + $crate::sp_runtime::traits::OnFinalize<$trait_instance::BlockNumber> for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )* { fn on_finalize(_block_number_not_used: $trait_instance::BlockNumber) { - use $crate::rstd::if_std; + use $crate::sp_std::if_std; if_std! { use $crate::tracing; - let span = tracing::span!(tracing::Level::INFO, "on_finalize"); + let span = tracing::span!(tracing::Level::DEBUG, "on_finalize"); let _enter = span.enter(); } { $( $impl )* } @@ -934,14 +931,14 @@ macro_rules! decl_module { fn on_finalize($param:ident : $param_ty:ty) { $( $impl:tt )* } ) => { impl<$trait_instance: $trait_name$(, $instance: $instantiable)?> - $crate::sr_primitives::traits::OnFinalize<$trait_instance::BlockNumber> + $crate::sp_runtime::traits::OnFinalize<$trait_instance::BlockNumber> for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )* { fn on_finalize($param: $param_ty) { - use $crate::rstd::if_std; + use $crate::sp_std::if_std; if_std! { use $crate::tracing; - let span = tracing::span!(tracing::Level::INFO, "on_finalize"); + let span = tracing::span!(tracing::Level::DEBUG, "on_finalize"); let _enter = span.enter(); } { $( $impl )* } @@ -954,7 +951,7 @@ macro_rules! decl_module { { $( $other_where_bounds:tt )* } ) => { impl<$trait_instance: $trait_name$(, $instance: $instantiable)?> - $crate::sr_primitives::traits::OnFinalize<$trait_instance::BlockNumber> + $crate::sp_runtime::traits::OnFinalize<$trait_instance::BlockNumber> for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )* { } @@ -995,10 +992,10 @@ macro_rules! decl_module { fn offchain_worker() { $( $impl:tt )* } ) => { impl<$trait_instance: $trait_name$(, $instance: $instantiable)?> - $crate::sr_primitives::traits::OffchainWorker<$trait_instance::BlockNumber> + $crate::sp_runtime::traits::OffchainWorker<$trait_instance::BlockNumber> for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )* { - fn generate_extrinsics(_block_number_not_used: $trait_instance::BlockNumber) { $( $impl )* } + fn offchain_worker(_block_number_not_used: $trait_instance::BlockNumber) { $( $impl )* } } }; @@ -1008,10 +1005,10 @@ macro_rules! decl_module { fn offchain_worker($param:ident : $param_ty:ty) { $( $impl:tt )* } ) => { impl<$trait_instance: $trait_name$(, $instance: $instantiable)?> - $crate::sr_primitives::traits::OffchainWorker<$trait_instance::BlockNumber> + $crate::sp_runtime::traits::OffchainWorker<$trait_instance::BlockNumber> for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )* { - fn generate_extrinsics($param: $param_ty) { $( $impl )* } + fn offchain_worker($param: $param_ty) { $( $impl )* } } }; @@ -1020,7 +1017,7 @@ macro_rules! decl_module { { $( $other_where_bounds:tt )* } ) => { impl<$trait_instance: $trait_name$(, $instance: $instantiable)?> - $crate::sr_primitives::traits::OffchainWorker<$trait_instance::BlockNumber> + $crate::sp_runtime::traits::OffchainWorker<$trait_instance::BlockNumber> for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )* {} }; @@ -1040,11 +1037,10 @@ macro_rules! decl_module { #[allow(unreachable_code)] $vis fn $name( $origin: $origin_ty $(, $param: $param_ty )* - ) -> $crate::dispatch::DispatchResult<$error_type> { - use $crate::rstd::if_std; - if_std! { + ) -> $crate::dispatch::DispatchResult { + $crate::sp_std::if_std! { use $crate::tracing; - let span = tracing::span!(tracing::Level::INFO, stringify!($name)); + let span = tracing::span!(tracing::Level::DEBUG, stringify!($name)); let _enter = span.enter(); } { @@ -1067,10 +1063,10 @@ macro_rules! decl_module { ) => { $(#[doc = $doc_attr])* $vis fn $name($origin: $origin_ty $(, $param: $param_ty )* ) -> $result { - use $crate::rstd::if_std; + use $crate::sp_std::if_std; if_std! { use $crate::tracing; - let span = tracing::span!(tracing::Level::INFO, stringify!($name)); + let span = tracing::span!(tracing::Level::DEBUG, stringify!($name)); let _enter = span.enter(); } { $( $impl )* } @@ -1190,7 +1186,7 @@ macro_rules! decl_module { { #[doc(hidden)] #[codec(skip)] - __PhantomItem($crate::rstd::marker::PhantomData<($trait_instance $(, $instance)?)>, $crate::dispatch::Never), + __PhantomItem($crate::sp_std::marker::PhantomData<($trait_instance $(, $instance)?)>, $crate::dispatch::Never), $( $generated_variants )* } }; @@ -1228,7 +1224,7 @@ macro_rules! decl_module { pub struct $mod_type< $trait_instance: $trait_name $(, $instance: $instantiable $( = $module_default_instance)?)? - >($crate::rstd::marker::PhantomData<($trait_instance $(, $instance)?)>) where + >($crate::sp_std::marker::PhantomData<($trait_instance $(, $instance)?)>) where $( $other_where_bounds )*; $crate::decl_module! { @@ -1321,7 +1317,10 @@ macro_rules! decl_module { &$weight, ($( $param_name, )*) ); - return $crate::dispatch::DispatchInfo { weight, class }; + let pays_fee = ::pays_fee( + &$weight + ); + return $crate::dispatch::DispatchInfo { weight, class, pays_fee }; } if let $call_type::__PhantomItem(_, _) = self { unreachable!("__PhantomItem should never be used.") } )* @@ -1337,7 +1336,10 @@ macro_rules! decl_module { &$crate::dispatch::SimpleDispatchInfo::default(), () ); - $crate::dispatch::DispatchInfo { weight, class } + let pays_fee = ::pays_fee( + &$crate::dispatch::SimpleDispatchInfo::default() + ); + $crate::dispatch::DispatchInfo { weight, class, pays_fee } } } @@ -1408,8 +1410,7 @@ macro_rules! decl_module { { type Trait = $trait_instance; type Origin = $origin_type; - type Error = $error_type; - fn dispatch(self, _origin: Self::Origin) -> $crate::dispatch::DispatchResult { + fn dispatch(self, _origin: Self::Origin) -> $crate::sp_runtime::DispatchResult { match self { $( $call_type::$fn_name( $( $param_name ),* ) => { @@ -1437,7 +1438,7 @@ macro_rules! decl_module { pub fn dispatch>( d: D, origin: D::Origin - ) -> $crate::dispatch::DispatchResult { + ) -> $crate::sp_runtime::DispatchResult { d.dispatch(origin) } } @@ -1505,11 +1506,10 @@ macro_rules! impl_outer_dispatch { impl $crate::dispatch::Dispatchable for $call_type { type Origin = $origin; type Trait = $call_type; - type Error = $crate::dispatch::DispatchError; fn dispatch( self, origin: $origin, - ) -> $crate::dispatch::DispatchResult<$crate::dispatch::DispatchError> { + ) -> $crate::sp_runtime::DispatchResult { $crate::impl_outer_dispatch! { @DISPATCH_MATCH self @@ -1556,11 +1556,7 @@ macro_rules! impl_outer_dispatch { $origin { $( $generated )* - $call_type::$name(call) => call.dispatch($origin).map_err(|e| { - let mut error: $crate::dispatch::DispatchError = e.into(); - error.module = Some($index); - error - }), + $call_type::$name(call) => call.dispatch($origin), } $index + 1; $( $rest ),* @@ -1876,7 +1872,7 @@ macro_rules! __check_reserved_fn_name { #[allow(dead_code)] mod tests { use super::*; - use crate::sr_primitives::traits::{OnInitialize, OnFinalize}; + use crate::sp_runtime::traits::{OnInitialize, OnFinalize}; use crate::weights::{DispatchInfo, DispatchClass}; pub trait Trait: system::Trait + Sized where Self::AccountId: From { @@ -1886,13 +1882,13 @@ mod tests { } pub mod system { - use super::Result; + use super::*; pub trait Trait { type AccountId; } - pub fn ensure_root(_: R) -> Result { + pub fn ensure_root(_: R) -> DispatchResult { Ok(()) } } @@ -1908,13 +1904,13 @@ mod tests { decl_module! { pub struct Module for enum Call where origin: T::Origin, T::AccountId: From { /// Hi, this is a comment. - fn aux_0(_origin) -> Result { unreachable!() } - fn aux_1(_origin, #[compact] _data: u32,) -> Result { unreachable!() } - fn aux_2(_origin, _data: i32, _data2: String) -> Result { unreachable!() } + fn aux_0(_origin) -> DispatchResult { unreachable!() } + fn aux_1(_origin, #[compact] _data: u32,) -> DispatchResult { unreachable!() } + fn aux_2(_origin, _data: i32, _data2: String) -> DispatchResult { unreachable!() } #[weight = SimpleDispatchInfo::FixedNormal(3)] - fn aux_3(_origin) -> Result { unreachable!() } - fn aux_4(_origin, _data: i32) -> Result { unreachable!() } - fn aux_5(_origin, _data: i32, #[compact] _data2: u32,) -> Result { unreachable!() } + fn aux_3(_origin) -> DispatchResult { unreachable!() } + fn aux_4(_origin, _data: i32) -> DispatchResult { unreachable!() } + fn aux_5(_origin, _data: i32, #[compact] _data2: u32,) -> DispatchResult { unreachable!() } #[weight = SimpleDispatchInfo::FixedNormal(7)] fn on_initialize(n: T::BlockNumber,) { if n.into() == 42 { panic!("on_initialize") } } @@ -2066,17 +2062,17 @@ mod tests { // operational. assert_eq!( Call::::operational().get_dispatch_info(), - DispatchInfo { weight: 5, class: DispatchClass::Operational }, + DispatchInfo { weight: 5, class: DispatchClass::Operational, pays_fee: true }, ); // default weight. assert_eq!( Call::::aux_0().get_dispatch_info(), - DispatchInfo { weight: 10_000, class: DispatchClass::Normal }, + DispatchInfo { weight: 10_000, class: DispatchClass::Normal, pays_fee: true }, ); // custom basic assert_eq!( Call::::aux_3().get_dispatch_info(), - DispatchInfo { weight: 3, class: DispatchClass::Normal }, + DispatchInfo { weight: 3, class: DispatchClass::Normal, pays_fee: true }, ); } diff --git a/frame/support/src/error.rs b/frame/support/src/error.rs index 87380c1a9433c80085aeb49e621196ccf225919b..0120b6da60138f0d2ca44cb6be0e1b1424167552 100644 --- a/frame/support/src/error.rs +++ b/frame/support/src/error.rs @@ -17,38 +17,64 @@ //! Macro for declaring a module error. #[doc(hidden)] -pub use sr_primitives::traits::LookupError; +pub use sp_runtime::traits::{LookupError, BadOrigin}; +#[doc(hidden)] pub use frame_metadata::{ModuleErrorMetadata, ErrorMetadata, DecodeDifferent}; /// Declare an error type for a runtime module. /// -/// The generated error type inherently has the variants `Other` and `CannotLookup`. `Other` can -/// hold any `&'static str` error message and is present for convenience/backward compatibility. -/// The `CannotLookup` variant indicates that some lookup could not be done. For both variants the -/// error type implements `From<&'static str>` and `From` to make them usable with the -/// try operator. +/// `decl_error!` supports only variants that do not hold any data. The dispatchable +/// functions return [`DispatchResult`](sp_runtime::DispatchResult). The error type +/// implements `From for DispatchResult` to make the error type usable as error +/// in the dispatchable functions. +/// +/// It is required that the error type is registed in `decl_module!` to make the error +/// exported in the metadata. /// /// # Usage /// /// ``` -/// # use frame_support::decl_error; +/// # use frame_support::{decl_error, decl_module}; /// decl_error! { /// /// Errors that can occur in my module. -/// pub enum MyError { +/// pub enum MyError for Module { /// /// Hey this is an error message that indicates bla. /// MyCoolErrorMessage, /// /// You are just not cool enough for my module! /// YouAreNotCoolEnough, /// } /// } +/// +/// # use frame_system::{self as system, Trait}; +/// +/// // You need to register the error type in `decl_module!` as well to make the error +/// // exported in the metadata. +/// +/// decl_module! { +/// pub struct Module for enum Call where origin: T::Origin { +/// type Error = MyError; +/// +/// fn do_something(origin) -> frame_support::dispatch::DispatchResult { +/// Err(MyError::::YouAreNotCoolEnough.into()) +/// } +/// } +/// } +/// +/// # fn main() {} /// ``` /// -/// `decl_error!` supports only variants that do not hold any data. +/// For instantiable modules you also need to give the instance generic type and bound to the +/// error declaration. #[macro_export] macro_rules! decl_error { ( $(#[$attr:meta])* - pub enum $error:ident { + pub enum $error:ident + for $module:ident< + $generic:ident: $trait:path + $(, $inst_generic:ident: $instance:path)? + > + { $( $( #[doc = $doc_attr:tt] )* $name:ident @@ -56,33 +82,42 @@ macro_rules! decl_error { $(,)? } ) => { - #[derive(Clone, PartialEq, Eq, $crate::RuntimeDebug)] $(#[$attr])* - pub enum $error { - Other(&'static str), - CannotLookup, + pub enum $error<$generic: $trait $(, $inst_generic: $instance)?> { + #[doc(hidden)] + __Ignore( + $crate::sp_std::marker::PhantomData<($generic $(, $inst_generic)?)>, + $crate::dispatch::Never, + ), $( $( #[doc = $doc_attr] )* $name ),* } - impl $crate::dispatch::ModuleDispatchError for $error { + impl<$generic: $trait $(, $inst_generic: $instance)?> $crate::sp_std::fmt::Debug + for $error<$generic $(, $inst_generic)?> + { + fn fmt(&self, f: &mut $crate::sp_std::fmt::Formatter<'_>) -> $crate::sp_std::fmt::Result { + f.write_str(self.as_str()) + } + } + + impl<$generic: $trait $(, $inst_generic: $instance)?> $error<$generic $(, $inst_generic)?> { fn as_u8(&self) -> u8 { $crate::decl_error! { @GENERATE_AS_U8 self $error {} - 2, + 0, $( $name ),* } } fn as_str(&self) -> &'static str { match self { - $error::Other(err) => err, - $error::CannotLookup => "Can not lookup", + Self::__Ignore(_, _) => unreachable!("`__Ignore` can never be constructed"), $( $error::$name => stringify!($name), )* @@ -90,33 +125,33 @@ macro_rules! decl_error { } } - impl From<&'static str> for $error { - fn from(val: &'static str) -> $error { - $error::Other(val) - } - } - - impl From<$crate::error::LookupError> for $error { - fn from(_: $crate::error::LookupError) -> $error { - $error::CannotLookup - } - } - - impl From<$error> for &'static str { - fn from(err: $error) -> &'static str { - use $crate::dispatch::ModuleDispatchError; + impl<$generic: $trait $(, $inst_generic: $instance)?> From<$error<$generic $(, $inst_generic)?>> + for &'static str + { + fn from(err: $error<$generic $(, $inst_generic)?>) -> &'static str { err.as_str() } } - impl Into<$crate::dispatch::DispatchError> for $error { - fn into(self) -> $crate::dispatch::DispatchError { - use $crate::dispatch::ModuleDispatchError; - $crate::dispatch::DispatchError::new(None, self.as_u8(), Some(self.as_str())) + impl<$generic: $trait $(, $inst_generic: $instance)?> From<$error<$generic $(, $inst_generic)?>> + for $crate::sp_runtime::DispatchError + { + fn from(err: $error<$generic $(, $inst_generic)?>) -> Self { + let index = <$generic::ModuleToIndex as $crate::traits::ModuleToIndex> + ::module_to_index::<$module<$generic $(, $inst_generic)?>>() + .expect("Every active module has an index in the runtime; qed") as u8; + + $crate::sp_runtime::DispatchError::Module { + index, + error: err.as_u8(), + message: Some(err.as_str()), + } } } - impl $crate::error::ModuleErrorMetadata for $error { + impl<$generic: $trait $(, $inst_generic: $instance)?> $crate::error::ModuleErrorMetadata + for $error<$generic $(, $inst_generic)?> + { fn metadata() -> &'static [$crate::error::ErrorMetadata] { &[ $( @@ -158,8 +193,7 @@ macro_rules! decl_error { $index:expr, ) => { match $self { - $error::Other(_) => 0, - $error::CannotLookup => 1, + $error::__Ignore(_, _) => unreachable!("`__Ignore` can never be constructed"), $( $generated )* } } diff --git a/frame/support/src/event.rs b/frame/support/src/event.rs index c2e962ffb2692cfc8db5dbabd7ce5650a393e35c..1c9a0b66fe74bd55eeba7fe0ce625380b5698f4e 100644 --- a/frame/support/src/event.rs +++ b/frame/support/src/event.rs @@ -280,7 +280,7 @@ macro_rules! __decl_generic_event { $( #[doc(hidden)] #[codec(skip)] - PhantomData($crate::rstd::marker::PhantomData<$instance>), + PhantomData($crate::sp_std::marker::PhantomData<$instance>), )? } impl<$( $generic_param ),* $(, $instance)? > From> for () { @@ -486,12 +486,12 @@ macro_rules! impl_outer_event { $name::[< $module_name $(_ $generic_instance )? >](x) } } - impl $crate::rstd::convert::TryInto< + impl $crate::sp_std::convert::TryInto< $module_name::Event < $( $generic_param, )? $( $module_name::$generic_instance )? > > for $name { type Error = (); - fn try_into(self) -> $crate::rstd::result::Result< + fn try_into(self) -> $crate::sp_std::result::Result< $module_name::Event < $( $generic_param, )? $( $module_name::$generic_instance )? >, Self::Error > { match self { @@ -530,7 +530,7 @@ macro_rules! __impl_outer_event_json_metadata { $crate::event::OuterEventMetadata { name: $crate::event::DecodeDifferent::Encode(stringify!($event_name)), events: $crate::event::DecodeDifferent::Encode(&[ - ("system", $crate::event::FnEncode(system::Event::metadata)) + ("system", $crate::event::FnEncode($system::Event::metadata)) $( , ( stringify!($module_name), @@ -542,22 +542,30 @@ macro_rules! __impl_outer_event_json_metadata { ]) } } - #[allow(dead_code)] - pub fn __module_events_system() -> &'static [$crate::event::EventMetadata] { - system::Event::metadata() - } - $crate::paste::item! { - $( - #[allow(dead_code)] - pub fn [< __module_events_ $module_name $( _ $instance )? >] () -> - &'static [$crate::event::EventMetadata] - { - $module_name::Event ::< $( $generic_params ),* > ::metadata() - } - )* + $crate::__impl_outer_event_json_metadata! { + @DECL_MODULE_EVENT_FNS + $system <> ; + $( $module_name < $( $generic_params ),* > $( $instance )? ; )* } } + }; + + (@DECL_MODULE_EVENT_FNS + $( + $module_name:ident < $( $generic_params:path ),* > $( $instance:ident )? ; + )* + ) => { + $crate::paste::item! { + $( + #[allow(dead_code)] + pub fn [< __module_events_ $module_name $( _ $instance )? >] () -> + &'static [$crate::event::EventMetadata] + { + $module_name::Event ::< $( $generic_params ),* > ::metadata() + } + )* + } } } diff --git a/frame/support/src/hash.rs b/frame/support/src/hash.rs index d51df162e5a865f709742e41eebec628ec607414..d9c1247f7bcdb90f8169a50596dc012a12f7a5ab 100644 --- a/frame/support/src/hash.rs +++ b/frame/support/src/hash.rs @@ -17,8 +17,8 @@ //! Hash utilities. use codec::Codec; -use rstd::prelude::Vec; -use runtime_io::hashing::{blake2_128, blake2_256, twox_64, twox_128, twox_256}; +use sp_std::prelude::Vec; +use sp_io::hashing::{blake2_128, blake2_256, twox_64, twox_128, twox_256}; // This trait must be kept coherent with frame-support-procedural HasherKind usage pub trait Hashable: Sized { diff --git a/frame/support/src/inherent.rs b/frame/support/src/inherent.rs index 935d3b4e74e4f47c14a7c6703a579533d0501dab..fc11cd0a2e6bc051adb9c27c0aeebf7d38e9ea0a 100644 --- a/frame/support/src/inherent.rs +++ b/frame/support/src/inherent.rs @@ -15,11 +15,11 @@ // along with Substrate. If not, see . #[doc(hidden)] -pub use crate::rstd::vec::Vec; +pub use crate::sp_std::vec::Vec; #[doc(hidden)] -pub use crate::sr_primitives::traits::{Block as BlockT, Extrinsic}; +pub use crate::sp_runtime::traits::{Block as BlockT, Extrinsic}; #[doc(hidden)] -pub use inherents::{InherentData, ProvideInherent, CheckInherentsResult, IsFatalError}; +pub use sp_inherents::{InherentData, ProvideInherent, CheckInherentsResult, IsFatalError}; /// Implement the outer inherent. diff --git a/frame/support/src/lib.rs b/frame/support/src/lib.rs index e67120347a26fa1d5fc31e3a2ffcf3649730feae..f0357cff2f40ece59f76f608669d252709a88089 100644 --- a/frame/support/src/lib.rs +++ b/frame/support/src/lib.rs @@ -29,7 +29,7 @@ pub extern crate tracing; #[cfg(feature = "std")] pub use serde; #[doc(hidden)] -pub use rstd; +pub use sp_std; #[doc(hidden)] pub use codec; #[cfg(feature = "std")] @@ -39,11 +39,11 @@ pub use once_cell; pub use paste; #[cfg(feature = "std")] #[doc(hidden)] -pub use state_machine::BasicExternalities; +pub use sp_state_machine::BasicExternalities; #[doc(hidden)] -pub use runtime_io::storage::root as storage_root; +pub use sp_io::storage::root as storage_root; #[doc(hidden)] -pub use sr_primitives::RuntimeDebug; +pub use sp_runtime::RuntimeDebug; #[macro_use] pub mod debug; @@ -58,8 +58,6 @@ mod origin; #[macro_use] pub mod metadata; #[macro_use] -mod runtime; -#[macro_use] pub mod inherent; #[macro_use] pub mod unsigned; @@ -69,9 +67,11 @@ pub mod traits; pub mod weights; pub use self::hash::{Twox256, Twox128, Blake2_256, Blake2_128, Twox64Concat, Hashable}; -pub use self::storage::{StorageValue, StorageMap, StorageLinkedMap, StorageDoubleMap}; +pub use self::storage::{ + StorageValue, StorageMap, StorageLinkedMap, StorageDoubleMap, StoragePrefixedMap +}; pub use self::dispatch::{Parameter, Callable, IsSubType}; -pub use sr_primitives::{self, ConsensusEngineId, print, traits::Printable}; +pub use sp_runtime::{self, ConsensusEngineId, print, traits::Printable}; /// Macro for easily creating a new implementation of the `Get` trait. Use similarly to /// how you would declare a `const`: @@ -116,7 +116,7 @@ macro_rules! parameter_types { } #[doc(inline)] -pub use frame_support_procedural::decl_storage; +pub use frame_support_procedural::{decl_storage, construct_runtime}; /// Return Err of the expression: `return Err($expression);`. /// @@ -124,7 +124,7 @@ pub use frame_support_procedural::decl_storage; #[macro_export] macro_rules! fail { ( $y:expr ) => {{ - return Err($y); + return Err($y.into()); }} } @@ -168,7 +168,7 @@ macro_rules! assert_noop { #[cfg(feature = "std")] macro_rules! assert_err { ( $x:expr , $y:expr $(,)? ) => { - assert_eq!($x, Err($y)); + assert_eq!($x, Err($y.into())); } } @@ -187,47 +187,6 @@ macro_rules! assert_ok { } } -/// Panic when the vectors are different, without taking the order into account. -/// -/// # Examples -/// -/// ```rust -/// #[macro_use] -/// # extern crate frame_support; -/// # use frame_support::{assert_eq_uvec}; -/// # fn main() { -/// assert_eq_uvec!(vec![1,2], vec![2,1]); -/// # } -/// ``` -/// -/// ```rust,should_panic -/// #[macro_use] -/// # extern crate frame_support; -/// # use frame_support::{assert_eq_uvec}; -/// # fn main() { -/// assert_eq_uvec!(vec![1,2,3], vec![2,1]); -/// # } -/// ``` -#[macro_export] -#[cfg(feature = "std")] -macro_rules! assert_eq_uvec { - ( $x:expr, $y:expr ) => { - $crate::__assert_eq_uvec!($x, $y); - $crate::__assert_eq_uvec!($y, $x); - } -} - -#[macro_export] -#[doc(hidden)] -#[cfg(feature = "std")] -macro_rules! __assert_eq_uvec { - ( $x:expr, $y:expr ) => { - $x.iter().for_each(|e| { - if !$y.contains(e) { panic!(format!("vectors not equal: {:?} != {:?}", $x, $y)); } - }); - } -} - /// The void type - it cannot exist. // Oh rust, you crack me up... #[derive(Clone, Eq, PartialEq, RuntimeDebug)] @@ -245,7 +204,7 @@ mod tests { DecodeDifferent, StorageEntryMetadata, StorageMetadata, StorageEntryType, StorageEntryModifier, DefaultByteGetter, StorageHasher, }; - use rstd::marker::PhantomData; + use sp_std::marker::PhantomData; pub trait Trait { type BlockNumber: Codec + EncodeLike + Default; @@ -290,7 +249,7 @@ mod tests { type Origin = u32; } - fn new_test_ext() -> runtime_io::TestExternalities { + fn new_test_ext() -> sp_io::TestExternalities { GenesisConfig::default().build_storage().unwrap().into() } @@ -335,6 +294,36 @@ mod tests { }); } + #[test] + fn double_map_swap_works() { + new_test_ext().execute_with(|| { + DataDM::insert(0, 1, 1); + DataDM::insert(1, 0, 2); + DataDM::insert(1, 1, 3); + + let get_all = || vec![ + DataDM::get(0, 1), + DataDM::get(1, 0), + DataDM::get(1, 1), + DataDM::get(2, 0), + DataDM::get(2, 1), + ]; + assert_eq!(get_all(), vec![1, 2, 3, 0, 0]); + + // Two existing + DataDM::swap(0, 1, 1, 0); + assert_eq!(get_all(), vec![2, 1, 3, 0, 0]); + + // Left existing + DataDM::swap(1, 0, 2, 0); + assert_eq!(get_all(), vec![2, 0, 3, 1, 0]); + + // Right existing + DataDM::swap(2, 1, 1, 1); + assert_eq!(get_all(), vec![2, 0, 0, 1, 3]); + }); + } + #[test] fn linked_map_basic_insert_remove_should_work() { new_test_ext().execute_with(|| { diff --git a/frame/support/src/metadata.rs b/frame/support/src/metadata.rs index c27cc4ac73608a93ff82674d36b20a3cbc01a51f..ad6a5c797cd3f63fb1179b509d6cbbc2cf5242cf 100644 --- a/frame/support/src/metadata.rs +++ b/frame/support/src/metadata.rs @@ -240,13 +240,14 @@ mod tests { mod system { use super::*; - pub trait Trait { + pub trait Trait: 'static { const ASSOCIATED_CONST: u64 = 500; type Origin: Into, Self::Origin>> + From>; type AccountId: From + Encode; type BlockNumber: From + Encode; type SomeValue: Get; + type ModuleToIndex: crate::traits::ModuleToIndex; } decl_module! { @@ -286,10 +287,8 @@ mod tests { mod event_module { use crate::dispatch::DispatchResult; - pub trait Trait { - type Origin; + pub trait Trait: super::system::Trait { type Balance; - type BlockNumber; } decl_event!( @@ -302,14 +301,14 @@ mod tests { decl_module! { pub struct Module for enum Call where origin: T::Origin { - type Error = Error; + type Error = Error; - fn aux_0(_origin) -> DispatchResult { unreachable!() } + fn aux_0(_origin) -> DispatchResult { unreachable!() } } } crate::decl_error! { - pub enum Error { + pub enum Error for Module { /// Some user input error UserInputError, /// Something bad happened @@ -372,9 +371,7 @@ mod tests { } impl event_module::Trait for TestRuntime { - type Origin = Origin; type Balance = u32; - type BlockNumber = u32; } impl event_module2::Trait for TestRuntime { @@ -392,6 +389,7 @@ mod tests { type AccountId = u32; type BlockNumber = u32; type SomeValue = SystemValue; + type ModuleToIndex = (); } impl_runtime_metadata!( diff --git a/frame/support/src/origin.rs b/frame/support/src/origin.rs index 6da9bc13858364f42aa9ab58ac750802b8588157..22e5c99e905c48c9c1b63ee4df460671364b6173 100644 --- a/frame/support/src/origin.rs +++ b/frame/support/src/origin.rs @@ -178,8 +178,8 @@ macro_rules! impl_outer_origin { $name::system(x) } } - impl Into<$crate::rstd::result::Result<$system::Origin<$runtime>, $name>> for $name { - fn into(self) -> $crate::rstd::result::Result<$system::Origin<$runtime>, Self> { + impl Into<$crate::sp_std::result::Result<$system::Origin<$runtime>, $name>> for $name { + fn into(self) -> $crate::sp_std::result::Result<$system::Origin<$runtime>, Self> { if let $name::system(l) = self { Ok(l) } else { @@ -200,12 +200,12 @@ macro_rules! impl_outer_origin { } } impl Into< - $crate::rstd::result::Result< + $crate::sp_std::result::Result< $module::Origin < $( $generic )? $(, $module::$generic_instance )? >, $name, >> for $name { - fn into(self) -> $crate::rstd::result::Result< + fn into(self) -> $crate::sp_std::result::Result< $module::Origin < $( $generic )? $(, $module::$generic_instance )? >, Self, > { diff --git a/frame/support/src/runtime.rs b/frame/support/src/runtime.rs deleted file mode 100644 index 52bf48baa574096c81835cf47b57972ddb76f4bb..0000000000000000000000000000000000000000 --- a/frame/support/src/runtime.rs +++ /dev/null @@ -1,948 +0,0 @@ -// Copyright 2018-2019 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate 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. - -// Substrate 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 Substrate. If not, see . - -//! Macros to define a runtime. A runtime is basically all your logic running in Substrate, -//! consisting of selected SRML modules and maybe some of your own modules. -//! A lot of supporting logic is automatically generated for a runtime, -//! mostly to combine data types and metadata of the included modules. - -/// Construct a runtime, with the given name and the given modules. -/// -/// The parameters here are specific types for `Block`, `NodeBlock`, and `InherentData` -/// and the modules that are used by the runtime. -/// `Block` is the block type that is used in the runtime and `NodeBlock` is the block type -/// that is used in the node. For instance they can differ in the extrinsics type. -/// -/// # Example: -/// -/// ```nocompile -/// construct_runtime!( -/// pub enum Runtime where -/// Block = Block, -/// NodeBlock = runtime::Block, -/// UncheckedExtrinsic = UncheckedExtrinsic -/// { -/// System: system, -/// Test: test::{default}, -/// Test2: test_with_long_module::{Module}, -/// -/// // Module with instances -/// Test3_Instance1: test3::::{Module, Call, Storage, Event, Config, Origin}, -/// Test3_DefaultInstance: test3::{Module, Call, Storage, Event, Config, Origin}, -/// } -/// ) -/// ``` -/// -/// The module `System: system` will expand to `System: system::{Module, Call, Storage, Event, Config}`. -/// The identifier `System` is the name of the module and the lower case identifier `system` is the -/// name of the Rust module/crate for this Substrate module. -/// -/// The module `Test: test::{default}` will expand to -/// `Test: test::{Module, Call, Storage, Event, Config}`. -/// -/// The module `Test2: test_with_long_module::{Module}` will expand to -/// `Test2: test_with_long_module::{Module}`. -/// -/// We provide support for the following types in a module: -/// -/// - `Module` -/// - `Call` -/// - `Storage` -/// - `Event` or `Event` (if the event is generic) -/// - `Origin` or `Origin` (if the origin is generic) -/// - `Config` or `Config` (if the config is generic) -/// - `Inherent $( (CALL) )*` - If the module provides/can check inherents. The optional parameter -/// is for modules that use a `Call` from a different module as -/// inherent. -/// - `ValidateUnsigned` - If the module validates unsigned extrinsics. -/// -/// # Note -/// -/// The population of the genesis storage depends on the order of modules. So, if one of your -/// modules depends on another module, the module that is depended upon needs to come before -/// the module depending on it. -#[macro_export] -macro_rules! construct_runtime { - - // Macro transformations (to convert invocations with incomplete parameters to the canonical - // form) - - ( - pub enum $runtime:ident - where - Block = $block:ident, - NodeBlock = $node_block:ty, - UncheckedExtrinsic = $uncheckedextrinsic:ident - { - $( $rest:tt )* - } - ) => { - $crate::construct_runtime!( - { - $runtime; - $block; - $node_block; - $uncheckedextrinsic; - }; - {}; - $( $rest )* - ); - }; - // No modules given, expand to the default module set. - ( - { $( $preset:tt )* }; - { $( $expanded:tt )* }; - $name:ident: $module:ident, - $( $rest:tt )* - ) => { - $crate::construct_runtime!( - { $( $preset )* }; - { $( $expanded )* }; - $name: $module::{default}, - $( $rest )* - ); - }; - // `default` identifier given, expand to default + given extra modules - ( - { $( $preset:tt )* }; - { $( $expanded:tt )* }; - $name:ident: $module:ident::{ - default - $(, - $modules:ident - $( <$modules_generic:ident> )* - $( ( $( $modules_args:ident ),* ) )* - )* - }, - $( $rest:tt )* - ) => { - $crate::construct_runtime!( - { $( $preset )* }; - { - $( $expanded )* - $name: $module::{ - Module, Call, Storage, Event, Config - $(, - $modules $( <$modules_generic> )* - $( ( $( $modules_args ),* ) )* - )* - }, - }; - $( $rest )* - ); - }; - // Take all modules as given by the user. - ( - { $( $preset:tt )* }; - { $( $expanded:tt )* }; - $name:ident: $module:ident :: $( < $module_instance:ident >:: )? { - $( - $modules:ident - $( <$modules_generic:ident> )* - $( ( $( $modules_args:ident ),* ) )* - ),* - }, - $( $rest:tt )* - ) => { - $crate::construct_runtime!( - { $( $preset )* }; - { - $( $expanded )* - $name: $module:: $( < $module_instance >:: )? { - $( - $modules $( <$modules_generic> )* - $( ( $( $modules_args ),* ) )* - ),* - }, - }; - $( $rest )* - ); - }; - // The main macro expansion that actually renders the Runtime code. - ( - { - $runtime:ident; - $block:ident; - $node_block:ty; - $uncheckedextrinsic:ident; - }; - { - $( - $name:ident: $module:ident :: $( < $module_instance:ident >:: )? { - $( - $modules:ident - $( <$modules_generic:ident> )* - $( ( $( $modules_args:ident ),* ) )* - ),* - }, - )* - }; - ) => { - #[derive(Clone, Copy, PartialEq, Eq, $crate::RuntimeDebug)] - pub struct $runtime; - impl $crate::sr_primitives::traits::GetNodeBlockType for $runtime { - type NodeBlock = $node_block; - } - impl $crate::sr_primitives::traits::GetRuntimeBlockType for $runtime { - type RuntimeBlock = $block; - } - $crate::__decl_outer_event!( - $runtime; - $( - $name: $module:: $( < $module_instance >:: )? { - $( $modules $( <$modules_generic> )* ),* - } - ),* - ); - $crate::__decl_outer_origin!( - $runtime; - $( - $name: $module:: $( < $module_instance >:: )? { - $( $modules $( <$modules_generic> )* ),* - } - ),* - ); - $crate::__decl_all_modules!( - $runtime; - ; - {}; - {}; - $( - $name: $module:: $( < $module_instance >:: )? { $( $modules ),* }, - )* - ); - $crate::__decl_outer_dispatch!( - $runtime; - ; - $( - $name: $module::{ $( $modules ),* } - ),*; - ); - $crate::__decl_runtime_metadata!( - $runtime; - {}; - $( - $name: $module:: $( < $module_instance >:: )? { $( $modules )* } - )* - ); - $crate::__decl_outer_config!( - $runtime; - {}; - $( - $name: $module:: $( < $module_instance >:: )? { - $( $modules $( <$modules_generic> )* ),* - }, - )* - ); - $crate::__decl_outer_inherent!( - $runtime; - $block; - $uncheckedextrinsic; - ; - $( - $name: $module::{ $( $modules $( ( $( $modules_args )* ) )* ),* } - ),*; - ); - $crate::__impl_outer_validate_unsigned!( - $runtime; - {}; - $( - $name: $module::{ $( $modules $( ( $( $modules_args )* ) )* )* } - )* - ); - } -} - -/// A macro that generates a "__decl" private macro that transforms parts of the runtime definition -/// to feed them into a public "impl" macro which accepts the format -/// "pub enum $name for $runtime where system = $system". -/// -/// Used to define Event and Origin associated types. -#[macro_export] -#[doc(hidden)] -macro_rules! __create_decl_macro { - ( - // Parameter $d is a hack for the following issue: - // https://github.com/rust-lang/rust/issues/35853 - $macro_name:ident, $macro_outer_name:ident, $macro_enum_name:ident, $d:tt - ) => { - #[macro_export] - #[doc(hidden)] - macro_rules! $macro_name { - ( - $runtime:ident; - $d( $name:ident : $module:ident:: $d( < $module_instance:ident >:: )? { - $d( $modules:ident $d( <$modules_generic:ident> ),* ),* - }),* - ) => { - $d crate::$macro_name!(@inner - $runtime; - ; - {}; - $d( - $name: $module:: $d( < $module_instance >:: )? { - $d( $modules $d( <$modules_generic> )* ),* - }, - )* - ); - }; - // Parse system module - (@inner - $runtime:ident; - ; // there can not be multiple `System`s - { $d( $parsed:tt )* }; - System: $module:ident::{ - $d( $modules:ident $d( <$modules_generic:ident> )* ),* - }, - $d( $rest:tt )* - ) => { - $d crate::$macro_name!(@inner - $runtime; - $module; - { $d( $parsed )* }; - $d( $rest )* - ); - }; - // Parse instantiable module with generic - (@inner - $runtime:ident; - $d( $system:ident )?; - { $d( $parsed:tt )* }; - $name:ident : $module:ident:: < $module_instance:ident >:: { - $macro_enum_name <$event_generic:ident> $d(, $ingore:ident $d( <$ignor:ident> )* )* - }, - $d( $rest:tt )* - ) => { - $d crate::$macro_name!(@inner - $runtime; - $d( $system )?; - { - $d( $parsed )* - $module $module_instance <$event_generic>, - }; - $d( $rest )* - ); - }; - // Parse instantiable module with no generic - (@inner - $runtime:ident; - $d( $system:ident )?; - { $d( $parsed:tt )* }; - $name:ident : $module:ident:: < $module_instance:ident >:: { - $macro_enum_name $d(, $ingore:ident $d( <$ignor:ident> )* )* - }, - $d( $rest:tt )* - ) => { - compile_error!(concat!( - "Instantiable module with not generic ", stringify!($macro_enum_name), - " cannot be constructed: module `", stringify!($name), "` must have generic ", - stringify!($macro_enum_name), "." - )); - }; - // Parse instantiable module with no generic - (@inner - $runtime:ident; - $d( $system:ident )?; - { $d( $parsed:tt )* }; - $name:ident : $module:ident:: { - $macro_enum_name $d( <$event_generic:ident> )* $d(, $ignore:ident $d( <$ignor:ident> )* )* - }, - $d( $rest:tt )* - ) => { - $d crate::$macro_name!(@inner - $runtime; - $d( $system )?; - { - $d( $parsed )* - $module $d( <$event_generic> )*, - }; - $d( $rest )* - ); - }; - // Ignore keyword - (@inner - $runtime:ident; - $d( $system:ident )?; - { $d( $parsed:tt )* }; - $name:ident : $module:ident:: $d( < $module_instance:ident >:: )? { - $ingore:ident $d( <$ignor:ident> )* $d(, $modules:ident $d( <$modules_generic:ident> )* )* - }, - $d( $rest:tt )* - ) => { - $d crate::$macro_name!(@inner - $runtime; - $d( $system )?; - { $d( $parsed )* }; - $name: $module:: $d( < $module_instance >:: )? { $d( $modules $d( <$modules_generic> )* ),* }, - $d( $rest )* - ); - }; - // Ignore module - (@inner - $runtime:ident; - $d( $system:ident )?; - { $d( $parsed:tt )* }; - $name:ident: $module:ident:: $d( < $module_instance:ident >:: )? {}, - $d( $rest:tt )* - ) => { - $d crate::$macro_name!(@inner - $runtime; - $d( $system )?; - { $d( $parsed )* }; - $d( $rest )* - ); - }; - // Expand - (@inner - $runtime:ident; - $system:ident; - { $d( $parsed_modules:ident $d( $instance:ident )? $d( <$parsed_generic:ident> )? ,)* }; - ) => { - $d crate::$macro_outer_name! { - pub enum $macro_enum_name for $runtime where system = $system { - $d( - $parsed_modules $d( $instance )? $d( <$parsed_generic> )?, - )* - } - } - } - } - } -} - -__create_decl_macro!(__decl_outer_event, impl_outer_event, Event, $); -__create_decl_macro!(__decl_outer_origin, impl_outer_origin, Origin, $); - -/// A macro that defines all modules as an associated types of the Runtime type. -#[macro_export] -#[doc(hidden)] -macro_rules! __decl_all_modules { - ( - $runtime:ident; - ; - { $( $parsed:tt )* }; - { $( $parsed_nested:tt )* }; - System: $module:ident::{ Module $(, $modules:ident )* }, - $( $rest:tt )* - ) => { - $crate::__decl_all_modules!( - $runtime; - $module; - { $( $parsed )* }; - { $( $parsed_nested )* }; - $( $rest )* - ); - }; - ( - $runtime:ident; - $( $system:ident )?; - { $( $parsed:tt )* }; - {}; - $name:ident: $module:ident:: $( < $module_instance:ident >:: )? { Module $(, $modules:ident )* }, - $( $rest:tt )* - ) => { - $crate::__decl_all_modules!( - $runtime; - $( $system )?; - { - $( $parsed )* - $module::$name $(<$module_instance>)?, - }; - { $name }; - $( $rest )* - ); - }; - ( - $runtime:ident; - $( $system:ident )?; - { $( $parsed:tt )* }; - { $( $parsed_nested:tt )* }; - $name:ident: $module:ident:: $( < $module_instance:ident >:: )? { Module $(, $modules:ident )* }, - $( $rest:tt )* - ) => { - $crate::__decl_all_modules!( - $runtime; - $( $system )?; - { - $( $parsed )* - $module::$name $(<$module_instance>)?, - }; - { ( $( $parsed_nested )*, $name, ) }; - $( $rest )* - ); - }; - ( - $runtime:ident; - $( $system:ident )?; - { $( $parsed:tt )* }; - { $( $parsed_nested:tt )* }; - $name:ident: $module:ident:: $( < $module_instance:ident >:: )? { $ignore:ident $(, $modules:ident )* }, - $( $rest:tt )* - ) => { - $crate::__decl_all_modules!( - $runtime; - $( $system )?; - { $( $parsed )* }; - { $( $parsed_nested )* }; - $name: $module::{ $( $modules ),* }, - $( $rest )* - ); - }; - ( - $runtime:ident; - $( $system:ident )?; - { $( $parsed:tt )* }; - $name:ident: $module:ident:: $( < $module_instance:ident >:: )? {}, - $( $rest:tt )* - ) => { - $crate::__decl_all_modules!( - $runtime; - $( $system )?; - { $( $parsed )* }; - { $( $parsed_nested )* }; - $( $rest )* - ); - }; - ( - $runtime:ident; - $system:ident; - { $( $parsed_module:ident :: $parsed_name:ident $(<$instance:ident>)? ,)*}; - { $( $parsed_nested:tt )* }; - ) => { - pub type System = system::Module<$runtime>; - $( - pub type $parsed_name = $parsed_module::Module<$runtime $(, $parsed_module::$instance )?>; - )* - type AllModules = ( $( $parsed_nested )* ); - } -} - -/// A macro that defines the Call enum to represent calls to functions in the modules included -/// in the runtime (by wrapping the values of all FooModule::Call enums). -#[macro_export] -#[doc(hidden)] -macro_rules! __decl_outer_dispatch { - ( - $runtime:ident; - $( $parsed_modules:ident :: $parsed_name:ident ),*; - $name:ident: $module:ident::{ - Call $(, $modules:ident $( <$modules_generic:ident> )* )* - } - $(, $rest_name:ident : $rest_module:ident::{ - $( $rest_modules:ident $( <$rest_modules_generic:ident> )* ),* - })*; - ) => { - $crate::__decl_outer_dispatch!( - $runtime; - $( $parsed_modules :: $parsed_name, )* $module::$name; - $( - $rest_name: $rest_module::{ - $( $rest_modules $( <$rest_modules_generic> )* ),* - } - ),*; - ); - }; - ( - $runtime:ident; - $( $parsed_modules:ident :: $parsed_name:ident ),*; - $name:ident: $module:ident::{ - $ignore:ident $( <$ignor:ident> )* $(, $modules:ident $( <$modules_generic:ident> )* )* - } - $(, $rest_name:ident : $rest_module:ident::{ - $( $rest_modules:ident $( <$rest_modules_generic:ident> )* ),* - })*; - ) => { - $crate::__decl_outer_dispatch!( - $runtime; - $( $parsed_modules :: $parsed_name ),*; - $name: $module::{ $( $modules $( <$modules_generic> )* ),* } - $( - , $rest_name: $rest_module::{ - $( $rest_modules $( <$rest_modules_generic> )* ),* - } - )*; - ); - }; - ( - $runtime:ident; - $( $parsed_modules:ident :: $parsed_name:ident ),*; - $name:ident: $module:ident::{} - $(, $rest_name:ident : $rest_module:ident::{ - $( $rest_modules:ident $( <$rest_modules_generic:ident> )* ),* - })*; - ) => { - $crate::__decl_outer_dispatch!( - $runtime; - $( $parsed_modules :: $parsed_name ),*; - $( - $rest_name: $rest_module::{ - $( $rest_modules $( <$rest_modules_generic> )* ),* - } - ),*; - ); - }; - ( - $runtime:ident; - $( $parsed_modules:ident :: $parsed_name:ident ),*; - ; - ) => { - $crate::impl_outer_dispatch!( - pub enum Call for $runtime where origin: Origin { - $( $parsed_modules::$parsed_name, )* - } - ); - }; -} - -/// A private macro that generates metadata() method for the runtime. See impl_runtime_metadata macro. -#[macro_export] -#[doc(hidden)] -macro_rules! __decl_runtime_metadata { - // leading is Module : parse - ( - $runtime:ident; - { $( $parsed:tt )* }; - $( { leading_module: $( $leading_module:ident )* } )? - $name:ident: $module:ident:: $( < $module_instance:ident >:: )? { - Module $( $modules:ident )* - } - $( $rest:tt )* - ) => { - $crate::__decl_runtime_metadata!( - $runtime; - { - $( $parsed )* - $module $( < $module_instance > )? as $name { - $( $( $leading_module )* )? $( $modules )* - } - }; - $( $rest )* - ); - }; - // leading isn't Module : put it in leadings - ( - $runtime:ident; - { $( $parsed:tt )* }; - $( { leading_module: $( $leading_module:ident )* } )? - $name:ident: $module:ident:: $( < $module_instance:ident >:: )? { - $other_module:ident $( $modules:ident )* - } - $( $rest:tt )* - ) => { - $crate::__decl_runtime_metadata!( - $runtime; - { $( $parsed )* }; - { leading_module: $( $( $leading_module )* )? $other_module } - $name: $module:: $( < $module_instance >:: )? { - $( $modules )* - } - $( $rest )* - ); - }; - // does not contain Module : skip - ( - $runtime:ident; - { $( $parsed:tt )* }; - $( { leading_module: $( $leading_module:ident )* } )? - $name:ident: $module:ident:: $( < $module_instance:ident >:: )? {} - $( $rest:tt )* - ) => { - $crate::__decl_runtime_metadata!( - $runtime; - { $( $parsed )* }; - $( $rest )* - ); - }; - // end of decl - ( - $runtime:ident; - { - $( - $parsed_modules:ident $( < $module_instance:ident > )? as $parsed_name:ident { - $( $withs:ident )* - } - )* - }; - ) => { - $crate::impl_runtime_metadata!( - for $runtime with modules - $( $parsed_modules::Module $( < $module_instance > )? as $parsed_name - with $( $withs )* , )* - ); - } -} - -/// A private macro that generates GenesisConfig for the runtime. See `impl_outer_config!` macro. -#[macro_export] -#[doc(hidden)] -macro_rules! __decl_outer_config { - ( - $runtime:ident; - { $( $parsed:tt )* }; - $name:ident: $module:ident:: $( < $module_instance:ident >:: )? { - Config $( <$config_generic:ident> )? - $(, $modules:ident $( <$modules_generic:ident> )* )* - }, - $( $rest:tt )* - ) => { - $crate::__decl_outer_config!( - $runtime; - { - $( $parsed )* - $module::$name $( $module_instance )? $( <$config_generic> )?, - }; - $( $rest )* - ); - }; - ( - $runtime:ident; - { $( $parsed:tt )* }; - $name:ident: $module:ident:: $( < $module_instance:ident >:: )? { - $ingore:ident $( <$ignore_gen:ident> )* - $(, $modules:ident $( <$modules_generic:ident> )* )* - }, - $( $rest:tt )* - ) => { - $crate::__decl_outer_config!( - $runtime; - { $( $parsed )* }; - $name: $module:: $( < $module_instance >:: )? { $( $modules $( <$modules_generic> )* ),* }, - $( $rest )* - ); - }; - ( - $runtime:ident; - { $( $parsed:tt )* }; - $name:ident: $module:ident:: $( < $module_instance:ident >:: )? {}, - $( $rest:tt )* - ) => { - $crate::__decl_outer_config!( - $runtime; - { $( $parsed )* }; - $( $rest )* - ); - }; - ( - $runtime:ident; - { - $( - $parsed_modules:ident :: $parsed_name:ident $( $parsed_instance:ident )? - $( - <$parsed_generic:ident> - )* - ,)* - }; - ) => { - $crate::paste::item! { - $crate::sr_primitives::impl_outer_config!( - pub struct GenesisConfig for $runtime { - $( - [< $parsed_name Config >] => - $parsed_modules $( $parsed_instance )? $( <$parsed_generic> )*, - )* - } - ); - } - }; -} - -/// A private macro that generates check_inherents() implementation for the runtime. -#[macro_export] -#[doc(hidden)] -macro_rules! __decl_outer_inherent { - ( - $runtime:ident; - $block:ident; - $uncheckedextrinsic:ident; - $( $parsed_name:ident :: $parsed_call:ident ),*; - $name:ident: $module:ident::{ - Inherent $(, $modules:ident $( ( $( $modules_call:ident )* ) )* )* - } - $(, $rest_name:ident : $rest_module:ident::{ - $( $rest_modules:ident $( ( $( $rest_call:ident )* ) )* ),* - })*; - ) => { - $crate::__decl_outer_inherent!( - $runtime; - $block; - $uncheckedextrinsic; - $( $parsed_name :: $parsed_call, )* $name::$name; - $( - $rest_name: $rest_module::{ - $( $rest_modules $( ( $( $rest_call )* ) )* ),* - } - ),*; - ); - }; - ( - $runtime:ident; - $block:ident; - $uncheckedextrinsic:ident; - $( $parsed_name:ident :: $parsed_call:ident ),*; - $name:ident: $module:ident::{ - Inherent ( $call:ident ) $(, $modules:ident $( ( $( $modules_call:ident )* ) )* )* - } - $(, $rest_name:ident : $rest_module:ident::{ - $( $rest_modules:ident $( ( $( $rest_call:ident )* ) )* ),* - })*; - ) => { - $crate::__decl_outer_inherent!( - $runtime; - $block; - $uncheckedextrinsic; - $( $parsed_name :: $parsed_call, )* $name::$call; - $( - $rest_name: $rest_module::{ - $( $rest_modules $( ( $( $rest_call )* ) )* ),* - } - ),*; - ); - }; - ( - $runtime:ident; - $block:ident; - $uncheckedextrinsic:ident; - $( $parsed_name:ident :: $parsed_call:ident ),*; - $name:ident: $module:ident::{ - $ignore:ident $( ( $( $ignor:ident )* ) )* - $(, $modules:ident $( ( $( $modules_call:ident )* ) )* )* - } - $(, $rest_name:ident : $rest_module:ident::{ - $( $rest_modules:ident $( ( $( $rest_call:ident )* ) )* ),* - })*; - ) => { - $crate::__decl_outer_inherent!( - $runtime; - $block; - $uncheckedextrinsic; - $( $parsed_name :: $parsed_call ),*; - $name: $module::{ $( $modules $( ( $( $modules_call )* ) )* ),* } - $( - , $rest_name: $rest_module::{ - $( $rest_modules $( ( $( $rest_call )* ) )* ),* - } - )*; - ); - }; - ( - $runtime:ident; - $block:ident; - $uncheckedextrinsic:ident; - $( $parsed_name:ident :: $parsed_call:ident ),*; - $name:ident: $module:ident::{} - $(, $rest_name:ident : $rest_module:ident::{ - $( $rest_modules:ident $( ( $( $rest_call:ident )* ) )* ),* - })*; - ) => { - $crate::__decl_outer_inherent!( - $runtime; - $block; - $uncheckedextrinsic; - $( $parsed_name :: $parsed_call ),*; - $( - $rest_name: $rest_module::{ - $( $rest_modules $( ( $( $rest_call )* ) )* ),* - } - ),*; - ); - }; - ( - $runtime:ident; - $block:ident; - $uncheckedextrinsic:ident; - $( $parsed_name:ident :: $parsed_call:ident ),*; - ; - ) => { - $crate::impl_outer_inherent!( - impl Inherents where Block = $block, UncheckedExtrinsic = $uncheckedextrinsic { - $( $parsed_name : $parsed_call, )* - } - ); - }; -} - -#[macro_export] -#[doc(hidden)] -// Those imports are used by event, config, origin and log macros to get access to its inner type -macro_rules! __decl_instance_import { - ( $( $module:ident <$instance:ident> )* ) => { - $crate::paste::item! { - $(use $module as [< $module _ $instance >];)* - } - }; -} - -/// A private macro that calls impl_outer_validate_unsigned for Call. -#[macro_export] -#[doc(hidden)] -macro_rules! __impl_outer_validate_unsigned { - ( - $runtime:ident; - { $( $parsed:tt )* }; - $name:ident: $module:ident:: $(<$module_instance:ident>::)? { - ValidateUnsigned $( $modules:ident $( ( $( $modules_args:ident )* ) )* )* - } - $( $rest:tt )* - ) => { - $crate::__impl_outer_validate_unsigned!( - $runtime; - { $( $parsed )* $name }; - $( $rest )* - ); - }; - ( - $runtime:ident; - { $( $parsed:tt )* }; - $name:ident: $module:ident:: $(<$module_instance:ident>::)? { - $ignore:ident $( ( $( $args_ignore:ident )* ) )* - $( $modules:ident $( ( $( $modules_args:ident )* ) )* )* - } - $( $rest:tt )* - ) => { - $crate::__impl_outer_validate_unsigned!( - $runtime; - { $( $parsed )* }; - $name: $module:: $(<$module_instance>::)? { - $( $modules $( ( $( $modules_args )* ) )* )* - } - $( $rest )* - ); - }; - ( - $runtime:ident; - { $( $parsed:tt )* }; - $name:ident: $module:ident:: $(<$module_instance:ident>::)? {} - $( $rest:tt )* - ) => { - $crate::__impl_outer_validate_unsigned!( - $runtime; - { $( $parsed )* }; - $( $rest )* - ); - }; - ( - $runtime:ident; - { $( - $parsed_modules:ident - )* }; - ) => { - $crate::impl_outer_validate_unsigned!( - impl ValidateUnsigned for $runtime { - $( $parsed_modules )* - } - ); - }; -} diff --git a/frame/support/src/storage/child.rs b/frame/support/src/storage/child.rs index bc6150c52f96b51b0d07f53757dd5d21f55f63bc..5aca2d312514855096e87befcaec88f2630252f0 100644 --- a/frame/support/src/storage/child.rs +++ b/frame/support/src/storage/child.rs @@ -19,14 +19,29 @@ //! This module is a currently only a variant of unhashed with additional `storage_key`. //! Note that `storage_key` must be unique and strong (strong in the sense of being long enough to //! avoid collision from a resistant hash function (which unique implies)). +//! +//! A **key collision free** unique id is required as parameter to avoid key collision +//! between child tries. +//! This unique id management and generation responsability is delegated to pallet module. // NOTE: could replace unhashed by having only one kind of storage (root being null storage key (storage_key can become Option<&[u8]>). -use crate::rstd::prelude::*; +use crate::sp_std::prelude::*; use codec::{Codec, Encode, Decode}; +pub use sp_core::storage::ChildInfo; /// Return the value of the item in storage under `key`, or `None` if there is no explicit entry. -pub fn get(storage_key: &[u8], key: &[u8]) -> Option { - runtime_io::storage::child_get(storage_key, key).and_then(|v| { +pub fn get( + storage_key: &[u8], + child_info: ChildInfo, + key: &[u8], +) -> Option { + let (data, child_type) = child_info.info(); + sp_io::storage::child_get( + storage_key, + data, + child_type, + key, + ).and_then(|v| { Decode::decode(&mut &v[..]).map(Some).unwrap_or_else(|_| { // TODO #3700: error should be handleable. runtime_print!("ERROR: Corrupted state in child trie at {:?}/{:?}", storage_key, key); @@ -37,83 +52,178 @@ pub fn get(storage_key: &[u8], key: &[u8]) -> Option { /// Return the value of the item in storage under `key`, or the type's default if there is no /// explicit entry. -pub fn get_or_default(storage_key: &[u8], key: &[u8]) -> T { - get(storage_key, key).unwrap_or_else(Default::default) +pub fn get_or_default( + storage_key: &[u8], + child_info: ChildInfo, + key: &[u8], +) -> T { + get(storage_key, child_info, key).unwrap_or_else(Default::default) } /// Return the value of the item in storage under `key`, or `default_value` if there is no /// explicit entry. -pub fn get_or(storage_key: &[u8], key: &[u8], default_value: T) -> T { - get(storage_key, key).unwrap_or(default_value) +pub fn get_or( + storage_key: &[u8], + child_info: ChildInfo, + key: &[u8], + default_value: T, +) -> T { + get(storage_key, child_info, key).unwrap_or(default_value) } /// Return the value of the item in storage under `key`, or `default_value()` if there is no /// explicit entry. pub fn get_or_else T>( storage_key: &[u8], + child_info: ChildInfo, key: &[u8], default_value: F, ) -> T { - get(storage_key, key).unwrap_or_else(default_value) + get(storage_key, child_info, key).unwrap_or_else(default_value) } /// Put `value` in storage under `key`. -pub fn put(storage_key: &[u8], key: &[u8], value: &T) { - value.using_encoded(|slice| runtime_io::storage::child_set(storage_key, key, slice)); +pub fn put( + storage_key: &[u8], + child_info: ChildInfo, + key: &[u8], + value: &T, +) { + let (data, child_type) = child_info.info(); + value.using_encoded(|slice| + sp_io::storage::child_set( + storage_key, + data, + child_type, + key, + slice, + ) + ); } /// Remove `key` from storage, returning its value if it had an explicit entry or `None` otherwise. -pub fn take(storage_key: &[u8], key: &[u8]) -> Option { - let r = get(storage_key, key); +pub fn take( + storage_key: &[u8], + child_info: ChildInfo, + key: &[u8], +) -> Option { + let r = get(storage_key, child_info, key); if r.is_some() { - kill(storage_key, key); + kill(storage_key, child_info, key); } r } /// Remove `key` from storage, returning its value, or, if there was no explicit entry in storage, /// the default for its type. -pub fn take_or_default(storage_key: &[u8], key: &[u8]) -> T { - take(storage_key, key).unwrap_or_else(Default::default) +pub fn take_or_default( + storage_key: &[u8], + child_info: ChildInfo, + key: &[u8], +) -> T { + take(storage_key, child_info, key).unwrap_or_else(Default::default) } /// Return the value of the item in storage under `key`, or `default_value` if there is no /// explicit entry. Ensure there is no explicit entry on return. -pub fn take_or(storage_key: &[u8],key: &[u8], default_value: T) -> T { - take(storage_key, key).unwrap_or(default_value) +pub fn take_or( + storage_key: &[u8], + child_info: ChildInfo, + key: &[u8], + default_value: T, +) -> T { + take(storage_key, child_info, key).unwrap_or(default_value) } /// Return the value of the item in storage under `key`, or `default_value()` if there is no /// explicit entry. Ensure there is no explicit entry on return. pub fn take_or_else T>( storage_key: &[u8], + child_info: ChildInfo, key: &[u8], default_value: F, ) -> T { - take(storage_key, key).unwrap_or_else(default_value) + take(storage_key, child_info, key).unwrap_or_else(default_value) } /// Check to see if `key` has an explicit entry in storage. -pub fn exists(storage_key: &[u8], key: &[u8]) -> bool { - runtime_io::storage::child_read(storage_key, key, &mut [0;0][..], 0).is_some() +pub fn exists( + storage_key: &[u8], + child_info: ChildInfo, + key: &[u8], +) -> bool { + let (data, child_type) = child_info.info(); + sp_io::storage::child_read( + storage_key, data, child_type, + key, &mut [0;0][..], 0, + ).is_some() } /// Remove all `storage_key` key/values -pub fn kill_storage(storage_key: &[u8]) { - runtime_io::storage::child_storage_kill(storage_key) +pub fn kill_storage( + storage_key: &[u8], + child_info: ChildInfo, +) { + let (data, child_type) = child_info.info(); + sp_io::storage::child_storage_kill( + storage_key, + data, + child_type, + ) } /// Ensure `key` has no explicit entry in storage. -pub fn kill(storage_key: &[u8], key: &[u8]) { - runtime_io::storage::child_clear(storage_key, key); +pub fn kill( + storage_key: &[u8], + child_info: ChildInfo, + key: &[u8], +) { + let (data, child_type) = child_info.info(); + sp_io::storage::child_clear( + storage_key, + data, + child_type, + key, + ); } /// Get a Vec of bytes from storage. -pub fn get_raw(storage_key: &[u8], key: &[u8]) -> Option> { - runtime_io::storage::child_get(storage_key, key) +pub fn get_raw( + storage_key: &[u8], + child_info: ChildInfo, + key: &[u8], +) -> Option> { + let (data, child_type) = child_info.info(); + sp_io::storage::child_get( + storage_key, + data, + child_type, + key, + ) } /// Put a raw byte slice into storage. -pub fn put_raw(storage_key: &[u8], key: &[u8], value: &[u8]) { - runtime_io::storage::child_set(storage_key, key, value) +pub fn put_raw( + storage_key: &[u8], + child_info: ChildInfo, + key: &[u8], + value: &[u8], +) { + let (data, child_type) = child_info.info(); + sp_io::storage::child_set( + storage_key, + data, + child_type, + key, + value, + ) +} + +/// Calculate current child root value. +pub fn child_root( + storage_key: &[u8], +) -> Vec { + sp_io::storage::child_root( + storage_key, + ) } diff --git a/frame/support/src/storage/generator/double_map.rs b/frame/support/src/storage/generator/double_map.rs index 072b530e4cd417723a3ceb39e9c21a6b97f76ec9..036b1f506e276416895e1d6b61d4ad3246a2fcba 100644 --- a/frame/support/src/storage/generator/double_map.rs +++ b/frame/support/src/storage/generator/double_map.rs @@ -14,10 +14,10 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use rstd::prelude::*; -use rstd::borrow::Borrow; +use sp_std::prelude::*; +use sp_std::borrow::Borrow; use codec::{Ref, FullCodec, FullEncode, Encode, EncodeLike, EncodeAppend}; -use crate::{storage::{self, unhashed}, hash::StorageHasher}; +use crate::{storage::{self, unhashed}, hash::{StorageHasher, Twox128}, traits::Len}; /// Generator for `StorageDoubleMap` used by `decl_storage`. /// @@ -29,7 +29,7 @@ use crate::{storage::{self, unhashed}, hash::StorageHasher}; /// /// Thus value for (key1, key2) is stored at: /// ```nocompile -/// Hasher1(key1_prefix ++ key1) ++ Hasher2(key2) +/// Twox128(module_prefix) ++ Twox128(storage_prefix) ++ Hasher1(encode(key1)) ++ Hasher2(encode(key2)) /// ``` /// /// # Warning @@ -49,8 +49,11 @@ pub trait StorageDoubleMap { /// Hasher for the second key. type Hasher2: StorageHasher; - /// Get the prefix for first key. - fn key1_prefix() -> &'static [u8]; + /// Module prefix. Used for generating final key. + fn module_prefix() -> &'static [u8]; + + /// Storage prefix. Used for generating final key. + fn storage_prefix() -> &'static [u8]; /// Convert an optional value retrieved from storage to the type queried. fn from_optional_value_to_query(v: Option) -> Self::Query; @@ -59,13 +62,23 @@ pub trait StorageDoubleMap { fn from_query_to_optional_value(v: Self::Query) -> Option; /// Generate the first part of the key used in top storage. - fn storage_double_map_final_key1(k1: KArg1) -> ::Output + fn storage_double_map_final_key1(k1: KArg1) -> Vec where KArg1: EncodeLike, { - let mut final_key1 = Self::key1_prefix().to_vec(); - k1.encode_to(&mut final_key1); - Self::Hasher1::hash(&final_key1) + let module_prefix_hashed = Twox128::hash(Self::module_prefix()); + let storage_prefix_hashed = Twox128::hash(Self::storage_prefix()); + let key_hashed = k1.borrow().using_encoded(Self::Hasher1::hash); + + let mut final_key = Vec::with_capacity( + module_prefix_hashed.len() + storage_prefix_hashed.len() + key_hashed.as_ref().len() + ); + + final_key.extend_from_slice(&module_prefix_hashed[..]); + final_key.extend_from_slice(&storage_prefix_hashed[..]); + final_key.extend_from_slice(key_hashed.as_ref()); + + final_key } /// Generate the full key used in top storage. @@ -74,7 +87,7 @@ pub trait StorageDoubleMap { KArg1: EncodeLike, KArg2: EncodeLike, { - let mut final_key = Self::storage_double_map_final_key1(k1).as_ref().to_vec(); + let mut final_key = Self::storage_double_map_final_key1(k1); final_key.extend_from_slice(k2.using_encoded(Self::Hasher2::hash).as_ref()); final_key } @@ -124,6 +137,29 @@ where G::from_optional_value_to_query(value) } + fn swap(x_k1: XKArg1, x_k2: XKArg2, y_k1: YKArg1, y_k2: YKArg2) + where + XKArg1: EncodeLike, + XKArg2: EncodeLike, + YKArg1: EncodeLike, + YKArg2: EncodeLike + { + let final_x_key = Self::storage_double_map_final_key(x_k1, x_k2); + let final_y_key = Self::storage_double_map_final_key(y_k1, y_k2); + + let v1 = unhashed::get_raw(&final_x_key); + if let Some(val) = unhashed::get_raw(&final_y_key) { + unhashed::put_raw(&final_x_key, &val); + } else { + unhashed::kill(&final_x_key) + } + if let Some(val) = v1 { + unhashed::put_raw(&final_y_key, &val); + } else { + unhashed::kill(&final_y_key) + } + } + fn insert(k1: KArg1, k2: KArg2, val: VArg) where KArg1: EncodeLike, @@ -145,6 +181,17 @@ where unhashed::kill_prefix(Self::storage_double_map_final_key1(k1).as_ref()) } + fn iter_prefix(k1: KArg1) -> storage::PrefixIterator + where KArg1: ?Sized + EncodeLike + { + let prefix = Self::storage_double_map_final_key1(k1); + storage::PrefixIterator:: { + prefix: prefix.clone(), + previous_key: prefix, + phantom_data: Default::default(), + } + } + fn mutate(k1: KArg1, k2: KArg2, f: F) -> R where KArg1: EncodeLike, @@ -182,7 +229,7 @@ where .unwrap_or_else(|| { match G::from_query_to_optional_value(G::from_optional_value_to_query(None)) { Some(value) => value.encode(), - None => vec![], + None => Vec::new(), } }); @@ -212,4 +259,52 @@ where Self::append(Ref::from(&k1), Ref::from(&k2), items.clone()) .unwrap_or_else(|_| Self::insert(k1, k2, items)); } + + fn decode_len(key1: KArg1, key2: KArg2) -> Result + where KArg1: EncodeLike, + KArg2: EncodeLike, + V: codec::DecodeLength + Len, + { + let final_key = Self::storage_double_map_final_key(key1, key2); + if let Some(v) = unhashed::get_raw(&final_key) { + ::len(&v).map_err(|e| e.what()) + } else { + let len = G::from_query_to_optional_value(G::from_optional_value_to_query(None)) + .map(|v| v.len()) + .unwrap_or(0); + + Ok(len) + } + } +} + +#[cfg(test)] +mod test { + use sp_io::TestExternalities; + use crate::storage::{self, StorageDoubleMap}; + use crate::hash::Twox128; + + #[test] + fn iter_prefix_works() { + TestExternalities::default().execute_with(|| { + struct MyStorage; + impl storage::generator::StorageDoubleMap for MyStorage { + type Query = Option; + fn module_prefix() -> &'static [u8] { b"MyModule" } + fn storage_prefix() -> &'static [u8] { b"MyStorage" } + type Hasher1 = Twox128; + type Hasher2 = Twox128; + fn from_optional_value_to_query(v: Option) -> Self::Query { v } + fn from_query_to_optional_value(v: Self::Query) -> Option { v } + } + + MyStorage::insert(1, 3, 7); + MyStorage::insert(1, 4, 8); + MyStorage::insert(2, 5, 9); + MyStorage::insert(2, 6, 10); + + assert_eq!(MyStorage::iter_prefix(1).collect::>(), vec![7, 8]); + assert_eq!(MyStorage::iter_prefix(2).collect::>(), vec![10, 9]); + }); + } } diff --git a/frame/support/src/storage/generator/linked_map.rs b/frame/support/src/storage/generator/linked_map.rs index cf403496990b97d34fa8891ddb5e82efac4ea9b7..b4b6daf2762e259fe411b6cee47158ddb49d36fb 100644 --- a/frame/support/src/storage/generator/linked_map.rs +++ b/frame/support/src/storage/generator/linked_map.rs @@ -15,48 +15,18 @@ // along with Substrate. If not, see . use codec::{FullCodec, Encode, Decode, EncodeLike, Ref}; -use crate::{storage::{self, unhashed}, hash::StorageHasher, traits::Len}; -use rstd::marker::PhantomData; +use crate::{storage::{self, unhashed}, hash::{StorageHasher, Twox128}, traits::Len}; +use sp_std::{prelude::*, marker::PhantomData}; /// Generator for `StorageLinkedMap` used by `decl_storage`. /// -/// # Mapping of keys to a storage path -/// -/// The key for the head of the map is stored at one fixed path: -/// ```nocompile -/// Hasher(head_key) -/// ``` -/// -/// For each key, the value stored under that key is appended with a -/// [`Linkage`](struct.Linkage.html) (which hold previous and next key) at the path: -/// ```nocompile -/// Hasher(prefix ++ key) -/// ``` -/// -/// Enumeration is done by getting the head of the linked map and then iterating getting the -/// value and linkage stored at the key until the found linkage has no next key. -/// -/// # Warning -/// -/// If the keys are not trusted (e.g. can be set by a user), a cryptographic `hasher` such as -/// `blake2_256` must be used. Otherwise, other values in storage can be compromised. +/// By default final key generation rely on `KeyFormat`. pub trait StorageLinkedMap { /// The type that get/take returns. type Query; - /// Hasher used to insert into storage. - type Hasher: StorageHasher; - /// The family of key formats used for this map. - type KeyFormat: KeyFormat; - - /// Prefix used to prepend each key. - fn prefix() -> &'static [u8]; - - /// The head key of the linked-map. - fn head_key() -> &'static [u8] { - ::head_key() - } + type KeyFormat: KeyFormat; /// Convert an optional value retrieved from storage to the type queried. fn from_optional_value_to_query(v: Option) -> Self::Query; @@ -65,41 +35,80 @@ pub trait StorageLinkedMap { fn from_query_to_optional_value(v: Self::Query) -> Option; /// Generate the full key used in top storage. - fn storage_linked_map_final_key(key: KeyArg) -> ::Output + fn storage_linked_map_final_key(key: KeyArg) -> Vec where KeyArg: EncodeLike, { - ::storage_linked_map_final_key::(Self::prefix(), &key) + ::storage_linked_map_final_key::(&key) } /// Generate the hashed key for head - fn storage_linked_map_final_head_key() -> ::Output { + fn storage_linked_map_final_head_key() -> Vec { ::storage_linked_map_final_head_key() } } /// A type-abstracted key format used for a family of linked-map types. +/// +/// # Default mapping of keys to a storage path +/// +/// The key for the head of the map is stored at one fixed path: +/// ```nocompile +/// Twox128(module_prefix) ++ Twox128(head_prefix) +/// ``` +/// +/// For each key, the value stored under that key is appended with a +/// [`Linkage`](struct.Linkage.html) (which hold previous and next key) at the path: +/// ```nocompile +/// Twox128(module_prefix) ++ Twox128(storage_prefix) ++ Hasher(encode(key)) +/// ``` +/// +/// Enumeration is done by getting the head of the linked map and then iterating getting the +/// value and linkage stored at the key until the found linkage has no next key. +/// +/// # Warning +/// +/// If the keys are not trusted (e.g. can be set by a user), a cryptographic `hasher` such as +/// `blake2_256` must be used. Otherwise, other values in storage can be compromised. pub trait KeyFormat { + /// Hasher. Used for generating final key and final head key. type Hasher: StorageHasher; - /// Key used to store linked map head. - fn head_key() -> &'static [u8]; + /// Module prefix. Used for generating final key. + fn module_prefix() -> &'static [u8]; + + /// Storage prefix. Used for generating final key. + fn storage_prefix() -> &'static [u8]; + + /// Storage prefix. Used for generating final head key. + fn head_prefix() -> &'static [u8]; /// Generate the full key used in top storage. - fn storage_linked_map_final_key(prefix: &[u8], key: &K) - -> ::Output + fn storage_linked_map_final_key(key: &K) -> Vec where K: Encode, { - let mut final_key = prefix.to_vec(); - key.encode_to(&mut final_key); - ::hash(&final_key) + let module_prefix_hashed = Twox128::hash(Self::module_prefix()); + let storage_prefix_hashed = Twox128::hash(Self::storage_prefix()); + let key_hashed = key.using_encoded(Self::Hasher::hash); + + let mut final_key = Vec::with_capacity( + module_prefix_hashed.len() + storage_prefix_hashed.len() + key_hashed.as_ref().len() + ); + + final_key.extend_from_slice(&module_prefix_hashed[..]); + final_key.extend_from_slice(&storage_prefix_hashed[..]); + final_key.extend_from_slice(key_hashed.as_ref()); + + final_key } - fn storage_linked_map_final_head_key() - -> ::Output - { - ::hash(Self::head_key()) + /// Generate the full key used in top storage to store the head of the linked map. + fn storage_linked_map_final_head_key() -> Vec { + [ + Twox128::hash(Self::module_prefix()), + Twox128::hash(Self::head_prefix()), + ].concat() } } @@ -135,17 +144,15 @@ struct EncodeLikeLinkage, NKey: EncodeLike, Key: Enco /// A key-value pair iterator for enumerable map. pub struct Enumerator { next: Option, - prefix: &'static [u8], _phantom: PhantomData<(V, F)>, } impl Enumerator { /// Create an explicit enumerator for testing. #[cfg(test)] - pub fn from_head(head: K, prefix: &'static [u8]) -> Self { + pub fn from_head(head: K) -> Self { Enumerator { next: Some(head), - prefix, _phantom: Default::default(), } } @@ -163,15 +170,15 @@ where let next = self.next.take()?; let (val, linkage): (V, Linkage) = { - let next_full_key = F::storage_linked_map_final_key(self.prefix, &next); + let next_full_key = F::storage_linked_map_final_key(&next); match read_with_linkage::(next_full_key.as_ref()) { Some(value) => value, None => { // TODO #3700: error should be handleable. runtime_print!( - "ERROR: Corrupted state: linked map head_key={:?}: \ + "ERROR: Corrupted state: linked map {:?}{:?}: \ next value doesn't exist at {:?}", - F::head_key(), next_full_key.as_ref(), + F::module_prefix(), F::storage_prefix(), next_full_key, ); return None } @@ -187,18 +194,14 @@ where /// /// Takes care of updating previous and next elements points /// as well as updates head if the element is first or last. -fn remove_linkage(linkage: Linkage, prefix: &[u8]) +fn remove_linkage(linkage: Linkage) where K: FullCodec, V: FullCodec, F: KeyFormat, { - let next_key = linkage.next.as_ref() - .map(|k| F::storage_linked_map_final_key(prefix, k)) - .map(|x| x.as_ref().to_vec()); - let prev_key = linkage.previous.as_ref() - .map(|k| F::storage_linked_map_final_key(prefix, k)) - .map(|x| x.as_ref().to_vec()); + let next_key = linkage.next.as_ref().map(|k| F::storage_linked_map_final_key(k)); + let prev_key = linkage.previous.as_ref().map(|k| F::storage_linked_map_final_key(k)); if let Some(prev_key) = prev_key { // Retrieve previous element and update `next` @@ -208,9 +211,9 @@ where } else { // TODO #3700: error should be handleable. runtime_print!( - "ERROR: Corrupted state: linked map head_key={:?}: \ + "ERROR: Corrupted state: linked map {:?}{:?}: \ previous value doesn't exist at {:?}", - F::head_key(), prev_key, + F::module_prefix(), F::storage_prefix(), prev_key, ); } } else { @@ -225,9 +228,9 @@ where } else { // TODO #3700: error should be handleable. runtime_print!( - "ERROR: Corrupted state: linked map head_key={:?}: \ + "ERROR: Corrupted state: linked map {:?}{:?}: \ next value doesn't exist at {:?}", - F::head_key(), next_key, + F::module_prefix(), F::storage_prefix(), next_key, ); } } @@ -245,7 +248,7 @@ where /// Generate linkage for newly inserted element. /// /// Takes care of updating head and previous head's pointer. -pub(super) fn new_head_linkage(key: KeyArg, prefix: &[u8]) -> Linkage +pub(super) fn new_head_linkage(key: KeyArg) -> Linkage where KeyArg: EncodeLike, K: FullCodec, @@ -255,7 +258,7 @@ where if let Some(head) = read_head::() { // update previous head predecessor { - let head_key = F::storage_linked_map_final_key(prefix, &head); + let head_key = F::storage_linked_map_final_key(&head); if let Some((data, linkage)) = read_with_linkage::(head_key.as_ref()) { let new_linkage = EncodeLikeLinkage::<_, _, K> { previous: Some(Ref::from(&key)), @@ -266,9 +269,9 @@ where } else { // TODO #3700: error should be handleable. runtime_print!( - "ERROR: Corrupted state: linked map head_key={:?}: \ + "ERROR: Corrupted state: linked map {:?}{:?}: \ head value doesn't exist at {:?}", - F::head_key(), head_key.as_ref(), + F::module_prefix(), F::storage_prefix(), head_key, ); // Thus we consider we are first - update the head and produce empty linkage @@ -333,7 +336,6 @@ where } fn swap, KeyArg2: EncodeLike>(key1: KeyArg1, key2: KeyArg2) { - let prefix = Self::prefix(); let final_key1 = Self::storage_linked_map_final_key(Ref::from(&key1)); let final_key2 = Self::storage_linked_map_final_key(Ref::from(&key2)); let full_value_1 = read_with_linkage::(final_key1.as_ref()); @@ -348,13 +350,13 @@ where // Remove key and insert the new one. (Some((value, _linkage)), None) => { Self::remove(key1); - let linkage = new_head_linkage::<_, _, V, G::KeyFormat>(key2, prefix); + let linkage = new_head_linkage::<_, _, V, G::KeyFormat>(key2); unhashed::put(final_key2.as_ref(), &(value, linkage)); } // Remove key and insert the new one. (None, Some((value, _linkage))) => { Self::remove(key2); - let linkage = new_head_linkage::<_, _, V, G::KeyFormat>(key1, prefix); + let linkage = new_head_linkage::<_, _, V, G::KeyFormat>(key1); unhashed::put(final_key1.as_ref(), &(value, linkage)); } // No-op. @@ -368,7 +370,7 @@ where // overwrite but reuse existing linkage Some((_data, linkage)) => linkage, // create new linkage - None => new_head_linkage::<_, _, V, G::KeyFormat>(key, Self::prefix()), + None => new_head_linkage::<_, _, V, G::KeyFormat>(key), }; unhashed::put(final_key.as_ref(), &(val, linkage)) } @@ -398,7 +400,7 @@ where let full_value: Option<(V, Linkage)> = unhashed::take(final_key.as_ref()); let value = full_value.map(|(data, linkage)| { - remove_linkage::(linkage, Self::prefix()); + remove_linkage::(linkage); data }); @@ -408,7 +410,6 @@ where fn enumerate() -> Self::Enumerator { Enumerator::<_, _, G::KeyFormat> { next: read_head::<_, G::KeyFormat>(), - prefix: Self::prefix(), _phantom: Default::default(), } } @@ -436,7 +437,6 @@ where where K2: FullCodec + Clone, V2: Decode, TK: Fn(K2) -> K, TV: Fn(V2) -> V { let head_key = read_head::().ok_or(None)?; - let prefix = G::prefix(); let mut last_key = None; let mut current_key = head_key.clone(); @@ -451,7 +451,7 @@ where }; loop { - let old_raw_key = G::KeyFormat::storage_linked_map_final_key(prefix, ¤t_key); + let old_raw_key = G::KeyFormat::storage_linked_map_final_key(¤t_key); let x = unhashed::take(old_raw_key.as_ref()); let (val, linkage): (V2, Linkage) = match x { Some(v) => v, diff --git a/frame/support/src/storage/generator/map.rs b/frame/support/src/storage/generator/map.rs index 3c3edac28a42a37f779c93c8eded02dc968672e0..0a6cc1f9ae814c845fa38a95ad0081fab6432802 100644 --- a/frame/support/src/storage/generator/map.rs +++ b/frame/support/src/storage/generator/map.rs @@ -15,16 +15,16 @@ // along with Substrate. If not, see . #[cfg(not(feature = "std"))] -use rstd::prelude::*; -use rstd::borrow::Borrow; +use sp_std::prelude::*; +use sp_std::borrow::Borrow; use codec::{FullCodec, FullEncode, Encode, EncodeLike, Ref, EncodeAppend}; -use crate::{storage::{self, unhashed}, hash::StorageHasher, traits::Len}; +use crate::{storage::{self, unhashed}, hash::{StorageHasher, Twox128}, traits::Len}; /// Generator for `StorageMap` used by `decl_storage`. /// -/// For each key value is stored at: +/// By default each key value is stored at: /// ```nocompile -/// Hasher(prefix ++ key) +/// Twox128(module_prefix) ++ Twox128(storage_prefix) ++ Hasher(encode(key)) /// ``` /// /// # Warning @@ -35,11 +35,14 @@ pub trait StorageMap { /// The type that get/take returns. type Query; - /// Hasher used to insert into storage. + /// Hasher. Used for generating final key. type Hasher: StorageHasher; - /// Prefix used to prepend each key. - fn prefix() -> &'static [u8]; + /// Module prefix. Used for generating final key. + fn module_prefix() -> &'static [u8]; + + /// Storage prefix. Used for generating final key. + fn storage_prefix() -> &'static [u8]; /// Convert an optional value retrieved from storage to the type queried. fn from_optional_value_to_query(v: Option) -> Self::Query; @@ -48,13 +51,23 @@ pub trait StorageMap { fn from_query_to_optional_value(v: Self::Query) -> Option; /// Generate the full key used in top storage. - fn storage_map_final_key(key: KeyArg) -> ::Output + fn storage_map_final_key(key: KeyArg) -> Vec where KeyArg: EncodeLike, { - let mut final_key = Self::prefix().to_vec(); - key.borrow().encode_to(&mut final_key); - Self::Hasher::hash(&final_key) + let module_prefix_hashed = Twox128::hash(Self::module_prefix()); + let storage_prefix_hashed = Twox128::hash(Self::storage_prefix()); + let key_hashed = key.borrow().using_encoded(Self::Hasher::hash); + + let mut final_key = Vec::with_capacity( + module_prefix_hashed.len() + storage_prefix_hashed.len() + key_hashed.as_ref().len() + ); + + final_key.extend_from_slice(&module_prefix_hashed[..]); + final_key.extend_from_slice(&storage_prefix_hashed[..]); + final_key.extend_from_slice(key_hashed.as_ref()); + + final_key } } @@ -62,7 +75,7 @@ impl> storage::StorageMap type Query = G::Query; fn hashed_key_for>(key: KeyArg) -> Vec { - Self::storage_map_final_key(key).as_ref().to_vec() + Self::storage_map_final_key(key) } fn swap, KeyArg2: EncodeLike>(key1: KeyArg1, key2: KeyArg2) { @@ -130,7 +143,7 @@ impl> storage::StorageMap .unwrap_or_else(|| { match G::from_query_to_optional_value(G::from_optional_value_to_query(None)) { Some(value) => value.encode(), - None => vec![], + None => Vec::new(), } }); diff --git a/frame/support/src/storage/generator/mod.rs b/frame/support/src/storage/generator/mod.rs index f546546dc7209440cb07dd4bbb09af0cf80fb863..27df37a5c5c0b731d663e39a8e935c613d5ca9ca 100644 --- a/frame/support/src/storage/generator/mod.rs +++ b/frame/support/src/storage/generator/mod.rs @@ -35,7 +35,7 @@ pub use value::StorageValue; #[cfg(test)] #[allow(dead_code)] mod tests { - use runtime_io::TestExternalities; + use sp_io::TestExternalities; use codec::{Encode, Decode}; use crate::storage::{unhashed, generator::{StorageValue, StorageLinkedMap}}; @@ -94,22 +94,18 @@ mod tests { let t = GenesisConfig::default().build_storage().unwrap(); TestExternalities::new(t).execute_with(|| { - let prefix = NumberMap::prefix(); - // start with a map of u32 -> u32. for i in 0u32..100u32 { - let final_key = ::storage_linked_map_final_key( - prefix, &i, - ); + let final_key = ::storage_linked_map_final_key(&i); - let linkage = linked_map::new_head_linkage::<_, u32, u32, Format>(&i, prefix); + let linkage = linked_map::new_head_linkage::<_, u32, u32, Format>(&i); unhashed::put(final_key.as_ref(), &(&i, linkage)); } let head = linked_map::read_head::().unwrap(); assert_eq!( - Enumerator::::from_head(head, prefix).collect::>(), + Enumerator::::from_head(head).collect::>(), (0..100).rev().map(|x| (x, x)).collect::>(), ); diff --git a/frame/support/src/storage/generator/value.rs b/frame/support/src/storage/generator/value.rs index 5ebc25a70af2a6eba052c5870ad61a5443fdb28d..f259b795ce3d626971c15dab1505c20d76909959 100644 --- a/frame/support/src/storage/generator/value.rs +++ b/frame/support/src/storage/generator/value.rs @@ -15,22 +15,25 @@ // along with Substrate. If not, see . #[cfg(not(feature = "std"))] -use rstd::prelude::*; +use sp_std::prelude::*; use codec::{FullCodec, Encode, EncodeAppend, EncodeLike, Decode}; use crate::{storage::{self, unhashed}, hash::{Twox128, StorageHasher}, traits::Len}; /// Generator for `StorageValue` used by `decl_storage`. /// -/// Value is stored at: +/// By default value is stored at: /// ```nocompile -/// Twox128(unhashed_key) +/// Twox128(module_prefix) ++ Twox128(storage_prefix) /// ``` pub trait StorageValue { /// The type that get/take returns. type Query; - /// Unhashed key used in storage - fn unhashed_key() -> &'static [u8]; + /// Module prefix. Used for generating final key. + fn module_prefix() -> &'static [u8]; + + /// Storage prefix. Used for generating final key. + fn storage_prefix() -> &'static [u8]; /// Convert an optional value retrieved from storage to the type queried. fn from_optional_value_to_query(v: Option) -> Self::Query; @@ -39,15 +42,18 @@ pub trait StorageValue { fn from_query_to_optional_value(v: Self::Query) -> Option; /// Generate the full key used in top storage. - fn storage_value_final_key() -> [u8; 16] { - Twox128::hash(Self::unhashed_key()) + fn storage_value_final_key() -> [u8; 32] { + let mut final_key = [0u8; 32]; + final_key[0..16].copy_from_slice(&Twox128::hash(Self::module_prefix())); + final_key[16..32].copy_from_slice(&Twox128::hash(Self::storage_prefix())); + final_key } } impl> storage::StorageValue for G { type Query = G::Query; - fn hashed_key() -> [u8; 16] { + fn hashed_key() -> [u8; 32] { Self::storage_value_final_key() } @@ -121,7 +127,7 @@ impl> storage::StorageValue for G { .unwrap_or_else(|| { match G::from_query_to_optional_value(G::from_optional_value_to_query(None)) { Some(value) => value.encode(), - None => vec![], + None => Vec::new(), } }); diff --git a/frame/support/src/storage/hashed.rs b/frame/support/src/storage/hashed.rs index 2eca8f5bcafbc8390537b4187a3b249f0049c3b1..d4740795db57af3c5b5400ec3dc167017420c4b0 100644 --- a/frame/support/src/storage/hashed.rs +++ b/frame/support/src/storage/hashed.rs @@ -17,7 +17,7 @@ //! Operation on runtime storage using hashed keys. use super::unhashed; -use rstd::prelude::*; +use sp_std::prelude::*; use codec::{Encode, Decode}; /// Return the value of the item in storage under `key`, or `None` if there is no explicit entry. diff --git a/frame/support/src/storage/mod.rs b/frame/support/src/storage/mod.rs index 91e17767885e9040426aff0c86ba2e9eae937385..43be8699f41f83662c7e16b5cc36565642fea7e4 100644 --- a/frame/support/src/storage/mod.rs +++ b/frame/support/src/storage/mod.rs @@ -16,9 +16,9 @@ //! Stuff to do with the runtime's storage. -use rstd::prelude::*; +use sp_std::{prelude::*, marker::PhantomData}; use codec::{FullCodec, FullEncode, Encode, EncodeAppend, EncodeLike, Decode}; -use crate::traits::Len; +use crate::{traits::Len, hash::{Twox128, StorageHasher}}; pub mod unhashed; pub mod hashed; @@ -34,7 +34,7 @@ pub trait StorageValue { type Query; /// Get the storage key. - fn hashed_key() -> [u8; 16]; + fn hashed_key() -> [u8; 32]; /// Does the value (explicitly) exist in storage? fn exists() -> bool; @@ -284,6 +284,14 @@ pub trait StorageDoubleMap { KArg1: EncodeLike, KArg2: EncodeLike; + /// Swap the values of two key-pairs. + fn swap(x_k1: XKArg1, x_k2: XKArg2, y_k1: YKArg1, y_k2: YKArg2) + where + XKArg1: EncodeLike, + XKArg2: EncodeLike, + YKArg1: EncodeLike, + YKArg2: EncodeLike; + fn insert(k1: KArg1, k2: KArg2, val: VArg) where KArg1: EncodeLike, @@ -297,6 +305,9 @@ pub trait StorageDoubleMap { fn remove_prefix(k1: KArg1) where KArg1: ?Sized + EncodeLike; + fn iter_prefix(k1: KArg1) -> PrefixIterator + where KArg1: ?Sized + EncodeLike; + fn mutate(k1: KArg1, k2: KArg2, f: F) -> R where KArg1: EncodeLike, @@ -330,4 +341,142 @@ pub trait StorageDoubleMap { V: EncodeAppend, Items: IntoIterator + Clone + EncodeLike, Items::IntoIter: ExactSizeIterator; + + /// Read the length of the value in a fast way, without decoding the entire value. + /// + /// `V` is required to implement `Codec::DecodeLength`. + /// + /// Note that `0` is returned as the default value if no encoded value exists at the given key. + /// Therefore, this function cannot be used as a sign of _existence_. use the `::exists()` + /// function for this purpose. + fn decode_len(key1: KArg1, key2: KArg2) -> Result + where + KArg1: EncodeLike, + KArg2: EncodeLike, + V: codec::DecodeLength + Len; +} + +/// Iterator for prefixed map. +pub struct PrefixIterator { + prefix: Vec, + previous_key: Vec, + phantom_data: PhantomData, +} + +impl Iterator for PrefixIterator { + type Item = Value; + + fn next(&mut self) -> Option { + match sp_io::storage::next_key(&self.previous_key) + .filter(|n| n.starts_with(&self.prefix[..])) + { + Some(next_key) => { + let value = unhashed::get(&next_key); + + if value.is_none() { + runtime_print!( + "ERROR: returned next_key has no value:\nkey is {:?}\nnext_key is {:?}", + &self.previous_key, &next_key, + ); + } + + self.previous_key = next_key; + + value + }, + _ => None, + } + } +} + +/// Trait for maps that store all its value after a unique prefix. +/// +/// By default the final prefix is: +/// ```nocompile +/// Twox128(module_prefix) ++ Twox128(storage_prefix) +/// ``` +pub trait StoragePrefixedMap { + + /// Module prefix. Used for generating final key. + fn module_prefix() -> &'static [u8]; + + /// Storage prefix. Used for generating final key. + fn storage_prefix() -> &'static [u8]; + + fn final_prefix() -> [u8; 32] { + let mut final_key = [0u8; 32]; + final_key[0..16].copy_from_slice(&Twox128::hash(Self::module_prefix())); + final_key[16..32].copy_from_slice(&Twox128::hash(Self::storage_prefix())); + final_key + } + + fn remove_all() { + sp_io::storage::clear_prefix(&Self::final_prefix()) + } + + fn iter() -> PrefixIterator { + let prefix = Self::final_prefix(); + PrefixIterator { + prefix: prefix.to_vec(), + previous_key: prefix.to_vec(), + phantom_data: Default::default(), + } + } +} + +#[cfg(test)] +mod test { + use sp_core::hashing::twox_128; + use sp_io::TestExternalities; + use crate::storage::{unhashed, StoragePrefixedMap}; + + #[test] + fn prefixed_map_works() { + TestExternalities::default().execute_with(|| { + struct MyStorage; + impl StoragePrefixedMap for MyStorage { + fn module_prefix() -> &'static [u8] { + b"MyModule" + } + + fn storage_prefix() -> &'static [u8] { + b"MyStorage" + } + } + + let key_before = { + let mut k = MyStorage::final_prefix(); + let last = k.iter_mut().last().unwrap(); + *last = last.checked_sub(1).unwrap(); + k + }; + let key_after = { + let mut k = MyStorage::final_prefix(); + let last = k.iter_mut().last().unwrap(); + *last = last.checked_add(1).unwrap(); + k + }; + + unhashed::put(&key_before[..], &32u64); + unhashed::put(&key_after[..], &33u64); + + let k = [twox_128(b"MyModule"), twox_128(b"MyStorage")].concat(); + assert_eq!(MyStorage::final_prefix().to_vec(), k); + + assert_eq!(MyStorage::iter().collect::>(), vec![]); + + unhashed::put(&[&k[..], &vec![1][..]].concat(), &1u64); + unhashed::put(&[&k[..], &vec![1, 1][..]].concat(), &2u64); + unhashed::put(&[&k[..], &vec![8][..]].concat(), &3u64); + unhashed::put(&[&k[..], &vec![10][..]].concat(), &4u64); + + assert_eq!(MyStorage::iter().collect::>(), vec![1, 2, 3, 4]); + + MyStorage::remove_all(); + + assert_eq!(MyStorage::iter().collect::>(), vec![]); + assert_eq!(unhashed::get(&key_before[..]), Some(32u64)); + assert_eq!(unhashed::get(&key_after[..]), Some(33u64)); + }); + } } diff --git a/frame/support/src/storage/unhashed.rs b/frame/support/src/storage/unhashed.rs index a128f6bf18d0e7af53d89618b6348d3e3b7d2687..55f99f3d81486d6bdc885494648dd0256f1aa291 100644 --- a/frame/support/src/storage/unhashed.rs +++ b/frame/support/src/storage/unhashed.rs @@ -16,12 +16,12 @@ //! Operation on unhashed runtime storage. -use rstd::prelude::*; +use sp_std::prelude::*; use codec::{Encode, Decode}; /// Return the value of the item in storage under `key`, or `None` if there is no explicit entry. pub fn get(key: &[u8]) -> Option { - runtime_io::storage::get(key).and_then(|val| { + sp_io::storage::get(key).and_then(|val| { Decode::decode(&mut &val[..]).map(Some).unwrap_or_else(|_| { // TODO #3700: error should be handleable. runtime_print!("ERROR: Corrupted state at {:?}", key); @@ -50,7 +50,7 @@ pub fn get_or_else T>(key: &[u8], default_valu /// Put `value` in storage under `key`. pub fn put(key: &[u8], value: &T) { - value.using_encoded(|slice| runtime_io::storage::set(key, slice)); + value.using_encoded(|slice| sp_io::storage::set(key, slice)); } /// Remove `key` from storage, returning its value if it had an explicit entry or `None` otherwise. @@ -82,25 +82,25 @@ pub fn take_or_else T>(key: &[u8], default_val /// Check to see if `key` has an explicit entry in storage. pub fn exists(key: &[u8]) -> bool { - runtime_io::storage::read(key, &mut [0;0][..], 0).is_some() + sp_io::storage::read(key, &mut [0;0][..], 0).is_some() } /// Ensure `key` has no explicit entry in storage. pub fn kill(key: &[u8]) { - runtime_io::storage::clear(key); + sp_io::storage::clear(key); } /// Ensure keys with the given `prefix` have no entries in storage. pub fn kill_prefix(prefix: &[u8]) { - runtime_io::storage::clear_prefix(prefix); + sp_io::storage::clear_prefix(prefix); } /// Get a Vec of bytes from storage. pub fn get_raw(key: &[u8]) -> Option> { - runtime_io::storage::get(key) + sp_io::storage::get(key) } /// Put a raw byte slice into storage. pub fn put_raw(key: &[u8], value: &[u8]) { - runtime_io::storage::set(key, value) + sp_io::storage::set(key, value) } diff --git a/frame/support/src/traits.rs b/frame/support/src/traits.rs index 167afd1b725087057c8a3a8205805ee73903a127..379f964d271a08ecab61d94e3383aec4a1c55584 100644 --- a/frame/support/src/traits.rs +++ b/frame/support/src/traits.rs @@ -18,14 +18,16 @@ //! //! NOTE: If you're looking for `parameter_types`, it has moved in to the top-level module. -use rstd::{prelude::*, result, marker::PhantomData, ops::Div, fmt::Debug}; +use sp_std::{prelude::*, result, marker::PhantomData, ops::Div, fmt::Debug}; use codec::{FullCodec, Codec, Encode, Decode}; -use primitives::u32_trait::Value as U32; -use sr_primitives::{ - ConsensusEngineId, +use sp_core::u32_trait::Value as U32; +use sp_runtime::{ + ConsensusEngineId, DispatchResult, DispatchError, traits::{MaybeSerializeDeserialize, SimpleArithmetic, Saturating}, }; +use crate::dispatch::Parameter; + /// Anything that can have a `::len()` method. pub trait Len { /// Return the length of data type. @@ -384,7 +386,7 @@ pub trait Currency { _amount: Self::Balance, reasons: WithdrawReasons, new_balance: Self::Balance, - ) -> result::Result<(), &'static str>; + ) -> DispatchResult; // PUBLIC MUTABLES (DANGEROUS) @@ -397,7 +399,7 @@ pub trait Currency { dest: &AccountId, value: Self::Balance, existence_requirement: ExistenceRequirement, - ) -> result::Result<(), &'static str>; + ) -> DispatchResult; /// Deducts up to `value` from the combined balance of `who`, preferring to deduct from the /// free balance. This function cannot fail. @@ -417,7 +419,7 @@ pub trait Currency { fn deposit_into_existing( who: &AccountId, value: Self::Balance - ) -> result::Result; + ) -> result::Result; /// Similar to deposit_creating, only accepts a `NegativeImbalance` and returns nothing on /// success. @@ -463,7 +465,7 @@ pub trait Currency { value: Self::Balance, reasons: WithdrawReasons, liveness: ExistenceRequirement, - ) -> result::Result; + ) -> result::Result; /// Similar to withdraw, only accepts a `PositiveImbalance` and returns nothing on success. fn settle( @@ -526,7 +528,7 @@ pub trait ReservableCurrency: Currency { /// /// If the free balance is lower than `value`, then no funds will be moved and an `Err` will /// be returned to notify of this. This is different behavior than `unreserve`. - fn reserve(who: &AccountId, value: Self::Balance) -> result::Result<(), &'static str>; + fn reserve(who: &AccountId, value: Self::Balance) -> DispatchResult; /// Moves up to `value` from reserved balance to free balance. This function cannot fail. /// @@ -550,7 +552,7 @@ pub trait ReservableCurrency: Currency { slashed: &AccountId, beneficiary: &AccountId, value: Self::Balance - ) -> result::Result; + ) -> result::Result; } /// An identifier for a lock. Used for disambiguating different locks so that @@ -600,6 +602,29 @@ pub trait LockableCurrency: Currency { ); } +/// A currency whose accounts can have balances which vest over time. +pub trait VestingCurrency: Currency { + /// The quantity used to denote time; usually just a `BlockNumber`. + type Moment; + + /// Get the amount that is currently being vested and cannot be transferred out of this account. + fn vesting_balance(who: &AccountId) -> Self::Balance; + + /// Adds a vesting schedule to a given account. + /// + /// If there already exists a vesting schedule for the given account, an `Err` is returned + /// and nothing is updated. + fn add_vesting_schedule( + who: &AccountId, + locked: Self::Balance, + per_block: Self::Balance, + starting_block: Self::Moment, + ) -> DispatchResult; + + /// Remove a vesting schedule for a given account. + fn remove_vesting_schedule(who: &AccountId); +} + bitmask! { /// Reasons for moving funds out of an account. #[derive(Encode, Decode)] @@ -622,7 +647,7 @@ bitmask! { } pub trait Time { - type Moment: SimpleArithmetic + FullCodec + Clone + Default + Copy; + type Moment: SimpleArithmetic + Parameter + Default + Copy; fn now() -> Self::Moment; } @@ -744,3 +769,23 @@ pub trait Randomness { Self::random(&[][..]) } } + +/// Implementors of this trait provide information about whether or not some validator has +/// been registered with them. The [Session module](../../pallet_session/index.html) is an implementor. +pub trait ValidatorRegistration { + /// Returns true if the provided validator ID has been registered with the implementing runtime + /// module + fn is_registered(id: &ValidatorId) -> bool; +} + +/// Something that can convert a given module into the index of the module in the runtime. +/// +/// The index of a module is determined by the position it appears in `construct_runtime!`. +pub trait ModuleToIndex { + /// Convert the given module `M` into an index. + fn module_to_index() -> Option; +} + +impl ModuleToIndex for () { + fn module_to_index() -> Option { Some(0) } +} diff --git a/frame/support/src/unsigned.rs b/frame/support/src/unsigned.rs index c6fafa8afa4e0f32d0e38ea1fc47e9b5cc8b29ca..37b66dc4b0b6a28555dce74fac6975d4f182e9fd 100644 --- a/frame/support/src/unsigned.rs +++ b/frame/support/src/unsigned.rs @@ -16,9 +16,9 @@ #[doc(hidden)] #[allow(deprecated)] -pub use crate::sr_primitives::traits::ValidateUnsigned; +pub use crate::sp_runtime::traits::ValidateUnsigned; #[doc(hidden)] -pub use crate::sr_primitives::transaction_validity::{ +pub use crate::sp_runtime::transaction_validity::{ TransactionValidity, UnknownTransaction, TransactionValidityError, }; diff --git a/frame/support/src/weights.rs b/frame/support/src/weights.rs index c87eca67b54127ebc50fc64edad0be7be78aad9f..406e6e9425f5c69a738dff15c826c372c45d6af9 100644 --- a/frame/support/src/weights.rs +++ b/frame/support/src/weights.rs @@ -39,15 +39,15 @@ use serde::{Serialize, Deserialize}; use impl_trait_for_tuples::impl_for_tuples; use codec::{Encode, Decode}; -use sr_arithmetic::traits::{Bounded, Zero}; -use sr_primitives::{ +use sp_arithmetic::traits::{Bounded, Zero}; +use sp_runtime::{ RuntimeDebug, traits::SignedExtension, generic::{CheckedExtrinsic, UncheckedExtrinsic}, }; /// Re-export priority as type -pub use sr_primitives::transaction_validity::TransactionPriority; +pub use sp_runtime::transaction_validity::TransactionPriority; /// Numeric range of a transaction weight. pub type Weight = u32; @@ -76,6 +76,14 @@ pub trait WeighBlock { fn on_finalize(_: BlockNumber) -> Weight { Zero::zero() } } +/// Indicates if dispatch function should pay fees or not. +/// If set to false, the block resource limits are applied, yet no fee is deducted. +pub trait PaysFee { + fn pays_fee(&self) -> bool { + true + } +} + /// Maybe I can do something to remove the duplicate code here. #[impl_for_tuples(30)] impl WeighBlock for SingleModule { @@ -146,17 +154,8 @@ pub struct DispatchInfo { pub weight: Weight, /// Class of this transaction. pub class: DispatchClass, -} - -impl DispatchInfo { - /// Determine if this dispatch should pay the base length-related fee or not. - pub fn pay_length_fee(&self) -> bool { - match self.class { - DispatchClass::Normal => true, - // For now we assume all operational transactions don't pay the length fee. - DispatchClass::Operational => false, - } - } + /// Does this transaction pay fees. + pub pays_fee: bool, } /// A `Dispatchable` function (aka transaction) that can carry some static information along with @@ -220,6 +219,20 @@ impl ClassifyDispatch for SimpleDispatchInfo { } } +impl PaysFee for SimpleDispatchInfo { + fn pays_fee(&self) -> bool { + match self { + SimpleDispatchInfo::FixedNormal(_) => true, + SimpleDispatchInfo::MaxNormal => true, + SimpleDispatchInfo::FreeNormal => true, + + SimpleDispatchInfo::FixedOperational(_) => true, + SimpleDispatchInfo::MaxOperational => true, + SimpleDispatchInfo::FreeOperational => false, + } + } +} + impl Default for SimpleDispatchInfo { fn default() -> Self { // Default weight of all transactions. @@ -236,7 +249,7 @@ impl SimpleDispatchInfo { /// A struct to represent a weight which is a function of the input arguments. The given closure's /// arguments must match the dispatch's argument types, given as a tuple. -pub struct FunctionOf(pub F, pub Class); +pub struct FunctionOf(pub F, pub Class, pub bool); impl WeighData for FunctionOf where @@ -256,6 +269,13 @@ where } } +impl PaysFee for FunctionOf { + fn pays_fee(&self) -> bool { + self.2 + } +} + + /// Implementation for unchecked extrinsic. impl GetDispatchInfo for UncheckedExtrinsic @@ -281,11 +301,12 @@ where /// Implementation for test extrinsic. #[cfg(feature = "std")] -impl GetDispatchInfo for sr_primitives::testing::TestXt { +impl GetDispatchInfo for sp_runtime::testing::TestXt { fn get_dispatch_info(&self) -> DispatchInfo { // for testing: weight == size. DispatchInfo { weight: self.encode().len() as _, + pays_fee: true, ..Default::default() } } @@ -318,10 +339,10 @@ mod tests { fn f0(_origin) { unimplemented!(); } // weight = a x 10 + b - #[weight = FunctionOf(|args: (&u32, &u32)| args.0 * 10 + args.1, DispatchClass::Normal)] + #[weight = FunctionOf(|args: (&u32, &u32)| args.0 * 10 + args.1, DispatchClass::Normal, true)] fn f11(_origin, _a: u32, _eb: u32) { unimplemented!(); } - #[weight = FunctionOf(|_: (&u32, &u32)| 0, 1u8)] + #[weight = FunctionOf(|_: (&u32, &u32)| 0, 1u8, true)] fn f12(_origin, _a: u32, _eb: u32) { unimplemented!(); } } } diff --git a/frame/support/test/Cargo.toml b/frame/support/test/Cargo.toml index 3d58898b0ccf657bc90c0a5b5a1d3eeeb91a6b1d..92dc32e478f1d62663902dd8e0ba4dc559de40fa 100644 --- a/frame/support/test/Cargo.toml +++ b/frame/support/test/Cargo.toml @@ -7,12 +7,12 @@ edition = "2018" [dependencies] serde = { version = "1.0.101", default-features = false, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -runtime-io ={ package = "sr-io", path = "../../../primitives/sr-io", default-features = false } -state-machine ={ package = "substrate-state-machine", path = "../../../primitives/state-machine", optional = true } -support = { package = "frame-support", version = "2", path = "../", default-features = false } -inherents = { package = "substrate-inherents", path = "../../../primitives/inherents", default-features = false } -sr-primitives = { package = "sr-primitives", path = "../../../primitives/sr-primitives", default-features = false } -primitives = { package = "substrate-primitives", path = "../../../primitives/core", default-features = false } +sp-io ={ path = "../../../primitives/io", default-features = false } +sp-state-machine = { version = "2.0.0", optional = true, path = "../../../primitives/state-machine" } +frame-support = { version = "2.0.0", default-features = false, path = "../" } +sp-inherents = { version = "2.0.0", default-features = false, path = "../../../primitives/inherents" } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../../primitives/runtime" } +sp-core = { version = "2.0.0", default-features = false, path = "../../../primitives/core" } trybuild = "1.0.17" pretty_assertions = "0.6.1" @@ -21,10 +21,10 @@ default = ["std"] std = [ "serde/std", "codec/std", - "runtime-io/std", - "support/std", - "inherents/std", - "primitives/std", - "sr-primitives/std", - "state-machine", + "sp-io/std", + "frame-support/std", + "sp-inherents/std", + "sp-core/std", + "sp-runtime/std", + "sp-state-machine", ] diff --git a/frame/support/test/src/lib.rs b/frame/support/test/src/lib.rs index 95fa5c6e95f18d01fd804d4c37a058013bb5fbb3..c6a93e1b776e406e80761e0feb0aa200a7ef237e 100644 --- a/frame/support/test/src/lib.rs +++ b/frame/support/test/src/lib.rs @@ -14,5 +14,5 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! Test crate for frame_support. Allow to make use of `support::decl_storage`. +//! Test crate for frame_support. Allow to make use of `frame_support::decl_storage`. //! See tests directory. diff --git a/frame/support/test/tests/construct_runtime_ui.rs b/frame/support/test/tests/construct_runtime_ui.rs new file mode 100644 index 0000000000000000000000000000000000000000..acddf01f037a665fd1c03a4e1643ebf1298168ac --- /dev/null +++ b/frame/support/test/tests/construct_runtime_ui.rs @@ -0,0 +1,10 @@ +use std::env; + +#[test] +fn ui() { + // As trybuild is using `cargo check`, we don't need the real WASM binaries. + env::set_var("BUILD_DUMMY_WASM_BINARY", "1"); + + let t = trybuild::TestCases::new(); + t.compile_fail("tests/construct_runtime_ui/*.rs"); +} diff --git a/frame/support/test/tests/construct_runtime_ui/abundant_where_param.rs b/frame/support/test/tests/construct_runtime_ui/abundant_where_param.rs new file mode 100644 index 0000000000000000000000000000000000000000..d5e9f225219de973fbfb043e5e3eaed67a243898 --- /dev/null +++ b/frame/support/test/tests/construct_runtime_ui/abundant_where_param.rs @@ -0,0 +1,12 @@ +use frame_support::construct_runtime; + +construct_runtime! { + pub enum Runtime where + Block = Block, + NodeBlock = Block, + Block = Block1, + UncheckedExtrinsic = Uxt, + {} +} + +fn main() {} diff --git a/frame/support/test/tests/construct_runtime_ui/abundant_where_param.stderr b/frame/support/test/tests/construct_runtime_ui/abundant_where_param.stderr new file mode 100644 index 0000000000000000000000000000000000000000..4bac57d63c8512cf4bcc7391c40e914ba2da8c56 --- /dev/null +++ b/frame/support/test/tests/construct_runtime_ui/abundant_where_param.stderr @@ -0,0 +1,5 @@ +error: `Block` was declared above. Please use exactly one delcataion for `Block`. + --> $DIR/abundant_where_param.rs:7:3 + | +7 | Block = Block1, + | ^^^^^ diff --git a/frame/support/test/tests/construct_runtime_ui/double_module_parts.rs b/frame/support/test/tests/construct_runtime_ui/double_module_parts.rs new file mode 100644 index 0000000000000000000000000000000000000000..0907f0bfb35d548754ef16c5e27ddb00602484e7 --- /dev/null +++ b/frame/support/test/tests/construct_runtime_ui/double_module_parts.rs @@ -0,0 +1,14 @@ +use frame_support::construct_runtime; + +construct_runtime! { + pub enum Runtime where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic + { + System: system, + Balance: balances::{Config, Call, Config, Origin}, + } +} + +fn main() {} diff --git a/frame/support/test/tests/construct_runtime_ui/double_module_parts.stderr b/frame/support/test/tests/construct_runtime_ui/double_module_parts.stderr new file mode 100644 index 0000000000000000000000000000000000000000..9d10474ce85abedb15b6aba78c8491437b0ca129 --- /dev/null +++ b/frame/support/test/tests/construct_runtime_ui/double_module_parts.stderr @@ -0,0 +1,5 @@ +error: `Config` was already declared before. Please remove the duplicate declaration + --> $DIR/double_module_parts.rs:10:37 + | +10 | Balance: balances::{Config, Call, Config, Origin}, + | ^^^^^^ diff --git a/frame/support/test/tests/construct_runtime_ui/double_module_parts_default.rs b/frame/support/test/tests/construct_runtime_ui/double_module_parts_default.rs new file mode 100644 index 0000000000000000000000000000000000000000..3d61abebe8da1947b02b996bde91413bc1e5f13c --- /dev/null +++ b/frame/support/test/tests/construct_runtime_ui/double_module_parts_default.rs @@ -0,0 +1,14 @@ +use frame_support::construct_runtime; + +construct_runtime! { + pub enum Runtime where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic + { + System: system, + Balance: balances::{default, Config}, + } +} + +fn main() {} diff --git a/frame/support/test/tests/construct_runtime_ui/double_module_parts_default.stderr b/frame/support/test/tests/construct_runtime_ui/double_module_parts_default.stderr new file mode 100644 index 0000000000000000000000000000000000000000..d8205acc4a104e2f13f2a92222d760c8808e626d --- /dev/null +++ b/frame/support/test/tests/construct_runtime_ui/double_module_parts_default.stderr @@ -0,0 +1,5 @@ +error: `Config` is already included in `default`. Either remove `default` or remove `Config` + --> $DIR/double_module_parts_default.rs:10:32 + | +10 | Balance: balances::{default, Config}, + | ^^^^^^ diff --git a/frame/support/test/tests/construct_runtime_ui/generics_in_invalid_module.rs b/frame/support/test/tests/construct_runtime_ui/generics_in_invalid_module.rs new file mode 100644 index 0000000000000000000000000000000000000000..5a9a4612ed0a476f8efd5f45c4d52705e9d99c20 --- /dev/null +++ b/frame/support/test/tests/construct_runtime_ui/generics_in_invalid_module.rs @@ -0,0 +1,14 @@ +use frame_support::construct_runtime; + +construct_runtime! { + pub enum Runtime where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic + { + System: system, + Balance: balances::::{Call, Origin}, + } +} + +fn main() {} diff --git a/frame/support/test/tests/construct_runtime_ui/generics_in_invalid_module.stderr b/frame/support/test/tests/construct_runtime_ui/generics_in_invalid_module.stderr new file mode 100644 index 0000000000000000000000000000000000000000..fe880549211bc338b94c743231868eddec76bd77 --- /dev/null +++ b/frame/support/test/tests/construct_runtime_ui/generics_in_invalid_module.stderr @@ -0,0 +1,5 @@ +error: `Call` is not allowed to have generics. Only the following modules are allowed to have generics: `Event`, `Origin`, `Config`. + --> $DIR/generics_in_invalid_module.rs:10:36 + | +10 | Balance: balances::::{Call, Origin}, + | ^^^^ diff --git a/frame/support/test/tests/construct_runtime_ui/invalid_module_details.rs b/frame/support/test/tests/construct_runtime_ui/invalid_module_details.rs new file mode 100644 index 0000000000000000000000000000000000000000..336e27e91517664ed7d7ae5d19d159ab72b0cb25 --- /dev/null +++ b/frame/support/test/tests/construct_runtime_ui/invalid_module_details.rs @@ -0,0 +1,13 @@ +use frame_support::construct_runtime; + +construct_runtime! { + pub enum Runtime where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic + { + system: System::(), + } +} + +fn main() {} diff --git a/frame/support/test/tests/construct_runtime_ui/invalid_module_details.stderr b/frame/support/test/tests/construct_runtime_ui/invalid_module_details.stderr new file mode 100644 index 0000000000000000000000000000000000000000..559a4637d67ff2cb363c639c7e21765d568ae826 --- /dev/null +++ b/frame/support/test/tests/construct_runtime_ui/invalid_module_details.stderr @@ -0,0 +1,5 @@ +error: expected curly braces + --> $DIR/invalid_module_details.rs:9:19 + | +9 | system: System::(), + | ^^ diff --git a/frame/support/test/tests/construct_runtime_ui/invalid_module_details_keyword.rs b/frame/support/test/tests/construct_runtime_ui/invalid_module_details_keyword.rs new file mode 100644 index 0000000000000000000000000000000000000000..0891483c92116b8d507ff663ed508fb408e5a26d --- /dev/null +++ b/frame/support/test/tests/construct_runtime_ui/invalid_module_details_keyword.rs @@ -0,0 +1,13 @@ +use frame_support::construct_runtime; + +construct_runtime! { + pub enum Runtime where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic + { + system: System::{enum}, + } +} + +fn main() {} diff --git a/frame/support/test/tests/construct_runtime_ui/invalid_module_details_keyword.stderr b/frame/support/test/tests/construct_runtime_ui/invalid_module_details_keyword.stderr new file mode 100644 index 0000000000000000000000000000000000000000..4441f6dc0f6a2f923947528b231f452bbd548eb6 --- /dev/null +++ b/frame/support/test/tests/construct_runtime_ui/invalid_module_details_keyword.stderr @@ -0,0 +1,5 @@ +error: expected `default` or identifier + --> $DIR/invalid_module_details_keyword.rs:9:20 + | +9 | system: System::{enum}, + | ^^^^ diff --git a/frame/support/test/tests/construct_runtime_ui/invalid_token_after_module.rs b/frame/support/test/tests/construct_runtime_ui/invalid_token_after_module.rs new file mode 100644 index 0000000000000000000000000000000000000000..448ae913f3f8d8059fd4e5705c9f87871325bc8c --- /dev/null +++ b/frame/support/test/tests/construct_runtime_ui/invalid_token_after_module.rs @@ -0,0 +1,13 @@ +use frame_support::construct_runtime; + +construct_runtime! { + pub enum Runtime where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic + { + system: System ? + } +} + +fn main() {} diff --git a/frame/support/test/tests/construct_runtime_ui/invalid_token_after_module.stderr b/frame/support/test/tests/construct_runtime_ui/invalid_token_after_module.stderr new file mode 100644 index 0000000000000000000000000000000000000000..8a6f15f7915b260f11f3a45522be19272a85fa6b --- /dev/null +++ b/frame/support/test/tests/construct_runtime_ui/invalid_token_after_module.stderr @@ -0,0 +1,5 @@ +error: expected `,` + --> $DIR/invalid_token_after_module.rs:9:18 + | +9 | system: System ? + | ^ diff --git a/frame/support/test/tests/construct_runtime_ui/invalid_token_after_name.rs b/frame/support/test/tests/construct_runtime_ui/invalid_token_after_name.rs new file mode 100644 index 0000000000000000000000000000000000000000..43538789f11191ed76d121e054183a110d74acb5 --- /dev/null +++ b/frame/support/test/tests/construct_runtime_ui/invalid_token_after_name.rs @@ -0,0 +1,13 @@ +use frame_support::construct_runtime; + +construct_runtime! { + pub enum Runtime where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic + { + system ? + } +} + +fn main() {} diff --git a/frame/support/test/tests/construct_runtime_ui/invalid_token_after_name.stderr b/frame/support/test/tests/construct_runtime_ui/invalid_token_after_name.stderr new file mode 100644 index 0000000000000000000000000000000000000000..eaae082c8460c849df5350521662fa8eaad20152 --- /dev/null +++ b/frame/support/test/tests/construct_runtime_ui/invalid_token_after_name.stderr @@ -0,0 +1,5 @@ +error: expected `:` + --> $DIR/invalid_token_after_name.rs:9:10 + | +9 | system ? + | ^ diff --git a/frame/support/test/tests/construct_runtime_ui/invalid_where_param.rs b/frame/support/test/tests/construct_runtime_ui/invalid_where_param.rs new file mode 100644 index 0000000000000000000000000000000000000000..13536338e07a679de291c795bd0bbffa35f32808 --- /dev/null +++ b/frame/support/test/tests/construct_runtime_ui/invalid_where_param.rs @@ -0,0 +1,12 @@ +use frame_support::construct_runtime; + +construct_runtime! { + pub enum Runtime where + Block = Block, + NodeBlock = Block, + TypeX = Block, + UnchekcedExtrinsic = UnchekcedExtrinsic, + {} +} + +fn main() {} diff --git a/frame/support/test/tests/construct_runtime_ui/invalid_where_param.stderr b/frame/support/test/tests/construct_runtime_ui/invalid_where_param.stderr new file mode 100644 index 0000000000000000000000000000000000000000..9e358b6a21fab0f7022c11f697042299a5357c6f --- /dev/null +++ b/frame/support/test/tests/construct_runtime_ui/invalid_where_param.stderr @@ -0,0 +1,5 @@ +error: expected one of: `Block`, `NodeBlock`, `UncheckedExtrinsic` + --> $DIR/invalid_where_param.rs:7:3 + | +7 | TypeX = Block, + | ^^^^^ diff --git a/frame/support/test/tests/construct_runtime_ui/missing_event_generic_on_module_with_instance.rs b/frame/support/test/tests/construct_runtime_ui/missing_event_generic_on_module_with_instance.rs new file mode 100644 index 0000000000000000000000000000000000000000..928871fab234f319722f31d6d03e6cd6eb243f14 --- /dev/null +++ b/frame/support/test/tests/construct_runtime_ui/missing_event_generic_on_module_with_instance.rs @@ -0,0 +1,14 @@ +use frame_support::construct_runtime; + +construct_runtime! { + pub enum Runtime where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic + { + System: system, + Balance: balances::::{Event}, + } +} + +fn main() {} diff --git a/frame/support/test/tests/construct_runtime_ui/missing_event_generic_on_module_with_instance.stderr b/frame/support/test/tests/construct_runtime_ui/missing_event_generic_on_module_with_instance.stderr new file mode 100644 index 0000000000000000000000000000000000000000..f80b4bd66abddb3a772e39dbe07291682200f953 --- /dev/null +++ b/frame/support/test/tests/construct_runtime_ui/missing_event_generic_on_module_with_instance.stderr @@ -0,0 +1,5 @@ +error: Instantiable module with no generic `Event` cannot be constructed: module `Balance` must have generic `Event` + --> $DIR/missing_event_generic_on_module_with_instance.rs:10:3 + | +10 | Balance: balances::::{Event}, + | ^^^^^^^ diff --git a/frame/support/test/tests/construct_runtime_ui/missing_module_instance.rs b/frame/support/test/tests/construct_runtime_ui/missing_module_instance.rs new file mode 100644 index 0000000000000000000000000000000000000000..fbc4b60db8b7877f74f5078dd7ef127b0a06bf78 --- /dev/null +++ b/frame/support/test/tests/construct_runtime_ui/missing_module_instance.rs @@ -0,0 +1,13 @@ +use frame_support::construct_runtime; + +construct_runtime! { + pub enum Runtime where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic + { + system: System::<>, + } +} + +fn main() {} diff --git a/frame/support/test/tests/construct_runtime_ui/missing_module_instance.stderr b/frame/support/test/tests/construct_runtime_ui/missing_module_instance.stderr new file mode 100644 index 0000000000000000000000000000000000000000..6303c74e42e5c7f4b35172dd614bfb00b05fe618 --- /dev/null +++ b/frame/support/test/tests/construct_runtime_ui/missing_module_instance.stderr @@ -0,0 +1,5 @@ +error: expected identifier + --> $DIR/missing_module_instance.rs:9:20 + | +9 | system: System::<>, + | ^ diff --git a/frame/support/test/tests/construct_runtime_ui/missing_origin_generic_on_module_with_instance.rs b/frame/support/test/tests/construct_runtime_ui/missing_origin_generic_on_module_with_instance.rs new file mode 100644 index 0000000000000000000000000000000000000000..35a5c8201ba03bcc2a6cae4aa00fd29ea30f1df3 --- /dev/null +++ b/frame/support/test/tests/construct_runtime_ui/missing_origin_generic_on_module_with_instance.rs @@ -0,0 +1,14 @@ +use frame_support::construct_runtime; + +construct_runtime! { + pub enum Runtime where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic + { + System: system, + Balance: balances::::{Origin}, + } +} + +fn main() {} diff --git a/frame/support/test/tests/construct_runtime_ui/missing_origin_generic_on_module_with_instance.stderr b/frame/support/test/tests/construct_runtime_ui/missing_origin_generic_on_module_with_instance.stderr new file mode 100644 index 0000000000000000000000000000000000000000..0f7d36aafb8631afddc995556cc3e4ec04c9a389 --- /dev/null +++ b/frame/support/test/tests/construct_runtime_ui/missing_origin_generic_on_module_with_instance.stderr @@ -0,0 +1,5 @@ +error: Instantiable module with no generic `Origin` cannot be constructed: module `Balance` must have generic `Origin` + --> $DIR/missing_origin_generic_on_module_with_instance.rs:10:3 + | +10 | Balance: balances::::{Origin}, + | ^^^^^^^ diff --git a/frame/support/test/tests/construct_runtime_ui/missing_system_module.rs b/frame/support/test/tests/construct_runtime_ui/missing_system_module.rs new file mode 100644 index 0000000000000000000000000000000000000000..71dabf91c1d206d29577982c19b3d54521da5ac1 --- /dev/null +++ b/frame/support/test/tests/construct_runtime_ui/missing_system_module.rs @@ -0,0 +1,12 @@ +use frame_support::construct_runtime; + +construct_runtime! { + pub enum Runtime where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic + { + } +} + +fn main() {} diff --git a/frame/support/test/tests/construct_runtime_ui/missing_system_module.stderr b/frame/support/test/tests/construct_runtime_ui/missing_system_module.stderr new file mode 100644 index 0000000000000000000000000000000000000000..5964a8aa769a65971bc04082cb364b9167fc132d --- /dev/null +++ b/frame/support/test/tests/construct_runtime_ui/missing_system_module.stderr @@ -0,0 +1,7 @@ +error: `System` module declaration is missing. Please add this line: `System: system::{Module, Call, Storage, Config, Event},` + --> $DIR/missing_system_module.rs:8:2 + | +8 | { + | _____^ +9 | | } + | |_____^ diff --git a/frame/support/test/tests/construct_runtime_ui/missing_where_block.rs b/frame/support/test/tests/construct_runtime_ui/missing_where_block.rs new file mode 100644 index 0000000000000000000000000000000000000000..5148330ae585c8d5961c8bf4ef740e4fc3868095 --- /dev/null +++ b/frame/support/test/tests/construct_runtime_ui/missing_where_block.rs @@ -0,0 +1,7 @@ +use frame_support::construct_runtime; + +construct_runtime! { + pub enum Runtime {} +} + +fn main() {} diff --git a/frame/support/test/tests/construct_runtime_ui/missing_where_block.stderr b/frame/support/test/tests/construct_runtime_ui/missing_where_block.stderr new file mode 100644 index 0000000000000000000000000000000000000000..4af672a2610b60afc489e8f0e5f7788a695ec9aa --- /dev/null +++ b/frame/support/test/tests/construct_runtime_ui/missing_where_block.stderr @@ -0,0 +1,5 @@ +error: expected `where` + --> $DIR/missing_where_block.rs:4:19 + | +4 | pub enum Runtime {} + | ^^ diff --git a/frame/support/test/tests/construct_runtime_ui/missing_where_param.rs b/frame/support/test/tests/construct_runtime_ui/missing_where_param.rs new file mode 100644 index 0000000000000000000000000000000000000000..2e311c5ea01aec5a0c708178e6b8766e4420625b --- /dev/null +++ b/frame/support/test/tests/construct_runtime_ui/missing_where_param.rs @@ -0,0 +1,10 @@ +use frame_support::construct_runtime; + +construct_runtime! { + pub enum Runtime where + Block = Block, + NodeBlock = Block, + {} +} + +fn main() {} diff --git a/frame/support/test/tests/construct_runtime_ui/missing_where_param.stderr b/frame/support/test/tests/construct_runtime_ui/missing_where_param.stderr new file mode 100644 index 0000000000000000000000000000000000000000..ac7313523c0c46c7e8fd52f9861d208361174ecf --- /dev/null +++ b/frame/support/test/tests/construct_runtime_ui/missing_where_param.stderr @@ -0,0 +1,5 @@ +error: Missing associated type for `UncheckedExtrinsic`. Add `UncheckedExtrinsic` = ... to where section. + --> $DIR/missing_where_param.rs:7:2 + | +7 | {} + | ^^ diff --git a/frame/support/test/tests/construct_runtime_ui/no_comma_after_where.rs b/frame/support/test/tests/construct_runtime_ui/no_comma_after_where.rs new file mode 100644 index 0000000000000000000000000000000000000000..954fadefa1794c521b191fc1022af35d498b6ed8 --- /dev/null +++ b/frame/support/test/tests/construct_runtime_ui/no_comma_after_where.rs @@ -0,0 +1,13 @@ +use frame_support::construct_runtime; + +construct_runtime! { + pub enum Runtime where + UncheckedExtrinsic = UncheckedExtrinsic + Block = Block, + NodeBlock = Block, + { + System: system, + } +} + +fn main() {} diff --git a/frame/support/test/tests/construct_runtime_ui/no_comma_after_where.stderr b/frame/support/test/tests/construct_runtime_ui/no_comma_after_where.stderr new file mode 100644 index 0000000000000000000000000000000000000000..caf4a7401b08ecdcd6589fa60627eeedd0aac132 --- /dev/null +++ b/frame/support/test/tests/construct_runtime_ui/no_comma_after_where.stderr @@ -0,0 +1,5 @@ +error: Expected `,` or `{` + --> $DIR/no_comma_after_where.rs:6:3 + | +6 | Block = Block, + | ^^^^^ diff --git a/frame/support/test/tests/construct_runtime_ui/params_in_invalid_module.rs b/frame/support/test/tests/construct_runtime_ui/params_in_invalid_module.rs new file mode 100644 index 0000000000000000000000000000000000000000..a739277d620998aac769af1d16e73d1a6e9b2daf --- /dev/null +++ b/frame/support/test/tests/construct_runtime_ui/params_in_invalid_module.rs @@ -0,0 +1,14 @@ +use frame_support::construct_runtime; + +construct_runtime! { + pub enum Runtime where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic + { + System: system, + Balance: balances::::{Call(toto), Origin}, + } +} + +fn main() {} diff --git a/frame/support/test/tests/construct_runtime_ui/params_in_invalid_module.stderr b/frame/support/test/tests/construct_runtime_ui/params_in_invalid_module.stderr new file mode 100644 index 0000000000000000000000000000000000000000..58f35720e31f739fb23eb3a50d7a09d970d7df05 --- /dev/null +++ b/frame/support/test/tests/construct_runtime_ui/params_in_invalid_module.stderr @@ -0,0 +1,5 @@ +error: `Call` is not allowed to have arguments in parens. Only the following modules are allowed to have arguments in parens: `Inherent`. + --> $DIR/params_in_invalid_module.rs:10:40 + | +10 | Balance: balances::::{Call(toto), Origin}, + | ^^^^^^ diff --git a/frame/support/test/tests/decl_error.rs b/frame/support/test/tests/decl_error.rs new file mode 100644 index 0000000000000000000000000000000000000000..42a799caad4a30d33f075b843d3248843e7d49b3 --- /dev/null +++ b/frame/support/test/tests/decl_error.rs @@ -0,0 +1,135 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +#![recursion_limit="128"] + +use sp_runtime::{generic, traits::{BlakeTwo256, Block as _, Verify}, DispatchError}; +use sp_core::{H256, sr25519}; + +mod system; + +pub trait Currency {} + +mod module1 { + use super::*; + + pub trait Trait: system::Trait {} + + frame_support::decl_module! { + pub struct Module, I: Instance = DefaultInstance> for enum Call + where origin: ::Origin + { + pub fn fail(_origin) -> frame_support::dispatch::DispatchResult { + Err(Error::::Something.into()) + } + } + } + + frame_support::decl_error! { + pub enum Error for Module, I: Instance> { + Something + } + } + + frame_support::decl_storage! { + trait Store for Module, I: Instance=DefaultInstance> as Module {} + } +} + +mod module2 { + use super::*; + + pub trait Trait: system::Trait {} + + frame_support::decl_module! { + pub struct Module for enum Call + where origin: ::Origin + { + pub fn fail(_origin) -> frame_support::dispatch::DispatchResult { + Err(Error::::Something.into()) + } + } + } + + frame_support::decl_error! { + pub enum Error for Module { + Something + } + } + + frame_support::decl_storage! { + trait Store for Module as Module {} + } +} + +impl module1::Trait for Runtime {} +impl module1::Trait for Runtime {} +impl module2::Trait for Runtime {} + +pub type Signature = sr25519::Signature; +pub type AccountId = ::Signer; +pub type BlockNumber = u64; +pub type Index = u64; + +impl system::Trait for Runtime { + type Hash = H256; + type Origin = Origin; + type BlockNumber = BlockNumber; + type AccountId = AccountId; + type Event = Event; + type ModuleToIndex = ModuleToIndex; +} + +frame_support::construct_runtime!( + pub enum Runtime where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic + { + System: system::{Module, Call, Event}, + Module1_1: module1::::{Module, Call, Storage}, + Module2: module2::{Module, Call, Storage}, + Module1_2: module1::::{Module, Call, Storage}, + } +); + +pub type Header = generic::Header; +pub type Block = generic::Block; +pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; + +#[test] +fn check_module1_1_error_type() { + assert_eq!( + Module1_1::fail(system::Origin::::Root.into()), + Err(DispatchError::Module { index: 1, error: 0, message: Some("Something") }), + ); +} + +#[test] +fn check_module1_2_error_type() { + assert_eq!( + Module1_2::fail(system::Origin::::Root.into()), + Err(DispatchError::Module { index: 3, error: 0, message: Some("Something") }), + ); +} + +#[test] +fn check_module2_error_type() { + assert_eq!( + Module2::fail(system::Origin::::Root.into()), + Err(DispatchError::Module { index: 2, error: 0, message: Some("Something") }), + ); +} diff --git a/frame/support/test/tests/decl_storage.rs b/frame/support/test/tests/decl_storage.rs index 396288d3be31d6c63e026bd0b3efa29bdf217fd4..e12799f479bf4d50e0e70d56e0d0e8b6e62edede 100644 --- a/frame/support/test/tests/decl_storage.rs +++ b/frame/support/test/tests/decl_storage.rs @@ -18,11 +18,12 @@ // Do not complain about unused `dispatch` and `dispatch_aux`. #[allow(dead_code)] mod tests { - use support::metadata::*; + use frame_support::metadata::*; + use sp_io::TestExternalities; use std::marker::PhantomData; use codec::{Encode, Decode, EncodeLike}; - support::decl_module! { + frame_support::decl_module! { pub struct Module for enum Call where origin: T::Origin {} } @@ -31,7 +32,7 @@ mod tests { type BlockNumber; } - support::decl_storage! { + frame_support::decl_storage! { trait Store for Module as TestStorage { // non-getters: pub / $default @@ -44,7 +45,7 @@ mod tests { // getters: pub / $default // we need at least one type which uses T, otherwise GenesisConfig will complain. GETU32 get(fn u32_getter): T::Origin; - pub PUBGETU32 get(fn pub_u32_getter) build(|config: &GenesisConfig| config.u32_getter_with_config): u32; + pub PUBGETU32 get(fn pub_u32_getter): u32; GETU32WITHCONFIG get(fn u32_getter_with_config) config(): u32; pub PUBGETU32WITHCONFIG get(fn pub_u32_getter_with_config) config(): u32; GETU32MYDEF get(fn u32_getter_mydef): Option; @@ -53,6 +54,10 @@ mod tests { pub PUBGETU32WITHCONFIGMYDEF get(fn pub_u32_getter_with_config_mydef) config(): u32 = 1; PUBGETU32WITHCONFIGMYDEFOPT get(fn pub_u32_getter_with_config_mydef_opt) config(): Option; + GetU32WithBuilder get(fn u32_with_builder) build(|_| 1): u32; + GetOptU32WithBuilderSome get(fn opt_u32_with_builder_some) build(|_| Some(1)): Option; + GetOptU32WithBuilderNone get(fn opt_u32_with_builder_none) build(|_| None): Option; + // map non-getters: pub / $default MAPU32 : map u32 => Option; pub PUBMAPU32 : map u32 => Option; @@ -209,7 +214,33 @@ mod tests { ), documentation: DecodeDifferent::Encode(&[]), }, - + StorageEntryMetadata { + name: DecodeDifferent::Encode("GetU32WithBuilder"), + modifier: StorageEntryModifier::Default, + ty: StorageEntryType::Plain(DecodeDifferent::Encode("u32")), + default: DecodeDifferent::Encode( + DefaultByteGetter(&__GetByteStructGetU32WithBuilder(PhantomData::)) + ), + documentation: DecodeDifferent::Encode(&[]), + }, + StorageEntryMetadata { + name: DecodeDifferent::Encode("GetOptU32WithBuilderSome"), + modifier: StorageEntryModifier::Optional, + ty: StorageEntryType::Plain(DecodeDifferent::Encode("u32")), + default: DecodeDifferent::Encode( + DefaultByteGetter(&__GetByteStructGetOptU32WithBuilderSome(PhantomData::)) + ), + documentation: DecodeDifferent::Encode(&[]), + }, + StorageEntryMetadata { + name: DecodeDifferent::Encode("GetOptU32WithBuilderNone"), + modifier: StorageEntryModifier::Optional, + ty: StorageEntryType::Plain(DecodeDifferent::Encode("u32")), + default: DecodeDifferent::Encode( + DefaultByteGetter(&__GetByteStructGetOptU32WithBuilderNone(PhantomData::)) + ), + documentation: DecodeDifferent::Encode(&[]), + }, StorageEntryMetadata { name: DecodeDifferent::Encode("MAPU32"), modifier: StorageEntryModifier::Optional, @@ -412,7 +443,7 @@ mod tests { #[test] fn store_metadata() { let metadata = Module::::storage_metadata(); - assert_eq!(EXPECTED_METADATA, metadata); + pretty_assertions::assert_eq!(EXPECTED_METADATA, metadata); } #[test] @@ -427,6 +458,16 @@ mod tests { assert_eq!(config.pub_u32_getter_with_config_mydef_opt, 0u32); } + #[test] + fn check_builder_config() { + let config = GenesisConfig::default(); + let storage = config.build_storage().unwrap(); + TestExternalities::from(storage).execute_with(|| { + assert_eq!(Module::::u32_with_builder(), 1); + assert_eq!(Module::::opt_u32_with_builder_some(), Some(1)); + assert_eq!(Module::::opt_u32_with_builder_none(), None); + }) + } } #[cfg(test)] @@ -437,13 +478,13 @@ mod test2 { type BlockNumber; } - support::decl_module! { + frame_support::decl_module! { pub struct Module for enum Call where origin: T::Origin {} } type PairOf = (T, T); - support::decl_storage! { + frame_support::decl_storage! { trait Store for Module as TestStorage { SingleDef : u32; PairDef : PairOf; @@ -472,10 +513,10 @@ mod test3 { type Origin; type BlockNumber; } - support::decl_module! { + frame_support::decl_module! { pub struct Module for enum Call where origin: T::Origin {} } - support::decl_storage! { + frame_support::decl_storage! { trait Store for Module as Test { Foo get(fn foo) config(initial_foo): u32; } @@ -494,7 +535,7 @@ mod test3 { #[cfg(test)] #[allow(dead_code)] mod test_append_and_len { - use runtime_io::TestExternalities; + use sp_io::TestExternalities; use codec::{Encode, Decode}; pub trait Trait { @@ -502,14 +543,14 @@ mod test_append_and_len { type BlockNumber; } - support::decl_module! { + frame_support::decl_module! { pub struct Module for enum Call where origin: T::Origin {} } #[derive(PartialEq, Eq, Clone, Encode, Decode)] struct NoDef(u32); - support::decl_storage! { + frame_support::decl_storage! { trait Store for Module as Test { NoDefault: Option; @@ -521,6 +562,10 @@ mod test_append_and_len { MapVecWithDefault: map u32 => Vec = vec![6, 9]; OptionMapVec: map u32 => Option>; + DoubleMapVec: double_map u32, blake2_256(u32) => Vec; + DoubleMapVecWithDefault: double_map u32, blake2_256(u32) => Vec = vec![6, 9]; + OptionDoubleMapVec: double_map u32, blake2_256(u32) => Option>; + LinkedMapVec: linked_map u32 => Vec; LinkedMapVecWithDefault: linked_map u32 => Vec = vec![6, 9]; OptionLinkedMapVec: linked_map u32 => Option>; @@ -596,11 +641,13 @@ mod test_append_and_len { OptionVec::put(&vec![1, 2, 3, 4, 5]); MapVec::insert(1, &vec![1, 2, 3, 4, 5, 6]); LinkedMapVec::insert(2, &vec![1, 2, 3]); + DoubleMapVec::insert(0, 1, &vec![1, 2]); assert_eq!(JustVec::decode_len().unwrap(), 4); assert_eq!(OptionVec::decode_len().unwrap(), 5); assert_eq!(MapVec::decode_len(1).unwrap(), 6); assert_eq!(LinkedMapVec::decode_len(2).unwrap(), 3); + assert_eq!(DoubleMapVec::decode_len(0, 1).unwrap(), 2); }); } @@ -636,6 +683,16 @@ mod test_append_and_len { assert_eq!(OptionLinkedMapVec::get(0), None); assert_eq!(OptionLinkedMapVec::decode_len(0), Ok(0)); + + // Double map + assert_eq!(DoubleMapVec::get(0, 0), vec![]); + assert_eq!(DoubleMapVec::decode_len(0, 1), Ok(0)); + + assert_eq!(DoubleMapVecWithDefault::get(0, 0), vec![6, 9]); + assert_eq!(DoubleMapVecWithDefault::decode_len(0, 1), Ok(2)); + + assert_eq!(OptionDoubleMapVec::get(0, 0), None); + assert_eq!(OptionDoubleMapVec::decode_len(0, 1), Ok(0)); }); } } diff --git a/frame/support/test/tests/decl_storage_ui/config_duplicate.rs b/frame/support/test/tests/decl_storage_ui/config_duplicate.rs index bdd7da7449aa80686313aca3f7b4a25a1d2fad33..e00f9a8f4c6d9ebc359ca0a8a85e1f7cc3771a26 100644 --- a/frame/support/test/tests/decl_storage_ui/config_duplicate.rs +++ b/frame/support/test/tests/decl_storage_ui/config_duplicate.rs @@ -19,11 +19,11 @@ pub trait Trait { type BlockNumber: codec::Codec + codec::EncodeLike + Default + Clone; } -support::decl_module! { +frame_support::decl_module! { pub struct Module for enum Call where origin: T::Origin {} } -support::decl_storage!{ +frame_support::decl_storage!{ trait Store for Module as FinalKeysNone { pub Value config(value): u32; pub Value2 config(value): u32; diff --git a/frame/support/test/tests/decl_storage_ui/config_get_duplicate.rs b/frame/support/test/tests/decl_storage_ui/config_get_duplicate.rs index 2bf8df45322ccd037091d305b522b65ecf9dd391..6ce8194b578d8a4a072e859bc6921d5a7acb7689 100644 --- a/frame/support/test/tests/decl_storage_ui/config_get_duplicate.rs +++ b/frame/support/test/tests/decl_storage_ui/config_get_duplicate.rs @@ -19,11 +19,11 @@ pub trait Trait { type BlockNumber: codec::Codec + codec::EncodeLike + Default + Clone; } -support::decl_module! { +frame_support::decl_module! { pub struct Module for enum Call where origin: T::Origin {} } -support::decl_storage!{ +frame_support::decl_storage!{ trait Store for Module as FinalKeysNone { pub Value get(fn value) config(): u32; pub Value2 config(value): u32; diff --git a/frame/support/test/tests/decl_storage_ui/get_duplicate.rs b/frame/support/test/tests/decl_storage_ui/get_duplicate.rs index 41ca708352e8b76a8279d2bcc3655a25fcd1ff0f..d593ddc477af179993edaaa5326af7f3279b4236 100644 --- a/frame/support/test/tests/decl_storage_ui/get_duplicate.rs +++ b/frame/support/test/tests/decl_storage_ui/get_duplicate.rs @@ -19,11 +19,11 @@ pub trait Trait { type BlockNumber: codec::Codec + codec::EncodeLike + Default + Clone; } -support::decl_module! { +frame_support::decl_module! { pub struct Module for enum Call where origin: T::Origin {} } -support::decl_storage!{ +frame_support::decl_storage!{ trait Store for Module as FinalKeysNone { pub Value get(fn value) config(): u32; pub Value2 get(fn value) config(): u32; diff --git a/frame/support/test/tests/final_keys.rs b/frame/support/test/tests/final_keys.rs index c1cf5c651a5459466060b1ad226ed0c2ca6fe3ba..3d4c3f506085aa4a760470807149dde668f7de18 100644 --- a/frame/support/test/tests/final_keys.rs +++ b/frame/support/test/tests/final_keys.rs @@ -14,10 +14,10 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use support::storage::unhashed; +use frame_support::storage::unhashed; use codec::Encode; -use support::{StorageDoubleMap, StorageLinkedMap, StorageMap, StorageValue}; -use runtime_io::{TestExternalities, hashing}; +use frame_support::{StorageDoubleMap, StorageLinkedMap, StorageMap, StorageValue, StoragePrefixedMap}; +use sp_io::{TestExternalities, hashing::{twox_128, blake2_128, blake2_256}}; mod no_instance { use codec::{Encode, Decode, EncodeLike}; @@ -27,11 +27,11 @@ mod no_instance { type BlockNumber: Encode + Decode + EncodeLike + Default + Clone; } - support::decl_module! { + frame_support::decl_module! { pub struct Module for enum Call where origin: T::Origin {} } - support::decl_storage!{ + frame_support::decl_storage!{ trait Store for Module as FinalKeysNone { pub Value config(value): u32; @@ -54,12 +54,12 @@ mod no_instance { mod instance { pub trait Trait: super::no_instance::Trait {} - support::decl_module! { + frame_support::decl_module! { pub struct Module, I: Instantiable = DefaultInstance> for enum Call where origin: T::Origin {} } - support::decl_storage!{ + frame_support::decl_storage!{ trait Store for Module, I: Instantiable = DefaultInstance> as FinalKeysSome { @@ -89,45 +89,50 @@ mod instance { fn final_keys_no_instance() { TestExternalities::default().execute_with(|| { no_instance::Value::put(1); - assert_eq!(unhashed::get::(&hashing::twox_128(b"FinalKeysNone Value")), Some(1u32)); + let k = [twox_128(b"FinalKeysNone"), twox_128(b"Value")].concat(); + assert_eq!(unhashed::get::(&k), Some(1u32)); no_instance::Map::insert(1, 2); - let mut k = b"FinalKeysNone Map".to_vec(); - k.extend(1u32.encode()); - assert_eq!(unhashed::get::(&hashing::blake2_256(&k)), Some(2u32)); + let mut k = [twox_128(b"FinalKeysNone"), twox_128(b"Map")].concat(); + k.extend(1u32.using_encoded(blake2_256).to_vec()); + assert_eq!(unhashed::get::(&k), Some(2u32)); + assert_eq!(&k[..32], &::final_prefix()); no_instance::Map2::insert(1, 2); - let mut k = b"FinalKeysNone Map2".to_vec(); - k.extend(1u32.encode()); - assert_eq!(unhashed::get::(&hashing::twox_128(&k)), Some(2u32)); + let mut k = [twox_128(b"FinalKeysNone"), twox_128(b"Map2")].concat(); + k.extend(1u32.using_encoded(twox_128).to_vec()); + assert_eq!(unhashed::get::(&k), Some(2u32)); + assert_eq!(&k[..32], &::final_prefix()); - let head = b"head of FinalKeysNone LinkedMap".to_vec(); - assert_eq!(unhashed::get::(&hashing::blake2_256(&head)), None); + let head = [twox_128(b"FinalKeysNone"), twox_128(b"HeadOfLinkedMap")].concat(); + assert_eq!(unhashed::get::(&head), None); no_instance::LinkedMap::insert(1, 2); - let mut k = b"FinalKeysNone LinkedMap".to_vec(); - k.extend(1u32.encode()); - assert_eq!(unhashed::get::(&hashing::blake2_256(&k)), Some(2u32)); - assert_eq!(unhashed::get::(&hashing::blake2_256(&head)), Some(1u32)); + let mut k = [twox_128(b"FinalKeysNone"), twox_128(b"LinkedMap")].concat(); + k.extend(1u32.using_encoded(blake2_256).to_vec()); + assert_eq!(unhashed::get::(&k), Some(2u32)); + assert_eq!(unhashed::get::(&head), Some(1u32)); + assert_eq!(&k[..32], &::final_prefix()); no_instance::LinkedMap2::insert(1, 2); - let mut k = b"FinalKeysNone LinkedMap2".to_vec(); - k.extend(1u32.encode()); - assert_eq!(unhashed::get::(&hashing::twox_128(&k)), Some(2u32)); + let mut k = [twox_128(b"FinalKeysNone"), twox_128(b"LinkedMap2")].concat(); + k.extend(1u32.using_encoded(twox_128).to_vec()); + assert_eq!(unhashed::get::(&k), Some(2u32)); + assert_eq!(&k[..32], &::final_prefix()); no_instance::DoubleMap::insert(&1, &2, &3); - let mut k = b"FinalKeysNone DoubleMap".to_vec(); - k.extend(1u32.encode()); - let mut k = hashing::blake2_256(&k).to_vec(); - k.extend(&hashing::blake2_256(&2u32.encode())); + let mut k = [twox_128(b"FinalKeysNone"), twox_128(b"DoubleMap")].concat(); + k.extend(1u32.using_encoded(blake2_256).to_vec()); + k.extend(2u32.using_encoded(blake2_256).to_vec()); assert_eq!(unhashed::get::(&k), Some(3u32)); + assert_eq!(&k[..32], &::final_prefix()); no_instance::DoubleMap2::insert(&1, &2, &3); - let mut k = b"FinalKeysNone DoubleMap2".to_vec(); - k.extend(1u32.encode()); - let mut k = hashing::twox_128(&k).to_vec(); - k.extend(&hashing::blake2_128(&2u32.encode())); + let mut k = [twox_128(b"FinalKeysNone"), twox_128(b"DoubleMap2")].concat(); + k.extend(1u32.using_encoded(twox_128).to_vec()); + k.extend(2u32.using_encoded(blake2_128).to_vec()); assert_eq!(unhashed::get::(&k), Some(3u32)); + assert_eq!(&k[..32], &::final_prefix()); }); } @@ -135,45 +140,50 @@ fn final_keys_no_instance() { fn final_keys_default_instance() { TestExternalities::default().execute_with(|| { >::put(1); - assert_eq!(unhashed::get::(&hashing::twox_128(b"FinalKeysSome Value")), Some(1u32)); + let k = [twox_128(b"FinalKeysSome"), twox_128(b"Value")].concat(); + assert_eq!(unhashed::get::(&k), Some(1u32)); >::insert(1, 2); - let mut k = b"FinalKeysSome Map".to_vec(); - k.extend(1u32.encode()); - assert_eq!(unhashed::get::(&hashing::blake2_256(&k)), Some(2u32)); + let mut k = [twox_128(b"FinalKeysSome"), twox_128(b"Map")].concat(); + k.extend(1u32.using_encoded(blake2_256).to_vec()); + assert_eq!(unhashed::get::(&k), Some(2u32)); + assert_eq!(&k[..32], &>::final_prefix()); >::insert(1, 2); - let mut k = b"FinalKeysSome Map2".to_vec(); - k.extend(1u32.encode()); - assert_eq!(unhashed::get::(&hashing::twox_128(&k)), Some(2u32)); + let mut k = [twox_128(b"FinalKeysSome"), twox_128(b"Map2")].concat(); + k.extend(1u32.using_encoded(twox_128).to_vec()); + assert_eq!(unhashed::get::(&k), Some(2u32)); + assert_eq!(&k[..32], &>::final_prefix()); - let head = b"head of FinalKeysSome LinkedMap".to_vec(); - assert_eq!(unhashed::get::(&hashing::blake2_256(&head)), None); + let head = [twox_128(b"FinalKeysSome"), twox_128(b"HeadOfLinkedMap")].concat(); + assert_eq!(unhashed::get::(&head), None); >::insert(1, 2); - let mut k = b"FinalKeysSome LinkedMap".to_vec(); - k.extend(1u32.encode()); - assert_eq!(unhashed::get::(&hashing::blake2_256(&k)), Some(2u32)); - assert_eq!(unhashed::get::(&hashing::blake2_256(&head)), Some(1u32)); + let mut k = [twox_128(b"FinalKeysSome"), twox_128(b"LinkedMap")].concat(); + k.extend(1u32.using_encoded(blake2_256).to_vec()); + assert_eq!(unhashed::get::(&k), Some(2u32)); + assert_eq!(unhashed::get::(&head), Some(1u32)); + assert_eq!(&k[..32], &>::final_prefix()); >::insert(1, 2); - let mut k = b"FinalKeysSome LinkedMap2".to_vec(); - k.extend(1u32.encode()); - assert_eq!(unhashed::get::(&hashing::twox_128(&k)), Some(2u32)); + let mut k = [twox_128(b"FinalKeysSome"), twox_128(b"LinkedMap2")].concat(); + k.extend(1u32.using_encoded(twox_128).to_vec()); + assert_eq!(unhashed::get::(&k), Some(2u32)); + assert_eq!(&k[..32], &>::final_prefix()); >::insert(&1, &2, &3); - let mut k = b"FinalKeysSome DoubleMap".to_vec(); - k.extend(1u32.encode()); - let mut k = hashing::blake2_256(&k).to_vec(); - k.extend(&hashing::blake2_256(&2u32.encode())); + let mut k = [twox_128(b"FinalKeysSome"), twox_128(b"DoubleMap")].concat(); + k.extend(1u32.using_encoded(blake2_256).to_vec()); + k.extend(2u32.using_encoded(blake2_256).to_vec()); assert_eq!(unhashed::get::(&k), Some(3u32)); + assert_eq!(&k[..32], &>::final_prefix()); >::insert(&1, &2, &3); - let mut k = b"FinalKeysSome DoubleMap2".to_vec(); - k.extend(1u32.encode()); - let mut k = hashing::twox_128(&k).to_vec(); - k.extend(&hashing::blake2_128(&2u32.encode())); + let mut k = [twox_128(b"FinalKeysSome"), twox_128(b"DoubleMap2")].concat(); + k.extend(1u32.using_encoded(twox_128).to_vec()); + k.extend(2u32.using_encoded(blake2_128).to_vec()); assert_eq!(unhashed::get::(&k), Some(3u32)); + assert_eq!(&k[..32], &>::final_prefix()); }); } @@ -181,47 +191,49 @@ fn final_keys_default_instance() { fn final_keys_instance_2() { TestExternalities::default().execute_with(|| { >::put(1); - assert_eq!( - unhashed::get::(&hashing::twox_128(b"Instance2FinalKeysSome Value")), - Some(1u32) - ); + let k = [twox_128(b"Instance2FinalKeysSome"), twox_128(b"Value")].concat(); + assert_eq!(unhashed::get::(&k), Some(1u32)); >::insert(1, 2); - let mut k = b"Instance2FinalKeysSome Map".to_vec(); - k.extend(1u32.encode()); - assert_eq!(unhashed::get::(&hashing::blake2_256(&k)), Some(2u32)); + let mut k = [twox_128(b"Instance2FinalKeysSome"), twox_128(b"Map")].concat(); + k.extend(1u32.using_encoded(blake2_256).to_vec()); + assert_eq!(unhashed::get::(&k), Some(2u32)); + assert_eq!(&k[..32], &>::final_prefix()); >::insert(1, 2); - let mut k = b"Instance2FinalKeysSome Map2".to_vec(); - k.extend(1u32.encode()); - assert_eq!(unhashed::get::(&hashing::twox_128(&k)), Some(2u32)); + let mut k = [twox_128(b"Instance2FinalKeysSome"), twox_128(b"Map2")].concat(); + k.extend(1u32.using_encoded(twox_128).to_vec()); + assert_eq!(unhashed::get::(&k), Some(2u32)); + assert_eq!(&k[..32], &>::final_prefix()); - let head = b"head of Instance2FinalKeysSome LinkedMap".to_vec(); - assert_eq!(unhashed::get::(&hashing::blake2_256(&head)), None); + let head = [twox_128(b"Instance2FinalKeysSome"), twox_128(b"HeadOfLinkedMap")].concat(); + assert_eq!(unhashed::get::(&head), None); >::insert(1, 2); - let mut k = b"Instance2FinalKeysSome LinkedMap".to_vec(); - k.extend(1u32.encode()); - assert_eq!(unhashed::get::(&hashing::blake2_256(&k)), Some(2u32)); - assert_eq!(unhashed::get::(&hashing::blake2_256(&head)), Some(1u32)); + let mut k = [twox_128(b"Instance2FinalKeysSome"), twox_128(b"LinkedMap")].concat(); + k.extend(1u32.using_encoded(blake2_256).to_vec()); + assert_eq!(unhashed::get::(&k), Some(2u32)); + assert_eq!(unhashed::get::(&head), Some(1u32)); + assert_eq!(&k[..32], &>::final_prefix()); >::insert(1, 2); - let mut k = b"Instance2FinalKeysSome LinkedMap2".to_vec(); - k.extend(1u32.encode()); - assert_eq!(unhashed::get::(&hashing::twox_128(&k)), Some(2u32)); + let mut k = [twox_128(b"Instance2FinalKeysSome"), twox_128(b"LinkedMap2")].concat(); + k.extend(1u32.using_encoded(twox_128).to_vec()); + assert_eq!(unhashed::get::(&k), Some(2u32)); + assert_eq!(&k[..32], &>::final_prefix()); >::insert(&1, &2, &3); - let mut k = b"Instance2FinalKeysSome DoubleMap".to_vec(); - k.extend(1u32.encode()); - let mut k = hashing::blake2_256(&k).to_vec(); - k.extend(&hashing::blake2_256(&2u32.encode())); + let mut k = [twox_128(b"Instance2FinalKeysSome"), twox_128(b"DoubleMap")].concat(); + k.extend(1u32.using_encoded(blake2_256).to_vec()); + k.extend(2u32.using_encoded(blake2_256).to_vec()); assert_eq!(unhashed::get::(&k), Some(3u32)); + assert_eq!(&k[..32], &>::final_prefix()); >::insert(&1, &2, &3); - let mut k = b"Instance2FinalKeysSome DoubleMap2".to_vec(); - k.extend(1u32.encode()); - let mut k = hashing::twox_128(&k).to_vec(); - k.extend(&hashing::blake2_128(&2u32.encode())); + let mut k = [twox_128(b"Instance2FinalKeysSome"), twox_128(b"DoubleMap2")].concat(); + k.extend(1u32.using_encoded(twox_128).to_vec()); + k.extend(2u32.using_encoded(blake2_128).to_vec()); assert_eq!(unhashed::get::(&k), Some(3u32)); + assert_eq!(&k[..32], &>::final_prefix()); }); } diff --git a/frame/support/test/tests/genesisconfig.rs b/frame/support/test/tests/genesisconfig.rs index e945c774c0d07e97cc5186316fe77425748d2d23..1b5a935983513fc75eb28ea5f9b80f941725ca0d 100644 --- a/frame/support/test/tests/genesisconfig.rs +++ b/frame/support/test/tests/genesisconfig.rs @@ -19,11 +19,11 @@ pub trait Trait { type Origin; } -support::decl_module! { +frame_support::decl_module! { pub struct Module for enum Call where origin: T::Origin {} } -support::decl_storage! { +frame_support::decl_storage! { trait Store for Module as Example { pub AppendableDM config(t): double_map u32, blake2_256(T::BlockNumber) => Vec; } diff --git a/frame/support/test/tests/instance.rs b/frame/support/test/tests/instance.rs index dc4fded17edc71d2a7cfffa06455ca6c514df3a2..cd1473626650bfb7a252c94f890655a660c4dbf4 100644 --- a/frame/support/test/tests/instance.rs +++ b/frame/support/test/tests/instance.rs @@ -16,8 +16,8 @@ #![recursion_limit="128"] -use sr_primitives::{generic, BuildStorage, traits::{BlakeTwo256, Block as _, Verify}}; -use support::{ +use sp_runtime::{generic, BuildStorage, traits::{BlakeTwo256, Block as _, Verify}}; +use frame_support::{ Parameter, traits::Get, parameter_types, metadata::{ DecodeDifferent, StorageMetadata, StorageEntryModifier, StorageEntryType, DefaultByteGetter, @@ -25,8 +25,8 @@ use support::{ }, StorageValue, StorageMap, StorageLinkedMap, StorageDoubleMap, }; -use inherents::{ProvideInherent, InherentData, InherentIdentifier, MakeFatalError}; -use primitives::{H256, sr25519}; +use sp_inherents::{ProvideInherent, InherentData, InherentIdentifier, MakeFatalError}; +use sp_core::{H256, sr25519}; mod system; @@ -46,7 +46,7 @@ mod module1 { type GenericType: Default + Clone + codec::Codec + codec::EncodeLike; } - support::decl_module! { + frame_support::decl_module! { pub struct Module, I: InstantiableThing> for enum Call where origin: ::Origin, T::BlockNumber: From @@ -62,7 +62,7 @@ mod module1 { } } - support::decl_storage! { + frame_support::decl_storage! { trait Store for Module, I: InstantiableThing> as Module1 where T::BlockNumber: From + std::fmt::Display { @@ -79,14 +79,14 @@ mod module1 { } } - support::decl_event! { + frame_support::decl_event! { pub enum Event where Phantom = std::marker::PhantomData { _Phantom(Phantom), AnotherVariant(u32), } } - #[derive(PartialEq, Eq, Clone, sr_primitives::RuntimeDebug)] + #[derive(PartialEq, Eq, Clone, sp_runtime::RuntimeDebug)] pub enum Origin, I> where T::BlockNumber: From { Members(u32), _Phantom(std::marker::PhantomData<(T, I)>), @@ -98,7 +98,7 @@ mod module1 { T::BlockNumber: From { type Call = Call; - type Error = MakeFatalError; + type Error = MakeFatalError; const INHERENT_IDENTIFIER: InherentIdentifier = INHERENT_IDENTIFIER; fn create_inherent(_data: &InherentData) -> Option { @@ -125,7 +125,7 @@ mod module2 { impl, I: Instance> Currency for Module {} - support::decl_module! { + frame_support::decl_module! { pub struct Module, I: Instance=DefaultInstance> for enum Call where origin: ::Origin { @@ -133,7 +133,7 @@ mod module2 { } } - support::decl_storage! { + frame_support::decl_storage! { trait Store for Module, I: Instance=DefaultInstance> as Module2 { pub Value config(value): T::Amount; pub Map config(map): map u64 => u64; @@ -142,13 +142,13 @@ mod module2 { } } - support::decl_event! { + frame_support::decl_event! { pub enum Event where Amount = >::Amount { Variant(Amount), } } - #[derive(PartialEq, Eq, Clone, sr_primitives::RuntimeDebug)] + #[derive(PartialEq, Eq, Clone, sp_runtime::RuntimeDebug)] pub enum Origin, I=DefaultInstance> { Members(u32), _Phantom(std::marker::PhantomData<(T, I)>), @@ -158,7 +158,7 @@ mod module2 { impl, I: Instance> ProvideInherent for Module { type Call = Call; - type Error = MakeFatalError; + type Error = MakeFatalError; const INHERENT_IDENTIFIER: InherentIdentifier = INHERENT_IDENTIFIER; fn create_inherent(_data: &InherentData) -> Option { @@ -181,7 +181,7 @@ mod module3 { type Currency2: Currency; } - support::decl_module! { + frame_support::decl_module! { pub struct Module for enum Call where origin: ::Origin {} } } @@ -238,9 +238,10 @@ impl system::Trait for Runtime { type BlockNumber = BlockNumber; type AccountId = AccountId; type Event = Event; + type ModuleToIndex = (); } -support::construct_runtime!( +frame_support::construct_runtime!( pub enum Runtime where Block = Block, NodeBlock = Block, @@ -271,7 +272,7 @@ pub type Header = generic::Header; pub type Block = generic::Block; pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; -fn new_test_ext() -> runtime_io::TestExternalities { +fn new_test_ext() -> sp_io::TestExternalities { GenesisConfig{ module1_Instance1: Some(module1::GenesisConfig { value: 3, @@ -300,8 +301,11 @@ fn new_test_ext() -> runtime_io::TestExternalities { #[test] fn storage_instance_independance() { - let mut storage = (std::collections::HashMap::new(), std::collections::HashMap::new()); - state_machine::BasicExternalities::execute_with_storage(&mut storage, || { + let mut storage = sp_core::storage::Storage { + top: std::collections::BTreeMap::new(), + children: std::collections::HashMap::new() + }; + sp_state_machine::BasicExternalities::execute_with_storage(&mut storage, || { module2::Value::::put(0); module2::Value::::put(0); module2::Value::::put(0); @@ -320,7 +324,7 @@ fn storage_instance_independance() { module2::DoubleMap::::insert(&0, &0, &0); }); // 16 storage values + 4 linked_map head. - assert_eq!(storage.0.len(), 16 + 4); + assert_eq!(storage.top.len(), 16 + 4); } #[test] @@ -472,14 +476,3 @@ fn test_instance_storage_metadata() { let metadata = Module2_2::storage_metadata(); pretty_assertions::assert_eq!(EXPECTED_METADATA, metadata); } - -#[test] -fn instance_prefix_is_prefix_of_entries() { - use module2::Instance; - - let prefix = module2::Instance2::PREFIX; - assert!(module2::Instance2::PREFIX_FOR_Value.starts_with(prefix)); - assert!(module2::Instance2::PREFIX_FOR_Map.starts_with(prefix)); - assert!(module2::Instance2::PREFIX_FOR_LinkedMap.starts_with(prefix)); - assert!(module2::Instance2::PREFIX_FOR_DoubleMap.starts_with(prefix)); -} diff --git a/frame/support/test/tests/issue2219.rs b/frame/support/test/tests/issue2219.rs index 72e0bc8caf198f5a4519b09dfc9fc02bb4d55ff6..f6679f34987fd8adfad5ddd4c1e03947e4539b3e 100644 --- a/frame/support/test/tests/issue2219.rs +++ b/frame/support/test/tests/issue2219.rs @@ -14,10 +14,10 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use support::sr_primitives::generic; -use support::sr_primitives::traits::{BlakeTwo256, Block as _, Verify}; -use support::codec::{Encode, Decode}; -use primitives::{H256, sr25519}; +use frame_support::sp_runtime::generic; +use frame_support::sp_runtime::traits::{BlakeTwo256, Block as _, Verify}; +use frame_support::codec::{Encode, Decode}; +use sp_core::{H256, sr25519}; use serde::{Serialize, Deserialize}; mod system; @@ -82,7 +82,7 @@ mod module { pub trait Trait: system::Trait {} - support::decl_module! { + frame_support::decl_module! { pub struct Module for enum Call where origin: T::Origin {} } @@ -99,7 +99,7 @@ mod module { } } - support::decl_storage! { + frame_support::decl_storage! { trait Store for Module as Actors { /// requirements to enter and maintain status in roles pub Parameters get(fn parameters) build(|config: &GenesisConfig| { @@ -160,11 +160,12 @@ impl system::Trait for Runtime { type BlockNumber = BlockNumber; type AccountId = AccountId; type Event = Event; + type ModuleToIndex = (); } impl module::Trait for Runtime {} -support::construct_runtime!( +frame_support::construct_runtime!( pub enum Runtime where Block = Block, NodeBlock = Block, diff --git a/frame/support/test/tests/reserved_keyword/on_initialize.rs b/frame/support/test/tests/reserved_keyword/on_initialize.rs index f9604c9487a9eb5098734071dd5740d6ec74f6fe..e389529bca57ecbafa4c13bcae9f53dce03c2a1e 100644 --- a/frame/support/test/tests/reserved_keyword/on_initialize.rs +++ b/frame/support/test/tests/reserved_keyword/on_initialize.rs @@ -2,7 +2,7 @@ macro_rules! reserved { ($($reserved:ident)*) => { $( mod $reserved { - pub use support::dispatch::Result; + pub use frame_support::dispatch; pub trait Trait { type Origin; @@ -10,16 +10,16 @@ macro_rules! reserved { } pub mod system { - use support::dispatch::Result; + use frame_support::dispatch; - pub fn ensure_root(_: R) -> Result { + pub fn ensure_root(_: R) -> dispatch::DispatchResult { Ok(()) } } - support::decl_module! { + frame_support::decl_module! { pub struct Module for enum Call where origin: T::Origin { - fn $reserved(_origin) -> Result { unreachable!() } + fn $reserved(_origin) -> dispatch::DispatchResult { unreachable!() } } } } diff --git a/frame/support/test/tests/system.rs b/frame/support/test/tests/system.rs index 2996724f625988feab38795dee5d1c046b98b17a..83786538e6961d613d2bf0461b8edc7142f6f339 100644 --- a/frame/support/test/tests/system.rs +++ b/frame/support/test/tests/system.rs @@ -1,4 +1,4 @@ -use support::codec::{Encode, Decode, EncodeLike}; +use frame_support::codec::{Encode, Decode, EncodeLike}; pub trait Trait: 'static + Eq + Clone { type Origin: Into, Self::Origin>> @@ -8,9 +8,10 @@ pub trait Trait: 'static + Eq + Clone { type Hash; type AccountId: Encode + EncodeLike + Decode; type Event: From; + type ModuleToIndex: frame_support::traits::ModuleToIndex; } -support::decl_module! { +frame_support::decl_module! { pub struct Module for enum Call where origin: T::Origin { } } @@ -20,15 +21,15 @@ impl Module { } } -support::decl_event!( +frame_support::decl_event!( pub enum Event { ExtrinsicSuccess, ExtrinsicFailed, } ); -support::decl_error! { - pub enum Error { +frame_support::decl_error! { + pub enum Error for Module { /// Test error documentation TestError, /// Error documentation @@ -38,7 +39,7 @@ support::decl_error! { } /// Origin for the system module. -#[derive(PartialEq, Eq, Clone, sr_primitives::RuntimeDebug)] +#[derive(PartialEq, Eq, Clone, sp_runtime::RuntimeDebug)] pub enum RawOrigin { Root, Signed(AccountId), diff --git a/frame/system/Cargo.toml b/frame/system/Cargo.toml index 9f1019d68846cbeba8e550862d08b60585886f03..227aecee2ee4362cf4973e9ecac991118c87be9a 100644 --- a/frame/system/Cargo.toml +++ b/frame/system/Cargo.toml @@ -8,12 +8,12 @@ edition = "2018" serde = { version = "1.0.101", optional = true, features = ["derive"] } safe-mix = { version = "1.0.0", default-features = false } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -primitives = { package = "substrate-primitives", path = "../../primitives/core", default-features = false } -rstd = { package = "sr-std", path = "../../primitives/sr-std", default-features = false } -runtime-io ={ package = "sr-io", path = "../../primitives/sr-io", default-features = false } -sr-primitives = { path = "../../primitives/sr-primitives", default-features = false } -sr-version = { path = "../../primitives/sr-version", default-features = false } -support = { package = "frame-support", path = "../support", default-features = false } +sp-core = { version = "2.0.0", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0", default-features = false, path = "../../primitives/std" } +sp-io ={ path = "../../primitives/io", default-features = false } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" } +sp-version = { version = "2.0.0", default-features = false, path = "../../primitives/version" } +frame-support = { version = "2.0.0", default-features = false, path = "../support" } impl-trait-for-tuples = "0.1.3" [dev-dependencies] @@ -25,12 +25,12 @@ std = [ "serde", "safe-mix/std", "codec/std", - "primitives/std", - "rstd/std", - "runtime-io/std", - "support/std", - "sr-primitives/std", - "sr-version/std", + "sp-core/std", + "sp-std/std", + "sp-io/std", + "frame-support/std", + "sp-runtime/std", + "sp-version/std", ] [[bench]] diff --git a/frame/system/benches/bench.rs b/frame/system/benches/bench.rs index f42d5f6bd30356cf359abccb50b083a7a1f044a7..21e9dbb0f2a486e8b14d45806ca3a8532139e767 100644 --- a/frame/system/benches/bench.rs +++ b/frame/system/benches/bench.rs @@ -16,9 +16,9 @@ use criterion::{Criterion, criterion_group, criterion_main, black_box}; use frame_system as system; -use support::{decl_module, decl_event, impl_outer_origin, impl_outer_event}; -use primitives::H256; -use sr_primitives::{Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header}; +use frame_support::{decl_module, decl_event, impl_outer_origin, impl_outer_event, weights::Weight}; +use sp_core::H256; +use sp_runtime::{Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header}; mod module { use super::*; @@ -50,9 +50,9 @@ impl_outer_event! { } } -support::parameter_types! { +frame_support::parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: u32 = 4 * 1024 * 1024; + pub const MaximumBlockWeight: Weight = 4 * 1024 * 1024; pub const MaximumBlockLength: u32 = 4 * 1024 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); } @@ -74,13 +74,14 @@ impl system::Trait for Runtime { type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); + type ModuleToIndex = (); } impl module::Trait for Runtime { type Event = Event; } -fn new_test_ext() -> runtime_io::TestExternalities { +fn new_test_ext() -> sp_io::TestExternalities { system::GenesisConfig::default().build_storage::().unwrap().into() } diff --git a/frame/system/rpc/Cargo.toml b/frame/system/rpc/Cargo.toml deleted file mode 100644 index c916287e91def9f71a16740f49990298b8f683bf..0000000000000000000000000000000000000000 --- a/frame/system/rpc/Cargo.toml +++ /dev/null @@ -1,23 +0,0 @@ -[package] -name = "frame-system-rpc" -version = "2.0.0" -authors = ["Parity Technologies "] -edition = "2018" - -[dependencies] -client = { package = "substrate-client", path = "../../../client/" } -codec = { package = "parity-scale-codec", version = "1.0.0" } -jsonrpc-core = "14.0.3" -jsonrpc-core-client = "14.0.3" -jsonrpc-derive = "14.0.3" -log = "0.4.8" -serde = { version = "1.0.101", features = ["derive"] } -sr-primitives = { path = "../../../primitives/sr-primitives" } -frame-system-rpc-runtime-api = { path = "./runtime-api" } -substrate-primitives = { path = "../../../primitives/core" } -transaction_pool = { package = "substrate-transaction-pool", path = "../../../client/transaction-pool" } - -[dev-dependencies] -test-client = { package = "substrate-test-runtime-client", path = "../../../test/utils/runtime/client" } -env_logger = "0.7.0" -futures = "0.3.1" diff --git a/frame/system/rpc/runtime-api/Cargo.toml b/frame/system/rpc/runtime-api/Cargo.toml index dd123cd69d982e3fb7bfb182be4a44caf8ead54f..f9beb848aad36a8ed826aabb844151d029d4115e 100644 --- a/frame/system/rpc/runtime-api/Cargo.toml +++ b/frame/system/rpc/runtime-api/Cargo.toml @@ -5,12 +5,12 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -sr-api = { path = "../../../../primitives/sr-api", default-features = false } -codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false } +sp-api = { version = "2.0.0", default-features = false, path = "../../../../primitives/api" } +codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false } [features] default = ["std"] std = [ - "sr-api/std", + "sp-api/std", "codec/std", ] diff --git a/frame/system/rpc/runtime-api/src/lib.rs b/frame/system/rpc/runtime-api/src/lib.rs index 5c8c64902b0daed08b5af7b6b10f05a1fc3d10aa..c3a9595af102a9fc6827fcc7c811cb2a1c7c64a7 100644 --- a/frame/system/rpc/runtime-api/src/lib.rs +++ b/frame/system/rpc/runtime-api/src/lib.rs @@ -22,7 +22,7 @@ #![cfg_attr(not(feature = "std"), no_std)] -sr_api::decl_runtime_apis! { +sp_api::decl_runtime_apis! { /// The API to query account nonce (aka transaction index). pub trait AccountNonceApi where AccountId: codec::Codec, diff --git a/frame/system/rpc/src/lib.rs b/frame/system/rpc/src/lib.rs deleted file mode 100644 index 10c416c79853caff3f651615bdf5680002dae8f9..0000000000000000000000000000000000000000 --- a/frame/system/rpc/src/lib.rs +++ /dev/null @@ -1,158 +0,0 @@ -// Copyright 2019 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate 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. - -// Substrate 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 Substrate. If not, see . - -//! System SRML specific RPC methods. - -use std::sync::Arc; - -use codec::{self, Codec, Encode}; -use client::blockchain::HeaderBackend; -use jsonrpc_core::{Result, Error, ErrorCode}; -use jsonrpc_derive::rpc; -use sr_primitives::{ - generic::BlockId, - traits, -}; -use substrate_primitives::hexdisplay::HexDisplay; -use transaction_pool::txpool::{self, Pool}; - -pub use frame_system_rpc_runtime_api::AccountNonceApi; -pub use self::gen_client::Client as SystemClient; - -/// System RPC methods. -#[rpc] -pub trait SystemApi { - /// Returns the next valid index (aka nonce) for given account. - /// - /// This method takes into consideration all pending transactions - /// currently in the pool and if no transactions are found in the pool - /// it fallbacks to query the index from the runtime (aka. state nonce). - #[rpc(name = "system_accountNextIndex", alias("account_nextIndex"))] - fn nonce(&self, account: AccountId) -> Result; -} - -const RUNTIME_ERROR: i64 = 1; - -/// An implementation of System-specific RPC methods. -pub struct System { - client: Arc, - pool: Arc>, - _marker: std::marker::PhantomData, -} - -impl System { - /// Create new `System` given client and transaction pool. - pub fn new(client: Arc, pool: Arc>) -> Self { - System { - client, - pool, - _marker: Default::default(), - } - } -} - -impl SystemApi for System -where - C: traits::ProvideRuntimeApi, - C: HeaderBackend, - C: Send + Sync + 'static, - C::Api: AccountNonceApi, - P: txpool::ChainApi + Sync + Send + 'static, - Block: traits::Block, - AccountId: Clone + std::fmt::Display + Codec, - Index: Clone + std::fmt::Display + Codec + traits::SimpleArithmetic, -{ - fn nonce(&self, account: AccountId) -> Result { - let api = self.client.runtime_api(); - let best = self.client.info().best_hash; - let at = BlockId::hash(best); - - let nonce = api.account_nonce(&at, account.clone()).map_err(|e| Error { - code: ErrorCode::ServerError(RUNTIME_ERROR), - message: "Unable to query nonce.".into(), - data: Some(format!("{:?}", e).into()), - })?; - - log::debug!(target: "rpc", "State nonce for {}: {}", account, nonce); - // Now we need to query the transaction pool - // and find transactions originating from the same sender. - // - // Since extrinsics are opaque to us, we look for them using - // `provides` tag. And increment the nonce if we find a transaction - // that matches the current one. - let mut current_nonce = nonce.clone(); - let mut current_tag = (account.clone(), nonce.clone()).encode(); - for tx in self.pool.ready() { - log::debug!( - target: "rpc", - "Current nonce to {}, checking {} vs {:?}", - current_nonce, - HexDisplay::from(¤t_tag), - tx.provides.iter().map(|x| format!("{}", HexDisplay::from(x))).collect::>(), - ); - // since transactions in `ready()` need to be ordered by nonce - // it's fine to continue with current iterator. - if tx.provides.get(0) == Some(¤t_tag) { - current_nonce += traits::One::one(); - current_tag = (account.clone(), current_nonce.clone()).encode(); - } - } - - Ok(current_nonce) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - use futures::executor::block_on; - use test_client::{ - runtime::Transfer, - AccountKeyring, - }; - - #[test] - fn should_return_next_nonce_for_some_account() { - // given - let _ = env_logger::try_init(); - let client = Arc::new(test_client::new()); - let pool = Arc::new(Pool::new(Default::default(), transaction_pool::FullChainApi::new(client.clone()))); - - let new_transaction = |nonce: u64| { - let t = Transfer { - from: AccountKeyring::Alice.into(), - to: AccountKeyring::Bob.into(), - amount: 5, - nonce, - }; - t.into_signed_tx() - }; - // Populate the pool - let ext0 = new_transaction(0); - block_on(pool.submit_one(&BlockId::number(0), ext0)).unwrap(); - let ext1 = new_transaction(1); - block_on(pool.submit_one(&BlockId::number(0), ext1)).unwrap(); - - let accounts = System::new(client, pool); - - // when - let nonce = accounts.nonce(AccountKeyring::Alice.into()); - - // then - assert_eq!(nonce.unwrap(), 2); - } -} diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index 699ff67d2c58c980271789cca22be2f3544a6548..f713811f215106420ad3475c3f2250cd0d6bf671 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -68,14 +68,14 @@ //! ### Example - Get extrinsic count and parent hash for the current block //! //! ``` -//! use support::{decl_module, dispatch::Result}; +//! use frame_support::{decl_module, dispatch}; //! use frame_system::{self as system, ensure_signed}; //! //! pub trait Trait: system::Trait {} //! //! decl_module! { //! pub struct Module for enum Call where origin: T::Origin { -//! pub fn system_module_example(origin) -> Result { +//! pub fn system_module_example(origin) -> dispatch::DispatchResult { //! let _sender = ensure_signed(origin)?; //! let _extrinsic_count = >::extrinsic_count(); //! let _parent_hash = >::parent_hash(); @@ -90,13 +90,13 @@ #[cfg(feature = "std")] use serde::Serialize; -use rstd::prelude::*; +use sp_std::prelude::*; #[cfg(any(feature = "std", test))] -use rstd::map; -use rstd::marker::PhantomData; -use rstd::fmt::Debug; -use sr_version::RuntimeVersion; -use sr_primitives::{ +use sp_std::map; +use sp_std::marker::PhantomData; +use sp_std::fmt::Debug; +use sp_version::RuntimeVersion; +use sp_runtime::{ RuntimeDebug, generic::{self, Era}, Perbill, DispatchOutcome, DispatchError, transaction_validity::{ @@ -105,24 +105,24 @@ use sr_primitives::{ }, traits::{ self, CheckEqual, SimpleArithmetic, Zero, SignedExtension, Lookup, LookupError, - SimpleBitOps, Hash, Member, MaybeDisplay, EnsureOrigin, SaturatedConversion, + SimpleBitOps, Hash, Member, MaybeDisplay, EnsureOrigin, BadOrigin, SaturatedConversion, MaybeSerialize, MaybeSerializeDeserialize, StaticLookup, One, Bounded, }, }; -use primitives::storage::well_known_keys; -use support::{ +use sp_core::storage::well_known_keys; +use frame_support::{ decl_module, decl_event, decl_storage, decl_error, storage, Parameter, - traits::{Contains, Get}, + traits::{Contains, Get, ModuleToIndex}, weights::{Weight, DispatchInfo, DispatchClass, SimpleDispatchInfo}, }; use codec::{Encode, Decode}; #[cfg(any(feature = "std", test))] -use runtime_io::TestExternalities; +use sp_io::TestExternalities; #[cfg(any(feature = "std", test))] -use primitives::ChangesTrieConfiguration; +use sp_core::ChangesTrieConfiguration; pub mod offchain; @@ -172,12 +172,12 @@ pub trait Trait: 'static + Eq + Clone { /// The block number type used by the runtime. type BlockNumber: Parameter + Member + MaybeSerializeDeserialize + Debug + MaybeDisplay + SimpleArithmetic - + Default + Bounded + Copy + rstd::hash::Hash; + + Default + Bounded + Copy + sp_std::hash::Hash + sp_std::str::FromStr; /// The output of the `Hashing` function. type Hash: Parameter + Member + MaybeSerializeDeserialize + Debug + MaybeDisplay + SimpleBitOps - + Default + Copy + CheckEqual + rstd::hash::Hash + AsRef<[u8]> + AsMut<[u8]>; + + Default + Copy + CheckEqual + sp_std::hash::Hash + AsRef<[u8]> + AsMut<[u8]>; /// The hashing system (algorithm) being used in the runtime (e.g. Blake2). type Hashing: Hash; @@ -219,6 +219,12 @@ pub trait Trait: 'static + Eq + Clone { /// Get the chain's current version. type Version: Get; + + /// Convert a module to its index in the runtime. + /// + /// Expects the `ModuleToIndex` type that is being generated by `construct_runtime!` in the + /// runtime. For tests it is okay to use `()` as type (returns `0` for each input). + type ModuleToIndex: ModuleToIndex; } pub type DigestOf = generic::Digest<::Hash>; @@ -229,7 +235,7 @@ pub type KeyValue = (Vec, Vec); decl_module! { pub struct Module for enum Call where origin: T::Origin { - type Error = Error; + type Error = Error; /// A big dispatch that will disallow any other transaction to be included. // TODO: this must be preferable available for testing really (not possible at the moment). @@ -319,11 +325,7 @@ decl_event!( decl_error! { /// Error for the System module - pub enum Error { - RequireSignedOrigin, - RequireRootOrigin, - RequireNoOrigin, - } + pub enum Error for Module {} } /// Origin for the System module. @@ -416,17 +418,17 @@ decl_storage! { } add_extra_genesis { config(changes_trie_config): Option; - #[serde(with = "primitives::bytes")] + #[serde(with = "sp_core::bytes")] config(code): Vec; build(|config: &GenesisConfig| { use codec::Encode; - runtime_io::storage::set(well_known_keys::CODE, &config.code); - runtime_io::storage::set(well_known_keys::EXTRINSIC_INDEX, &0u32.encode()); + sp_io::storage::set(well_known_keys::CODE, &config.code); + sp_io::storage::set(well_known_keys::EXTRINSIC_INDEX, &0u32.encode()); if let Some(ref changes_trie_config) = config.changes_trie_config { - runtime_io::storage::set( + sp_io::storage::set( well_known_keys::CHANGES_TRIE_CONFIG, &changes_trie_config.encode(), ); @@ -435,7 +437,7 @@ decl_storage! { } } -pub struct EnsureRoot(rstd::marker::PhantomData); +pub struct EnsureRoot(sp_std::marker::PhantomData); impl< O: Into, O>> + From>, AccountId, @@ -449,7 +451,7 @@ impl< } } -pub struct EnsureSigned(rstd::marker::PhantomData); +pub struct EnsureSigned(sp_std::marker::PhantomData); impl< O: Into, O>> + From>, AccountId, @@ -463,7 +465,7 @@ impl< } } -pub struct EnsureSignedBy(rstd::marker::PhantomData<(Who, AccountId)>); +pub struct EnsureSignedBy(sp_std::marker::PhantomData<(Who, AccountId)>); impl< O: Into, O>> + From>, Who: Contains, @@ -478,7 +480,7 @@ impl< } } -pub struct EnsureNone(rstd::marker::PhantomData); +pub struct EnsureNone(sp_std::marker::PhantomData); impl< O: Into, O>> + From>, AccountId, @@ -492,7 +494,7 @@ impl< } } -pub struct EnsureNever(rstd::marker::PhantomData); +pub struct EnsureNever(sp_std::marker::PhantomData); impl EnsureOrigin for EnsureNever { type Success = T; fn try_origin(o: O) -> Result { @@ -502,32 +504,32 @@ impl EnsureOrigin for EnsureNever { /// Ensure that the origin `o` represents a signed extrinsic (i.e. transaction). /// Returns `Ok` with the account that signed the extrinsic or an `Err` otherwise. -pub fn ensure_signed(o: OuterOrigin) -> Result +pub fn ensure_signed(o: OuterOrigin) -> Result where OuterOrigin: Into, OuterOrigin>> { match o.into() { Ok(RawOrigin::Signed(t)) => Ok(t), - _ => Err(Error::RequireSignedOrigin), + _ => Err(BadOrigin), } } /// Ensure that the origin `o` represents the root. Returns `Ok` or an `Err` otherwise. -pub fn ensure_root(o: OuterOrigin) -> Result<(), Error> +pub fn ensure_root(o: OuterOrigin) -> Result<(), BadOrigin> where OuterOrigin: Into, OuterOrigin>> { match o.into() { Ok(RawOrigin::Root) => Ok(()), - _ => Err(Error::RequireRootOrigin), + _ => Err(BadOrigin), } } /// Ensure that the origin `o` represents an unsigned extrinsic. Returns `Ok` or an `Err` otherwise. -pub fn ensure_none(o: OuterOrigin) -> Result<(), Error> +pub fn ensure_none(o: OuterOrigin) -> Result<(), BadOrigin> where OuterOrigin: Into, OuterOrigin>> { match o.into() { Ok(RawOrigin::None) => Ok(()), - _ => Err(Error::RequireNoOrigin), + _ => Err(BadOrigin), } } @@ -668,13 +670,17 @@ impl Module { } } - let storage_root = T::Hashing::storage_root(); - let storage_changes_root = T::Hashing::storage_changes_root(parent_hash); + let storage_root = T::Hash::decode(&mut &sp_io::storage::root()[..]) + .expect("Node is configured to use the same hash; qed"); + let storage_changes_root = sp_io::storage::changes_root(&parent_hash.encode()); // we can't compute changes trie root earlier && put it to the Digest // because it will include all currently existing temporaries. if let Some(storage_changes_root) = storage_changes_root { - let item = generic::DigestItem::ChangesTrieRoot(storage_changes_root); + let item = generic::DigestItem::ChangesTrieRoot( + T::Hash::decode(&mut &storage_changes_root[..]) + .expect("Node is configured to use the same hash; qed") + ); digest.push(item); } @@ -699,11 +705,14 @@ impl Module { /// Get the basic externalities for this module, useful for tests. #[cfg(any(feature = "std", test))] pub fn externalities() -> TestExternalities { - TestExternalities::new((map![ - >::hashed_key_for(T::BlockNumber::zero()) => [69u8; 32].encode(), - >::hashed_key().to_vec() => T::BlockNumber::one().encode(), - >::hashed_key().to_vec() => [69u8; 32].encode() - ], map![])) + TestExternalities::new(sp_core::storage::Storage { + top: map![ + >::hashed_key_for(T::BlockNumber::zero()) => [69u8; 32].encode(), + >::hashed_key().to_vec() => T::BlockNumber::one().encode(), + >::hashed_key().to_vec() => [69u8; 32].encode() + ], + children: map![], + }) } /// Set the block number to something in particular. Can be used as an alternative to @@ -855,7 +864,7 @@ impl SignedExtension for CheckWeight { type DispatchInfo = DispatchInfo; type Pre = (); - fn additional_signed(&self) -> rstd::result::Result<(), TransactionValidityError> { Ok(()) } + fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { Ok(()) } fn pre_dispatch( self, @@ -895,12 +904,12 @@ impl SignedExtension for CheckWeight { impl Debug for CheckWeight { #[cfg(feature = "std")] - fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { write!(f, "CheckWeight") } #[cfg(not(feature = "std"))] - fn fmt(&self, _: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { Ok(()) } } @@ -918,12 +927,12 @@ impl CheckNonce { impl Debug for CheckNonce { #[cfg(feature = "std")] - fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { self.0.fmt(f) } #[cfg(not(feature = "std"))] - fn fmt(&self, _: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { Ok(()) } } @@ -935,7 +944,7 @@ impl SignedExtension for CheckNonce { type DispatchInfo = DispatchInfo; type Pre = (); - fn additional_signed(&self) -> rstd::result::Result<(), TransactionValidityError> { Ok(()) } + fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { Ok(()) } fn pre_dispatch( self, @@ -991,23 +1000,23 @@ impl SignedExtension for CheckNonce { /// Check for transaction mortality. #[derive(Encode, Decode, Clone, Eq, PartialEq)] -pub struct CheckEra((Era, rstd::marker::PhantomData)); +pub struct CheckEra((Era, sp_std::marker::PhantomData)); impl CheckEra { /// utility constructor. Used only in client/factory code. pub fn from(era: Era) -> Self { - Self((era, rstd::marker::PhantomData)) + Self((era, sp_std::marker::PhantomData)) } } impl Debug for CheckEra { #[cfg(feature = "std")] - fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { self.0.fmt(f) } #[cfg(not(feature = "std"))] - fn fmt(&self, _: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { Ok(()) } } @@ -1047,16 +1056,16 @@ impl SignedExtension for CheckEra { /// Nonce check and increment to give replay protection for transactions. #[derive(Encode, Decode, Clone, Eq, PartialEq)] -pub struct CheckGenesis(rstd::marker::PhantomData); +pub struct CheckGenesis(sp_std::marker::PhantomData); impl Debug for CheckGenesis { #[cfg(feature = "std")] - fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { write!(f, "CheckGenesis") } #[cfg(not(feature = "std"))] - fn fmt(&self, _: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { Ok(()) } } @@ -1064,7 +1073,7 @@ impl Debug for CheckGenesis { impl CheckGenesis { /// Creates new `SignedExtension` to check genesis hash. pub fn new() -> Self { - Self(rstd::marker::PhantomData) + Self(sp_std::marker::PhantomData) } } @@ -1082,16 +1091,16 @@ impl SignedExtension for CheckGenesis { /// Ensure the runtime version registered in the transaction is the same as at present. #[derive(Encode, Decode, Clone, Eq, PartialEq)] -pub struct CheckVersion(rstd::marker::PhantomData); +pub struct CheckVersion(sp_std::marker::PhantomData); impl Debug for CheckVersion { #[cfg(feature = "std")] - fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { write!(f, "CheckVersion") } #[cfg(not(feature = "std"))] - fn fmt(&self, _: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { Ok(()) } } @@ -1099,7 +1108,7 @@ impl Debug for CheckVersion { impl CheckVersion { /// Create new `SignedExtension` to check runtime version. pub fn new() -> Self { - Self(rstd::marker::PhantomData) + Self(sp_std::marker::PhantomData) } } @@ -1115,10 +1124,10 @@ impl SignedExtension for CheckVersion { } } -pub struct ChainContext(rstd::marker::PhantomData); +pub struct ChainContext(sp_std::marker::PhantomData); impl Default for ChainContext { fn default() -> Self { - ChainContext(rstd::marker::PhantomData) + ChainContext(sp_std::marker::PhantomData) } } @@ -1134,9 +1143,9 @@ impl Lookup for ChainContext { #[cfg(test)] mod tests { use super::*; - use primitives::H256; - use sr_primitives::{traits::{BlakeTwo256, IdentityLookup}, testing::Header, DispatchError}; - use support::{impl_outer_origin, parameter_types}; + use sp_core::H256; + use sp_runtime::{traits::{BlakeTwo256, IdentityLookup}, testing::Header, DispatchError}; + use frame_support::{impl_outer_origin, parameter_types}; impl_outer_origin! { pub enum Origin for Test where system = super {} @@ -1168,6 +1177,7 @@ mod tests { type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; type Version = (); + type ModuleToIndex = (); } impl From for u16 { @@ -1183,7 +1193,7 @@ mod tests { const CALL: &::Call = &(); - fn new_test_ext() -> runtime_io::TestExternalities { + fn new_test_ext() -> sp_io::TestExternalities { GenesisConfig::default().build_storage::().unwrap().into() } @@ -1223,7 +1233,7 @@ mod tests { System::initialize(&2, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default()); System::deposit_event(42u16); System::note_applied_extrinsic(&Ok(()), 0, Default::default()); - System::note_applied_extrinsic(&Err(DispatchError::new(Some(1), 2, None)), 0, Default::default()); + System::note_applied_extrinsic(&Err(DispatchError::BadOrigin), 0, Default::default()); System::note_finished_extrinsics(); System::deposit_event(3u16); System::finalize(); @@ -1413,7 +1423,7 @@ mod tests { fn signed_ext_check_weight_works_operational_tx() { new_test_ext().execute_with(|| { let normal = DispatchInfo { weight: 100, ..Default::default() }; - let op = DispatchInfo { weight: 100, class: DispatchClass::Operational }; + let op = DispatchInfo { weight: 100, class: DispatchClass::Operational, pays_fee: true }; let len = 0_usize; let normal_limit = normal_weight_limit(); @@ -1435,8 +1445,8 @@ mod tests { #[test] fn signed_ext_check_weight_priority_works() { new_test_ext().execute_with(|| { - let normal = DispatchInfo { weight: 100, class: DispatchClass::Normal }; - let op = DispatchInfo { weight: 100, class: DispatchClass::Operational }; + let normal = DispatchInfo { weight: 100, class: DispatchClass::Normal, pays_fee: true }; + let op = DispatchInfo { weight: 100, class: DispatchClass::Operational, pays_fee: true }; let len = 0_usize; let priority = CheckWeight::(PhantomData) @@ -1469,7 +1479,7 @@ mod tests { reset_check_weight(normal, normal_limit + 1, true); // Operational ones don't have this limit. - let op = DispatchInfo { weight: 0, class: DispatchClass::Operational }; + let op = DispatchInfo { weight: 0, class: DispatchClass::Operational, pays_fee: true }; reset_check_weight(op, normal_limit, false); reset_check_weight(op, normal_limit + 100, false); reset_check_weight(op, 1024, false); @@ -1496,7 +1506,7 @@ mod tests { #[test] fn signed_ext_check_era_should_change_longevity() { new_test_ext().execute_with(|| { - let normal = DispatchInfo { weight: 100, class: DispatchClass::Normal }; + let normal = DispatchInfo { weight: 100, class: DispatchClass::Normal, pays_fee: true }; let len = 0_usize; let ext = ( CheckWeight::(PhantomData), diff --git a/frame/system/src/offchain.rs b/frame/system/src/offchain.rs index 9f0a3ab1b2442d90986a4f09e3d5b1b4ae9463a0..32cda26af10c046d6bd16114121531b4c8fe32d5 100644 --- a/frame/system/src/offchain.rs +++ b/frame/system/src/offchain.rs @@ -17,8 +17,8 @@ //! Module helpers for offchain calls. use codec::Encode; -use sr_primitives::app_crypto::{self, RuntimeAppPublic}; -use sr_primitives::traits::{Extrinsic as ExtrinsicT, IdentifyAccount}; +use sp_runtime::app_crypto::{self, RuntimeAppPublic}; +use sp_runtime::traits::{Extrinsic as ExtrinsicT, IdentifyAccount}; /// A trait responsible for signing a payload using given account. pub trait Signer { @@ -41,7 +41,7 @@ impl Signer for AppPublic where Signature: From< <::Signature as app_crypto::AppSignature>::Generic >, - Public: rstd::convert::TryInto<::Generic> + Public: sp_std::convert::TryInto<::Generic> { fn sign(public: Public, raw_payload: &Payload) -> Option { raw_payload.using_encoded(|payload| { @@ -56,7 +56,7 @@ impl Signer for AppPublic where } } -/// Creates runtime-specific signed transaction. +/// Creates a runtime-specific signed transaction. pub trait CreateTransaction { /// A `Public` key representing a particular `AccountId`. type Public: IdentifyAccount + Clone; @@ -111,11 +111,11 @@ pub trait SubmitSignedTransaction { ::create_transaction::(call, public, id, expected) .ok_or(())?; let xt = Self::Extrinsic::new(call, Some(signature_data)).ok_or(())?; - runtime_io::offchain::submit_transaction(xt.encode()) + sp_io::offchain::submit_transaction(xt.encode()) } } -/// A trait to submit unsigned transactions in offchain calls. +/// A trait to submit unsigned transactions in off-chain calls. pub trait SubmitUnsignedTransaction { /// Unchecked extrinsic type. type Extrinsic: ExtrinsicT + codec::Encode; @@ -126,13 +126,13 @@ pub trait SubmitUnsignedTransaction { /// and `Err` if transaction was rejected from the pool. fn submit_unsigned(call: impl Into) -> Result<(), ()> { let xt = Self::Extrinsic::new(call.into(), None).ok_or(())?; - runtime_io::offchain::submit_transaction(xt.encode()) + sp_io::offchain::submit_transaction(xt.encode()) } } /// A default type used to submit transactions to the pool. pub struct TransactionSubmitter { - _signer: rstd::marker::PhantomData<(S, C, E)>, + _signer: sp_std::marker::PhantomData<(S, C, E)>, } impl Default for TransactionSubmitter { diff --git a/frame/timestamp/Cargo.toml b/frame/timestamp/Cargo.toml index 247d219ea8ad8e0c5f04d1fa878a036c0c6b2696..354a4740b712cdaaac7a641e4c268de159cd6efe 100644 --- a/frame/timestamp/Cargo.toml +++ b/frame/timestamp/Cargo.toml @@ -7,27 +7,27 @@ edition = "2018" [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -rstd = { package = "sr-std", path = "../../primitives/sr-std", default-features = false } -sr-primitives = { path = "../../primitives/sr-primitives", default-features = false } -inherents = { package = "substrate-inherents", path = "../../primitives/inherents", default-features = false } -support = { package = "frame-support", path = "../support", default-features = false } -system = { package = "frame-system", path = "../system", default-features = false } -sp-timestamp = { path = "../../primitives/timestamp", default-features = false } +sp-std = { version = "2.0.0", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" } +sp-inherents = { version = "2.0.0", default-features = false, path = "../../primitives/inherents" } +frame-support = { version = "2.0.0", default-features = false, path = "../support" } +frame-system = { version = "2.0.0", default-features = false, path = "../system" } +sp-timestamp = { version = "2.0.0", default-features = false, path = "../../primitives/timestamp" } impl-trait-for-tuples = "0.1.3" [dev-dependencies] -runtime-io ={ package = "sr-io", path = "../../primitives/sr-io" } -primitives = { package = "substrate-primitives", path = "../../primitives/core" } +sp-io ={ version = "2.0.0", path = "../../primitives/io" } +sp-core = { version = "2.0.0", path = "../../primitives/core" } [features] default = ["std"] std = [ - "inherents/std", + "sp-inherents/std", "codec/std", - "rstd/std", - "sr-primitives/std", - "support/std", + "sp-std/std", + "sp-runtime/std", + "frame-support/std", "serde", - "system/std", + "frame-system/std", "sp-timestamp/std" ] diff --git a/frame/timestamp/src/lib.rs b/frame/timestamp/src/lib.rs index 9585f350eb86fcbd40082f3ce78db92859cced45..449e509c23ad68c716346eaced0b506321c53e62 100644 --- a/frame/timestamp/src/lib.rs +++ b/frame/timestamp/src/lib.rs @@ -61,15 +61,15 @@ //! ### Get current timestamp //! //! ``` -//! use support::{decl_module, dispatch::Result}; +//! use frame_support::{decl_module, dispatch}; //! # use pallet_timestamp as timestamp; -//! use system::ensure_signed; +//! use frame_system::{self as system, ensure_signed}; //! //! pub trait Trait: timestamp::Trait {} //! //! decl_module! { //! pub struct Module for enum Call where origin: T::Origin { -//! pub fn get_time(origin) -> Result { +//! pub fn get_time(origin) -> dispatch::DispatchResult { //! let _sender = ensure_signed(origin)?; //! let _now = >::get(); //! Ok(()) @@ -90,25 +90,25 @@ #![cfg_attr(not(feature = "std"), no_std)] -use rstd::{result, cmp}; -use inherents::{ProvideInherent, InherentData, InherentIdentifier}; -use support::{Parameter, decl_storage, decl_module}; -use support::traits::{Time, Get}; -use sr_primitives::{ +use sp_std::{result, cmp}; +use sp_inherents::{ProvideInherent, InherentData, InherentIdentifier}; +use frame_support::{Parameter, decl_storage, decl_module}; +use frame_support::traits::{Time, Get}; +use sp_runtime::{ RuntimeString, traits::{ SimpleArithmetic, Zero, SaturatedConversion, Scale } }; -use support::weights::SimpleDispatchInfo; -use system::ensure_none; +use frame_support::weights::SimpleDispatchInfo; +use frame_system::ensure_none; use sp_timestamp::{ InherentError, INHERENT_IDENTIFIER, InherentType, OnTimestampSet, }; /// The module configuration trait -pub trait Trait: system::Trait { +pub trait Trait: frame_system::Trait { /// Type used for expressing timestamp. type Moment: Parameter + Default + SimpleArithmetic + Scale + Copy; @@ -240,24 +240,24 @@ impl Time for Module { mod tests { use super::*; - use support::{impl_outer_origin, assert_ok, parameter_types}; - use runtime_io::TestExternalities; - use primitives::H256; - use sr_primitives::{Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header}; + use frame_support::{impl_outer_origin, assert_ok, parameter_types, weights::Weight}; + use sp_io::TestExternalities; + use sp_core::H256; + use sp_runtime::{Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header}; impl_outer_origin! { - pub enum Origin for Test {} + pub enum Origin for Test where system = frame_system {} } #[derive(Clone, Eq, PartialEq)] pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockWeight: Weight = 1024; pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } - impl system::Trait for Test { + impl frame_system::Trait for Test { type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -273,6 +273,7 @@ mod tests { type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; type Version = (); + type ModuleToIndex = (); } parameter_types! { pub const MinimumPeriod: u64 = 5; @@ -286,7 +287,7 @@ mod tests { #[test] fn timestamp_works() { - let t = system::GenesisConfig::default().build_storage::().unwrap(); + let t = frame_system::GenesisConfig::default().build_storage::().unwrap(); TestExternalities::new(t).execute_with(|| { Timestamp::set_timestamp(42); assert_ok!(Timestamp::dispatch(Call::set(69), Origin::NONE)); @@ -297,7 +298,7 @@ mod tests { #[test] #[should_panic(expected = "Timestamp must be updated only once in the block")] fn double_timestamp_should_fail() { - let t = system::GenesisConfig::default().build_storage::().unwrap(); + let t = frame_system::GenesisConfig::default().build_storage::().unwrap(); TestExternalities::new(t).execute_with(|| { Timestamp::set_timestamp(42); assert_ok!(Timestamp::dispatch(Call::set(69), Origin::NONE)); @@ -308,7 +309,7 @@ mod tests { #[test] #[should_panic(expected = "Timestamp must increment by at least between sequential blocks")] fn block_period_minimum_enforced() { - let t = system::GenesisConfig::default().build_storage::().unwrap(); + let t = frame_system::GenesisConfig::default().build_storage::().unwrap(); TestExternalities::new(t).execute_with(|| { Timestamp::set_timestamp(42); let _ = Timestamp::dispatch(Call::set(46), Origin::NONE); diff --git a/frame/transaction-payment/Cargo.toml b/frame/transaction-payment/Cargo.toml index 70f0f2643ccd39f42957207323933880eb842462..ceb1ba9ebb586f0824d8b30a8dea8dcf77f6da4a 100644 --- a/frame/transaction-payment/Cargo.toml +++ b/frame/transaction-payment/Cargo.toml @@ -6,24 +6,24 @@ edition = "2018" [dependencies] codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -rstd = { package = "sr-std", path = "../../primitives/sr-std", default-features = false } -sr-primitives = { path = "../../primitives/sr-primitives", default-features = false } -support = { package = "frame-support", path = "../support", default-features = false } -system = { package = "frame-system", path = "../system", default-features = false } -transaction-payment-rpc-runtime-api = { package = "pallet-transaction-payment-rpc-runtime-api", path = "./rpc/runtime-api", default-features = false } +sp-std = { version = "2.0.0", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0", default-features = false, path = "../support" } +frame-system = { version = "2.0.0", default-features = false, path = "../system" } +pallet-transaction-payment-rpc-runtime-api = { version = "2.0.0", default-features = false, path = "./rpc/runtime-api" } [dev-dependencies] -runtime-io = { package = "sr-io", path = "../../primitives/sr-io" } -primitives = { package = "substrate-primitives", path = "../../primitives/core" } -balances = { package = "pallet-balances", path = "../balances" } +sp-io = { version = "2.0.0", path = "../../primitives/io" } +sp-core = { version = "2.0.0", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0", path = "../balances" } [features] default = ["std"] std = [ "codec/std", - "rstd/std", - "sr-primitives/std", - "support/std", - "system/std", - "transaction-payment-rpc-runtime-api/std" + "sp-std/std", + "sp-runtime/std", + "frame-support/std", + "frame-system/std", + "pallet-transaction-payment-rpc-runtime-api/std" ] diff --git a/frame/transaction-payment/rpc/Cargo.toml b/frame/transaction-payment/rpc/Cargo.toml index 92bbda3220b4a90997b54465384e5d0dd64934f1..f7e886fd0df6e144028b93f2a2496f136e069422 100644 --- a/frame/transaction-payment/rpc/Cargo.toml +++ b/frame/transaction-payment/rpc/Cargo.toml @@ -5,13 +5,13 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -client = { package = "substrate-client", path = "../../../client/" } codec = { package = "parity-scale-codec", version = "1.0.0" } jsonrpc-core = "14.0.3" jsonrpc-core-client = "14.0.3" jsonrpc-derive = "14.0.3" -primitives = { package = "substrate-primitives", path = "../../../primitives/core" } -rpc-primitives = { package = "substrate-rpc-primitives", path = "../../../primitives/rpc" } +sp-core = { version = "2.0.0", path = "../../../primitives/core" } +sp-rpc = { version = "2.0.0", path = "../../../primitives/rpc" } serde = { version = "1.0.101", features = ["derive"] } -sr-primitives = { path = "../../../primitives/sr-primitives" } -pallet-transaction-payment-rpc-runtime-api = { path = "./runtime-api" } +sp-runtime = { version = "2.0.0", path = "../../../primitives/runtime" } +sp-blockchain = { version = "2.0.0", path = "../../../primitives/blockchain" } +pallet-transaction-payment-rpc-runtime-api = { version = "2.0.0", path = "./runtime-api" } diff --git a/frame/transaction-payment/rpc/runtime-api/Cargo.toml b/frame/transaction-payment/rpc/runtime-api/Cargo.toml index 008b5bb78c4e2078e65ab0e6d71d3c379f5ad28c..3cf28bf662a249535befe93b4a3dcfbe4935e18f 100644 --- a/frame/transaction-payment/rpc/runtime-api/Cargo.toml +++ b/frame/transaction-payment/rpc/runtime-api/Cargo.toml @@ -6,11 +6,11 @@ edition = "2018" [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } -sr-api = { path = "../../../../primitives/sr-api", default-features = false } +sp-api = { version = "2.0.0", default-features = false, path = "../../../../primitives/api" } codec = { package = "parity-scale-codec", version = "1.0.6", default-features = false, features = ["derive"] } -rstd = { package = "sr-std", path = "../../../../primitives/sr-std", default-features = false } -sr-primitives = { path = "../../../../primitives/sr-primitives", default-features = false } -support = { package = "frame-support", path = "../../../support", default-features = false } +sp-std = { version = "2.0.0", default-features = false, path = "../../../../primitives/std" } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../../../primitives/runtime" } +frame-support = { version = "2.0.0", default-features = false, path = "../../../support" } [dev-dependencies] serde_json = "1.0.41" @@ -19,8 +19,9 @@ serde_json = "1.0.41" default = ["std"] std = [ "serde", - "sr-api/std", + "sp-api/std", "codec/std", - "rstd/std", - "sr-primitives/std", + "sp-std/std", + "sp-runtime/std", + "frame-support/std", ] diff --git a/frame/transaction-payment/rpc/runtime-api/src/lib.rs b/frame/transaction-payment/rpc/runtime-api/src/lib.rs index 755e98a212bd89607c50fae812e2f2c31d9f7bc8..ea2b7c26771db052aa49596401bc8b6ee604f9c5 100644 --- a/frame/transaction-payment/rpc/runtime-api/src/lib.rs +++ b/frame/transaction-payment/rpc/runtime-api/src/lib.rs @@ -18,16 +18,16 @@ #![cfg_attr(not(feature = "std"), no_std)] -use rstd::prelude::*; -use support::weights::{Weight, DispatchClass}; +use sp_std::prelude::*; +use frame_support::weights::{Weight, DispatchClass}; use codec::{Encode, Codec, Decode}; #[cfg(feature = "std")] use serde::{Serialize, Deserialize}; +use sp_runtime::traits::{UniqueSaturatedInto, SaturatedConversion}; /// Some information related to a dispatchable that can be queried from the runtime. #[derive(Eq, PartialEq, Encode, Decode, Default)] -#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] -#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))] +#[cfg_attr(feature = "std", derive(Debug))] pub struct RuntimeDispatchInfo { /// Weight of this dispatch. pub weight: Weight, @@ -38,7 +38,42 @@ pub struct RuntimeDispatchInfo { pub partial_fee: Balance, } -sr_api::decl_runtime_apis! { +/// A capped version of `RuntimeDispatchInfo`. +/// +/// The `Balance` is capped (or expanded) to `u64` to avoid serde issues with `u128`. +#[derive(Eq, PartialEq, Encode, Decode, Default)] +#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] +#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))] +pub struct CappedDispatchInfo { + /// Weight of this dispatch. + pub weight: Weight, + /// Class of this dispatch. + pub class: DispatchClass, + /// The partial inclusion fee of this dispatch. This does not include tip or anything else which + /// is dependent on the signature (aka. depends on a `SignedExtension`). + pub partial_fee: u64, +} + +impl CappedDispatchInfo { + /// Create a new `CappedDispatchInfo` from `RuntimeDispatchInfo`. + pub fn new>( + dispatch: RuntimeDispatchInfo, + ) -> Self { + let RuntimeDispatchInfo { + weight, + class, + partial_fee, + } = dispatch; + + Self { + weight, + class, + partial_fee: partial_fee.saturated_into(), + } + } +} + +sp_api::decl_runtime_apis! { pub trait TransactionPaymentApi where Balance: Codec, Extrinsic: Codec, @@ -59,6 +94,7 @@ mod tests { partial_fee: 1_000_000_u64, }; + let info = CappedDispatchInfo::new(info); assert_eq!( serde_json::to_string(&info).unwrap(), r#"{"weight":5,"class":"normal","partialFee":1000000}"#, diff --git a/frame/transaction-payment/rpc/src/lib.rs b/frame/transaction-payment/rpc/src/lib.rs index 54ec16f032b5699b28ec22a84bc589027f8ca577..e7f4638113fe65a6498b54362920fb8986fe0361 100644 --- a/frame/transaction-payment/rpc/src/lib.rs +++ b/frame/transaction-payment/rpc/src/lib.rs @@ -18,15 +18,15 @@ use std::sync::Arc; use codec::{Codec, Decode}; -use client::blockchain::HeaderBackend; +use sp_blockchain::HeaderBackend; use jsonrpc_core::{Error as RpcError, ErrorCode, Result}; use jsonrpc_derive::rpc; -use sr_primitives::{ +use sp_runtime::{ generic::BlockId, - traits::{Block as BlockT, ProvideRuntimeApi}, + traits::{Block as BlockT, ProvideRuntimeApi, UniqueSaturatedInto}, }; -use primitives::Bytes; -use pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo; +use sp_core::Bytes; +use pallet_transaction_payment_rpc_runtime_api::CappedDispatchInfo; pub use pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi as TransactionPaymentRuntimeApi; pub use self::gen_client::Client as TransactionPaymentClient; @@ -37,7 +37,7 @@ pub trait TransactionPaymentApi { &self, encoded_xt: Bytes, at: Option - ) -> Result>; + ) -> Result; } /// A struct that implements the [`TransactionPaymentApi`]. @@ -78,14 +78,14 @@ where C: ProvideRuntimeApi, C: HeaderBackend, C::Api: TransactionPaymentRuntimeApi, - Balance: Codec, + Balance: Codec + UniqueSaturatedInto, Extrinsic: Codec + Send + Sync + 'static, { fn query_info( &self, encoded_xt: Bytes, at: Option<::Hash> - ) -> Result> { + ) -> Result { let api = self.client.runtime_api(); let at = BlockId::hash(at.unwrap_or_else(|| // If the block hash is not supplied assume the best block. @@ -103,6 +103,6 @@ where code: ErrorCode::ServerError(Error::RuntimeError.into()), message: "Unable to query dispatch info.".into(), data: Some(format!("{:?}", e).into()), - }) + }).map(CappedDispatchInfo::new) } } diff --git a/frame/transaction-payment/src/lib.rs b/frame/transaction-payment/src/lib.rs index c3fa13c0ba869751baa6e2ab8c2b1f9194f58216..60cd5716d5668f3987c12fc0f4c5c5160e1faa4e 100644 --- a/frame/transaction-payment/src/lib.rs +++ b/frame/transaction-payment/src/lib.rs @@ -31,14 +31,14 @@ #![cfg_attr(not(feature = "std"), no_std)] -use rstd::prelude::*; +use sp_std::prelude::*; use codec::{Encode, Decode}; -use support::{ +use frame_support::{ decl_storage, decl_module, traits::{Currency, Get, OnUnbalanced, ExistenceRequirement, WithdrawReason}, weights::{Weight, DispatchInfo, GetDispatchInfo}, }; -use sr_primitives::{ +use sp_runtime::{ Fixed64, transaction_validity::{ TransactionPriority, ValidTransaction, InvalidTransaction, TransactionValidityError, @@ -46,15 +46,15 @@ use sr_primitives::{ }, traits::{Zero, Saturating, SignedExtension, SaturatedConversion, Convert}, }; -use transaction_payment_rpc_runtime_api::RuntimeDispatchInfo; +use pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo; type Multiplier = Fixed64; type BalanceOf = - <::Currency as Currency<::AccountId>>::Balance; + <::Currency as Currency<::AccountId>>::Balance; type NegativeImbalanceOf = - <::Currency as Currency<::AccountId>>::NegativeImbalance; + <::Currency as Currency<::AccountId>>::NegativeImbalance; -pub trait Trait: system::Trait { +pub trait Trait: frame_system::Trait { /// The currency type in which fees will be paid. type Currency: Currency + Send + Sync; @@ -120,7 +120,7 @@ impl Module { let dispatch_info = ::get_dispatch_info(&unchecked_extrinsic); let partial_fee = >::compute_fee(len, dispatch_info, 0u32.into()); - let DispatchInfo { weight, class } = dispatch_info; + let DispatchInfo { weight, class, .. } = dispatch_info; RuntimeDispatchInfo { weight, class, partial_fee } } @@ -140,12 +140,17 @@ impl ChargeTransactionPayment { /// Compute the final fee value for a particular transaction. /// /// The final fee is composed of: - /// - _length-fee_: This is the amount paid merely to pay for size of the transaction. - /// - _weight-fee_: This amount is computed based on the weight of the transaction. Unlike + /// - _base_fee_: This is the minimum amount a user pays for a transaction. + /// - _len_fee_: This is the amount paid merely to pay for size of the transaction. + /// - _weight_fee_: This amount is computed based on the weight of the transaction. Unlike /// size-fee, this is not input dependent and reflects the _complexity_ of the execution /// and the time it consumes. + /// - _targeted_fee_adjustment_: This is a multiplier that can tune the final fee based on + /// the congestion of the network. /// - (optional) _tip_: if included in the transaction, it will be added on top. Only signed /// transactions can have a tip. + /// + /// final_fee = base_fee + targeted_fee_adjustment(len_fee + weight_fee) + tip; fn compute_fee( len: u32, info: ::DispatchInfo, @@ -154,38 +159,41 @@ impl ChargeTransactionPayment { where BalanceOf: Sync + Send, { - let len_fee = if info.pay_length_fee() { + if info.pays_fee { let len = >::from(len); - let base = T::TransactionBaseFee::get(); let per_byte = T::TransactionByteFee::get(); - base.saturating_add(per_byte.saturating_mul(len)) - } else { - Zero::zero() - }; + let len_fee = per_byte.saturating_mul(len); - let weight_fee = { - // cap the weight to the maximum defined in runtime, otherwise it will be the `Bounded` - // maximum of its data type, which is not desired. - let capped_weight = info.weight.min(::MaximumBlockWeight::get()); - T::WeightToFee::convert(capped_weight) - }; + let weight_fee = { + // cap the weight to the maximum defined in runtime, otherwise it will be the `Bounded` + // maximum of its data type, which is not desired. + let capped_weight = info.weight.min(::MaximumBlockWeight::get()); + T::WeightToFee::convert(capped_weight) + }; + + // the adjustable part of the fee + let adjustable_fee = len_fee.saturating_add(weight_fee); + let targeted_fee_adjustment = NextFeeMultiplier::get(); + // adjusted_fee = adjustable_fee + (adjustable_fee * targeted_fee_adjustment) + let adjusted_fee = targeted_fee_adjustment.saturated_multiply_accumulate(adjustable_fee); - // everything except for tip - let basic_fee = len_fee.saturating_add(weight_fee); - let fee_update = NextFeeMultiplier::get(); - let adjusted_fee = fee_update.saturated_multiply_accumulate(basic_fee); + let base_fee = T::TransactionBaseFee::get(); + let final_fee = base_fee.saturating_add(adjusted_fee).saturating_add(tip); - adjusted_fee.saturating_add(tip) + final_fee + } else { + tip + } } } -impl rstd::fmt::Debug for ChargeTransactionPayment { +impl sp_std::fmt::Debug for ChargeTransactionPayment { #[cfg(feature = "std")] - fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { write!(f, "ChargeTransactionPayment<{:?}>", self.0) } #[cfg(not(feature = "std"))] - fn fmt(&self, _: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { Ok(()) } } @@ -198,7 +206,7 @@ impl SignedExtension for ChargeTransactionPayment type AdditionalSigned = (); type DispatchInfo = DispatchInfo; type Pre = (); - fn additional_signed(&self) -> rstd::result::Result<(), TransactionValidityError> { Ok(()) } + fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { Ok(()) } fn validate( &self, @@ -237,44 +245,45 @@ impl SignedExtension for ChargeTransactionPayment mod tests { use super::*; use codec::Encode; - use support::{ + use frame_support::{ parameter_types, impl_outer_origin, impl_outer_dispatch, weights::{DispatchClass, DispatchInfo, GetDispatchInfo, Weight}, }; - use primitives::H256; - use sr_primitives::{ + use sp_core::H256; + use sp_runtime::{ Perbill, testing::{Header, TestXt}, traits::{BlakeTwo256, IdentityLookup, Extrinsic}, }; - use balances::Call as BalancesCall; - use rstd::cell::RefCell; - use transaction_payment_rpc_runtime_api::RuntimeDispatchInfo; + use pallet_balances::Call as BalancesCall; + use sp_std::cell::RefCell; + use pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo; - const CALL: &::Call = &Call::Balances(BalancesCall::transfer(2, 69)); + const CALL: &::Call = &Call::Balances(BalancesCall::transfer(2, 69)); impl_outer_dispatch! { pub enum Call for Runtime where origin: Origin { - balances::Balances, - system::System, + pallet_balances::Balances, + frame_system::System, } } #[derive(Clone, PartialEq, Eq, Debug)] pub struct Runtime; + use frame_system as system; impl_outer_origin!{ pub enum Origin for Runtime {} } parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockWeight: Weight = 1024; pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } - impl system::Trait for Runtime { + impl frame_system::Trait for Runtime { type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -290,6 +299,7 @@ mod tests { type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); + type ModuleToIndex = (); } parameter_types! { @@ -298,7 +308,7 @@ mod tests { pub const ExistentialDeposit: u64 = 0; } - impl balances::Trait for Runtime { + impl pallet_balances::Trait for Runtime { type Balance = u64; type OnFreeBalanceZero = (); type OnNewAccount = (); @@ -334,7 +344,7 @@ mod tests { } impl Trait for Runtime { - type Currency = balances::Module; + type Currency = pallet_balances::Module; type OnTransactionPayment = (); type TransactionBaseFee = TransactionBaseFee; type TransactionByteFee = TransactionByteFee; @@ -342,8 +352,8 @@ mod tests { type FeeMultiplierUpdate = (); } - type Balances = balances::Module; - type System = system::Module; + type Balances = pallet_balances::Module; + type System = frame_system::Module; type TransactionPayment = Module; pub struct ExtBuilder { @@ -380,10 +390,10 @@ mod tests { TRANSACTION_BYTE_FEE.with(|v| *v.borrow_mut() = self.byte_fee); WEIGHT_TO_FEE.with(|v| *v.borrow_mut() = self.weight_to_fee); } - pub fn build(self) -> runtime_io::TestExternalities { + pub fn build(self) -> sp_io::TestExternalities { self.set_constants(); - let mut t = system::GenesisConfig::default().build_storage::().unwrap(); - balances::GenesisConfig:: { + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); + pallet_balances::GenesisConfig:: { balances: vec![ (1, 10 * self.balance_factor), (2, 20 * self.balance_factor), @@ -400,7 +410,7 @@ mod tests { /// create a transaction info struct from weight. Handy to avoid building the whole struct. pub fn info_from_weight(w: Weight) -> DispatchInfo { - DispatchInfo { weight: w, ..Default::default() } + DispatchInfo { weight: w, pays_fee: true, ..Default::default() } } #[test] @@ -445,7 +455,7 @@ mod tests { // fee will be proportional to what is the actual maximum weight in the runtime. assert_eq!( Balances::free_balance(&1), - (10000 - ::MaximumBlockWeight::get()) as u64 + (10000 - ::MaximumBlockWeight::get()) as u64 ); }); } @@ -461,12 +471,14 @@ mod tests { // 1 ain't have a penny. assert_eq!(Balances::free_balance(&1), 0); + let len = 100; + // like a FreeOperational let operational_transaction = DispatchInfo { weight: 0, - class: DispatchClass::Operational + class: DispatchClass::Operational, + pays_fee: false, }; - let len = 100; assert!( ChargeTransactionPayment::::from(0) .validate(&1, CALL, operational_transaction , len) @@ -476,7 +488,8 @@ mod tests { // like a FreeNormal let free_transaction = DispatchInfo { weight: 0, - class: DispatchClass::Normal + class: DispatchClass::Normal, + pays_fee: true, }; assert!( ChargeTransactionPayment::::from(0) @@ -503,7 +516,7 @@ mod tests { .pre_dispatch(&1, CALL, info_from_weight(3), len) .is_ok() ); - assert_eq!(Balances::free_balance(&1), 100 - 10 - (5 + 10 + 3) * 3 / 2); + assert_eq!(Balances::free_balance(&1), 100 - 10 - 5 - (10 + 3) * 3 / 2); }) } @@ -529,16 +542,111 @@ mod tests { RuntimeDispatchInfo { weight: info.weight, class: info.class, - partial_fee: ( + partial_fee: 5 /* base */ - + len as u64 /* len * 1 */ - + info.weight.min(MaximumBlockWeight::get()) as u64 * 2 /* weight * weight_to_fee */ - ) * 3 / 2 + + ( + len as u64 /* len * 1 */ + + info.weight.min(MaximumBlockWeight::get()) as u64 * 2 /* weight * weight_to_fee */ + ) * 3 / 2 }, ); }); } -} + #[test] + fn compute_fee_works_without_multiplier() { + ExtBuilder::default() + .fees(100, 10, 1) + .balance_factor(0) + .build() + .execute_with(|| + { + // Next fee multiplier is zero + assert_eq!(NextFeeMultiplier::get(), Fixed64::from_natural(0)); + + // Tip only, no fees works + let dispatch_info = DispatchInfo { + weight: 0, + class: DispatchClass::Operational, + pays_fee: false, + }; + assert_eq!(ChargeTransactionPayment::::compute_fee(0, dispatch_info, 10), 10); + // No tip, only base fee works + let dispatch_info = DispatchInfo { + weight: 0, + class: DispatchClass::Operational, + pays_fee: true, + }; + assert_eq!(ChargeTransactionPayment::::compute_fee(0, dispatch_info, 0), 100); + // Tip + base fee works + assert_eq!(ChargeTransactionPayment::::compute_fee(0, dispatch_info, 69), 169); + // Len (byte fee) + base fee works + assert_eq!(ChargeTransactionPayment::::compute_fee(42, dispatch_info, 0), 520); + // Weight fee + base fee works + let dispatch_info = DispatchInfo { + weight: 1000, + class: DispatchClass::Operational, + pays_fee: true, + }; + assert_eq!(ChargeTransactionPayment::::compute_fee(0, dispatch_info, 0), 1100); + }); + } + + #[test] + fn compute_fee_works_with_multiplier() { + ExtBuilder::default() + .fees(100, 10, 1) + .balance_factor(0) + .build() + .execute_with(|| + { + // Add a next fee multiplier + NextFeeMultiplier::put(Fixed64::from_rational(1, 2)); // = 1/2 = .5 + // Base fee is unaffected by multiplier + let dispatch_info = DispatchInfo { + weight: 0, + class: DispatchClass::Operational, + pays_fee: true, + }; + assert_eq!(ChargeTransactionPayment::::compute_fee(0, dispatch_info, 0), 100); + // Everything works together :) + let dispatch_info = DispatchInfo { + weight: 123, + class: DispatchClass::Operational, + pays_fee: true, + }; + // 123 weight, 456 length, 100 base + // adjustable fee = (123 * 1) + (456 * 10) = 4683 + // adjusted fee = (4683 * .5) + 4683 = 7024.5 -> 7024 + // final fee = 100 + 7024 + 789 tip = 7913 + assert_eq!(ChargeTransactionPayment::::compute_fee(456, dispatch_info, 789), 7913); + }); + } + + #[test] + fn compute_fee_does_not_overflow() { + ExtBuilder::default() + .fees(100, 10, 1) + .balance_factor(0) + .build() + .execute_with(|| + { + // Overflow is handled + let dispatch_info = DispatchInfo { + weight: ::max_value(), + class: DispatchClass::Operational, + pays_fee: true, + }; + assert_eq!( + ChargeTransactionPayment::::compute_fee( + ::max_value(), + dispatch_info, + ::max_value() + ), + ::max_value() + ); + }); + } +} diff --git a/frame/treasury/Cargo.toml b/frame/treasury/Cargo.toml index a39802840fec2eb0c6a7420f161ea107478adf51..9fd76ddd9cefaa0e126c41a679c125e4cd73dfe3 100644 --- a/frame/treasury/Cargo.toml +++ b/frame/treasury/Cargo.toml @@ -7,24 +7,24 @@ edition = "2018" [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -rstd = { package = "sr-std", path = "../../primitives/sr-std", default-features = false } -sr-primitives = { path = "../../primitives/sr-primitives", default-features = false } -support = { package = "frame-support", path = "../support", default-features = false } -system = { package = "frame-system", path = "../system", default-features = false } -balances = { package = "pallet-balances", path = "../balances", default-features = false } +sp-std = { version = "2.0.0", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0", default-features = false, path = "../support" } +frame-system = { version = "2.0.0", default-features = false, path = "../system" } +pallet-balances = { version = "2.0.0", default-features = false, path = "../balances" } [dev-dependencies] -runtime-io ={ package = "sr-io", path = "../../primitives/sr-io" } -primitives = { package = "substrate-primitives", path = "../../primitives/core" } +sp-io ={ version = "2.0.0", path = "../../primitives/io" } +sp-core = { version = "2.0.0", path = "../../primitives/core" } [features] default = ["std"] std = [ "serde", "codec/std", - "rstd/std", - "sr-primitives/std", - "support/std", - "system/std", - "balances/std", + "sp-std/std", + "sp-runtime/std", + "frame-support/std", + "frame-system/std", + "pallet-balances/std", ] diff --git a/frame/treasury/src/lib.rs b/frame/treasury/src/lib.rs index d71f8731c43dd771a811feb1ef38f65a6a778ce3..ee0e1adc5ee51fa7b5bd1de311821680b0fbf0cc 100644 --- a/frame/treasury/src/lib.rs +++ b/frame/treasury/src/lib.rs @@ -25,7 +25,7 @@ //! ## Overview //! //! The Treasury Module itself provides the pot to store funds, and a means for stakeholders to -//! propose, approve, and deny expendatures. The chain will need to provide a method (e.g. +//! propose, approve, and deny expenditures. The chain will need to provide a method (e.g. //! inflation, fees) for collecting funds. //! //! By way of example, the Council could vote to fund the Treasury with a portion of the block @@ -59,27 +59,25 @@ #[cfg(feature = "std")] use serde::{Serialize, Deserialize}; -use rstd::prelude::*; -use support::{decl_module, decl_storage, decl_event, ensure, print}; -use support::traits::{ +use sp_std::prelude::*; +use frame_support::{decl_module, decl_storage, decl_event, ensure, print, decl_error}; +use frame_support::traits::{ Currency, ExistenceRequirement, Get, Imbalance, OnUnbalanced, ReservableCurrency, WithdrawReason }; -use sr_primitives::{Permill, ModuleId}; -use sr_primitives::traits::{ - Zero, EnsureOrigin, StaticLookup, AccountIdConversion, Saturating -}; -use support::weights::SimpleDispatchInfo; +use sp_runtime::{Permill, ModuleId}; +use sp_runtime::traits::{Zero, EnsureOrigin, StaticLookup, AccountIdConversion, Saturating}; +use frame_support::weights::SimpleDispatchInfo; use codec::{Encode, Decode}; -use system::ensure_signed; +use frame_system::{self as system, ensure_signed}; -type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; -type PositiveImbalanceOf = <::Currency as Currency<::AccountId>>::PositiveImbalance; -type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; +type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +type PositiveImbalanceOf = <::Currency as Currency<::AccountId>>::PositiveImbalance; +type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; const MODULE_ID: ModuleId = ModuleId(*b"py/trsry"); -pub trait Trait: system::Trait { +pub trait Trait: frame_system::Trait { /// The staking balance. type Currency: Currency + ReservableCurrency; @@ -90,7 +88,7 @@ pub trait Trait: system::Trait { type RejectOrigin: EnsureOrigin; /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// Handler for the unbalanced decrease when slashing for a rejected proposal. type ProposalRejection: OnUnbalanced>; @@ -126,7 +124,10 @@ decl_module! { /// Percentage of spare funds (if any) that are burnt per spend period. const Burn: Permill = T::Burn::get(); + type Error = Error; + fn deposit_event() = default; + /// Put forward a suggestion for spending. A deposit proportional to the value /// is reserved and slashed if the proposal is rejected. It is returned once the /// proposal is awarded. @@ -147,7 +148,7 @@ decl_module! { let bond = Self::calculate_bond(value); T::Currency::reserve(&proposer, bond) - .map_err(|_| "Proposer's balance too low")?; + .map_err(|_| Error::::InsufficientProposersBalance)?; let c = Self::proposal_count(); ProposalCount::put(c + 1); @@ -165,8 +166,8 @@ decl_module! { /// # #[weight = SimpleDispatchInfo::FixedOperational(100_000)] fn reject_proposal(origin, #[compact] proposal_id: ProposalIndex) { - T::RejectOrigin::ensure_origin(origin)?; - let proposal = >::take(proposal_id).ok_or("No proposal at that index")?; + T::RejectOrigin::ensure_origin(origin).map_err(|e| Into::<&str>::into(e))?; + let proposal = >::take(proposal_id).ok_or(Error::::InvalidProposalIndex)?; let value = proposal.bond; let imbalance = T::Currency::slash_reserved(&proposal.proposer, value).0; @@ -183,9 +184,9 @@ decl_module! { /// # #[weight = SimpleDispatchInfo::FixedOperational(100_000)] fn approve_proposal(origin, #[compact] proposal_id: ProposalIndex) { - T::ApproveOrigin::ensure_origin(origin)?; + T::ApproveOrigin::ensure_origin(origin).map_err(|e| Into::<&str>::into(e))?; - ensure!(>::exists(proposal_id), "No proposal at that index"); + ensure!(>::exists(proposal_id), Error::::InvalidProposalIndex); Approvals::mutate(|v| v.push(proposal_id)); } @@ -201,7 +202,7 @@ decl_module! { /// A spending proposal. #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -#[derive(Encode, Decode, Clone, PartialEq, Eq, sr_primitives::RuntimeDebug)] +#[derive(Encode, Decode, Clone, PartialEq, Eq, sp_runtime::RuntimeDebug)] pub struct Proposal { proposer: AccountId, value: Balance, @@ -235,7 +236,7 @@ decl_event!( pub enum Event where Balance = BalanceOf, - ::AccountId + ::AccountId { /// New proposal. Proposed(ProposalIndex), @@ -252,6 +253,16 @@ decl_event!( } ); +decl_error! { + /// Error for the treasury module. + pub enum Error for Module { + /// Proposer's balance is too low. + InsufficientProposersBalance, + /// No proposal at that index. + InvalidProposalIndex, + } +} + impl Module { // Add public immutables and private mutables. @@ -351,25 +362,25 @@ impl OnUnbalanced> for Module { mod tests { use super::*; - use support::{assert_noop, assert_ok, impl_outer_origin, parameter_types}; - use primitives::H256; - use sr_primitives::{ + use frame_support::{assert_noop, assert_ok, impl_outer_origin, parameter_types, weights::Weight}; + use sp_core::H256; + use sp_runtime::{ traits::{BlakeTwo256, OnFinalize, IdentityLookup}, testing::Header, Perbill }; impl_outer_origin! { - pub enum Origin for Test {} + pub enum Origin for Test where system = frame_system {} } #[derive(Clone, Eq, PartialEq)] pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockWeight: Weight = 1024; pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } - impl system::Trait for Test { + impl frame_system::Trait for Test { type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -385,13 +396,14 @@ mod tests { type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; type Version = (); + type ModuleToIndex = (); } parameter_types! { pub const ExistentialDeposit: u64 = 1; pub const TransferFee: u64 = 0; pub const CreationFee: u64 = 0; } - impl balances::Trait for Test { + impl pallet_balances::Trait for Test { type Balance = u64; type OnNewAccount = (); type OnFreeBalanceZero = (); @@ -409,9 +421,9 @@ mod tests { pub const Burn: Permill = Permill::from_percent(50); } impl Trait for Test { - type Currency = balances::Module; - type ApproveOrigin = system::EnsureRoot; - type RejectOrigin = system::EnsureRoot; + type Currency = pallet_balances::Module; + type ApproveOrigin = frame_system::EnsureRoot; + type RejectOrigin = frame_system::EnsureRoot; type Event = (); type ProposalRejection = (); type ProposalBond = ProposalBond; @@ -419,12 +431,12 @@ mod tests { type SpendPeriod = SpendPeriod; type Burn = Burn; } - type Balances = balances::Module; + type Balances = pallet_balances::Module; type Treasury = Module; - fn new_test_ext() -> runtime_io::TestExternalities { - let mut t = system::GenesisConfig::default().build_storage::().unwrap(); - balances::GenesisConfig::{ + fn new_test_ext() -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); + pallet_balances::GenesisConfig::{ // Total issuance will be 200 with treasury account initialized at ED. balances: vec![(0, 100), (1, 98), (2, 1)], vesting: vec![], @@ -471,7 +483,10 @@ mod tests { #[test] fn spend_proposal_fails_when_proposer_poor() { new_test_ext().execute_with(|| { - assert_noop!(Treasury::propose_spend(Origin::signed(2), 100, 3), "Proposer's balance too low"); + assert_noop!( + Treasury::propose_spend(Origin::signed(2), 100, 3), + Error::::InsufficientProposersBalance, + ); }); } @@ -523,21 +538,21 @@ mod tests { assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); assert_ok!(Treasury::reject_proposal(Origin::ROOT, 0)); - assert_noop!(Treasury::reject_proposal(Origin::ROOT, 0), "No proposal at that index"); + assert_noop!(Treasury::reject_proposal(Origin::ROOT, 0), Error::::InvalidProposalIndex); }); } #[test] fn reject_non_existant_spend_proposal_fails() { new_test_ext().execute_with(|| { - assert_noop!(Treasury::reject_proposal(Origin::ROOT, 0), "No proposal at that index"); + assert_noop!(Treasury::reject_proposal(Origin::ROOT, 0), Error::::InvalidProposalIndex); }); } #[test] fn accept_non_existant_spend_proposal_fails() { new_test_ext().execute_with(|| { - assert_noop!(Treasury::approve_proposal(Origin::ROOT, 0), "No proposal at that index"); + assert_noop!(Treasury::approve_proposal(Origin::ROOT, 0), Error::::InvalidProposalIndex); }); } @@ -548,7 +563,7 @@ mod tests { assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); assert_ok!(Treasury::reject_proposal(Origin::ROOT, 0)); - assert_noop!(Treasury::approve_proposal(Origin::ROOT, 0), "No proposal at that index"); + assert_noop!(Treasury::approve_proposal(Origin::ROOT, 0), Error::::InvalidProposalIndex); }); } @@ -614,13 +629,13 @@ mod tests { // This is usefull for chain that will just update runtime. #[test] fn inexisting_account_works() { - let mut t = system::GenesisConfig::default().build_storage::().unwrap(); - balances::GenesisConfig::{ + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); + pallet_balances::GenesisConfig::{ balances: vec![(0, 100), (1, 99), (2, 1)], vesting: vec![], }.assimilate_storage(&mut t).unwrap(); // Treasury genesis config is not build thus treasury account does not exist - let mut t: runtime_io::TestExternalities = t.into(); + let mut t: sp_io::TestExternalities = t.into(); t.execute_with(|| { assert_eq!(Balances::free_balance(&Treasury::account_id()), 0); // Account does not exist diff --git a/frame/utility/Cargo.toml b/frame/utility/Cargo.toml index c6f5db29f9dc99be6f7a920e15fc4e5418a79174..f74e059e369719d6fe47f96a06e41b22e07c7b68 100644 --- a/frame/utility/Cargo.toml +++ b/frame/utility/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "frame-utility" +name = "pallet-utility" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" @@ -7,24 +7,24 @@ edition = "2018" [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false } -support = { package = "frame-support", path = "../support", default-features = false } -system = { package = "frame-system", path = "../system", default-features = false } -sr-primitives = { path = "../../primitives/sr-primitives", default-features = false } -rstd = { package = "sr-std", path = "../../primitives/sr-std", default-features = false } -runtime-io = { package = "sr-io", path = "../../primitives/sr-io", default-features = false } +frame-support = { version = "2.0.0", default-features = false, path = "../support" } +frame-system = { version = "2.0.0", default-features = false, path = "../system" } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0", default-features = false, path = "../../primitives/io" } [dev-dependencies] -primitives = { package = "substrate-primitives", path = "../../primitives/core" } -balances = { package = "pallet-balances", path = "../balances" } +sp-core = { version = "2.0.0", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0", path = "../balances" } [features] default = ["std"] std = [ "serde", "codec/std", - "sr-primitives/std", - "support/std", - "system/std", - "runtime-io/std", - "rstd/std" + "sp-runtime/std", + "frame-support/std", + "frame-system/std", + "sp-io/std", + "sp-std/std" ] diff --git a/frame/utility/src/lib.rs b/frame/utility/src/lib.rs index ae5a4bd6cbc39f98474b7b2004afacbeee4f4b42..7f8552c4022730c46b4e6a440371c6fbc499c064 100644 --- a/frame/utility/src/lib.rs +++ b/frame/utility/src/lib.rs @@ -20,15 +20,15 @@ // Ensure we're `no_std` when compiling for Wasm. #![cfg_attr(not(feature = "std"), no_std)] -use rstd::prelude::*; -use support::{decl_module, decl_event, Parameter, weights::SimpleDispatchInfo}; -use system::ensure_root; -use sr_primitives::{traits::Dispatchable, DispatchError}; +use sp_std::prelude::*; +use frame_support::{decl_module, decl_event, Parameter, weights::SimpleDispatchInfo}; +use frame_system::{self as system, ensure_root}; +use sp_runtime::{traits::Dispatchable, DispatchError}; /// Configuration trait. -pub trait Trait: system::Trait { +pub trait Trait: frame_system::Trait { /// The overarching event type. - type Event: From + Into<::Event>; + type Event: From + Into<::Event>; /// The overarching call type. type Call: Parameter + Dispatchable; @@ -51,7 +51,7 @@ decl_module! { fn batch(origin, calls: Vec<::Call>) { ensure_root(origin)?; let results = calls.into_iter() - .map(|call| call.dispatch(system::RawOrigin::Root.into())) + .map(|call| call.dispatch(frame_system::RawOrigin::Root.into())) .map(|res| res.map_err(Into::into)) .collect::>(); Self::deposit_event(Event::BatchExecuted(results)); @@ -63,17 +63,20 @@ decl_module! { mod tests { use super::*; - use support::{assert_ok, assert_noop, impl_outer_origin, parameter_types, impl_outer_dispatch}; - use primitives::H256; - use sr_primitives::{Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header}; + use frame_support::{ + assert_ok, assert_noop, impl_outer_origin, parameter_types, impl_outer_dispatch, + weights::Weight + }; + use sp_core::H256; + use sp_runtime::{Perbill, traits::{BlakeTwo256, IdentityLookup, BadOrigin}, testing::Header}; impl_outer_origin! { - pub enum Origin for Test {} + pub enum Origin for Test where system = frame_system {} } impl_outer_dispatch! { pub enum Call for Test where origin: Origin { - balances::Balances, + pallet_balances::Balances, utility::Utility, } } @@ -85,11 +88,11 @@ mod tests { pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: u32 = 1024; + pub const MaximumBlockWeight: Weight = 1024; pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } - impl system::Trait for Test { + impl frame_system::Trait for Test { type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -105,13 +108,14 @@ mod tests { type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); + type ModuleToIndex = (); } parameter_types! { pub const ExistentialDeposit: u64 = 0; pub const TransferFee: u64 = 0; pub const CreationFee: u64 = 0; } - impl balances::Trait for Test { + impl pallet_balances::Trait for Test { type Balance = u64; type OnFreeBalanceZero = (); type OnNewAccount = (); @@ -126,12 +130,12 @@ mod tests { type Event = (); type Call = Call; } - type Balances = balances::Module; + type Balances = pallet_balances::Module; type Utility = Module; - fn new_test_ext() -> runtime_io::TestExternalities { - let mut t = system::GenesisConfig::default().build_storage::().unwrap(); - balances::GenesisConfig:: { + fn new_test_ext() -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); + pallet_balances::GenesisConfig:: { balances: vec![(1, 10), (2, 0)], vesting: vec![], }.assimilate_storage(&mut t).unwrap(); @@ -143,13 +147,16 @@ mod tests { new_test_ext().execute_with(|| { assert_eq!(Balances::free_balance(1), 10); assert_eq!(Balances::free_balance(2), 0); - assert_noop!(Utility::batch(Origin::signed(1), vec![ - Call::Balances(balances::Call::force_transfer(1, 2, 5)), - Call::Balances(balances::Call::force_transfer(1, 2, 5)) - ]), "RequireRootOrigin"); + assert_noop!( + Utility::batch(Origin::signed(1), vec![ + Call::Balances(pallet_balances::Call::force_transfer(1, 2, 5)), + Call::Balances(pallet_balances::Call::force_transfer(1, 2, 5)) + ]), + BadOrigin, + ); assert_ok!(Utility::batch(Origin::ROOT, vec![ - Call::Balances(balances::Call::force_transfer(1, 2, 5)), - Call::Balances(balances::Call::force_transfer(1, 2, 5)) + Call::Balances(pallet_balances::Call::force_transfer(1, 2, 5)), + Call::Balances(pallet_balances::Call::force_transfer(1, 2, 5)) ])); assert_eq!(Balances::free_balance(1), 0); assert_eq!(Balances::free_balance(2), 10); diff --git a/primitives/api/Cargo.toml b/primitives/api/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..5085e8faf3ff3bf94d9d1de2708a98f6f7e45616 --- /dev/null +++ b/primitives/api/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "sp-api" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false } +sp-api-proc-macro = { version = "2.0.0", path = "proc-macro" } +sp-core = { version = "2.0.0", default-features = false, path = "../core" } +sp-std = { version = "2.0.0", default-features = false, path = "../std" } +sp-runtime = { version = "2.0.0", default-features = false, path = "../runtime" } +sp-version = { version = "2.0.0", default-features = false, path = "../version" } +sp-state-machine = { version = "2.0.0", optional = true, path = "../../primitives/state-machine" } + +[dev-dependencies] +sp-test-primitives = { version = "2.0.0", path = "../test-primitives" } + +[features] +default = [ "std" ] +std = [ + "codec/std", + "sp-core/std", + "sp-std/std", + "sp-runtime/std", + "sp-state-machine", + "sp-version/std", +] diff --git a/primitives/api/proc-macro/Cargo.toml b/primitives/api/proc-macro/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..122c889add49988c0bdd0198bc46e79222d9b1c2 --- /dev/null +++ b/primitives/api/proc-macro/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "sp-api-proc-macro" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[lib] +proc-macro = true + +[dependencies] +quote = "1.0.2" +syn = { version = "1.0.8", features = ["full", "fold", "extra-traits", "visit"] } +proc-macro2 = "1.0.6" +blake2-rfc = "0.2.18" +proc-macro-crate = "0.1.4" + +# Required for the doc tests +[features] +default = [ "std" ] +std = [] diff --git a/primitives/sr-api/proc-macro/src/decl_runtime_apis.rs b/primitives/api/proc-macro/src/decl_runtime_apis.rs similarity index 100% rename from primitives/sr-api/proc-macro/src/decl_runtime_apis.rs rename to primitives/api/proc-macro/src/decl_runtime_apis.rs diff --git a/primitives/sr-api/proc-macro/src/impl_runtime_apis.rs b/primitives/api/proc-macro/src/impl_runtime_apis.rs similarity index 100% rename from primitives/sr-api/proc-macro/src/impl_runtime_apis.rs rename to primitives/api/proc-macro/src/impl_runtime_apis.rs diff --git a/primitives/api/proc-macro/src/lib.rs b/primitives/api/proc-macro/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..30b1c26945681747aff1ccfa9ed541368feb8a5c --- /dev/null +++ b/primitives/api/proc-macro/src/lib.rs @@ -0,0 +1,36 @@ +// Copyright 2018-2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Macros for declaring and implementing runtime apis. + +#![recursion_limit = "512"] +extern crate proc_macro; + +use proc_macro::TokenStream; + +mod impl_runtime_apis; +mod decl_runtime_apis; +mod utils; + +#[proc_macro] +pub fn impl_runtime_apis(input: TokenStream) -> TokenStream { + impl_runtime_apis::impl_runtime_apis_impl(input) +} + +#[proc_macro] +pub fn decl_runtime_apis(input: TokenStream) -> TokenStream { + decl_runtime_apis::decl_runtime_apis_impl(input) +} diff --git a/primitives/sr-api/proc-macro/src/utils.rs b/primitives/api/proc-macro/src/utils.rs similarity index 93% rename from primitives/sr-api/proc-macro/src/utils.rs rename to primitives/api/proc-macro/src/utils.rs index a46397be1b8490dcc1f87b9064aaa598707cd093..afa414264125f55ce3a93af366e78c0c1be6f4d1 100644 --- a/primitives/sr-api/proc-macro/src/utils.rs +++ b/primitives/api/proc-macro/src/utils.rs @@ -32,22 +32,22 @@ pub fn unwrap_or_error(res: Result) -> TokenStream { } fn generate_hidden_includes_mod_name(unique_id: &'static str) -> Ident { - Ident::new(&format!("sr_api_hidden_includes_{}", unique_id), Span::call_site()) + Ident::new(&format!("sp_api_hidden_includes_{}", unique_id), Span::call_site()) } /// Generates the hidden includes that are required to make the macro independent from its scope. pub fn generate_hidden_includes(unique_id: &'static str) -> TokenStream { - if env::var("CARGO_PKG_NAME").unwrap() == "sr-api" { + if env::var("CARGO_PKG_NAME").unwrap() == "sp-api" { TokenStream::new() } else { let mod_name = generate_hidden_includes_mod_name(unique_id); - match crate_name("sr-api") { + match crate_name("sp-api") { Ok(client_name) => { let client_name = Ident::new(&client_name, Span::call_site()); quote!( #[doc(hidden)] mod #mod_name { - pub extern crate #client_name as sr_api; + pub extern crate #client_name as sp_api; } ) }, @@ -60,13 +60,13 @@ pub fn generate_hidden_includes(unique_id: &'static str) -> TokenStream { }.into() } -/// Generates the access to the `substrate_client` crate. +/// Generates the access to the `sc_client` crate. pub fn generate_crate_access(unique_id: &'static str) -> TokenStream { - if env::var("CARGO_PKG_NAME").unwrap() == "sr-api" { - quote!( crate ) + if env::var("CARGO_PKG_NAME").unwrap() == "sp-api" { + quote!( sp_api ) } else { let mod_name = generate_hidden_includes_mod_name(unique_id); - quote!( self::#mod_name::sr_api ) + quote!( self::#mod_name::sp_api ) }.into() } diff --git a/primitives/sr-api/src/lib.rs b/primitives/api/src/lib.rs similarity index 50% rename from primitives/sr-api/src/lib.rs rename to primitives/api/src/lib.rs index 4a5cbf513f13ebdc8957f0c3231e4a92ea7005b6..b655cf093960e6834e0554fe561a8ecaea411ec4 100644 --- a/primitives/sr-api/src/lib.rs +++ b/primitives/api/src/lib.rs @@ -30,17 +30,20 @@ #![cfg_attr(not(feature = "std"), no_std)] +// Make doc tests happy +extern crate self as sp_api; + #[doc(hidden)] #[cfg(feature = "std")] -pub use state_machine::{OverlayedChanges, StorageProof}; +pub use sp_state_machine::{OverlayedChanges, StorageProof}; #[doc(hidden)] #[cfg(feature = "std")] -pub use primitives::NativeOrEncoded; +pub use sp_core::NativeOrEncoded; #[doc(hidden)] #[cfg(not(feature = "std"))] -pub use primitives::to_substrate_wasm_fn_return_value; +pub use sp_core::to_substrate_wasm_fn_return_value; #[doc(hidden)] -pub use sr_primitives::{ +pub use sp_runtime::{ traits::{ Block as BlockT, GetNodeBlockType, GetRuntimeBlockType, Header as HeaderT, ApiRef, RuntimeApiInfo, Hash as HashT, @@ -48,24 +51,179 @@ pub use sr_primitives::{ generic::BlockId, transaction_validity::TransactionValidity, }; #[doc(hidden)] -pub use primitives::{offchain, ExecutionContext}; +pub use sp_core::{offchain, ExecutionContext}; #[doc(hidden)] -pub use sr_version::{ApiId, RuntimeVersion, ApisVec, create_apis_vec}; +pub use sp_version::{ApiId, RuntimeVersion, ApisVec, create_apis_vec}; #[doc(hidden)] -pub use rstd::{slice, mem}; +pub use sp_std::{slice, mem}; #[cfg(feature = "std")] -use rstd::result; +use sp_std::result; #[doc(hidden)] pub use codec::{Encode, Decode}; -use primitives::OpaqueMetadata; +use sp_core::OpaqueMetadata; #[cfg(feature = "std")] use std::{panic::UnwindSafe, cell::RefCell}; -pub use sr_api_proc_macro::{decl_runtime_apis, impl_runtime_apis}; +/// Declares given traits as runtime apis. +/// +/// The macro will create two declarations, one for using on the client side and one for using +/// on the runtime side. The declaration for the runtime side is hidden in its own module. +/// The client side declaration gets two extra parameters per function, +/// `&self` and `at: &BlockId`. The runtime side declaration will match the given trait +/// declaration. Besides one exception, the macro adds an extra generic parameter `Block: BlockT` +/// to the client side and the runtime side. This generic parameter is usable by the user. +/// +/// For implementing these macros you should use the `impl_runtime_apis!` macro. +/// +/// # Example +/// +/// ```rust +/// sp_api::decl_runtime_apis! { +/// /// Declare the api trait. +/// pub trait Balance { +/// /// Get the balance. +/// fn get_balance() -> u64; +/// /// Set the balance. +/// fn set_balance(val: u64); +/// } +/// +/// /// You can declare multiple api traits in one macro call. +/// /// In one module you can call the macro at maximum one time. +/// pub trait BlockBuilder { +/// /// The macro adds an explicit `Block: BlockT` generic parameter for you. +/// /// You can use this generic parameter as you would defined it manually. +/// fn build_block() -> Block; +/// } +/// } +/// +/// # fn main() {} +/// ``` +/// +/// # Runtime api trait versioning +/// +/// To support versioning of the traits, the macro supports the attribute `#[api_version(1)]`. +/// The attribute supports any `u32` as version. By default, each trait is at version `1`, if no +/// version is provided. We also support changing the signature of a method. This signature +/// change is highlighted with the `#[changed_in(2)]` attribute above a method. A method that is +/// tagged with this attribute is callable by the name `METHOD_before_version_VERSION`. This +/// method will only support calling into wasm, trying to call into native will fail (change the +/// spec version!). Such a method also does not need to be implemented in the runtime. +/// +/// ```rust +/// sp_api::decl_runtime_apis! { +/// /// Declare the api trait. +/// #[api_version(2)] +/// pub trait Balance { +/// /// Get the balance. +/// fn get_balance() -> u64; +/// /// Set balance. +/// fn set_balance(val: u64); +/// /// Set balance, old version. +/// /// +/// /// Is callable by `set_balance_before_version_2`. +/// #[changed_in(2)] +/// fn set_balance(val: u16); +/// /// In version 2, we added this new function. +/// fn increase_balance(val: u64); +/// } +/// } +/// +/// # fn main() {} +/// ``` +/// +/// To check if a given runtime implements a runtime api trait, the `RuntimeVersion` has the +/// function `has_api()`. Also the `ApiExt` provides a function `has_api(at: &BlockId)` to +/// check if the runtime at the given block id implements the requested runtime api trait. +pub use sp_api_proc_macro::decl_runtime_apis; + +/// Tags given trait implementations as runtime apis. +/// +/// All traits given to this macro, need to be declared with the `decl_runtime_apis!` macro. +/// The implementation of the trait should follow the declaration given to the `decl_runtime_apis!` +/// macro, besides the `Block` type that is required as first generic parameter for each runtime +/// api trait. When implementing a runtime api trait, it is required that the trait is referenced +/// by a path, e.g. `impl my_trait::MyTrait for Runtime`. The macro will use this path to access +/// the declaration of the trait for the runtime side. +/// +/// The macro also generates the api implementations for the client side and provides it through +/// the `RuntimeApi` type. The `RuntimeApi` is hidden behind a `feature` called `std`. +/// +/// To expose version information about all implemented api traits, the constant +/// `RUNTIME_API_VERSIONS` is generated. This constant should be used to instantiate the `apis` +/// field of `RuntimeVersion`. +/// +/// # Example +/// +/// ```rust +/// use sp_version::create_runtime_str; +/// # +/// # use sp_runtime::traits::GetNodeBlockType; +/// # use sp_test_primitives::{Block, Header}; +/// # +/// # /// The declaration of the `Runtime` type and the implementation of the `GetNodeBlockType` +/// # /// trait are done by the `construct_runtime!` macro in a real runtime. +/// # pub struct Runtime {} +/// # impl GetNodeBlockType for Runtime { +/// # type NodeBlock = Block; +/// # } +/// # +/// # sp_api::decl_runtime_apis! { +/// # /// Declare the api trait. +/// # pub trait Balance { +/// # /// Get the balance. +/// # fn get_balance() -> u64; +/// # /// Set the balance. +/// # fn set_balance(val: u64); +/// # } +/// # pub trait BlockBuilder { +/// # fn build_block() -> Block; +/// # } +/// # } +/// +/// /// All runtime api implementations need to be done in one call of the macro! +/// sp_api::impl_runtime_apis! { +/// # impl sp_api::Core for Runtime { +/// # fn version() -> sp_version::RuntimeVersion { +/// # unimplemented!() +/// # } +/// # fn execute_block(_block: Block) {} +/// # fn initialize_block(_header: &Header) {} +/// # } +/// +/// impl self::Balance for Runtime { +/// fn get_balance() -> u64 { +/// 1 +/// } +/// fn set_balance(_bal: u64) { +/// // Store the balance +/// } +/// } +/// +/// impl self::BlockBuilder for Runtime { +/// fn build_block() -> Block { +/// unimplemented!("Please implement me!") +/// } +/// } +/// } +/// +/// /// Runtime version. This needs to be declared for each runtime. +/// pub const VERSION: sp_version::RuntimeVersion = sp_version::RuntimeVersion { +/// spec_name: create_runtime_str!("node"), +/// impl_name: create_runtime_str!("test-node"), +/// authoring_version: 1, +/// spec_version: 1, +/// impl_version: 0, +/// // Here we are exposing the runtime api versions. +/// apis: RUNTIME_API_VERSIONS, +/// }; +/// +/// # fn main() {} +/// ``` +pub use sp_api_proc_macro::impl_runtime_apis; #[cfg(feature = "std")] /// A type that records all accessed trie nodes and generates a proof out of it. -pub type ProofRecorder = state_machine::ProofRecorder< +pub type ProofRecorder = sp_state_machine::ProofRecorder< <<::Header as HeaderT>::Hashing as HashT>::Hasher >; @@ -176,7 +334,7 @@ pub trait CallRuntimeAt { /// Extracts the `Api::Error` for a type that provides a runtime api. #[cfg(feature = "std")] pub type ApiErrorFor = < - ::Api as ApiExt + ::Api as ApiExt >::Error; decl_runtime_apis! { diff --git a/primitives/api/test/Cargo.toml b/primitives/api/test/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..f1f0dfb50f12b501a21a4a409c632585db1e3158 --- /dev/null +++ b/primitives/api/test/Cargo.toml @@ -0,0 +1,30 @@ +[package] +name = "sp-api-test" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +sp-api = { version = "2.0.0", path = "../" } +substrate-test-runtime-client = { version = "2.0.0", path = "../../../test-utils/runtime/client" } +sp-version = { version = "2.0.0", path = "../../version" } +sp-runtime = { version = "2.0.0", path = "../../runtime" } +sp-blockchain = { version = "2.0.0", path = "../../blockchain" } +sp-consensus = { version = "0.8", path = "../../../primitives/consensus/common" } +codec = { package = "parity-scale-codec", version = "1.0.0" } +sp-state-machine = { version = "2.0.0", path = "../../../primitives/state-machine" } +trybuild = "1.0.17" +rustversion = "1.0.0" + +[dev-dependencies] +criterion = "0.3.0" +substrate-test-runtime-client = { version = "2.0.0", path = "../../../test-utils/runtime/client" } + +[[bench]] +name = "bench" +harness = false + +# We only need this to generate the correct code. +[features] +default = [ "std" ] +std = [] diff --git a/primitives/sr-api/benches/bench.rs b/primitives/api/test/benches/bench.rs similarity index 85% rename from primitives/sr-api/benches/bench.rs rename to primitives/api/test/benches/bench.rs index 49c8e1e3804159f77623a37ec02a1c5ba7d1c515..9b418340972aeb8d9b1b8def5b5a41bdd8cf5c9a 100644 --- a/primitives/sr-api/benches/bench.rs +++ b/primitives/api/test/benches/bench.rs @@ -15,16 +15,16 @@ // along with Substrate. If not, see . use criterion::{Criterion, criterion_group, criterion_main}; -use test_client::{ +use substrate_test_runtime_client::{ DefaultTestClientBuilderExt, TestClientBuilder, TestClientBuilderExt, runtime::TestAPI, }; -use sr_primitives::{generic::BlockId, traits::ProvideRuntimeApi}; -use state_machine::ExecutionStrategy; +use sp_runtime::{generic::BlockId, traits::ProvideRuntimeApi}; +use sp_state_machine::ExecutionStrategy; -fn sr_api_benchmark(c: &mut Criterion) { +fn sp_api_benchmark(c: &mut Criterion) { c.bench_function("add one with same runtime api", |b| { - let client = test_client::new(); + let client = substrate_test_runtime_client::new(); let runtime_api = client.runtime_api(); let block_id = BlockId::Number(client.info().chain.best_number); @@ -32,14 +32,14 @@ fn sr_api_benchmark(c: &mut Criterion) { }); c.bench_function("add one with recreating runtime api", |b| { - let client = test_client::new(); + let client = substrate_test_runtime_client::new(); let block_id = BlockId::Number(client.info().chain.best_number); b.iter(|| client.runtime_api().benchmark_add_one(&block_id, &1)) }); c.bench_function("vector add one with same runtime api", |b| { - let client = test_client::new(); + let client = substrate_test_runtime_client::new(); let runtime_api = client.runtime_api(); let block_id = BlockId::Number(client.info().chain.best_number); let data = vec![0; 1000]; @@ -48,7 +48,7 @@ fn sr_api_benchmark(c: &mut Criterion) { }); c.bench_function("vector add one with recreating runtime api", |b| { - let client = test_client::new(); + let client = substrate_test_runtime_client::new(); let block_id = BlockId::Number(client.info().chain.best_number); let data = vec![0; 1000]; @@ -68,5 +68,5 @@ fn sr_api_benchmark(c: &mut Criterion) { }); } -criterion_group!(benches, sr_api_benchmark); +criterion_group!(benches, sp_api_benchmark); criterion_main!(benches); diff --git a/primitives/sr-api/test/tests/decl_and_impl.rs b/primitives/api/test/tests/decl_and_impl.rs similarity index 85% rename from primitives/sr-api/test/tests/decl_and_impl.rs rename to primitives/api/test/tests/decl_and_impl.rs index 91863e186521f34d9556f697957f0641c8dc2bca..b25c8c2710d1d6e0e2dbd7826f7441d2ca4507c0 100644 --- a/primitives/sr-api/test/tests/decl_and_impl.rs +++ b/primitives/api/test/tests/decl_and_impl.rs @@ -14,11 +14,12 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use sr_api::{RuntimeApiInfo, decl_runtime_apis, impl_runtime_apis}; +use sp_api::{RuntimeApiInfo, decl_runtime_apis, impl_runtime_apis}; -use sr_primitives::{traits::{GetNodeBlockType, Block as BlockT}, generic::BlockId}; +use sp_runtime::{traits::{GetNodeBlockType, Block as BlockT}, generic::BlockId}; -use test_client::{client::error::Result, runtime::Block}; +use substrate_test_runtime_client::runtime::Block; +use sp_blockchain::Result; /// The declaration of the `Runtime` type and the implementation of the `GetNodeBlockType` /// trait are done by the `construct_runtime!` macro in a real runtime. @@ -67,8 +68,8 @@ impl_runtime_apis! { fn same_name() {} } - impl sr_api::Core for Runtime { - fn version() -> sr_version::RuntimeVersion { + impl sp_api::Core for Runtime { + fn version() -> sp_version::RuntimeVersion { unimplemented!() } fn execute_block(_: Block) { @@ -80,8 +81,11 @@ impl_runtime_apis! { } } -type TestClient = test_client::client::Client< - test_client::Backend, test_client::Executor, Block, RuntimeApi +type TestClient = substrate_test_runtime_client::sc_client::Client< + substrate_test_runtime_client::Backend, + substrate_test_runtime_client::Executor, + Block, + RuntimeApi, >; #[test] @@ -123,5 +127,5 @@ fn check_runtime_api_versions_contains() { fn check_runtime_api_versions() { check_runtime_api_versions_contains::>(); check_runtime_api_versions_contains::>(); - check_runtime_api_versions_contains::>(); + check_runtime_api_versions_contains::>(); } diff --git a/primitives/sr-api/test/tests/runtime_calls.rs b/primitives/api/test/tests/runtime_calls.rs similarity index 98% rename from primitives/sr-api/test/tests/runtime_calls.rs rename to primitives/api/test/tests/runtime_calls.rs index ce6300bc4128287e893b47ec4492ce331341619a..34184c936a2ba2a17a5e96fe44204528b5240914 100644 --- a/primitives/sr-api/test/tests/runtime_calls.rs +++ b/primitives/api/test/tests/runtime_calls.rs @@ -14,21 +14,21 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use test_client::{ +use substrate_test_runtime_client::{ prelude::*, DefaultTestClientBuilderExt, TestClientBuilder, runtime::{TestAPI, DecodeFails, Transfer, Header}, }; -use sr_primitives::{ +use sp_runtime::{ generic::BlockId, traits::{ProvideRuntimeApi, Header as HeaderT, Hash as HashT}, }; -use state_machine::{ +use sp_state_machine::{ ExecutionStrategy, create_proof_check_backend, execution_proof_check_on_trie_backend, }; -use consensus_common::SelectChain; +use sp_consensus::SelectChain; use codec::Encode; fn calling_function_with_strat(strat: ExecutionStrategy) { @@ -193,6 +193,5 @@ fn record_proof_works() { &executor, "Core_execute_block", &block.encode(), - None, ).expect("Executes block while using the proof backend"); } diff --git a/primitives/sr-api/test/tests/trybuild.rs b/primitives/api/test/tests/trybuild.rs similarity index 100% rename from primitives/sr-api/test/tests/trybuild.rs rename to primitives/api/test/tests/trybuild.rs diff --git a/primitives/sr-api/test/tests/ui/adding_self_parameter.rs b/primitives/api/test/tests/ui/adding_self_parameter.rs similarity index 65% rename from primitives/sr-api/test/tests/ui/adding_self_parameter.rs rename to primitives/api/test/tests/ui/adding_self_parameter.rs index 9195598b5a437ff7909018191576eba978cde2e8..117fa261886b9f0a740081d5d5b913a26a3d4fd2 100644 --- a/primitives/sr-api/test/tests/ui/adding_self_parameter.rs +++ b/primitives/api/test/tests/ui/adding_self_parameter.rs @@ -1,4 +1,4 @@ -sr_api::decl_runtime_apis! { +sp_api::decl_runtime_apis! { pub trait Api { fn test(&self); } diff --git a/primitives/sr-api/test/tests/ui/adding_self_parameter.stderr b/primitives/api/test/tests/ui/adding_self_parameter.stderr similarity index 100% rename from primitives/sr-api/test/tests/ui/adding_self_parameter.stderr rename to primitives/api/test/tests/ui/adding_self_parameter.stderr diff --git a/primitives/sr-api/test/tests/ui/changed_in_unknown_version.rs b/primitives/api/test/tests/ui/changed_in_unknown_version.rs similarity index 73% rename from primitives/sr-api/test/tests/ui/changed_in_unknown_version.rs rename to primitives/api/test/tests/ui/changed_in_unknown_version.rs index 1fcb5d4be1e5a1553126a384c1109016e1dc03c8..151f3e5f4d637a4497c2e829b1890762adb08e03 100644 --- a/primitives/sr-api/test/tests/ui/changed_in_unknown_version.rs +++ b/primitives/api/test/tests/ui/changed_in_unknown_version.rs @@ -1,5 +1,5 @@ -use sr_primitives::traits::GetNodeBlockType; -use test_client::runtime::Block; +use sp_runtime::traits::GetNodeBlockType; +use substrate_test_runtime_client::runtime::Block; /// The declaration of the `Runtime` type and the implementation of the `GetNodeBlockType` /// trait are done by the `construct_runtime!` macro in a real runtime. @@ -8,7 +8,7 @@ impl GetNodeBlockType for Runtime { type NodeBlock = Block; } -sr_api::decl_runtime_apis! { +sp_api::decl_runtime_apis! { pub trait Api { #[changed_in(2)] fn test(data: u64); diff --git a/primitives/sr-api/test/tests/ui/changed_in_unknown_version.stderr b/primitives/api/test/tests/ui/changed_in_unknown_version.stderr similarity index 100% rename from primitives/sr-api/test/tests/ui/changed_in_unknown_version.stderr rename to primitives/api/test/tests/ui/changed_in_unknown_version.stderr diff --git a/primitives/api/test/tests/ui/declaring_old_block.rs b/primitives/api/test/tests/ui/declaring_old_block.rs new file mode 100644 index 0000000000000000000000000000000000000000..ba98bf9bf688317b4a8d6dd940b61112fba82485 --- /dev/null +++ b/primitives/api/test/tests/ui/declaring_old_block.rs @@ -0,0 +1,9 @@ +use sp_runtime::traits::Block as BlockT; + +sp_api::decl_runtime_apis! { + pub trait Api { + fn test(); + } +} + +fn main() {} diff --git a/primitives/sr-api/test/tests/ui/declaring_old_block.stderr b/primitives/api/test/tests/ui/declaring_old_block.stderr similarity index 79% rename from primitives/sr-api/test/tests/ui/declaring_old_block.stderr rename to primitives/api/test/tests/ui/declaring_old_block.stderr index e27294692b3e095f5a0b0251c63099a60fc81051..373e669c7849a4896cf97788c512035308a35b15 100644 --- a/primitives/sr-api/test/tests/ui/declaring_old_block.stderr +++ b/primitives/api/test/tests/ui/declaring_old_block.stderr @@ -10,10 +10,10 @@ error: `Block: BlockT` generic parameter will be added automatically by the `dec 4 | pub trait Api { | ^^^^^^ -warning: unused import: `sr_primitives::traits::Block as BlockT` +warning: unused import: `sp_runtime::traits::Block as BlockT` --> $DIR/declaring_old_block.rs:1:5 | -1 | use sr_primitives::traits::Block as BlockT; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +1 | use sp_runtime::traits::Block as BlockT; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `#[warn(unused_imports)]` on by default diff --git a/primitives/api/test/tests/ui/declaring_own_block_with_different_name.rs b/primitives/api/test/tests/ui/declaring_own_block_with_different_name.rs new file mode 100644 index 0000000000000000000000000000000000000000..67bb9cab10502cc7ef33fe9106d95221547a9a99 --- /dev/null +++ b/primitives/api/test/tests/ui/declaring_own_block_with_different_name.rs @@ -0,0 +1,9 @@ +use sp_runtime::traits::Block as BlockT; + +sp_api::decl_runtime_apis! { + pub trait Api { + fn test(); + } +} + +fn main() {} diff --git a/primitives/sr-api/test/tests/ui/declaring_own_block_with_different_name.stderr b/primitives/api/test/tests/ui/declaring_own_block_with_different_name.stderr similarity index 73% rename from primitives/sr-api/test/tests/ui/declaring_own_block_with_different_name.stderr rename to primitives/api/test/tests/ui/declaring_own_block_with_different_name.stderr index 88359f19afc72a5ab4db074454fcc21e2813e46e..fe445b822dd88a25e340beb75fc834a5ff85febf 100644 --- a/primitives/sr-api/test/tests/ui/declaring_own_block_with_different_name.stderr +++ b/primitives/api/test/tests/ui/declaring_own_block_with_different_name.stderr @@ -4,10 +4,10 @@ error: `Block: BlockT` generic parameter will be added automatically by the `dec 4 | pub trait Api { | ^^^^^^ -warning: unused import: `sr_primitives::traits::Block as BlockT` +warning: unused import: `sp_runtime::traits::Block as BlockT` --> $DIR/declaring_own_block_with_different_name.rs:1:5 | -1 | use sr_primitives::traits::Block as BlockT; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +1 | use sp_runtime::traits::Block as BlockT; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `#[warn(unused_imports)]` on by default diff --git a/primitives/sr-api/test/tests/ui/empty_impl_runtime_apis_call.rs b/primitives/api/test/tests/ui/empty_impl_runtime_apis_call.rs similarity index 66% rename from primitives/sr-api/test/tests/ui/empty_impl_runtime_apis_call.rs rename to primitives/api/test/tests/ui/empty_impl_runtime_apis_call.rs index fee4e475e39aaa95e10a1665acca9c7d56cde739..93343fb72ab5d28bc33fb17ff6973747f02465ba 100644 --- a/primitives/sr-api/test/tests/ui/empty_impl_runtime_apis_call.rs +++ b/primitives/api/test/tests/ui/empty_impl_runtime_apis_call.rs @@ -1,5 +1,5 @@ -use sr_primitives::traits::GetNodeBlockType; -use test_client::runtime::Block; +use sp_runtime::traits::GetNodeBlockType; +use substrate_test_runtime_client::runtime::Block; /// The declaration of the `Runtime` type and the implementation of the `GetNodeBlockType` /// trait are done by the `construct_runtime!` macro in a real runtime. @@ -8,12 +8,12 @@ impl GetNodeBlockType for Runtime { type NodeBlock = Block; } -sr_api::decl_runtime_apis! { +sp_api::decl_runtime_apis! { pub trait Api { fn test(data: u64); } } -sr_api::impl_runtime_apis! {} +sp_api::impl_runtime_apis! {} fn main() {} diff --git a/primitives/sr-api/test/tests/ui/empty_impl_runtime_apis_call.stderr b/primitives/api/test/tests/ui/empty_impl_runtime_apis_call.stderr similarity index 80% rename from primitives/sr-api/test/tests/ui/empty_impl_runtime_apis_call.stderr rename to primitives/api/test/tests/ui/empty_impl_runtime_apis_call.stderr index e7bf3b8563f931fdeb9b16b6fa781aee9a919c1a..f927912879ad037b448c24d3193679432a43d9f0 100644 --- a/primitives/sr-api/test/tests/ui/empty_impl_runtime_apis_call.stderr +++ b/primitives/api/test/tests/ui/empty_impl_runtime_apis_call.stderr @@ -1,5 +1,5 @@ error: No api implementation given! --> $DIR/empty_impl_runtime_apis_call.rs:17:1 | -17 | sr_api::impl_runtime_apis! {} +17 | sp_api::impl_runtime_apis! {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation diff --git a/primitives/sr-api/test/tests/ui/impl_incorrect_method_signature.rs b/primitives/api/test/tests/ui/impl_incorrect_method_signature.rs similarity index 73% rename from primitives/sr-api/test/tests/ui/impl_incorrect_method_signature.rs rename to primitives/api/test/tests/ui/impl_incorrect_method_signature.rs index 08c3ce8320fb50869cf47ff419bca6f11c4dba8f..e4eba99d9e87a724f7fafb16dcf2161fd6d79687 100644 --- a/primitives/sr-api/test/tests/ui/impl_incorrect_method_signature.rs +++ b/primitives/api/test/tests/ui/impl_incorrect_method_signature.rs @@ -1,5 +1,5 @@ -use sr_primitives::traits::{GetNodeBlockType, Block as BlockT}; -use test_client::runtime::Block; +use sp_runtime::traits::{GetNodeBlockType, Block as BlockT}; +use substrate_test_runtime_client::runtime::Block; /// The declaration of the `Runtime` type and the implementation of the `GetNodeBlockType` /// trait are done by the `construct_runtime!` macro in a real runtime. @@ -8,18 +8,18 @@ impl GetNodeBlockType for Runtime { type NodeBlock = Block; } -sr_api::decl_runtime_apis! { +sp_api::decl_runtime_apis! { pub trait Api { fn test(data: u64); } } -sr_api::impl_runtime_apis! { +sp_api::impl_runtime_apis! { impl self::Api for Runtime { fn test(data: String) {} } - impl sr_api::Core for Runtime { + impl sp_api::Core for Runtime { fn version() -> runtime_api::RuntimeVersion { unimplemented!() } diff --git a/primitives/sr-api/test/tests/ui/impl_incorrect_method_signature.stderr b/primitives/api/test/tests/ui/impl_incorrect_method_signature.stderr similarity index 58% rename from primitives/sr-api/test/tests/ui/impl_incorrect_method_signature.stderr rename to primitives/api/test/tests/ui/impl_incorrect_method_signature.stderr index 2bf8da343fe6bbd65bdbff6ba4c3419ada0c01d4..d55e686a114ca9b0c13e6023a136441096f57389 100644 --- a/primitives/sr-api/test/tests/ui/impl_incorrect_method_signature.stderr +++ b/primitives/api/test/tests/ui/impl_incorrect_method_signature.stderr @@ -19,14 +19,14 @@ error[E0053]: method `test` has an incompatible type for trait error[E0053]: method `Api_test_runtime_api_impl` has an incompatible type for trait --> $DIR/impl_incorrect_method_signature.rs:17:1 | -11 | / sr_api::decl_runtime_apis! { +11 | / sp_api::decl_runtime_apis! { 12 | | pub trait Api { 13 | | fn test(data: u64); 14 | | } 15 | | } | |_- type in trait 16 | -17 | sr_api::impl_runtime_apis! { +17 | sp_api::impl_runtime_apis! { | -^^^^^^^^^^^^^^^^^^^^^^^^^ | | | _expected u64, found struct `std::string::String` @@ -39,13 +39,13 @@ error[E0053]: method `Api_test_runtime_api_impl` has an incompatible type for tr 33 | | } | |_- in this macro invocation | - = note: expected type `fn(&RuntimeApiImpl, &sr_api_hidden_includes_DECL_RUNTIME_APIS::sr_api::BlockId, substrate_test_runtime::Extrinsic>>, sr_api_hidden_includes_DECL_RUNTIME_APIS::sr_api::ExecutionContext, std::option::Option, std::vec::Vec) -> std::result::Result, , substrate_test_runtime::Extrinsic>>>::Error>` - found type `fn(&RuntimeApiImpl, &sr_api_hidden_includes_DECL_RUNTIME_APIS::sr_api::BlockId, substrate_test_runtime::Extrinsic>>, sr_api_hidden_includes_DECL_RUNTIME_APIS::sr_api::ExecutionContext, std::option::Option, std::vec::Vec) -> std::result::Result, , substrate_test_runtime::Extrinsic>>>::Error>` + = note: expected type `fn(&RuntimeApiImpl, &sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::BlockId, substrate_test_runtime::Extrinsic>>, sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::ExecutionContext, std::option::Option, std::vec::Vec) -> std::result::Result, , substrate_test_runtime::Extrinsic>>>::Error>` + found type `fn(&RuntimeApiImpl, &sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::BlockId, substrate_test_runtime::Extrinsic>>, sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::ExecutionContext, std::option::Option, std::vec::Vec) -> std::result::Result, , substrate_test_runtime::Extrinsic>>>::Error>` error[E0308]: mismatched types --> $DIR/impl_incorrect_method_signature.rs:17:1 | -17 | / sr_api::impl_runtime_apis! { +17 | / sp_api::impl_runtime_apis! { 18 | | impl self::Api for Runtime { 19 | | fn test(data: String) {} 20 | | } diff --git a/primitives/sr-api/test/tests/ui/impl_two_traits_with_same_name.rs b/primitives/api/test/tests/ui/impl_two_traits_with_same_name.rs similarity index 78% rename from primitives/sr-api/test/tests/ui/impl_two_traits_with_same_name.rs rename to primitives/api/test/tests/ui/impl_two_traits_with_same_name.rs index 6aee0ec6c2bb4596621df8ae76be2b3b4eca56ef..9c01dc0e92cabbddc83e3742831ff0f510e242cd 100644 --- a/primitives/sr-api/test/tests/ui/impl_two_traits_with_same_name.rs +++ b/primitives/api/test/tests/ui/impl_two_traits_with_same_name.rs @@ -1,5 +1,5 @@ -use sr_primitives::traits::GetNodeBlockType; -use test_client::runtime::Block; +use sp_runtime::traits::GetNodeBlockType; +use substrate_test_runtime_client::runtime::Block; /// The declaration of the `Runtime` type and the implementation of the `GetNodeBlockType` /// trait are done by the `construct_runtime!` macro in a real runtime. @@ -8,7 +8,7 @@ impl GetNodeBlockType for Runtime { type NodeBlock = Block; } -sr_api::decl_runtime_apis! { +sp_api::decl_runtime_apis! { pub trait Api { fn test(data: u64); } @@ -24,7 +24,7 @@ mod second { } } -sr_api::impl_runtime_apis! { +sp_api::impl_runtime_apis! { impl self::Api for Runtime { fn test(data: u64) {} } diff --git a/primitives/sr-api/test/tests/ui/impl_two_traits_with_same_name.stderr b/primitives/api/test/tests/ui/impl_two_traits_with_same_name.stderr similarity index 81% rename from primitives/sr-api/test/tests/ui/impl_two_traits_with_same_name.stderr rename to primitives/api/test/tests/ui/impl_two_traits_with_same_name.stderr index 9aa38805b940f628f35ca6c15fae825fd183b9d3..cc267aaee091b08729540050614c78f86bf38380 100644 --- a/primitives/sr-api/test/tests/ui/impl_two_traits_with_same_name.stderr +++ b/primitives/api/test/tests/ui/impl_two_traits_with_same_name.stderr @@ -13,7 +13,7 @@ error: cannot find macro `decl_runtime_apis` in this scope error[E0425]: cannot find function `test2_call_api_at` in `second::runtime_decl_for_Api` --> $DIR/impl_two_traits_with_same_name.rs:27:1 | -27 | / sr_api::impl_runtime_apis! { +27 | / sp_api::impl_runtime_apis! { 28 | | impl self::Api for Runtime { 29 | | fn test(data: u64) {} 30 | | } @@ -28,7 +28,7 @@ error[E0425]: cannot find function `test2_call_api_at` in `second::runtime_decl_ error[E0425]: cannot find function `test2_native_call_generator` in `second::runtime_decl_for_Api` --> $DIR/impl_two_traits_with_same_name.rs:27:1 | -27 | / sr_api::impl_runtime_apis! { +27 | / sp_api::impl_runtime_apis! { 28 | | impl self::Api for Runtime { 29 | | fn test(data: u64) {} 30 | | } @@ -49,7 +49,7 @@ error[E0576]: cannot find method or associated constant `test2` in `second::runt error[E0603]: module `runtime_decl_for_Api` is private --> $DIR/impl_two_traits_with_same_name.rs:27:1 | -27 | / sr_api::impl_runtime_apis! { +27 | / sp_api::impl_runtime_apis! { 28 | | impl self::Api for Runtime { 29 | | fn test(data: u64) {} 30 | | } @@ -58,7 +58,7 @@ error[E0603]: module `runtime_decl_for_Api` is private 35 | | } | |_^ -error[E0119]: conflicting implementations of trait `runtime_decl_for_Api::Api, substrate_test_runtime::Extrinsic>>` for type `Runtime`: +error[E0119]: conflicting implementations of trait `runtime_decl_for_Api::Api, substrate_test_runtime::Extrinsic>>` for type `Runtime`: --> $DIR/impl_two_traits_with_same_name.rs:32:2 | 28 | impl self::Api for Runtime { @@ -67,7 +67,7 @@ error[E0119]: conflicting implementations of trait `runtime_decl_for_Api::Api for Runtime { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Runtime` -error[E0119]: conflicting implementations of trait `Api, substrate_test_runtime::Extrinsic>>` for type `RuntimeApiImpl<_>`: +error[E0119]: conflicting implementations of trait `Api, substrate_test_runtime::Extrinsic>>` for type `RuntimeApiImpl<_>`: --> $DIR/impl_two_traits_with_same_name.rs:32:2 | 28 | impl self::Api for Runtime { diff --git a/primitives/sr-api/test/tests/ui/invalid_api_version.rs b/primitives/api/test/tests/ui/invalid_api_version.rs similarity index 71% rename from primitives/sr-api/test/tests/ui/invalid_api_version.rs rename to primitives/api/test/tests/ui/invalid_api_version.rs index 0b7f5e88ff74bf4da6c8173845e79d7da62b6502..e038dd0aa6585b03c30e39a9383dd58fecef0dac 100644 --- a/primitives/sr-api/test/tests/ui/invalid_api_version.rs +++ b/primitives/api/test/tests/ui/invalid_api_version.rs @@ -1,4 +1,4 @@ -sr_api::decl_runtime_apis! { +sp_api::decl_runtime_apis! { #[api_version] pub trait Api { fn test(data: u64); diff --git a/primitives/sr-api/test/tests/ui/invalid_api_version.stderr b/primitives/api/test/tests/ui/invalid_api_version.stderr similarity index 91% rename from primitives/sr-api/test/tests/ui/invalid_api_version.stderr rename to primitives/api/test/tests/ui/invalid_api_version.stderr index 7e63eb8ebf8a4491cbec297ddf15d79d585ffed2..6d0bb8d9f34cfdc5e1730cea1549d968b4a099f7 100644 --- a/primitives/sr-api/test/tests/ui/invalid_api_version.stderr +++ b/primitives/api/test/tests/ui/invalid_api_version.stderr @@ -1,7 +1,7 @@ error: can't qualify macro invocation with `pub` --> $DIR/invalid_api_version.rs:1:1 | -1 | / sr_api::decl_runtime_apis! { +1 | / sp_api::decl_runtime_apis! { 2 | | #[api_version] 3 | | pub trait Api { 4 | | fn test(data: u64); @@ -16,7 +16,7 @@ error: can't qualify macro invocation with `pub` error: Unexpected `api_version` attribute. The supported format is `api_version(1)` --> $DIR/invalid_api_version.rs:1:1 | -1 | / sr_api::decl_runtime_apis! { +1 | / sp_api::decl_runtime_apis! { 2 | | #[api_version] 3 | | pub trait Api { 4 | | fn test(data: u64); diff --git a/primitives/sr-api/test/tests/ui/invalid_api_version_2.rs b/primitives/api/test/tests/ui/invalid_api_version_2.rs similarity index 73% rename from primitives/sr-api/test/tests/ui/invalid_api_version_2.rs rename to primitives/api/test/tests/ui/invalid_api_version_2.rs index 4e29d36e1ba2fd3f946eeb18a30adf664e6b8715..bb8ed8ed11fea503c931f433c784a182987c320b 100644 --- a/primitives/sr-api/test/tests/ui/invalid_api_version_2.rs +++ b/primitives/api/test/tests/ui/invalid_api_version_2.rs @@ -1,4 +1,4 @@ -sr_api::decl_runtime_apis! { +sp_api::decl_runtime_apis! { #[api_version("1")] pub trait Api { fn test(data: u64); diff --git a/primitives/sr-api/test/tests/ui/invalid_api_version_2.stderr b/primitives/api/test/tests/ui/invalid_api_version_2.stderr similarity index 91% rename from primitives/sr-api/test/tests/ui/invalid_api_version_2.stderr rename to primitives/api/test/tests/ui/invalid_api_version_2.stderr index e080b2dd1a0d6a75021e7e76b3fb8537eb618073..60d33bff41094789a12aa7a54cedf6cd57c1326e 100644 --- a/primitives/sr-api/test/tests/ui/invalid_api_version_2.stderr +++ b/primitives/api/test/tests/ui/invalid_api_version_2.stderr @@ -1,7 +1,7 @@ error: can't qualify macro invocation with `pub` --> $DIR/invalid_api_version_2.rs:1:1 | -1 | / sr_api::decl_runtime_apis! { +1 | / sp_api::decl_runtime_apis! { 2 | | #[api_version("1")] 3 | | pub trait Api { 4 | | fn test(data: u64); @@ -16,7 +16,7 @@ error: can't qualify macro invocation with `pub` error: Unexpected `api_version` attribute. The supported format is `api_version(1)` --> $DIR/invalid_api_version_2.rs:1:1 | -1 | / sr_api::decl_runtime_apis! { +1 | / sp_api::decl_runtime_apis! { 2 | | #[api_version("1")] 3 | | pub trait Api { 4 | | fn test(data: u64); diff --git a/primitives/sr-api/test/tests/ui/invalid_api_version_3.rs b/primitives/api/test/tests/ui/invalid_api_version_3.rs similarity index 72% rename from primitives/sr-api/test/tests/ui/invalid_api_version_3.rs rename to primitives/api/test/tests/ui/invalid_api_version_3.rs index bafe566840d2554afef3eb83ab42780980c7f1ea..d010866e23731dc737e6cdd810b45b0bba3b5d34 100644 --- a/primitives/sr-api/test/tests/ui/invalid_api_version_3.rs +++ b/primitives/api/test/tests/ui/invalid_api_version_3.rs @@ -1,4 +1,4 @@ -sr_api::decl_runtime_apis! { +sp_api::decl_runtime_apis! { #[api_version()] pub trait Api { fn test(data: u64); diff --git a/primitives/sr-api/test/tests/ui/invalid_api_version_3.stderr b/primitives/api/test/tests/ui/invalid_api_version_3.stderr similarity index 91% rename from primitives/sr-api/test/tests/ui/invalid_api_version_3.stderr rename to primitives/api/test/tests/ui/invalid_api_version_3.stderr index fd6e15852f74bacdc01c9d543a1150a3841f4bee..c2b64657ffda2496eea3c879d1618d38fb7c3ec1 100644 --- a/primitives/sr-api/test/tests/ui/invalid_api_version_3.stderr +++ b/primitives/api/test/tests/ui/invalid_api_version_3.stderr @@ -1,7 +1,7 @@ error: can't qualify macro invocation with `pub` --> $DIR/invalid_api_version_3.rs:1:1 | -1 | / sr_api::decl_runtime_apis! { +1 | / sp_api::decl_runtime_apis! { 2 | | #[api_version()] 3 | | pub trait Api { 4 | | fn test(data: u64); @@ -16,7 +16,7 @@ error: can't qualify macro invocation with `pub` error: Unexpected `api_version` attribute. The supported format is `api_version(1)` --> $DIR/invalid_api_version_3.rs:1:1 | -1 | / sr_api::decl_runtime_apis! { +1 | / sp_api::decl_runtime_apis! { 2 | | #[api_version()] 3 | | pub trait Api { 4 | | fn test(data: u64); diff --git a/primitives/sr-api/test/tests/ui/missing_block_generic_parameter.rs b/primitives/api/test/tests/ui/missing_block_generic_parameter.rs similarity index 71% rename from primitives/sr-api/test/tests/ui/missing_block_generic_parameter.rs rename to primitives/api/test/tests/ui/missing_block_generic_parameter.rs index d35253a7219a4f0653fffc04b6f8c5267812d23e..e194fdbf4ab65a5cdaee8e879852f14933911ffe 100644 --- a/primitives/sr-api/test/tests/ui/missing_block_generic_parameter.rs +++ b/primitives/api/test/tests/ui/missing_block_generic_parameter.rs @@ -1,5 +1,5 @@ -use sr_primitives::traits::GetNodeBlockType; -use test_client::runtime::Block; +use sp_runtime::traits::GetNodeBlockType; +use substrate_test_runtime_client::runtime::Block; /// The declaration of the `Runtime` type and the implementation of the `GetNodeBlockType` /// trait are done by the `construct_runtime!` macro in a real runtime. @@ -8,13 +8,13 @@ impl GetNodeBlockType for Runtime { type NodeBlock = Block; } -sr_api::decl_runtime_apis! { +sp_api::decl_runtime_apis! { pub trait Api { fn test(data: u64); } } -sr_api::impl_runtime_apis! { +sp_api::impl_runtime_apis! { impl self::Api for Runtime { fn test(data: u64) { unimplemented!() diff --git a/primitives/sr-api/test/tests/ui/missing_block_generic_parameter.stderr b/primitives/api/test/tests/ui/missing_block_generic_parameter.stderr similarity index 100% rename from primitives/sr-api/test/tests/ui/missing_block_generic_parameter.stderr rename to primitives/api/test/tests/ui/missing_block_generic_parameter.stderr diff --git a/primitives/sr-api/test/tests/ui/missing_path_for_trait.rs b/primitives/api/test/tests/ui/missing_path_for_trait.rs similarity index 71% rename from primitives/sr-api/test/tests/ui/missing_path_for_trait.rs rename to primitives/api/test/tests/ui/missing_path_for_trait.rs index fb78374ebdf7052f6484e51214071dea965c76ab..d7540ce88a8a192c24899b1e4b0dc93f3b2a9ca7 100644 --- a/primitives/sr-api/test/tests/ui/missing_path_for_trait.rs +++ b/primitives/api/test/tests/ui/missing_path_for_trait.rs @@ -1,5 +1,5 @@ -use sr_primitives::traits::GetNodeBlockType; -use test_client::runtime::Block; +use sp_runtime::traits::GetNodeBlockType; +use substrate_test_runtime_client::runtime::Block; /// The declaration of the `Runtime` type and the implementation of the `GetNodeBlockType` /// trait are done by the `construct_runtime!` macro in a real runtime. @@ -8,13 +8,13 @@ impl GetNodeBlockType for Runtime { type NodeBlock = Block; } -sr_api::decl_runtime_apis! { +sp_api::decl_runtime_apis! { pub trait Api { fn test(data: u64); } } -sr_api::impl_runtime_apis! { +sp_api::impl_runtime_apis! { impl Api for Runtime { fn test(data: u64) { unimplemented!() diff --git a/primitives/sr-api/test/tests/ui/missing_path_for_trait.stderr b/primitives/api/test/tests/ui/missing_path_for_trait.stderr similarity index 100% rename from primitives/sr-api/test/tests/ui/missing_path_for_trait.stderr rename to primitives/api/test/tests/ui/missing_path_for_trait.stderr diff --git a/primitives/sr-api/test/tests/ui/type_reference_in_impl_runtime_apis_call.rs b/primitives/api/test/tests/ui/type_reference_in_impl_runtime_apis_call.rs similarity index 74% rename from primitives/sr-api/test/tests/ui/type_reference_in_impl_runtime_apis_call.rs rename to primitives/api/test/tests/ui/type_reference_in_impl_runtime_apis_call.rs index 41bbd8a9eee53a52975825e975c6379572e2091e..f45f0844c674447dbd4dd728647c4f4efab80253 100644 --- a/primitives/sr-api/test/tests/ui/type_reference_in_impl_runtime_apis_call.rs +++ b/primitives/api/test/tests/ui/type_reference_in_impl_runtime_apis_call.rs @@ -1,5 +1,5 @@ -use sr_primitives::traits::{GetNodeBlockType, Block as BlockT}; -use test_client::runtime::Block; +use sp_runtime::traits::{GetNodeBlockType, Block as BlockT}; +use substrate_test_runtime_client::runtime::Block; /// The declaration of the `Runtime` type and the implementation of the `GetNodeBlockType` /// trait are done by the `construct_runtime!` macro in a real runtime. @@ -8,20 +8,20 @@ impl GetNodeBlockType for Runtime { type NodeBlock = Block; } -sr_api::decl_runtime_apis! { +sp_api::decl_runtime_apis! { pub trait Api { fn test(data: u64); } } -sr_api::impl_runtime_apis! { +sp_api::impl_runtime_apis! { impl self::Api for Runtime { fn test(data: &u64) { unimplemented!() } } - impl sr_api::Core for Runtime { + impl sp_api::Core for Runtime { fn version() -> runtime_api::RuntimeVersion { unimplemented!() } diff --git a/primitives/sr-api/test/tests/ui/type_reference_in_impl_runtime_apis_call.stderr b/primitives/api/test/tests/ui/type_reference_in_impl_runtime_apis_call.stderr similarity index 58% rename from primitives/sr-api/test/tests/ui/type_reference_in_impl_runtime_apis_call.stderr rename to primitives/api/test/tests/ui/type_reference_in_impl_runtime_apis_call.stderr index 4614fe89b8ceafc8f26f3edeefd6d024d3e3d672..5129bb6c152205430d570209662d7f995dd4c0a9 100644 --- a/primitives/sr-api/test/tests/ui/type_reference_in_impl_runtime_apis_call.stderr +++ b/primitives/api/test/tests/ui/type_reference_in_impl_runtime_apis_call.stderr @@ -19,14 +19,14 @@ error[E0053]: method `test` has an incompatible type for trait error[E0053]: method `Api_test_runtime_api_impl` has an incompatible type for trait --> $DIR/type_reference_in_impl_runtime_apis_call.rs:17:1 | -11 | / sr_api::decl_runtime_apis! { +11 | / sp_api::decl_runtime_apis! { 12 | | pub trait Api { 13 | | fn test(data: u64); 14 | | } 15 | | } | |_- type in trait 16 | -17 | sr_api::impl_runtime_apis! { +17 | sp_api::impl_runtime_apis! { | -^^^^^^^^^^^^^^^^^^^^^^^^^ | | | _expected u64, found &u64 @@ -39,13 +39,13 @@ error[E0053]: method `Api_test_runtime_api_impl` has an incompatible type for tr 35 | | } | |_- in this macro invocation | - = note: expected type `fn(&RuntimeApiImpl, &sr_api_hidden_includes_DECL_RUNTIME_APIS::sr_api::BlockId, substrate_test_runtime::Extrinsic>>, sr_api_hidden_includes_DECL_RUNTIME_APIS::sr_api::ExecutionContext, std::option::Option, std::vec::Vec) -> std::result::Result, , substrate_test_runtime::Extrinsic>>>::Error>` - found type `fn(&RuntimeApiImpl, &sr_api_hidden_includes_DECL_RUNTIME_APIS::sr_api::BlockId, substrate_test_runtime::Extrinsic>>, sr_api_hidden_includes_DECL_RUNTIME_APIS::sr_api::ExecutionContext, std::option::Option<&u64>, std::vec::Vec) -> std::result::Result, , substrate_test_runtime::Extrinsic>>>::Error>` + = note: expected type `fn(&RuntimeApiImpl, &sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::BlockId, substrate_test_runtime::Extrinsic>>, sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::ExecutionContext, std::option::Option, std::vec::Vec) -> std::result::Result, , substrate_test_runtime::Extrinsic>>>::Error>` + found type `fn(&RuntimeApiImpl, &sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::BlockId, substrate_test_runtime::Extrinsic>>, sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::ExecutionContext, std::option::Option<&u64>, std::vec::Vec) -> std::result::Result, , substrate_test_runtime::Extrinsic>>>::Error>` error[E0308]: mismatched types --> $DIR/type_reference_in_impl_runtime_apis_call.rs:17:1 | -17 | / sr_api::impl_runtime_apis! { +17 | / sp_api::impl_runtime_apis! { 18 | | impl self::Api for Runtime { 19 | | fn test(data: &u64) { 20 | | unimplemented!() diff --git a/primitives/application-crypto/Cargo.toml b/primitives/application-crypto/Cargo.toml index 598f74ac15bd40e738a36e6b88cd62ab81124c56..f6487ebc298c39a8aee2ddfaba9f71876659ca02 100644 --- a/primitives/application-crypto/Cargo.toml +++ b/primitives/application-crypto/Cargo.toml @@ -1,28 +1,24 @@ [package] -name = "substrate-application-crypto" +name = "sp-application-crypto" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" description = "Provides facilities for generating application specific crypto wrapper types." [dependencies] -primitives = { package = "substrate-primitives", path = "../core", default-features = false } +sp-core = { version = "2.0.0", default-features = false, path = "../core" } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } serde = { version = "1.0.101", optional = true, features = ["derive"] } -rstd = { package = "sr-std", path = "../sr-std", default-features = false } -runtime-io = { package = "sr-io", path = "../../primitives/sr-io", default-features = false } - -[dev-dependencies] -test-client = { package = "substrate-test-runtime-client", path = "../../test/utils/runtime/client" } -sr-primitives = { path = "../../primitives/sr-primitives" } +sp-std = { version = "2.0.0", default-features = false, path = "../std" } +sp-io = { version = "2.0.0", default-features = false, path = "../../primitives/io" } [features] default = [ "std" ] -std = [ "full_crypto", "primitives/std", "codec/std", "serde", "rstd/std", "runtime-io/std" ] +std = [ "full_crypto", "sp-core/std", "codec/std", "serde", "sp-std/std", "sp-io/std" ] -# This feature enables all crypto primitives for `no_std` builds like microcontrollers -# or Intel SGX. +# This feature enables all crypto primitives for `no_std` builds like microcontrollers +# or Intel SGX. # For the regular wasm runtime builds this should not be used. full_crypto = [ - "primitives/full_crypto" -] \ No newline at end of file + "sp-core/full_crypto" +] diff --git a/primitives/application-crypto/src/ed25519.rs b/primitives/application-crypto/src/ed25519.rs index 468907a5c40a45b26b604a96f86a68f8d2986142..14796a4b55e3bc3fe5c3a98e33d0674e7220cb0d 100644 --- a/primitives/application-crypto/src/ed25519.rs +++ b/primitives/application-crypto/src/ed25519.rs @@ -18,12 +18,12 @@ use crate::{RuntimePublic, KeyTypeId}; -use rstd::vec::Vec; +use sp_std::vec::Vec; -pub use primitives::ed25519::*; +pub use sp_core::ed25519::*; mod app { - use primitives::testing::ED25519; + use sp_core::testing::ED25519; crate::app_crypto!(super, ED25519); impl crate::traits::BoundToRuntimeAppPublic for Public { @@ -39,42 +39,19 @@ impl RuntimePublic for Public { type Signature = Signature; fn all(key_type: KeyTypeId) -> crate::Vec { - runtime_io::crypto::ed25519_public_keys(key_type) + sp_io::crypto::ed25519_public_keys(key_type) } fn generate_pair(key_type: KeyTypeId, seed: Option>) -> Self { - runtime_io::crypto::ed25519_generate(key_type, seed) + sp_io::crypto::ed25519_generate(key_type, seed) } fn sign>(&self, key_type: KeyTypeId, msg: &M) -> Option { - runtime_io::crypto::ed25519_sign(key_type, self, msg.as_ref()) + sp_io::crypto::ed25519_sign(key_type, self, msg.as_ref()) } fn verify>(&self, msg: &M, signature: &Self::Signature) -> bool { - runtime_io::crypto::ed25519_verify(&signature, msg.as_ref(), self) + sp_io::crypto::ed25519_verify(&signature, msg.as_ref(), self) } } -#[cfg(test)] -mod tests { - use sr_primitives::{generic::BlockId, traits::ProvideRuntimeApi}; - use primitives::{testing::{KeyStore, ED25519}, crypto::Pair}; - use test_client::{ - TestClientBuilder, DefaultTestClientBuilderExt, TestClientBuilderExt, - runtime::{TestAPI, app_crypto::ed25519::{AppPair, AppPublic}}, - }; - - #[test] - fn ed25519_works_in_runtime() { - let keystore = KeyStore::new(); - let test_client = TestClientBuilder::new().set_keystore(keystore.clone()).build(); - let (signature, public) = test_client.runtime_api() - .test_ed25519_crypto(&BlockId::Number(0)) - .expect("Tests `ed25519` crypto."); - - let key_pair = keystore.read().ed25519_key_pair(ED25519, &public.as_ref()) - .expect("There should be at a `ed25519` key in the keystore for the given public key."); - - assert!(AppPair::verify(&signature, "ed25519", &AppPublic::from(key_pair.public()))); - } -} diff --git a/primitives/application-crypto/src/lib.rs b/primitives/application-crypto/src/lib.rs index dd8b02fc1d8558b337789df7f774795858ccd8fe..0d8df56535f0b8a0b6586bec4ed62e779bd59d79 100644 --- a/primitives/application-crypto/src/lib.rs +++ b/primitives/application-crypto/src/lib.rs @@ -21,11 +21,11 @@ #![cfg_attr(not(feature = "std"), no_std)] #[doc(hidden)] -pub use primitives::{self, crypto::{CryptoType, Public, Derive, IsWrappedBy, Wraps}, RuntimeDebug}; +pub use sp_core::{self, crypto::{CryptoType, Public, Derive, IsWrappedBy, Wraps}, RuntimeDebug}; #[doc(hidden)] #[cfg(feature = "full_crypto")] -pub use primitives::crypto::{SecretStringError, DeriveJunction, Ss58Codec, Pair}; -pub use primitives::{crypto::{KeyTypeId, key_types}}; +pub use sp_core::crypto::{SecretStringError, DeriveJunction, Ss58Codec, Pair}; +pub use sp_core::{crypto::{KeyTypeId, key_types}}; #[doc(hidden)] pub use codec; @@ -33,7 +33,7 @@ pub use codec; #[cfg(feature = "std")] pub use serde; #[doc(hidden)] -pub use rstd::{ops::Deref, vec::Vec}; +pub use sp_std::{ops::Deref, vec::Vec}; pub mod ed25519; pub mod sr25519; @@ -45,7 +45,7 @@ pub use traits::*; /// Application-specific types whose identifier is `$key_type`. /// /// ```rust -///# use substrate_application_crypto::{app_crypto, wrap, ed25519, KeyTypeId}; +///# use sp_application_crypto::{app_crypto, wrap, ed25519, KeyTypeId}; /// // Declare a new set of crypto types using Ed25519 logic that identifies as `KeyTypeId` /// // of value `b"fuba"`. /// app_crypto!(ed25519, KeyTypeId(*b"_uba")); @@ -66,7 +66,7 @@ macro_rules! app_crypto { /// Application-specific types whose identifier is `$key_type`. /// /// ```rust -///# use substrate_application_crypto::{app_crypto, wrap, ed25519, KeyTypeId}; +///# use sp_application_crypto::{app_crypto, wrap, ed25519, KeyTypeId}; /// // Declare a new set of crypto types using Ed25519 logic that identifies as `KeyTypeId` /// // of value `b"fuba"`. /// app_crypto!(ed25519, KeyTypeId(*b"_uba")); @@ -102,7 +102,7 @@ macro_rules! app_crypto_pair { type Seed = <$pair as $crate::Pair>::Seed; type Signature = Signature; type DeriveError = <$pair as $crate::Pair>::DeriveError; - + #[cfg(feature = "std")] fn generate_with_phrase(password: Option<&str>) -> (Self, String, Self::Seed) { let r = <$pair>::generate_with_phrase(password); @@ -353,7 +353,7 @@ macro_rules! app_crypto_signature_not_full_crypto { )] pub struct Signature($sig); } - + impl $crate::CryptoType for Signature {} impl $crate::AppKey for Signature { @@ -390,7 +390,7 @@ macro_rules! app_crypto_signature_common { /// Implement bidirectional `From` and on-way `AsRef`/`AsMut` for two types, `$inner` and `$outer`. /// /// ```rust -/// substrate_application_crypto::wrap! { +/// sp_application_crypto::wrap! { /// pub struct Wrapper(u32); /// } /// ``` diff --git a/primitives/application-crypto/src/sr25519.rs b/primitives/application-crypto/src/sr25519.rs index 2ad279a6bfd4220756ad0baedba37c8ab0916b46..f3d2a8484379d7f72eac95cd883cad840f5b4079 100644 --- a/primitives/application-crypto/src/sr25519.rs +++ b/primitives/application-crypto/src/sr25519.rs @@ -18,12 +18,12 @@ use crate::{RuntimePublic, KeyTypeId}; -use rstd::vec::Vec; +use sp_std::vec::Vec; -pub use primitives::sr25519::*; +pub use sp_core::sr25519::*; mod app { - use primitives::testing::SR25519; + use sp_core::testing::SR25519; crate::app_crypto!(super, SR25519); impl crate::traits::BoundToRuntimeAppPublic for Public { @@ -39,42 +39,18 @@ impl RuntimePublic for Public { type Signature = Signature; fn all(key_type: KeyTypeId) -> crate::Vec { - runtime_io::crypto::sr25519_public_keys(key_type) + sp_io::crypto::sr25519_public_keys(key_type) } fn generate_pair(key_type: KeyTypeId, seed: Option>) -> Self { - runtime_io::crypto::sr25519_generate(key_type, seed) + sp_io::crypto::sr25519_generate(key_type, seed) } fn sign>(&self, key_type: KeyTypeId, msg: &M) -> Option { - runtime_io::crypto::sr25519_sign(key_type, self, msg.as_ref()) + sp_io::crypto::sr25519_sign(key_type, self, msg.as_ref()) } fn verify>(&self, msg: &M, signature: &Self::Signature) -> bool { - runtime_io::crypto::sr25519_verify(&signature, msg.as_ref(), self) + sp_io::crypto::sr25519_verify(&signature, msg.as_ref(), self) } -} - -#[cfg(test)] -mod tests { - use sr_primitives::{generic::BlockId, traits::ProvideRuntimeApi}; - use primitives::{testing::{KeyStore, SR25519}, crypto::Pair}; - use test_client::{ - TestClientBuilder, DefaultTestClientBuilderExt, TestClientBuilderExt, - runtime::{TestAPI, app_crypto::sr25519::{AppPair, AppPublic}}, - }; - - #[test] - fn sr25519_works_in_runtime() { - let keystore = KeyStore::new(); - let test_client = TestClientBuilder::new().set_keystore(keystore.clone()).build(); - let (signature, public) = test_client.runtime_api() - .test_sr25519_crypto(&BlockId::Number(0)) - .expect("Tests `sr25519` crypto."); - - let key_pair = keystore.read().sr25519_key_pair(SR25519, public.as_ref()) - .expect("There should be at a `sr25519` key in the keystore for the given public key."); - - assert!(AppPair::verify(&signature, "sr25519", &AppPublic::from(key_pair.public()))); - } -} +} \ No newline at end of file diff --git a/primitives/application-crypto/src/traits.rs b/primitives/application-crypto/src/traits.rs index 0575d2ba06048710caf598c095b4faa4afbc2f42..917ec3b0e90af0b21dd9a8d117694c6b3670670a 100644 --- a/primitives/application-crypto/src/traits.rs +++ b/primitives/application-crypto/src/traits.rs @@ -15,11 +15,11 @@ // along with Substrate. If not, see . #[cfg(feature = "full_crypto")] -use primitives::crypto::Pair; +use sp_core::crypto::Pair; use codec::Codec; -use primitives::crypto::{KeyTypeId, CryptoType, IsWrappedBy, Public}; -use rstd::{fmt::Debug, vec::Vec}; +use sp_core::crypto::{KeyTypeId, CryptoType, IsWrappedBy, Public}; +use sp_std::{fmt::Debug, vec::Vec}; /// An application-specific key. pub trait AppKey: 'static + Send + Sync + Sized + CryptoType + Clone { @@ -42,9 +42,9 @@ pub trait AppKey: 'static + Send + Sync + Sized + CryptoType + Clone { /// Type which implements Hash in std, not when no-std (std variant). #[cfg(any(feature = "std", feature = "full_crypto"))] -pub trait MaybeHash: rstd::hash::Hash {} +pub trait MaybeHash: sp_std::hash::Hash {} #[cfg(any(feature = "std", feature = "full_crypto"))] -impl MaybeHash for T {} +impl MaybeHash for T {} /// Type which implements Hash in std, not when no-std (no-std variant). #[cfg(all(not(feature = "std"), not(feature = "full_crypto")))] @@ -54,9 +54,9 @@ impl MaybeHash for T {} /// Type which implements Debug and Hash in std, not when no-std (no-std variant with crypto). #[cfg(all(not(feature = "std"), feature = "full_crypto"))] -pub trait MaybeDebugHash: rstd::hash::Hash {} +pub trait MaybeDebugHash: sp_std::hash::Hash {} #[cfg(all(not(feature = "std"), feature = "full_crypto"))] -impl MaybeDebugHash for T {} +impl MaybeDebugHash for T {} /// A application's public key. pub trait AppPublic: diff --git a/primitives/application-crypto/test/Cargo.toml b/primitives/application-crypto/test/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..dabdc1d6e9243a7d5d18756b3748bdcc8d280bfe --- /dev/null +++ b/primitives/application-crypto/test/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "sp-application-crypto-test" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" +description = "Integration tests for application-crypto" +publish = false + +[dependencies] +sp-core = { version = "2.0.0", default-features = false, path = "../../core" } +substrate-test-runtime-client = { version = "2.0.0", path = "../../../test-utils/runtime/client" } +sp-runtime = { version = "2.0.0", path = "../../runtime" } +sp-application-crypto = { version = "2.0.0", path = "../" } diff --git a/primitives/application-crypto/test/src/ed25519.rs b/primitives/application-crypto/test/src/ed25519.rs new file mode 100644 index 0000000000000000000000000000000000000000..40f318509e6dcb8448cdd80352765776254b4f28 --- /dev/null +++ b/primitives/application-crypto/test/src/ed25519.rs @@ -0,0 +1,39 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Integration tests for ed25519 + +use sp_runtime::{generic::BlockId, traits::ProvideRuntimeApi}; +use sp_core::{testing::{KeyStore, ED25519}, crypto::Pair}; +use substrate_test_runtime_client::{ + TestClientBuilder, DefaultTestClientBuilderExt, TestClientBuilderExt, + runtime::TestAPI, +}; +use sp_application_crypto::ed25519::{AppPair, AppPublic}; + +#[test] +fn ed25519_works_in_runtime() { + let keystore = KeyStore::new(); + let test_client = TestClientBuilder::new().set_keystore(keystore.clone()).build(); + let (signature, public) = test_client.runtime_api() + .test_ed25519_crypto(&BlockId::Number(0)) + .expect("Tests `ed25519` crypto."); + + let key_pair = keystore.read().ed25519_key_pair(ED25519, &public.as_ref()) + .expect("There should be at a `ed25519` key in the keystore for the given public key."); + + assert!(AppPair::verify(&signature, "ed25519", &AppPublic::from(key_pair.public()))); +} diff --git a/primitives/application-crypto/test/src/lib.rs b/primitives/application-crypto/test/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..282ace5b1f66df0a553a347de7bc25acc34a434e --- /dev/null +++ b/primitives/application-crypto/test/src/lib.rs @@ -0,0 +1,22 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Integration tests for application crypto + +#[cfg(test)] +mod ed25519; +#[cfg(test)] +mod sr25519; \ No newline at end of file diff --git a/primitives/application-crypto/test/src/sr25519.rs b/primitives/application-crypto/test/src/sr25519.rs new file mode 100644 index 0000000000000000000000000000000000000000..f0bc3e09b2e00e01ed1e151a6c043356bc84c48b --- /dev/null +++ b/primitives/application-crypto/test/src/sr25519.rs @@ -0,0 +1,40 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Integration tests for sr25519 + + +use sp_runtime::{generic::BlockId, traits::ProvideRuntimeApi}; +use sp_core::{testing::{KeyStore, SR25519}, crypto::Pair}; +use substrate_test_runtime_client::{ + TestClientBuilder, DefaultTestClientBuilderExt, TestClientBuilderExt, + runtime::TestAPI, +}; +use sp_application_crypto::sr25519::{AppPair, AppPublic}; + +#[test] +fn sr25519_works_in_runtime() { + let keystore = KeyStore::new(); + let test_client = TestClientBuilder::new().set_keystore(keystore.clone()).build(); + let (signature, public) = test_client.runtime_api() + .test_sr25519_crypto(&BlockId::Number(0)) + .expect("Tests `sr25519` crypto."); + + let key_pair = keystore.read().sr25519_key_pair(SR25519, public.as_ref()) + .expect("There should be at a `sr25519` key in the keystore for the given public key."); + + assert!(AppPair::verify(&signature, "sr25519", &AppPublic::from(key_pair.public()))); +} diff --git a/primitives/sr-arithmetic/Cargo.toml b/primitives/arithmetic/Cargo.toml similarity index 70% rename from primitives/sr-arithmetic/Cargo.toml rename to primitives/arithmetic/Cargo.toml index 47b3315e86193762fb4606c2715cc12ec8d68f13..71be14862a0ab0ccbc81c5f2823f24bec0e7c426 100644 --- a/primitives/sr-arithmetic/Cargo.toml +++ b/primitives/arithmetic/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "sr-arithmetic" +name = "sp-arithmetic" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" @@ -8,9 +8,9 @@ edition = "2018" codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } integer-sqrt = "0.1.2" num-traits = { version = "0.2.8", default-features = false } -rstd = { package = "sr-std", path = "../sr-std", default-features = false } +sp-std = { version = "2.0.0", default-features = false, path = "../std" } serde = { version = "1.0.101", optional = true, features = ["derive"] } -substrate-debug-derive = { path = "../../primitives/core/debug-derive", default-features = false } +sp-debug-derive = { version = "2.0.0", default-features = false, path = "../../primitives/debug-derive" } [dev-dependencies] primitive-types = "0.6.0" @@ -22,9 +22,9 @@ default = ["std"] std = [ "codec/std", "num-traits/std", - "rstd/std", + "sp-std/std", "serde", - "substrate-debug-derive/std", + "sp-debug-derive/std", ] [[bench]] diff --git a/primitives/sr-arithmetic/benches/bench.rs b/primitives/arithmetic/benches/bench.rs similarity index 98% rename from primitives/sr-arithmetic/benches/bench.rs rename to primitives/arithmetic/benches/bench.rs index 22c0ce6f566e965b1fc8885b6427753fec2ad74a..ea6a2d2fd8cc0a570eb41ad0068eb807f489c41e 100644 --- a/primitives/sr-arithmetic/benches/bench.rs +++ b/primitives/arithmetic/benches/bench.rs @@ -15,7 +15,7 @@ // along with Substrate. If not, see . use criterion::{Criterion, Throughput, BenchmarkId, criterion_group, criterion_main}; -use sr_arithmetic::biguint::{BigUint, Single}; +use sp_arithmetic::biguint::{BigUint, Single}; use rand::Rng; fn random_big_uint(size: usize) -> BigUint { diff --git a/primitives/sr-arithmetic/fuzzer/.gitignore b/primitives/arithmetic/fuzzer/.gitignore similarity index 100% rename from primitives/sr-arithmetic/fuzzer/.gitignore rename to primitives/arithmetic/fuzzer/.gitignore diff --git a/primitives/sr-arithmetic/fuzzer/Cargo.lock b/primitives/arithmetic/fuzzer/Cargo.lock similarity index 99% rename from primitives/sr-arithmetic/fuzzer/Cargo.lock rename to primitives/arithmetic/fuzzer/Cargo.lock index 83fcd3db3d1c4d4745a97180fbdcdae96d9467e2..de8a764f1f9b14cea92d0e46f40f62205abeacfd 100644 --- a/primitives/sr-arithmetic/fuzzer/Cargo.lock +++ b/primitives/arithmetic/fuzzer/Cargo.lock @@ -285,39 +285,30 @@ dependencies = [ ] [[package]] -name = "sr-arithmetic" +name = "sp-arithmetic" version = "2.0.0" dependencies = [ "integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-std 2.0.0", - "substrate-debug-derive 2.0.0", + "sp-debug-derive 2.0.0", + "sp-std 2.0.0", ] [[package]] -name = "sr-arithmetic-fuzzer" +name = "sp-arithmetic-fuzzer" version = "2.0.0" dependencies = [ "honggfuzz 0.5.45 (registry+https://github.com/rust-lang/crates.io-index)", "num-bigint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "primitive-types 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-arithmetic 2.0.0", + "sp-arithmetic 2.0.0", ] [[package]] -name = "sr-std" -version = "2.0.0" - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "substrate-debug-derive" +name = "sp-debug-derive" version = "2.0.0" dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -325,6 +316,15 @@ dependencies = [ "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "sp-std" +version = "2.0.0" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "syn" version = "0.15.44" diff --git a/primitives/sr-arithmetic/fuzzer/Cargo.toml b/primitives/arithmetic/fuzzer/Cargo.toml similarity index 79% rename from primitives/sr-arithmetic/fuzzer/Cargo.toml rename to primitives/arithmetic/fuzzer/Cargo.toml index 482905c4350106cffa386455c487c030fab16829..e8568db3707fb2fb8b13d6f332dadf4073ad2fe5 100644 --- a/primitives/sr-arithmetic/fuzzer/Cargo.toml +++ b/primitives/arithmetic/fuzzer/Cargo.toml @@ -1,11 +1,11 @@ [package] -name = "sr-arithmetic-fuzzer" +name = "sp-arithmetic-fuzzer" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" [dependencies] -sr-arithmetic = { path = ".." } +sp-arithmetic = { version = "2.0.0", path = ".." } honggfuzz = "0.5" primitive-types = "0.6" num-bigint = "0.2" diff --git a/primitives/sr-arithmetic/fuzzer/src/biguint.rs b/primitives/arithmetic/fuzzer/src/biguint.rs similarity index 99% rename from primitives/sr-arithmetic/fuzzer/src/biguint.rs rename to primitives/arithmetic/fuzzer/src/biguint.rs index bd270a97cac7102b37d3bd400f7c02c080e6cdaf..c3dbe812129090d4858ba727e6ac54805c349189 100644 --- a/primitives/sr-arithmetic/fuzzer/src/biguint.rs +++ b/primitives/arithmetic/fuzzer/src/biguint.rs @@ -27,7 +27,7 @@ //! [here](https://docs.rs/honggfuzz/). use honggfuzz::fuzz; -use sr_arithmetic::biguint::{BigUint, Single}; +use sp_arithmetic::biguint::{BigUint, Single}; use std::convert::TryFrom; fn main() { diff --git a/primitives/sr-arithmetic/fuzzer/src/rational128.rs b/primitives/arithmetic/fuzzer/src/rational128.rs similarity index 97% rename from primitives/sr-arithmetic/fuzzer/src/rational128.rs rename to primitives/arithmetic/fuzzer/src/rational128.rs index b2a00d754527f042cec53f4f6986d8571ad7530e..f32caa9010a6bcebd1d69a05fc90c17bb3291c32 100644 --- a/primitives/sr-arithmetic/fuzzer/src/rational128.rs +++ b/primitives/arithmetic/fuzzer/src/rational128.rs @@ -27,7 +27,7 @@ //! [here](https://docs.rs/honggfuzz/). use honggfuzz::fuzz; -use sr_arithmetic::{helpers_128bit::multiply_by_rational, traits::Zero}; +use sp_arithmetic::{helpers_128bit::multiply_by_rational, traits::Zero}; fn main() { loop { diff --git a/primitives/sr-arithmetic/src/biguint.rs b/primitives/arithmetic/src/biguint.rs similarity index 98% rename from primitives/sr-arithmetic/src/biguint.rs rename to primitives/arithmetic/src/biguint.rs index 1a701a5ebd460cd950e312a11fbc3ca2e6c15769..9d69ccad81f9abd71f447c037b08d1279244c6bc 100644 --- a/primitives/sr-arithmetic/src/biguint.rs +++ b/primitives/arithmetic/src/biguint.rs @@ -17,7 +17,7 @@ //! Infinite precision unsigned integer for substrate runtime. use num_traits::Zero; -use rstd::{cmp::Ordering, ops, prelude::*, cell::RefCell, convert::TryFrom}; +use sp_std::{cmp::Ordering, ops, prelude::*, cell::RefCell, convert::TryFrom}; // A sensible value for this would be half of the dword size of the host machine. Since the // runtime is compiled to 32bit webassembly, using 32 and 64 for single and double respectively @@ -427,9 +427,9 @@ impl BigUint { } } -impl rstd::fmt::Debug for BigUint { +impl sp_std::fmt::Debug for BigUint { #[cfg(feature = "std")] - fn fmt(&self, f: &mut rstd::fmt::Formatter<'_>) -> rstd::fmt::Result { + fn fmt(&self, f: &mut sp_std::fmt::Formatter<'_>) -> sp_std::fmt::Result { write!( f, "BigUint {{ {:?} ({:?})}}", @@ -439,7 +439,7 @@ impl rstd::fmt::Debug for BigUint { } #[cfg(not(feature = "std"))] - fn fmt(&self, _: &mut rstd::fmt::Formatter<'_>) -> rstd::fmt::Result { + fn fmt(&self, _: &mut sp_std::fmt::Formatter<'_>) -> sp_std::fmt::Result { Ok(()) } @@ -646,7 +646,7 @@ pub mod tests { #[test] fn can_try_build_numbers_from_types() { - use rstd::convert::TryFrom; + use sp_std::convert::TryFrom; assert_eq!(u64::try_from(with_limbs(1)).unwrap(), 1); assert_eq!(u64::try_from(with_limbs(2)).unwrap(), u32::max_value() as u64 + 2); assert_eq!( diff --git a/primitives/sr-arithmetic/src/fixed64.rs b/primitives/arithmetic/src/fixed64.rs similarity index 97% rename from primitives/sr-arithmetic/src/fixed64.rs rename to primitives/arithmetic/src/fixed64.rs index 5c68cc5529abf63434b2c106413f9121b6c5e105..6f906b0b2961c8dc56db9763824adc4a4d3bd255 100644 --- a/primitives/sr-arithmetic/src/fixed64.rs +++ b/primitives/arithmetic/src/fixed64.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use rstd::{ +use sp_std::{ ops, prelude::*, convert::{TryFrom, TryInto}, }; @@ -179,14 +179,14 @@ impl CheckedDiv for Fixed64 { } } -impl rstd::fmt::Debug for Fixed64 { +impl sp_std::fmt::Debug for Fixed64 { #[cfg(feature = "std")] - fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { write!(f, "Fixed64({},{})", self.0 / DIV, (self.0 % DIV) / 1000) } #[cfg(not(feature = "std"))] - fn fmt(&self, _: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { Ok(()) } } diff --git a/primitives/sr-arithmetic/src/helpers_128bit.rs b/primitives/arithmetic/src/helpers_128bit.rs similarity index 98% rename from primitives/sr-arithmetic/src/helpers_128bit.rs rename to primitives/arithmetic/src/helpers_128bit.rs index 10cc94ae777e66d2f802a464947f7bce4385301e..475d802f3f7089ef64bb66c1905cdeb94d01cdfa 100644 --- a/primitives/sr-arithmetic/src/helpers_128bit.rs +++ b/primitives/arithmetic/src/helpers_128bit.rs @@ -21,7 +21,7 @@ use crate::biguint; use num_traits::Zero; -use rstd::{cmp::{min, max}, convert::TryInto, mem}; +use sp_std::{cmp::{min, max}, convert::TryInto, mem}; /// Helper gcd function used in Rational128 implementation. pub fn gcd(a: u128, b: u128) -> u128 { diff --git a/primitives/sr-arithmetic/src/lib.rs b/primitives/arithmetic/src/lib.rs similarity index 96% rename from primitives/sr-arithmetic/src/lib.rs rename to primitives/arithmetic/src/lib.rs index 7b285002e54001ced6f9fcdeccfbd246f4a47519..fc1d75ae96f2644340bc91a700427c3a0920b9a4 100644 --- a/primitives/sr-arithmetic/src/lib.rs +++ b/primitives/arithmetic/src/lib.rs @@ -18,7 +18,7 @@ #![cfg_attr(not(feature = "std"), no_std)] -/// Copied from `sr-primitives` and documented there. +/// Copied from `sp-runtime` and documented there. #[cfg(test)] macro_rules! assert_eq_error_rate { ($x:expr, $y:expr, $error:expr $(,)?) => { diff --git a/primitives/sr-arithmetic/src/per_things.rs b/primitives/arithmetic/src/per_things.rs similarity index 98% rename from primitives/sr-arithmetic/src/per_things.rs rename to primitives/arithmetic/src/per_things.rs index 2dd1e62d0b4db7aa45cd39b5ed3088fb84167013..47dfc98f3b0cad0559694c8467c6ff24b9fcb8a8 100644 --- a/primitives/sr-arithmetic/src/per_things.rs +++ b/primitives/arithmetic/src/per_things.rs @@ -17,18 +17,18 @@ #[cfg(feature = "std")] use serde::{Serialize, Deserialize}; -use rstd::{ops, prelude::*, convert::TryInto}; +use sp_std::{ops, prelude::*, convert::TryInto}; use codec::{Encode, Decode, CompactAs}; use crate::traits::{SaturatedConversion, UniqueSaturatedInto, Saturating}; -use substrate_debug_derive::RuntimeDebug; +use sp_debug_derive::RuntimeDebug; macro_rules! implement_per_thing { ($name:ident, $test_mod:ident, [$($test_units:tt),+], $max:tt, $type:ty, $upper_type:ty, $title:expr $(,)?) => { /// A fixed point representation of a number between in the range [0, 1]. /// #[doc = $title] - #[cfg_attr(feature = "std", derive(Serialize, Deserialize, Ord, PartialOrd))] - #[derive(Encode, Decode, Default, Copy, Clone, PartialEq, Eq, RuntimeDebug, CompactAs)] + #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] + #[derive(Encode, Decode, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, RuntimeDebug, CompactAs)] pub struct $name($type); impl $name { diff --git a/primitives/sr-arithmetic/src/rational128.rs b/primitives/arithmetic/src/rational128.rs similarity index 99% rename from primitives/sr-arithmetic/src/rational128.rs rename to primitives/arithmetic/src/rational128.rs index 3247321199d6142e05fd8a11befcaad3e3e16186..a747be84a810ec877575ae5a1ee74c16347c010e 100644 --- a/primitives/sr-arithmetic/src/rational128.rs +++ b/primitives/arithmetic/src/rational128.rs @@ -14,10 +14,10 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use rstd::{cmp::Ordering, prelude::*}; +use sp_std::{cmp::Ordering, prelude::*}; use crate::helpers_128bit; use num_traits::Zero; -use substrate_debug_derive::RuntimeDebug; +use sp_debug_derive::RuntimeDebug; /// A wrapper for any rational number with a 128 bit numerator and denominator. #[derive(Clone, Copy, Default, Eq, RuntimeDebug)] diff --git a/primitives/sr-arithmetic/src/traits.rs b/primitives/arithmetic/src/traits.rs similarity index 98% rename from primitives/sr-arithmetic/src/traits.rs rename to primitives/arithmetic/src/traits.rs index d02425066ff9d7f8e34efe6e73b94262ba197b64..d8a46ffd30ecb6ab30c25ffc82ed3550b9e231fc 100644 --- a/primitives/sr-arithmetic/src/traits.rs +++ b/primitives/arithmetic/src/traits.rs @@ -16,14 +16,14 @@ //! Primitives for the runtime modules. -use rstd::{self, convert::{TryFrom, TryInto}}; +use sp_std::{self, convert::{TryFrom, TryInto}}; use codec::HasCompact; pub use integer_sqrt::IntegerSquareRoot; pub use num_traits::{ Zero, One, Bounded, CheckedAdd, CheckedSub, CheckedMul, CheckedDiv, CheckedShl, CheckedShr }; -use rstd::ops::{ +use sp_std::ops::{ Add, Sub, Mul, Div, Rem, AddAssign, SubAssign, MulAssign, DivAssign, RemAssign, Shl, Shr }; diff --git a/primitives/authority-discovery/Cargo.toml b/primitives/authority-discovery/Cargo.toml index 1e975b5680105592290a42188eb302c34e317f77..516ea413acd55cc5e6820538140dbc8f3da11ce2 100644 --- a/primitives/authority-discovery/Cargo.toml +++ b/primitives/authority-discovery/Cargo.toml @@ -1,23 +1,23 @@ [package] -name = "substrate-authority-discovery-primitives" +name = "sp-authority-discovery" version = "2.0.0" authors = ["Parity Technologies "] description = "Authority discovery primitives" edition = "2018" [dependencies] -app-crypto = { package = "substrate-application-crypto", path = "../application-crypto", default-features = false } +sp-application-crypto = { version = "2.0.0", default-features = false, path = "../application-crypto" } codec = { package = "parity-scale-codec", default-features = false, version = "1.0.3" } -rstd = { package = "sr-std", path = "../sr-std", default-features = false } -sr-api = { path = "../sr-api", default-features = false } -sr-primitives = { path = "../sr-primitives", default-features = false } +sp-std = { version = "2.0.0", default-features = false, path = "../std" } +sp-api = { version = "2.0.0", default-features = false, path = "../api" } +sp-runtime = { version = "2.0.0", default-features = false, path = "../runtime" } [features] default = ["std"] std = [ - "app-crypto/std", + "sp-application-crypto/std", "codec/std", - "rstd/std", - "sr-api/std", - "sr-primitives/std" + "sp-std/std", + "sp-api/std", + "sp-runtime/std" ] diff --git a/primitives/authority-discovery/src/lib.rs b/primitives/authority-discovery/src/lib.rs index 0116ca02aad1f4f3a0e56c1f0f46f6d2a8107099..41ad384f917ccb01cc32d971aa02bfe07a62e5d5 100644 --- a/primitives/authority-discovery/src/lib.rs +++ b/primitives/authority-discovery/src/lib.rs @@ -18,10 +18,10 @@ #![cfg_attr(not(feature = "std"), no_std)] -use rstd::vec::Vec; +use sp_std::vec::Vec; mod app { - use app_crypto::{app_crypto, key_types::AUTHORITY_DISCOVERY, sr25519}; + use sp_application_crypto::{app_crypto, key_types::AUTHORITY_DISCOVERY, sr25519}; app_crypto!(sr25519, AUTHORITY_DISCOVERY); } @@ -35,10 +35,10 @@ pub type AuthorityId = app::Public; /// An authority discovery authority signature. pub type AuthoritySignature = app::Signature; -sr_api::decl_runtime_apis! { +sp_api::decl_runtime_apis! { /// The authority discovery api. /// - /// This api is used by the `core/authority-discovery` module to retrieve identifiers + /// This api is used by the `client/authority-discovery` module to retrieve identifiers /// of the current authority set. pub trait AuthorityDiscoveryApi { /// Retrieve authority identifiers of the current authority set. diff --git a/primitives/authorship/Cargo.toml b/primitives/authorship/Cargo.toml index 1c95fed52ff04b2cd931f433a41033d914297f57..d8ddbb7a9218a07584fd9b363a0dbe5c26e1e1d5 100644 --- a/primitives/authorship/Cargo.toml +++ b/primitives/authorship/Cargo.toml @@ -6,14 +6,16 @@ description = "Authorship primitives" edition = "2018" [dependencies] -sp-inherents = { package = "substrate-inherents", path = "../inherents", default-features = false } -rstd = { package = "sr-std", path = "../sr-std", default-features = false } +sp-inherents = { version = "2.0.0", default-features = false, path = "../inherents" } +sp-runtime = { version = "2.0.0", default-features = false, path = "../runtime" } +sp-std = { version = "2.0.0", default-features = false, path = "../std" } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } [features] default = [ "std" ] std = [ - "codec/std", - "rstd/std", - "sp-inherents/std", + "codec/std", + "sp-std/std", + "sp-inherents/std", + "sp-runtime/std", ] diff --git a/primitives/authorship/src/lib.rs b/primitives/authorship/src/lib.rs index e381c97094619a0216adfab940871a10cba054eb..7494e583383da039d6f663a646006f88ed43df25 100644 --- a/primitives/authorship/src/lib.rs +++ b/primitives/authorship/src/lib.rs @@ -18,14 +18,30 @@ #![cfg_attr(not(feature = "std"), no_std)] -use rstd::{result::Result, prelude::*}; +use sp_std::{result::Result, prelude::*}; use codec::{Encode, Decode}; -use sp_inherents::{Error, InherentIdentifier, InherentData}; +use sp_inherents::{Error, InherentIdentifier, InherentData, IsFatalError}; +use sp_runtime::RuntimeString; /// The identifier for the `uncles` inherent. pub const INHERENT_IDENTIFIER: InherentIdentifier = *b"uncles00"; +/// Errors that can occur while checking the authorship inherent. +#[derive(Encode, sp_runtime::RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode))] +pub enum InherentError { + Uncles(RuntimeString), +} + +impl IsFatalError for InherentError { + fn is_fatal_error(&self) -> bool { + match self { + InherentError::Uncles(_) => true, + } + } +} + /// Auxiliary trait to extract uncles inherent data. pub trait UnclesInherentData { /// Get uncles. @@ -72,4 +88,4 @@ where F: Fn() -> Vec fn error_to_string(&self, _error: &[u8]) -> Option { Some(format!("no further information")) } -} \ No newline at end of file +} diff --git a/primitives/block-builder/Cargo.toml b/primitives/block-builder/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..5bbe9ea123faf07b880a42a378dcca0468dd1789 --- /dev/null +++ b/primitives/block-builder/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "sp-block-builder" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +sp-runtime = { version = "2.0.0", default-features = false, path = "../runtime" } +sp-api = { version = "2.0.0", default-features = false, path = "../api" } +sp-std = { version = "2.0.0", default-features = false, path = "../std" } +codec = { package = "parity-scale-codec", version = "1.0.6", default-features = false } +sp-inherents = { version = "2.0.0", default-features = false, path = "../inherents" } + +[features] +default = [ "std" ] +std = [ + "sp-runtime/std", + "codec/std", + "sp-inherents/std", + "sp-api/std", + "sp-std/std", +] diff --git a/primitives/block-builder/runtime-api/Cargo.toml b/primitives/block-builder/runtime-api/Cargo.toml deleted file mode 100644 index 7f3b17fb21579e5444c7e8c0e3260f126dc7e60b..0000000000000000000000000000000000000000 --- a/primitives/block-builder/runtime-api/Cargo.toml +++ /dev/null @@ -1,22 +0,0 @@ -[package] -name = "substrate-block-builder-runtime-api" -version = "2.0.0" -authors = ["Parity Technologies "] -edition = "2018" - -[dependencies] -sr-primitives = { path = "../../sr-primitives", default-features = false } -sr-api = { path = "../../sr-api", default-features = false } -rstd = { package = "sr-std", path = "../../sr-std", default-features = false } -codec = { package = "parity-scale-codec", version = "1.0.6", default-features = false } -inherents = { package = "substrate-inherents", path = "../../inherents", default-features = false } - -[features] -default = [ "std" ] -std = [ - "sr-primitives/std", - "codec/std", - "inherents/std", - "sr-api/std", - "rstd/std", -] diff --git a/primitives/block-builder/runtime-api/src/lib.rs b/primitives/block-builder/src/lib.rs similarity index 90% rename from primitives/block-builder/runtime-api/src/lib.rs rename to primitives/block-builder/src/lib.rs index f8a5f93b99246eaf2df44c75290f9cb47699780a..95f187da9a2c65a95ae07a5d08b1346f048c1c74 100644 --- a/primitives/block-builder/runtime-api/src/lib.rs +++ b/primitives/block-builder/src/lib.rs @@ -18,16 +18,16 @@ #![cfg_attr(not(feature = "std"), no_std)] -use sr_primitives::{traits::Block as BlockT, ApplyExtrinsicResult}; +use sp_runtime::{traits::Block as BlockT, ApplyExtrinsicResult}; -use inherents::{InherentData, CheckInherentsResult}; +use sp_inherents::{InherentData, CheckInherentsResult}; /// Definitions for supporting the older version of API: v3 /// /// These definitions are taken from the 2c58e30246a029b53d51e5b24c31974ac539ee8b git revision. #[deprecated(note = "These definitions here are only for compatibility reasons")] pub mod compatability_v3 { - use sr_primitives::{DispatchOutcome, transaction_validity}; + use sp_runtime::{DispatchOutcome, transaction_validity}; use codec::{Encode, Decode}; #[derive(Eq, PartialEq, Clone, Copy, Decode, Encode, Debug)] @@ -41,7 +41,7 @@ pub mod compatability_v3 { pub type ApplyResult = Result; } -sr_api::decl_runtime_apis! { +sp_api::decl_runtime_apis! { /// The `BlockBuilder` api trait that provides the required functionality for building a block. #[api_version(4)] pub trait BlockBuilder { @@ -64,7 +64,7 @@ sr_api::decl_runtime_apis! { /// Generate inherent extrinsics. The inherent data will vary from chain to chain. fn inherent_extrinsics( inherent: InherentData, - ) -> rstd::vec::Vec<::Extrinsic>; + ) -> sp_std::vec::Vec<::Extrinsic>; /// Check that the inherents are valid. The inherent data will vary from chain to chain. fn check_inherents(block: Block, data: InherentData) -> CheckInherentsResult; /// Generate a random seed. diff --git a/primitives/blockchain/Cargo.toml b/primitives/blockchain/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..4f3f0d0b5fad0b08211294723c0dd4ebe098c470 --- /dev/null +++ b/primitives/blockchain/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "sp-blockchain" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +log = "0.4.8" +lru = "0.4.0" +parking_lot = "0.9.0" +derive_more = "0.99.2" +codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } +sp-consensus = { version = "0.8", path = "../consensus/common" } +sp-runtime = { version = "2.0.0", path = "../runtime" } +sp-block-builder = { version = "2.0.0", path = "../block-builder" } +sp-state-machine = { version = "2.0.0", path = "../state-machine" } diff --git a/client/api/src/blockchain.rs b/primitives/blockchain/src/backend.rs similarity index 96% rename from client/api/src/blockchain.rs rename to primitives/blockchain/src/backend.rs index 73b7c138d020e62238750b72fe8bf202e42ec109..0baede8ab29dbbd0374d4503746fae35ef1be304 100644 --- a/client/api/src/blockchain.rs +++ b/primitives/blockchain/src/backend.rs @@ -18,13 +18,13 @@ use std::sync::Arc; -use sr_primitives::traits::{Block as BlockT, Header as HeaderT, NumberFor}; -use sr_primitives::generic::BlockId; -use sr_primitives::Justification; +use sp_runtime::traits::{Block as BlockT, Header as HeaderT, NumberFor}; +use sp_runtime::generic::BlockId; +use sp_runtime::Justification; use log::warn; -use parking_lot::Mutex; +use parking_lot::RwLock; -use header_metadata::HeaderMetadata; +use crate::header_metadata::HeaderMetadata; use crate::error::{Error, Result}; @@ -109,7 +109,7 @@ pub trait Backend: HeaderBackend + HeaderMetadata>, - import_lock: &Mutex<()>, + import_lock: &RwLock<()>, ) -> Result> { let target_header = { match self.header(BlockId::Hash(target_hash))? { @@ -130,7 +130,7 @@ pub trait Backend: HeaderBackend + HeaderMetadata = result::Result; +/// Error when the runtime failed to apply an extrinsic. +#[derive(Debug, Display)] +pub enum ApplyExtrinsicFailed { + /// The transaction cannot be included into the current block. + /// + /// This doesn't necessary mean that the transaction itself is invalid, but it might be just + /// unappliable onto the current block. + #[display(fmt = "Extrinsic is not valid: {:?}", _0)] + Validity(TransactionValidityError), + /// This is used for miscelanious errors that can be represented by string and not handleable. + /// + /// This will become obsolete with complete migration to v4 APIs. + #[display(fmt = "Extrinsic failed: {:?}", _0)] + Msg(String), +} + /// Substrate Client error #[derive(Debug, Display, From)] pub enum Error { /// Consensus Error #[display(fmt = "Consensus: {}", _0)] - Consensus(consensus::Error), + Consensus(sp_consensus::Error), /// Backend error. #[display(fmt = "Backend error: {}", _0)] + #[from(ignore)] Backend(String), /// Unknown block. #[display(fmt = "UnknownBlock: {}", _0)] + #[from(ignore)] UnknownBlock(String), /// The `apply_extrinsic` is not valid due to the given `TransactionValidityError`. - #[display(fmt = "Extrinsic is not valid: {:?}", _0)] - ApplyExtrinsicFailed(TransactionValidityError), + #[display(fmt = "{:?}", _0)] + ApplyExtrinsicFailed(ApplyExtrinsicFailed), /// Execution error. #[display(fmt = "Execution: {}", _0)] - Execution(Box), + Execution(Box), /// Blockchain error. #[display(fmt = "Blockchain: {}", _0)] Blockchain(Box), @@ -50,8 +71,9 @@ pub enum Error { #[display(fmt = "Current state of blockchain has invalid authorities set")] InvalidAuthoritiesSet, /// Could not get runtime version. - #[display(fmt = "On-chain runtime does not specify version")] - VersionInvalid, + #[display(fmt = "Failed to get runtime version: {}", _0)] + #[from(ignore)] + VersionInvalid(String), /// Genesis config is invalid. #[display(fmt = "Genesis config provided is invalid")] GenesisInvalid, @@ -60,6 +82,7 @@ pub enum Error { JustificationDecode, /// Justification for header is correctly encoded, but invalid. #[display(fmt = "bad justification for header: {}", _0)] + #[from(ignore)] BadJustification(String), /// Not available on light client. #[display(fmt = "This method is not currently available when running in light client mode")] @@ -75,18 +98,21 @@ pub enum Error { RemoteFetchFailed, /// Error decoding call result. #[display(fmt = "Error decoding call result of {}: {}", _0, _1)] - CallResultDecode(&'static str, codec::Error), + CallResultDecode(&'static str, CodecError), /// Error converting a parameter between runtime and node. #[display(fmt = "Error converting `{}` between runtime and node", _0)] + #[from(ignore)] RuntimeParamConversion(String), /// Changes tries are not supported. #[display(fmt = "Changes tries are not supported by the runtime")] ChangesTriesNotSupported, /// Key changes query has failed. #[display(fmt = "Failed to check changes proof: {}", _0)] + #[from(ignore)] ChangesTrieAccessFailed(String), /// Last finalized block not parent of current. #[display(fmt = "Did not finalize blocks in sequential order.")] + #[from(ignore)] NonSequentialFinalization(String), /// Safety violation: new best block not descendent of last finalized. #[display(fmt = "Potential long-range attack: block not in finalized chain.")] @@ -112,26 +138,20 @@ impl error::Error for Error { } } -impl From for Error { - fn from(s: String) -> Self { - Error::Msg(s) - } -} - impl<'a> From<&'a str> for Error { fn from(s: &'a str) -> Self { Error::Msg(s.into()) } } -impl From for Error { - fn from(err: block_builder::ApplyExtrinsicFailed) -> Self { - use block_builder::ApplyExtrinsicFailed; - match err { - ApplyExtrinsicFailed::Validity(tx_validity) => Self::ApplyExtrinsicFailed(tx_validity), - ApplyExtrinsicFailed::Msg(msg) => Self::Msg(msg), +#[allow(deprecated)] +impl From for ApplyExtrinsicFailed { + fn from(e: compatability_v3::ApplyError) -> Self { + use self::compatability_v3::ApplyError::*; + match e { + Validity(tx_validity) => Self::Validity(tx_validity), + e => Self::Msg(format!("Apply extrinsic failed: {:?}", e)), } - } } @@ -142,7 +162,7 @@ impl Error { } /// Chain a state error. - pub fn from_state(e: Box) -> Self { + pub fn from_state(e: Box) -> Self { Error::Execution(e) } } diff --git a/client/header-metadata/src/lib.rs b/primitives/blockchain/src/header_metadata.rs similarity index 99% rename from client/header-metadata/src/lib.rs rename to primitives/blockchain/src/header_metadata.rs index 5ec58ad754b7223c2658d85bc8c3f095be7a3250..450bf70e8ed8ddabcac19b933c19a4d37fba3bfc 100644 --- a/client/header-metadata/src/lib.rs +++ b/primitives/blockchain/src/header_metadata.rs @@ -17,7 +17,7 @@ //! Implements tree backend, cached header metadata and algorithms //! to compute routes efficiently over the tree of headers. -use sr_primitives::traits::{Block as BlockT, NumberFor, Header}; +use sp_runtime::traits::{Block as BlockT, NumberFor, Header}; use parking_lot::RwLock; use lru::LruCache; diff --git a/primitives/blockchain/src/lib.rs b/primitives/blockchain/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..2a8a7c96fe132d7dbea3561a88595f1111106187 --- /dev/null +++ b/primitives/blockchain/src/lib.rs @@ -0,0 +1,25 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Substrate blockchain traits and primtives + +mod backend; +mod header_metadata; +mod error; + +pub use error::*; +pub use backend::*; +pub use header_metadata::*; diff --git a/primitives/consensus/aura/Cargo.toml b/primitives/consensus/aura/Cargo.toml index bb772cb7a79aa09413bb203a5bb674a2dbbc72f5..57958ed851d344c2b9c4af3e244954d65d63328b 100644 --- a/primitives/consensus/aura/Cargo.toml +++ b/primitives/consensus/aura/Cargo.toml @@ -1,27 +1,27 @@ [package] -name = "substrate-consensus-aura-primitives" -version = "2.0.0" +name = "sp-consensus-aura" +version = "0.8.0" authors = ["Parity Technologies "] description = "Primitives for Aura consensus" edition = "2018" [dependencies] -app-crypto = { package = "substrate-application-crypto", path = "../../application-crypto", default-features = false } +sp-application-crypto = { version = "2.0.0", default-features = false, path = "../../application-crypto" } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false } -rstd = { package = "sr-std", path = "../../sr-std", default-features = false } -sr-api = { path = "../../sr-api", default-features = false } -sr-primitives = { path = "../../sr-primitives", default-features = false } -inherents = { package = "substrate-inherents", path = "../../inherents", default-features = false } -sp-timestamp = { path = "../../timestamp", default-features = false } +sp-std = { version = "2.0.0", default-features = false, path = "../../std" } +sp-api = { version = "2.0.0", default-features = false, path = "../../api" } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../runtime" } +sp-inherents = { version = "2.0.0", default-features = false, path = "../../inherents" } +sp-timestamp = { version = "2.0.0", default-features = false, path = "../../timestamp" } [features] default = ["std"] std = [ - "app-crypto/std", + "sp-application-crypto/std", "codec/std", - "rstd/std", - "sr-api/std", - "sr-primitives/std", - "inherents/std", + "sp-std/std", + "sp-api/std", + "sp-runtime/std", + "sp-inherents/std", "sp-timestamp/std", ] diff --git a/primitives/consensus/aura/src/inherents.rs b/primitives/consensus/aura/src/inherents.rs index 11a429b817a511e4f2954bef0f3c7bb454ac32a1..566ed6ccc42ba5a43da45718444486dac0756db3 100644 --- a/primitives/consensus/aura/src/inherents.rs +++ b/primitives/consensus/aura/src/inherents.rs @@ -16,13 +16,10 @@ /// Contains the inherents for the AURA module -use sp_timestamp::TimestampInherentData; -use inherents::{InherentIdentifier, InherentData, Error}; -use rstd::result::Result; -use codec::Decode; +use sp_inherents::{InherentIdentifier, InherentData, Error}; #[cfg(feature = "std")] -use inherents::{InherentDataProviders, ProvideInherentData}; +use sp_inherents::{InherentDataProviders, ProvideInherentData}; /// The Aura inherent identifier. pub const INHERENT_IDENTIFIER: InherentIdentifier = *b"auraslot"; @@ -86,12 +83,16 @@ impl ProvideInherentData for InherentDataProvider { &self, inherent_data: &mut InherentData, ) ->Result<(), Error> { + use sp_timestamp::TimestampInherentData; + let timestamp = inherent_data.timestamp_inherent_data()?; let slot_num = timestamp / self.slot_duration; inherent_data.put_data(INHERENT_IDENTIFIER, &slot_num) } fn error_to_string(&self, error: &[u8]) -> Option { - inherents::Error::decode(&mut &error[..]).map(|e| e.into_string()).ok() + use codec::Decode; + + sp_inherents::Error::decode(&mut &error[..]).map(|e| e.into_string()).ok() } } diff --git a/primitives/consensus/aura/src/lib.rs b/primitives/consensus/aura/src/lib.rs index 8a89452ac355c3b2cd157a2062dd88f5322ab2d8..770ed47319c345e4dbba9f27e4796f96066b159f 100644 --- a/primitives/consensus/aura/src/lib.rs +++ b/primitives/consensus/aura/src/lib.rs @@ -19,14 +19,14 @@ #![cfg_attr(not(feature = "std"), no_std)] use codec::{Encode, Decode, Codec}; -use rstd::vec::Vec; -use sr_primitives::ConsensusEngineId; +use sp_std::vec::Vec; +use sp_runtime::ConsensusEngineId; pub mod inherents; pub mod sr25519 { mod app_sr25519 { - use app_crypto::{app_crypto, key_types::AURA, sr25519}; + use sp_application_crypto::{app_crypto, key_types::AURA, sr25519}; app_crypto!(sr25519, AURA); } @@ -43,7 +43,7 @@ pub mod sr25519 { pub mod ed25519 { mod app_ed25519 { - use app_crypto::{app_crypto, key_types::AURA, ed25519}; + use sp_application_crypto::{app_crypto, key_types::AURA, ed25519}; app_crypto!(ed25519, AURA); } @@ -75,7 +75,7 @@ pub enum ConsensusLog { OnDisabled(AuthorityIndex), } -sr_api::decl_runtime_apis! { +sp_api::decl_runtime_apis! { /// API necessary for block authorship with aura. pub trait AuraApi { /// Return the slot duration in seconds for Aura. diff --git a/primitives/consensus/babe/Cargo.toml b/primitives/consensus/babe/Cargo.toml index bbdcbf9b66074641387a7a5f70ed22be210196ab..11c186faa9a1be1f0da16263e009d0ca7279c523 100644 --- a/primitives/consensus/babe/Cargo.toml +++ b/primitives/consensus/babe/Cargo.toml @@ -1,31 +1,31 @@ [package] -name = "substrate-consensus-babe-primitives" -version = "2.0.0" +name = "sp-consensus-babe" +version = "0.8.0" authors = ["Parity Technologies "] description = "Primitives for BABE consensus" edition = "2018" [dependencies] -app-crypto = { package = "substrate-application-crypto", path = "../../application-crypto", default-features = false } +sp-application-crypto = { version = "2.0.0", default-features = false, path = "../../application-crypto" } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false } -rstd = { package = "sr-std", path = "../../sr-std", default-features = false } +sp-std = { version = "2.0.0", default-features = false, path = "../../std" } schnorrkel = { version = "0.8.5", features = ["preaudit_deprecated"], optional = true } -slots = { package = "substrate-consensus-slots", path = "../../../client/consensus/slots", optional = true } -sr-api = { path = "../../sr-api", default-features = false } -sr-primitives = { path = "../../sr-primitives", default-features = false } -sp-inherents = { package = "substrate-inherents", path = "../../inherents", default-features = false } -sp-timestamp = { path = "../../timestamp", default-features = false } +sp-api = { version = "2.0.0", default-features = false, path = "../../api" } +sp-consensus = { version = "0.8", optional = true, path = "../common" } +sp-inherents = { version = "2.0.0", default-features = false, path = "../../inherents" } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../runtime" } +sp-timestamp = { version = "2.0.0", default-features = false, path = "../../timestamp" } [features] default = ["std"] std = [ - "app-crypto/std", + "sp-application-crypto/std", "codec/std", - "rstd/std", + "sp-std/std", "schnorrkel", - "slots", - "sr-api/std", - "sr-primitives/std", + "sp-api/std", + "sp-consensus", "sp-inherents/std", + "sp-runtime/std", "sp-timestamp/std", ] diff --git a/primitives/consensus/babe/src/digest.rs b/primitives/consensus/babe/src/digest.rs index 95dd247810782396499596ffaa3a1d4d74c2ce65..343cec4db79aae5e6185e995f61944ba825b0a30 100644 --- a/primitives/consensus/babe/src/digest.rs +++ b/primitives/consensus/babe/src/digest.rs @@ -22,7 +22,7 @@ use super::{BABE_ENGINE_ID, AuthoritySignature}; use super::{VRF_OUTPUT_LENGTH, VRF_PROOF_LENGTH}; use super::{AuthorityId, AuthorityIndex, SlotNumber, BabeAuthorityWeight}; #[cfg(feature = "std")] -use sr_primitives::{DigestItem, generic::OpaqueDigestItemId}; +use sp_runtime::{DigestItem, generic::OpaqueDigestItemId}; #[cfg(feature = "std")] use std::fmt::Debug; use codec::{Decode, Encode}; @@ -33,7 +33,7 @@ use schnorrkel::{ SignatureError, errors::MultiSignatureStage, vrf::{VRFProof, VRFOutput, VRF_OUTPUT_LENGTH, VRF_PROOF_LENGTH} }; -use rstd::vec::Vec; +use sp_std::vec::Vec; /// A BABE pre-runtime digest. This contains all data required to validate a @@ -195,7 +195,7 @@ impl Decode for BabePreDigest { /// Information about the next epoch. This is broadcast in the first block /// of the epoch. -#[derive(Decode, Encode, Default, PartialEq, Eq, Clone, sr_primitives::RuntimeDebug)] +#[derive(Decode, Encode, Default, PartialEq, Eq, Clone, sp_runtime::RuntimeDebug)] pub struct NextEpochDescriptor { /// The authorities. pub authorities: Vec<(AuthorityId, BabeAuthorityWeight)>, diff --git a/primitives/consensus/babe/src/inherents.rs b/primitives/consensus/babe/src/inherents.rs index 0ebefaaaf02fdf6a704e046b522cb9c13e895a66..5a4e042352dcba865ce034537ee03c86dad04ff0 100644 --- a/primitives/consensus/babe/src/inherents.rs +++ b/primitives/consensus/babe/src/inherents.rs @@ -23,7 +23,7 @@ use sp_timestamp::TimestampInherentData; #[cfg(feature = "std")] use codec::Decode; -use rstd::result::Result; +use sp_std::result::Result; /// The BABE inherent identifier. pub const INHERENT_IDENTIFIER: InherentIdentifier = *b"babeslot"; diff --git a/primitives/consensus/babe/src/lib.rs b/primitives/consensus/babe/src/lib.rs index 532aaa6dc1a9d4eac50978f9abce675439252265..196f1be1a65d62d71e659dfbb98bbd19d1f04c19 100644 --- a/primitives/consensus/babe/src/lib.rs +++ b/primitives/consensus/babe/src/lib.rs @@ -23,15 +23,15 @@ mod digest; pub mod inherents; use codec::{Encode, Decode}; -use rstd::vec::Vec; -use sr_primitives::{ConsensusEngineId, RuntimeDebug}; +use sp_std::vec::Vec; +use sp_runtime::{ConsensusEngineId, RuntimeDebug}; #[cfg(feature = "std")] pub use digest::{BabePreDigest, CompatibleDigestItem}; pub use digest::{BABE_VRF_PREFIX, RawBabePreDigest, NextEpochDescriptor}; mod app { - use app_crypto::{app_crypto, key_types::BABE, sr25519}; + use sp_application_crypto::{app_crypto, key_types::BABE, sr25519}; app_crypto!(sr25519, BABE); } @@ -157,7 +157,7 @@ pub struct BabeConfiguration { } #[cfg(feature = "std")] -impl slots::SlotData for BabeConfiguration { +impl sp_consensus::SlotData for BabeConfiguration { fn slot_duration(&self) -> u64 { self.slot_duration } @@ -165,7 +165,7 @@ impl slots::SlotData for BabeConfiguration { const SLOT_KEY: &'static [u8] = b"babe_configuration"; } -sr_api::decl_runtime_apis! { +sp_api::decl_runtime_apis! { /// API necessary for block authorship with BABE. pub trait BabeApi { /// Return the configuration for BABE. Currently, diff --git a/primitives/consensus/common/Cargo.toml b/primitives/consensus/common/Cargo.toml index 11a266ac9dc1042bad4e3497d63bb1acc4c26527..768552a8edbd12124cf50eb5a93625c3a97b80d2 100644 --- a/primitives/consensus/common/Cargo.toml +++ b/primitives/consensus/common/Cargo.toml @@ -1,26 +1,26 @@ [package] -name = "substrate-consensus-common" -version = "2.0.0" +name = "sp-consensus" +version = "0.8.0" authors = ["Parity Technologies "] description = "Common utilities for substrate consensus" edition = "2018" [dependencies] -derive_more = "0.15.0" +derive_more = "0.99.2" libp2p = { version = "0.13.0", default-features = false } log = "0.4.8" -primitives = { package = "substrate-primitives", path= "../../core" } -inherents = { package = "substrate-inherents", path = "../../inherents" } +sp-core = { path= "../../core" } +sp-inherents = { version = "2.0.0", path = "../../inherents" } futures = { version = "0.3.1", features = ["thread-pool"] } futures-timer = "0.4.0" -rstd = { package = "sr-std", path = "../../sr-std" } -runtime_version = { package = "sr-version", path = "../../sr-version" } -sr-primitives = { path = "../../sr-primitives" } +sp-std = { version = "2.0.0", path = "../../std" } +sp-version = { version = "2.0.0", path = "../../version" } +sp-runtime = { version = "2.0.0", path = "../../runtime" } codec = { package = "parity-scale-codec", version = "1.0.0", features = ["derive"] } parking_lot = "0.9.0" [dev-dependencies] -test-client = { package = "substrate-test-runtime-client", path = "../../../test/utils/runtime/client" } +sp-test-primitives = { version = "2.0.0", path = "../../test-primitives" } [features] default = [] diff --git a/primitives/consensus/common/src/block_import.rs b/primitives/consensus/common/src/block_import.rs index 79d9be7b84e2363388d1b0c4431784d656c7c2de..aab70625ff80f14ba025decdb8b5e9499713ade9 100644 --- a/primitives/consensus/common/src/block_import.rs +++ b/primitives/consensus/common/src/block_import.rs @@ -16,8 +16,8 @@ //! Block import helpers. -use sr_primitives::traits::{Block as BlockT, DigestItemFor, Header as HeaderT, NumberFor}; -use sr_primitives::Justification; +use sp_runtime::traits::{Block as BlockT, DigestItemFor, Header as HeaderT, NumberFor}; +use sp_runtime::Justification; use std::borrow::Cow; use std::collections::HashMap; use std::sync::Arc; @@ -105,6 +105,8 @@ pub struct BlockCheckParams { pub parent_hash: Block::Hash, /// Allow importing the block skipping state verification if parent state is missing. pub allow_missing_state: bool, + /// Re-validate existing block. + pub import_existing: bool, } /// Data required to import a Block. @@ -142,6 +144,8 @@ pub struct BlockImportParams { pub fork_choice: ForkChoiceStrategy, /// Allow importing the block skipping state verification if parent state is missing. pub allow_missing_state: bool, + /// Re-validate existing block. + pub import_existing: bool, } impl BlockImportParams { diff --git a/primitives/consensus/common/src/block_validation.rs b/primitives/consensus/common/src/block_validation.rs index be181b05c6f4d2085f5dfca2012fa067911fdbd6..42231bbf4c84cfbea17b312d8df6b1a35e06a986 100644 --- a/primitives/consensus/common/src/block_validation.rs +++ b/primitives/consensus/common/src/block_validation.rs @@ -17,7 +17,7 @@ //! Block announcement validation. use crate::BlockStatus; -use sr_primitives::{generic::BlockId, traits::Block}; +use sp_runtime::{generic::BlockId, traits::Block}; use std::{error::Error, sync::Arc}; /// A type which provides access to chain information. diff --git a/primitives/consensus/common/src/error.rs b/primitives/consensus/common/src/error.rs index 16781b04ff27f7e00c86373add1fc32be017a5dc..29e9a3ee920de1d4a6b9f4e5a5af5800f0958734 100644 --- a/primitives/consensus/common/src/error.rs +++ b/primitives/consensus/common/src/error.rs @@ -15,8 +15,8 @@ // along with Substrate. If not, see . //! Error types in Consensus -use runtime_version::RuntimeVersion; -use primitives::ed25519::{Public, Signature}; +use sp_version::RuntimeVersion; +use sp_core::ed25519::{Public, Signature}; use std::error; /// Result type alias. @@ -36,7 +36,7 @@ pub enum Error { FaultyTimer(std::io::Error), /// Error while working with inherent data. #[display(fmt="InherentData error: {}", _0)] - InherentData(inherents::Error), + InherentData(sp_inherents::Error), /// Unable to propose a block. #[display(fmt="Unable to create block proposal.")] CannotPropose, @@ -67,9 +67,11 @@ pub enum Error { Other(Box), /// Error from the client while importing #[display(fmt="Import failed: {}", _0)] + #[from(ignore)] ClientImport(String), /// Error from the client while importing #[display(fmt="Chain lookup failed: {}", _0)] + #[from(ignore)] ChainLookup(String), } diff --git a/primitives/consensus/common/src/evaluation.rs b/primitives/consensus/common/src/evaluation.rs index 7a3e565aa09d1ab8c389436e331e3f3d6ab6476c..875ce41e01a1fe2bad874101ff6000adef5a72fd 100644 --- a/primitives/consensus/common/src/evaluation.rs +++ b/primitives/consensus/common/src/evaluation.rs @@ -19,7 +19,7 @@ use super::MAX_BLOCK_SIZE; use codec::Encode; -use sr_primitives::traits::{Block as BlockT, Header as HeaderT, One, CheckedConversion}; +use sp_runtime::traits::{Block as BlockT, Header as HeaderT, One, CheckedConversion}; // This is just a best effort to encode the number. None indicated that it's too big to encode // in a u128. diff --git a/primitives/consensus/common/src/import_queue.rs b/primitives/consensus/common/src/import_queue.rs index 4bc986e1a3ee60a5ee5cb8238fdadcc0248ca28c..1d8ea0f0ceb0cffb4dc05acd8ff3c26c88cefc54 100644 --- a/primitives/consensus/common/src/import_queue.rs +++ b/primitives/consensus/common/src/import_queue.rs @@ -26,7 +26,7 @@ //! queues to be instantiated simply. use std::collections::HashMap; -use sr_primitives::{Justification, traits::{Block as BlockT, Header as _, NumberFor}}; +use sp_runtime::{Justification, traits::{Block as BlockT, Header as _, NumberFor}}; use crate::error::Error as ConsensusError; use crate::block_import::{ BlockImport, BlockOrigin, BlockImportParams, ImportedAux, JustificationImport, ImportResult, @@ -65,6 +65,8 @@ pub struct IncomingBlock { pub origin: Option, /// Allow importing the block skipping state verification if parent state is missing. pub allow_missing_state: bool, + /// Re-validate existing block. + pub import_existing: bool, } /// Type of keys in the blockchain cache that consensus module could use for its needs. @@ -230,6 +232,7 @@ pub fn import_single_block>( number, parent_hash, allow_missing_state: block.allow_missing_state, + import_existing: block.import_existing, }))? { BlockImportResult::ImportedUnknown { .. } => (), r => return Ok(r), // Any other successful result means that the block is already imported. diff --git a/primitives/consensus/common/src/import_queue/basic_queue.rs b/primitives/consensus/common/src/import_queue/basic_queue.rs index 2ab6d0c5e3b7dd43e12834a2ac3813348387ade7..42a31ceb640cf7f5ebbddcda45115724110bb6cc 100644 --- a/primitives/consensus/common/src/import_queue/basic_queue.rs +++ b/primitives/consensus/common/src/import_queue/basic_queue.rs @@ -17,7 +17,7 @@ use std::{mem, pin::Pin, time::Duration}; use futures::{prelude::*, channel::mpsc, task::Context, task::Poll}; use futures_timer::Delay; -use sr_primitives::{Justification, traits::{Block as BlockT, Header as HeaderT, NumberFor}}; +use sp_runtime::{Justification, traits::{Block as BlockT, Header as HeaderT, NumberFor}}; use crate::block_import::BlockOrigin; use crate::import_queue::{ diff --git a/primitives/consensus/common/src/import_queue/buffered_link.rs b/primitives/consensus/common/src/import_queue/buffered_link.rs index b88f1bfd1e8846b22d2684148bb9d5d86d270ec3..4772af92f1f3dfd090bcc665e91e5dc28ecec913 100644 --- a/primitives/consensus/common/src/import_queue/buffered_link.rs +++ b/primitives/consensus/common/src/import_queue/buffered_link.rs @@ -21,9 +21,9 @@ //! # Example //! //! ``` -//! use substrate_consensus_common::import_queue::Link; -//! # use substrate_consensus_common::import_queue::buffered_link::buffered_link; -//! # use test_client::runtime::Block; +//! use sp_consensus::import_queue::Link; +//! # use sp_consensus::import_queue::buffered_link::buffered_link; +//! # use sp_test_primitives::Block; //! # struct DummyLink; impl Link for DummyLink {} //! # let mut my_link = DummyLink; //! let (mut tx, mut rx) = buffered_link::(); @@ -38,7 +38,7 @@ //! use futures::{prelude::*, channel::mpsc}; -use sr_primitives::traits::{Block as BlockT, NumberFor}; +use sp_runtime::traits::{Block as BlockT, NumberFor}; use std::{pin::Pin, task::Context, task::Poll}; use crate::import_queue::{Origin, Link, BlockImportResult, BlockImportError}; @@ -161,7 +161,7 @@ impl BufferedLinkReceiver { #[cfg(test)] mod tests { - use test_client::runtime::Block; + use sp_test_primitives::Block; #[test] fn is_closed() { diff --git a/primitives/consensus/common/src/lib.rs b/primitives/consensus/common/src/lib.rs index 154ea7bb52f7c78c03b38d1cee86179cdaf179f4..413f541340d89604bec8bfea808341ea82fb6bef 100644 --- a/primitives/consensus/common/src/lib.rs +++ b/primitives/consensus/common/src/lib.rs @@ -31,9 +31,9 @@ use std::sync::Arc; use std::time::Duration; -use sr_primitives::traits::{Block as BlockT, DigestFor}; +use sp_runtime::{traits::{Block as BlockT, DigestFor}, generic::BlockId}; use futures::prelude::*; -pub use inherents::InherentData; +pub use sp_inherents::InherentData; pub mod block_validation; pub mod offline_tracker; @@ -123,13 +123,78 @@ impl SyncOracle for NoNetwork { fn is_offline(&mut self) -> bool { false } } -impl SyncOracle for Arc -where T: ?Sized, for<'r> &'r T: SyncOracle -{ +impl SyncOracle for Arc where T: ?Sized, for<'r> &'r T: SyncOracle { fn is_major_syncing(&mut self) -> bool { <&T>::is_major_syncing(&mut &**self) } + fn is_offline(&mut self) -> bool { <&T>::is_offline(&mut &**self) } } + +/// Checks if the current active native block authoring implementation can author with the runtime +/// at the given block. +pub trait CanAuthorWith { + /// See trait docs for more information. + /// + /// # Return + /// + /// - Returns `Ok(())` when authoring is supported. + /// - Returns `Err(_)` when authoring is not supported. + fn can_author_with(&self, at: &BlockId) -> Result<(), String>; +} + +/// Checks if the node can author blocks by using +/// [`NativeVersion::can_author_with`](sp_version::NativeVersion::can_author_with). +pub struct CanAuthorWithNativeVersion(T); + +impl CanAuthorWithNativeVersion { + /// Creates a new instance of `Self`. + pub fn new(inner: T) -> Self { + Self(inner) + } +} + +impl, Block: BlockT> CanAuthorWith + for CanAuthorWithNativeVersion +{ + fn can_author_with(&self, at: &BlockId) -> Result<(), String> { + match self.0.runtime_version(at) { + Ok(version) => self.0.native_version().can_author_with(&version), + Err(e) => { + Err(format!( + "Failed to get runtime version at `{}` and will disable authoring. Error: {}", + at, + e, + )) + } + } + } +} + +/// Returns always `true` for `can_author_with`. This is useful for tests. +pub struct AlwaysCanAuthor; + +impl CanAuthorWith for AlwaysCanAuthor { + fn can_author_with(&self, _: &BlockId) -> Result<(), String> { + Ok(()) + } +} + +/// A type from which a slot duration can be obtained. +pub trait SlotData { + /// Gets the slot duration. + fn slot_duration(&self) -> u64; + + /// The static slot key + const SLOT_KEY: &'static [u8]; +} + +impl SlotData for u64 { + fn slot_duration(&self) -> u64 { + *self + } + + const SLOT_KEY: &'static [u8] = b"aura_slot_duration"; +} diff --git a/primitives/consensus/common/src/select_chain.rs b/primitives/consensus/common/src/select_chain.rs index e696db6b877b47d1290637a00e76f7dc6cbf9ee5..da0bae4900517fad654372d2a5ae3622074ff68c 100644 --- a/primitives/consensus/common/src/select_chain.rs +++ b/primitives/consensus/common/src/select_chain.rs @@ -15,7 +15,7 @@ // along with Substrate Consensus Common. If not, see . use crate::error::Error; -use sr_primitives::traits::{Block as BlockT, NumberFor}; +use sp_runtime::traits::{Block as BlockT, NumberFor}; /// The SelectChain trait defines the strategy upon which the head is chosen diff --git a/primitives/consensus/pow/Cargo.toml b/primitives/consensus/pow/Cargo.toml index 99aa00da8ee8e0a66b1abfe9075fca4e82866a8d..12e97890d7a1c2e57ce61e5f9ffecf7168a9ec2c 100644 --- a/primitives/consensus/pow/Cargo.toml +++ b/primitives/consensus/pow/Cargo.toml @@ -1,23 +1,23 @@ [package] -name = "substrate-consensus-pow-primitives" -version = "2.0.0" +name = "sp-consensus-pow" +version = "0.8.0" authors = ["Parity Technologies "] description = "Primitives for Aura consensus" edition = "2018" [dependencies] -sr-api = { path = "../../sr-api", default-features = false } -rstd = { package = "sr-std", path = "../../sr-std", default-features = false } -sr-primitives = { path = "../../sr-primitives", default-features = false } -primitives = { package = "substrate-primitives", path = "../../core", default-features = false } +sp-api = { version = "2.0.0", default-features = false, path = "../../api" } +sp-std = { version = "2.0.0", default-features = false, path = "../../std" } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../runtime" } +sp-core = { version = "2.0.0", default-features = false, path = "../../core" } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } [features] default = ["std"] std = [ - "rstd/std", - "sr-api/std", - "sr-primitives/std", - "primitives/std", + "sp-std/std", + "sp-api/std", + "sp-runtime/std", + "sp-core/std", "codec/std", ] diff --git a/primitives/consensus/pow/src/lib.rs b/primitives/consensus/pow/src/lib.rs index 400ed0594a02693fad349059e5a484ecad43fcf2..6a1c1179edcfc643c752522837ad31958b74c1f5 100644 --- a/primitives/consensus/pow/src/lib.rs +++ b/primitives/consensus/pow/src/lib.rs @@ -18,8 +18,8 @@ #![cfg_attr(not(feature = "std"), no_std)] -use rstd::vec::Vec; -use sr_primitives::ConsensusEngineId; +use sp_std::vec::Vec; +use sp_runtime::ConsensusEngineId; use codec::Decode; /// The `ConsensusEngineId` of PoW. @@ -33,7 +33,7 @@ pub trait TotalDifficulty { fn increment(&mut self, other: Self); } -impl TotalDifficulty for primitives::U256 { +impl TotalDifficulty for sp_core::U256 { fn increment(&mut self, other: Self) { let ret = self.saturating_add(other); *self = ret; @@ -47,7 +47,7 @@ impl TotalDifficulty for u128 { } } -sr_api::decl_runtime_apis! { +sp_api::decl_runtime_apis! { /// API necessary for timestamp-based difficulty adjustment algorithms. pub trait TimestampApi { /// Return the timestamp in the current block. diff --git a/primitives/core/Cargo.toml b/primitives/core/Cargo.toml index 240da745f46ca983bf67afae7ea118f78ccc9807..706a9cb276f7195642a528ec2729e585ef52ef4a 100644 --- a/primitives/core/Cargo.toml +++ b/primitives/core/Cargo.toml @@ -1,45 +1,48 @@ [package] -name = "substrate-primitives" +name = "sp-core" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" [dependencies] -rstd = { package = "sr-std", path = "../sr-std", default-features = false } +sp-std = { version = "2.0.0", default-features = false, path = "../std" } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } rustc-hex = { version = "2.0.1", default-features = false } log = { version = "0.4.8", default-features = false } serde = { version = "1.0.101", optional = true, features = ["derive"] } -twox-hash = { version = "1.5.0", default-features = false, optional = true } byteorder = { version = "1.3.2", default-features = false } primitive-types = { version = "0.6", default-features = false, features = ["codec"] } impl-serde = { version = "0.2.3", optional = true } wasmi = { version = "0.6.2", optional = true } hash-db = { version = "0.15.2", default-features = false } hash256-std-hasher = { version = "0.15.2", default-features = false } -ed25519-dalek = { version = "0.9.1", default-features = false, features = ["u64_backend"], optional = true } base58 = { version = "0.1.0", optional = true } -blake2-rfc = { version = "0.2.18", default-features = false, optional = true } -schnorrkel = { version = "0.8.5", features = ["preaudit_deprecated"], default-features = false, optional = true } rand = { version = "0.7.2", optional = true } -sha2 = { version = "0.8.0", default-features = false, optional = true } substrate-bip39 = { version = "0.3.1", optional = true } tiny-bip39 = { version = "0.6.2", optional = true } -hex = { version = "0.4", default-features = false, optional = true } regex = { version = "1.3.1", optional = true } num-traits = { version = "0.2.8", default-features = false } zeroize = { version = "1.0.0", default-features = false } lazy_static = { version = "1.4.0", default-features = false, optional = true } parking_lot = { version = "0.9.0", optional = true } -libsecp256k1 = { version = "0.3.0", default-features = false, optional = true } +sp-debug-derive = { version = "2.0.0", path = "../debug-derive" } +sp-externalities = { version = "2.0.0", optional = true, path = "../externalities" } +sp-storage = { version = "2.0.0", default-features = false, path = "../storage" } + +# full crypto +ed25519-dalek = { version = "1.0.0-pre.3", default-features = false, features = ["u64_backend", "alloc"], optional = true } +blake2-rfc = { version = "0.2.18", default-features = false, optional = true } tiny-keccak = { version = "2.0.1", features = ["keccak"], optional = true } -substrate-debug-derive = { version = "2.0.0", path = "./debug-derive" } -externalities = { package = "substrate-externalities", path = "../externalities", optional = true } -primitives-storage = { package = "substrate-primitives-storage", path = "storage", default-features = false } -runtime-interface = { package = "substrate-runtime-interface", path = "../runtime-interface", default-features = false } +schnorrkel = { version = "0.8.5", features = ["preaudit_deprecated", "u64_backend"], default-features = false, optional = true } +libsecp256k1 = { version = "0.3.2", default-features = false, optional = true } +sha2 = { version = "0.8.0", default-features = false, optional = true } +hex = { version = "0.4", default-features = false, optional = true } +twox-hash = { version = "1.5.0", default-features = false, optional = true } + +sp-runtime-interface = { version = "2.0.0", default-features = false, path = "../runtime-interface" } [dev-dependencies] -substrate-serializer = { path = "../serializer" } +sp-serializer = { version = "2.0.0", path = "../serializer" } pretty_assertions = "0.6.1" hex-literal = "0.2.1" rand = "0.7.2" @@ -70,7 +73,7 @@ std = [ "codec/std", "hash256-std-hasher/std", "hash-db/std", - "rstd/std", + "sp-std/std", "serde", "rustc-hex/std", "twox-hash/std", @@ -89,10 +92,10 @@ std = [ "num-traits/std", "libsecp256k1", "tiny-keccak", - "substrate-debug-derive/std", - "externalities", - "primitives-storage/std", - "runtime-interface/std", + "sp-debug-derive/std", + "sp-externalities", + "sp-storage/std", + "sp-runtime-interface/std", "zeroize/alloc" ] @@ -108,5 +111,5 @@ full_crypto = [ "hex", "sha2", "twox-hash", - "runtime-interface/disable_target_static_assertions", + "sp-runtime-interface/disable_target_static_assertions", ] diff --git a/primitives/core/benches/bench.rs b/primitives/core/benches/bench.rs index 5245af44a81313698fadb65f2e5dec4e9d99ee44..d03407de5f152f3437c9db2a99512d1bd7a76df3 100644 --- a/primitives/core/benches/bench.rs +++ b/primitives/core/benches/bench.rs @@ -16,11 +16,10 @@ #[macro_use] extern crate criterion; -use substrate_primitives as primitives; use criterion::{Criterion, black_box, Bencher, Fun}; use std::time::Duration; -use primitives::crypto::Pair as _; -use primitives::hashing::{twox_128, blake2_128}; +use sp_core::crypto::Pair as _; +use sp_core::hashing::{twox_128, blake2_128}; const MAX_KEY_SIZE: u32 = 32; @@ -72,7 +71,7 @@ fn bench_ed25519(c: &mut Criterion) { let msg = (0..msg_size) .map(|_| rand::random::()) .collect::>(); - let key = primitives::ed25519::Pair::generate().0; + let key = sp_core::ed25519::Pair::generate().0; b.iter(|| key.sign(&msg)) }, vec![32, 1024, 1024 * 1024]); @@ -80,10 +79,10 @@ fn bench_ed25519(c: &mut Criterion) { let msg = (0..msg_size) .map(|_| rand::random::()) .collect::>(); - let key = primitives::ed25519::Pair::generate().0; + let key = sp_core::ed25519::Pair::generate().0; let sig = key.sign(&msg); let public = key.public(); - b.iter(|| primitives::ed25519::Pair::verify(&sig, &msg, &public)) + b.iter(|| sp_core::ed25519::Pair::verify(&sig, &msg, &public)) }, vec![32, 1024, 1024 * 1024]); } diff --git a/primitives/core/src/changes_trie.rs b/primitives/core/src/changes_trie.rs index 5e88485a039945c02660572b18a8c8277d53f298..f746e1dc8d7b2acb99f54d824a7fcb4de4a20fc6 100644 --- a/primitives/core/src/changes_trie.rs +++ b/primitives/core/src/changes_trie.rs @@ -57,8 +57,8 @@ impl ChangesTrieConfiguration { ) -> bool where Number: From + PartialEq + - ::rstd::ops::Rem + ::rstd::ops::Sub + - ::rstd::cmp::PartialOrd + Zero, + ::sp_std::ops::Rem + ::sp_std::ops::Sub + + ::sp_std::cmp::PartialOrd + Zero, { block > zero && self.is_digest_build_enabled() @@ -92,8 +92,8 @@ impl ChangesTrieConfiguration { ) -> Option where Number: Clone + From + PartialOrd + PartialEq + - ::rstd::ops::Add + ::rstd::ops::Sub + - ::rstd::ops::Div + ::rstd::ops::Mul + Zero, + ::sp_std::ops::Add + ::sp_std::ops::Sub + + ::sp_std::ops::Div + ::sp_std::ops::Mul + Zero, { if block <= zero { return None; @@ -126,8 +126,8 @@ impl ChangesTrieConfiguration { ) -> Option<(Number, Number)> where Number: Clone + From + PartialOrd + PartialEq + - ::rstd::ops::Add + ::rstd::ops::Sub + - ::rstd::ops::Div + ::rstd::ops::Mul, + ::sp_std::ops::Add + ::sp_std::ops::Sub + + ::sp_std::ops::Div + ::sp_std::ops::Mul, { if !self.is_digest_build_enabled() { return None; @@ -160,8 +160,8 @@ impl ChangesTrieConfiguration { pub fn digest_level_at_block(&self, zero: Number, block: Number) -> Option<(u32, u32, u32)> where Number: Clone + From + PartialEq + - ::rstd::ops::Rem + ::rstd::ops::Sub + - ::rstd::cmp::PartialOrd + Zero, + ::sp_std::ops::Rem + ::sp_std::ops::Sub + + ::sp_std::cmp::PartialOrd + Zero, { if !self.is_digest_build_required_at_block(zero.clone(), block.clone()) { return None; diff --git a/primitives/core/src/crypto.rs b/primitives/core/src/crypto.rs index f5484efed7a38ca39fce39312e2ea581bd704a4e..fe3a53c83a37966c295fed28897080790eb5b8b2 100644 --- a/primitives/core/src/crypto.rs +++ b/primitives/core/src/crypto.rs @@ -18,10 +18,12 @@ //! Cryptographic utilities. // end::description[] -use rstd::{vec::Vec, hash::Hash}; +use sp_std::hash::Hash; +#[cfg(feature = "full_crypto")] +use sp_std::vec::Vec; #[cfg(feature = "std")] -use rstd::convert::TryInto; -use rstd::convert::TryFrom; +use sp_std::convert::TryInto; +use sp_std::convert::TryFrom; #[cfg(feature = "std")] use parking_lot::Mutex; #[cfg(feature = "std")] @@ -34,8 +36,8 @@ use base58::{FromBase58, ToBase58}; use zeroize::Zeroize; #[doc(hidden)] -pub use rstd::ops::Deref; -use runtime_interface::pass_by::PassByInner; +pub use sp_std::ops::Deref; +use sp_runtime_interface::pass_by::PassByInner; /// The root phrase for our publicly known keys. pub const DEV_PHRASE: &str = "bottom drive obey lake curtain smoke basket hold race lonely fit walk"; @@ -86,7 +88,7 @@ impl AsRef for Protected { } } -impl rstd::ops::Deref for Protected { +impl sp_std::ops::Deref for Protected { type Target = T; fn deref(&self) -> &T { @@ -266,6 +268,7 @@ pub trait Ss58Codec: Sized + AsMut<[u8]> + AsRef<[u8]> + Default { Ss58AddressFormat::PolkadotAccountDirect => Ok(r), Ss58AddressFormat::KusamaAccountDirect => Ok(r), Ss58AddressFormat::DothereumAccountDirect => Ok(r), + Ss58AddressFormat::EdgewareAccountDirect => Ok(r), v if v == *DEFAULT_VERSION.lock() => Ok(r), _ => Err(PublicError::UnknownVersion), }) @@ -299,6 +302,7 @@ pub trait Ss58Codec: Sized + AsMut<[u8]> + AsRef<[u8]> + Default { Ss58AddressFormat::PolkadotAccountDirect => Ok(r), Ss58AddressFormat::KusamaAccountDirect => Ok(r), Ss58AddressFormat::DothereumAccountDirect => Ok(r), + Ss58AddressFormat::EdgewareAccountDirect => Ok(r), v if v == *DEFAULT_VERSION.lock() => Ok(r), _ => Err(PublicError::UnknownVersion), }) @@ -353,76 +357,87 @@ lazy_static::lazy_static! { = Mutex::new(Ss58AddressFormat::SubstrateAccountDirect); } -/// A known address (sub)format/network ID for SS58. #[cfg(feature = "full_crypto")] -#[derive(Copy, Clone, PartialEq, Eq)] -pub enum Ss58AddressFormat { - /// Any Substrate network, direct checksum, standard account (*25519). - SubstrateAccountDirect, - /// Polkadot Relay-chain, direct checksum, standard account (*25519). - PolkadotAccountDirect, - /// Kusama Relay-chain, direct checksum, standard account (*25519). - KusamaAccountDirect, - /// Dothereum Para-chain, direct checksum, standard account (*25519). - DothereumAccountDirect, - /// Use a manually provided numeric value. - Custom(u8), -} +macro_rules! ss58_address_format { + ( $( $identifier:tt => ($number:expr, $name:expr, $desc:tt) )* ) => ( + /// A known address (sub)format/network ID for SS58. + #[derive(Copy, Clone, PartialEq, Eq)] + pub enum Ss58AddressFormat { + $(#[doc = $desc] $identifier),*, + /// Use a manually provided numeric value. + Custom(u8), + } -#[cfg(feature = "full_crypto")] -impl From for u8 { - fn from(x: Ss58AddressFormat) -> u8 { - match x { - Ss58AddressFormat::SubstrateAccountDirect => 42, - Ss58AddressFormat::PolkadotAccountDirect => 0, - Ss58AddressFormat::KusamaAccountDirect => 2, - Ss58AddressFormat::DothereumAccountDirect => 20, - Ss58AddressFormat::Custom(n) => n, + static ALL_SS58_ADDRESS_FORMATS: [Ss58AddressFormat; 0 $(+ { let _ = $number; 1})*] = [ + $(Ss58AddressFormat::$identifier),*, + ]; + + impl Ss58AddressFormat { + /// All known address formats. + pub fn all() -> &'static [Ss58AddressFormat] { + &ALL_SS58_ADDRESS_FORMATS + } } - } -} -#[cfg(feature = "full_crypto")] -impl TryFrom for Ss58AddressFormat { - type Error = (); - fn try_from(x: u8) -> Result { - match x { - 42 => Ok(Ss58AddressFormat::SubstrateAccountDirect), - 0 => Ok(Ss58AddressFormat::PolkadotAccountDirect), - 2 => Ok(Ss58AddressFormat::KusamaAccountDirect), - 20 => Ok(Ss58AddressFormat::DothereumAccountDirect), - _ => Err(()), + impl From for u8 { + fn from(x: Ss58AddressFormat) -> u8 { + match x { + $(Ss58AddressFormat::$identifier => $number),*, + Ss58AddressFormat::Custom(n) => n, + } + } } - } -} -#[cfg(feature = "full_crypto")] -impl<'a> TryFrom<&'a str> for Ss58AddressFormat { - type Error = (); - fn try_from(x: &'a str) -> Result { - match x { - "substrate" => Ok(Ss58AddressFormat::SubstrateAccountDirect), - "polkadot" => Ok(Ss58AddressFormat::PolkadotAccountDirect), - "kusama" => Ok(Ss58AddressFormat::KusamaAccountDirect), - "dothereum" => Ok(Ss58AddressFormat::DothereumAccountDirect), - a => a.parse::().map(Ss58AddressFormat::Custom).map_err(|_| ()), + impl TryFrom for Ss58AddressFormat { + type Error = (); + + fn try_from(x: u8) -> Result { + match x { + $($number => Ok(Ss58AddressFormat::$identifier)),*, + _ => Err(()), + } + } } - } -} -#[cfg(feature = "std")] -impl From for String { - fn from(x: Ss58AddressFormat) -> String { - match x { - Ss58AddressFormat::SubstrateAccountDirect => "substrate".into(), - Ss58AddressFormat::PolkadotAccountDirect => "polkadot".into(), - Ss58AddressFormat::KusamaAccountDirect => "kusama".into(), - Ss58AddressFormat::DothereumAccountDirect => "dothereum".into(), - Ss58AddressFormat::Custom(x) => x.to_string(), + impl<'a> TryFrom<&'a str> for Ss58AddressFormat { + type Error = (); + + fn try_from(x: &'a str) -> Result { + match x { + $($name => Ok(Ss58AddressFormat::$identifier)),*, + a => a.parse::().map(Ss58AddressFormat::Custom).map_err(|_| ()), + } + } } - } + + #[cfg(feature = "std")] + impl From for String { + fn from(x: Ss58AddressFormat) -> String { + match x { + $(Ss58AddressFormat::$identifier => $name.into()),*, + Ss58AddressFormat::Custom(x) => x.to_string(), + } + } + } + ) } +#[cfg(feature = "full_crypto")] +ss58_address_format!( + SubstrateAccountDirect => + (42, "substrate", "Any Substrate network, direct checksum, standard account (*25519).") + PolkadotAccountDirect => + (0, "polkadot", "Polkadot Relay-chain, direct checksum, standard account (*25519).") + KusamaAccountDirect => + (2, "kusama", "Kusama Relay-chain, direct checksum, standard account (*25519).") + DothereumAccountDirect => + (20, "dothereum", "Dothereum Para-chain, direct checksum, standard account (*25519).") + KulupuAccountDirect => + (16, "kulupu", "Kulupu mainnet, direct checksum, standard account (*25519).") + EdgewareAccountDirect => + (7, "edgeware", "Edgeware mainnet, direct checksum, standard account (*25519).") +); + /// Set the default "version" (actually, this is a bit of a misnomer and the version byte is /// typically used not just to encode format/version but also network identity) that is used for /// encoding and decoding SS58 addresses. If an unknown version is provided then it fails. @@ -430,6 +445,7 @@ impl From for String { /// Current known "versions" are: /// - 0 direct (payload) checksum for 32-byte *25519 Polkadot addresses. /// - 2 direct (payload) checksum for 32-byte *25519 Kusama addresses. +/// - 7 direct (payload) checksum for 32-byte *25519 Edgeware addresses. /// - 20 direct (payload) checksum for 32-byte *25519 Dothereum addresses. /// - 42 direct (payload) checksum for 32-byte *25519 addresses on any Substrate-based network. #[cfg(feature = "std")] @@ -552,7 +568,7 @@ impl From<[u8; 32]> for AccountId32 { } } -impl<'a> rstd::convert::TryFrom<&'a [u8]> for AccountId32 { +impl<'a> sp_std::convert::TryFrom<&'a [u8]> for AccountId32 { type Error = (); fn try_from(x: &'a [u8]) -> Result { if x.len() == 32 { @@ -578,15 +594,15 @@ impl std::fmt::Display for AccountId32 { } } -impl rstd::fmt::Debug for AccountId32 { +impl sp_std::fmt::Debug for AccountId32 { #[cfg(feature = "std")] - fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { let s = self.to_ss58check(); write!(f, "{} ({}...)", crate::hexdisplay::HexDisplay::from(&self.0), &s[0..8]) } #[cfg(not(feature = "std"))] - fn fmt(&self, _: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { Ok(()) } } @@ -625,7 +641,7 @@ mod dummy { fn as_mut(&mut self) -> &mut[u8] { unsafe { #[allow(mutable_transmutes)] - rstd::mem::transmute::<_, &'static mut [u8]>(&b""[..]) + sp_std::mem::transmute::<_, &'static mut [u8]>(&b""[..]) } } } @@ -772,8 +788,8 @@ pub trait Pair: CryptoType + Sized + Clone + Send + Sync + 'static { /// /// `None` is returned if no matches are found. #[cfg(feature = "std")] - fn from_string_with_seed(s: &str, password_override: Option<&str>) - -> Result<(Self, Option), SecretStringError> + fn from_string_with_seed(s: &str, password_override: Option<&str>) + -> Result<(Self, Option), SecretStringError> { let re = Regex::new(r"^(?P[\d\w ]+)?(?P(//?[^/]+)*)(///(?P.*))?$") .expect("constructed from known-good static value; qed"); diff --git a/primitives/core/src/ecdsa.rs b/primitives/core/src/ecdsa.rs index 7ba750f49b948ec20f4bb21d123a46455943fa6b..e097d0c5e6fe60bed89cde89264f5f06e30b505a 100644 --- a/primitives/core/src/ecdsa.rs +++ b/primitives/core/src/ecdsa.rs @@ -19,9 +19,9 @@ // end::description[] #[cfg(feature = "full_crypto")] -use rstd::vec::Vec; +use sp_std::vec::Vec; -use rstd::cmp::Ordering; +use sp_std::cmp::Ordering; use codec::{Encode, Decode}; #[cfg(feature = "full_crypto")] @@ -46,9 +46,9 @@ use secp256k1::{PublicKey, SecretKey}; #[cfg(feature = "full_crypto")] type Seed = [u8; 32]; -/// The ECDSA 33-byte compressed public key. +/// The ECDSA 64-byte raw public key. #[derive(Clone, Encode, Decode)] -pub struct Public(pub [u8; 33]); +pub struct Public(pub [u8; 64]); impl PartialOrd for Public { fn partial_cmp(&self, other: &Self) -> Option { @@ -72,7 +72,7 @@ impl Eq for Public {} impl Default for Public { fn default() -> Self { - Public([0u8; 33]) + Public([0u8; 64]) } } @@ -84,8 +84,8 @@ pub struct Pair { secret: SecretKey, } -impl AsRef<[u8; 33]> for Public { - fn as_ref(&self) -> &[u8; 33] { +impl AsRef<[u8; 64]> for Public { + fn as_ref(&self) -> &[u8; 64] { &self.0 } } @@ -102,12 +102,12 @@ impl AsMut<[u8]> for Public { } } -impl rstd::convert::TryFrom<&[u8]> for Public { +impl sp_std::convert::TryFrom<&[u8]> for Public { type Error = (); fn try_from(data: &[u8]) -> Result { - if data.len() == 33 { - let mut inner = [0u8; 33]; + if data.len() == 64 { + let mut inner = [0u8; 64]; inner.copy_from_slice(data); Ok(Public(inner)) } else { @@ -116,7 +116,7 @@ impl rstd::convert::TryFrom<&[u8]> for Public { } } -impl From for [u8; 33] { +impl From for [u8; 64] { fn from(x: Public) -> Self { x.0 } @@ -129,8 +129,8 @@ impl From for Public { } } -impl UncheckedFrom<[u8; 33]> for Public { - fn unchecked_from(x: [u8; 33]) -> Self { +impl UncheckedFrom<[u8; 64]> for Public { + fn unchecked_from(x: [u8; 64]) -> Self { Public(x) } } @@ -166,8 +166,8 @@ impl<'de> Deserialize<'de> for Public { } #[cfg(feature = "full_crypto")] -impl rstd::hash::Hash for Public { - fn hash(&self, state: &mut H) { +impl sp_std::hash::Hash for Public { + fn hash(&self, state: &mut H) { self.0.hash(state); } } @@ -176,7 +176,7 @@ impl rstd::hash::Hash for Public { #[derive(Encode, Decode)] pub struct Signature([u8; 65]); -impl rstd::convert::TryFrom<&[u8]> for Signature { +impl sp_std::convert::TryFrom<&[u8]> for Signature { type Error = (); fn try_from(data: &[u8]) -> Result { @@ -261,9 +261,9 @@ impl std::fmt::Debug for Signature { } #[cfg(feature = "full_crypto")] -impl rstd::hash::Hash for Signature { - fn hash(&self, state: &mut H) { - rstd::hash::Hash::hash(&self.0[..], state); +impl sp_std::hash::Hash for Signature { + fn hash(&self, state: &mut H) { + sp_std::hash::Hash::hash(&self.0[..], state); } } @@ -292,7 +292,7 @@ impl Signature { let message = secp256k1::Message::parse(&blake2_256(message.as_ref())); let sig: (_, _) = self.try_into().ok()?; secp256k1::recover(&message, &sig.0, &sig.1).ok() - .map(|recovered| Public(recovered.serialize_compressed())) + .map(|recovered| Public::from_full(recovered.serialize())) } } @@ -332,16 +332,27 @@ pub enum PublicError { } impl Public { - /// A new instance from the given 33-byte `data`. + /// A new instance from the given 64-byte `data`. /// /// NOTE: No checking goes on to ensure this is a real public key. Only use it if /// you are certain that the array actually is a pubkey. GIGO! - pub fn from_raw(data: [u8; 33]) -> Self { + pub fn from_raw(data: [u8; 64]) -> Self { Public(data) } + /// A new instance from the given 65-byte `data`. + /// + /// NOTE: No checking goes on to ensure this is a real public key. Only use it if + /// you are certain that the array actually is a pubkey. GIGO! + pub fn from_full(data: [u8; 65]) -> Self { + let raw_key = &data[1..]; + let mut key = [0u8; 64]; + key.copy_from_slice(raw_key); + Public(key) + } + /// Return a slice filled with raw data. - pub fn as_array_ref(&self) -> &[u8; 33] { + pub fn as_array_ref(&self) -> &[u8; 64] { self.as_ref() } } @@ -352,7 +363,7 @@ impl TraitPublic for Public { /// NOTE: No checking goes on to ensure this is a real public key. Only use it if /// you are certain that the array actually is a pubkey. GIGO! fn from_slice(data: &[u8]) -> Self { - let mut r = [0u8; 33]; + let mut r = [0u8; 64]; r.copy_from_slice(data); Public(r) } @@ -448,7 +459,7 @@ impl TraitPair for Pair { /// Get the public key. fn public(&self) -> Public { - Public(self.public.serialize_compressed()) + Public::from_full(self.public.serialize()) } /// Sign a message. @@ -462,7 +473,7 @@ impl TraitPair for Pair { let message = secp256k1::Message::parse(&blake2_256(message.as_ref())); let sig: (_, _) = match sig.try_into() { Ok(x) => x, _ => return false }; match secp256k1::recover(&message, &sig.0, &sig.1) { - Ok(actual) => &pubkey.0[..] == &actual.serialize_compressed()[..], + Ok(actual) => &pubkey.0[..] == &actual.serialize()[1..], _ => false, } } @@ -477,7 +488,7 @@ impl TraitPair for Pair { let ri = match secp256k1::RecoveryId::parse(sig[64]) { Ok(x) => x, _ => return false }; let sig = match secp256k1::Signature::parse_slice(&sig[0..64]) { Ok(x) => x, _ => return false }; match secp256k1::recover(&message, &sig, &ri) { - Ok(actual) => pubkey.as_ref() == &actual.serialize_compressed()[..], + Ok(actual) => pubkey.as_ref() == &actual.serialize()[1..], _ => false, } } @@ -558,7 +569,7 @@ mod test { ); let public = pair.public(); assert_eq!(public, Public::from_raw( - hex!("028db55b05db86c0b1786ca49f095d76344c9e6056b2f02701a7e7f3c20aabfd91") + hex!("8db55b05db86c0b1786ca49f095d76344c9e6056b2f02701a7e7f3c20aabfd913ebbe148dd17c56551a52952371071a6c604b3f3abe8f2c8fa742158ea6dd7d4") )); let message = b""; let signature = hex!("3dde91174bd9359027be59a428b8146513df80a2a3c7eda2194f64de04a69ab97b753169e94db6ffd50921a2668a48b94ca11e3d32c1ff19cfe88890aa7e8f3c00"); @@ -575,7 +586,7 @@ mod test { ).unwrap(); let public = pair.public(); assert_eq!(public, Public::from_raw( - hex!("028db55b05db86c0b1786ca49f095d76344c9e6056b2f02701a7e7f3c20aabfd91") + hex!("8db55b05db86c0b1786ca49f095d76344c9e6056b2f02701a7e7f3c20aabfd913ebbe148dd17c56551a52952371071a6c604b3f3abe8f2c8fa742158ea6dd7d4") )); let message = b""; let signature = hex!("3dde91174bd9359027be59a428b8146513df80a2a3c7eda2194f64de04a69ab97b753169e94db6ffd50921a2668a48b94ca11e3d32c1ff19cfe88890aa7e8f3c00"); @@ -599,7 +610,7 @@ mod test { let pair = Pair::from_seed(b"12345678901234567890123456789012"); let public = pair.public(); assert_eq!(public, Public::from_raw( - hex!("035676109c54b9a16d271abeb4954316a40a32bcce023ac14c8e26e958aa68fba9") + hex!("5676109c54b9a16d271abeb4954316a40a32bcce023ac14c8e26e958aa68fba995840f3de562156558efbfdac3f16af0065e5f66795f4dd8262a228ef8c6d813") )); let message = hex!("2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee00000000000000000200d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a4500000000000000"); let signature = pair.sign(&message[..]); diff --git a/primitives/core/src/ed25519.rs b/primitives/core/src/ed25519.rs index 37933ee6786b286b761e9fc4d453e8ad633c17e8..180e3b0ccb0406ce2856c112299fe369ab26ee6c 100644 --- a/primitives/core/src/ed25519.rs +++ b/primitives/core/src/ed25519.rs @@ -19,7 +19,7 @@ // end::description[] #[cfg(feature = "full_crypto")] -use rstd::vec::Vec; +use sp_std::vec::Vec; use crate::{hash::H256, hash::H512}; use codec::{Encode, Decode}; @@ -39,8 +39,8 @@ use crate::crypto::Ss58Codec; #[cfg(feature = "std")] use serde::{de, Serializer, Serialize, Deserializer, Deserialize}; use crate::{crypto::{Public as TraitPublic, UncheckedFrom, CryptoType, Derive}}; -use runtime_interface::pass_by::PassByInner; -use rstd::ops::Deref; +use sp_runtime_interface::pass_by::PassByInner; +use sp_std::ops::Deref; /// A secret seed. It's not called a "secret key" because ring doesn't expose the secret keys /// of the key pair (yeah, dumb); as such we're forced to remember the seed manually if we @@ -94,7 +94,7 @@ impl Deref for Public { } } -impl rstd::convert::TryFrom<&[u8]> for Public { +impl sp_std::convert::TryFrom<&[u8]> for Public { type Error = (); fn try_from(data: &[u8]) -> Result { @@ -155,15 +155,15 @@ impl std::fmt::Display for Public { } } -impl rstd::fmt::Debug for Public { +impl sp_std::fmt::Debug for Public { #[cfg(feature = "std")] - fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { let s = self.to_ss58check(); write!(f, "{} ({}...)", crate::hexdisplay::HexDisplay::from(&self.0), &s[0..8]) } #[cfg(not(feature = "std"))] - fn fmt(&self, _: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { Ok(()) } } @@ -187,7 +187,7 @@ impl<'de> Deserialize<'de> for Public { #[derive(Encode, Decode, PassByInner)] pub struct Signature(pub [u8; 64]); -impl rstd::convert::TryFrom<&[u8]> for Signature { +impl sp_std::convert::TryFrom<&[u8]> for Signature { type Error = (); fn try_from(data: &[u8]) -> Result { @@ -270,22 +270,22 @@ impl AsMut<[u8]> for Signature { } } -impl rstd::fmt::Debug for Signature { +impl sp_std::fmt::Debug for Signature { #[cfg(feature = "std")] - fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { write!(f, "{}", crate::hexdisplay::HexDisplay::from(&self.0)) } #[cfg(not(feature = "std"))] - fn fmt(&self, _: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { Ok(()) } } #[cfg(feature = "full_crypto")] -impl rstd::hash::Hash for Signature { - fn hash(&self, state: &mut H) { - rstd::hash::Hash::hash(&self.0[..], state); +impl sp_std::hash::Hash for Signature { + fn hash(&self, state: &mut H) { + sp_std::hash::Hash::hash(&self.0[..], state); } } @@ -445,7 +445,7 @@ impl TraitPair for Pair { fn from_seed_slice(seed_slice: &[u8]) -> Result { let secret = ed25519_dalek::SecretKey::from_bytes(seed_slice) .map_err(|_| SecretStringError::InvalidSeedLength)?; - let public = ed25519_dalek::PublicKey::from(secret.expand::()); + let public = ed25519_dalek::PublicKey::from(&secret); Ok(Pair(ed25519_dalek::Keypair { secret, public })) } @@ -474,7 +474,7 @@ impl TraitPair for Pair { /// Sign a message. fn sign(&self, message: &[u8]) -> Signature { - let r = self.0.sign::(message).to_bytes(); + let r = self.0.sign(message).to_bytes(); Signature::from_raw(r) } @@ -498,7 +498,7 @@ impl TraitPair for Pair { Err(_) => return false }; - match public_key.verify::(message.as_ref(), &sig) { + match public_key.verify(message.as_ref(), &sig) { Ok(_) => true, _ => false, } diff --git a/primitives/core/src/hash.rs b/primitives/core/src/hash.rs index c63463e32ae2b94fad78ff5789c500dbeeb11109..8b1f9a523320d98d98db8183418ec7254289a56c 100644 --- a/primitives/core/src/hash.rs +++ b/primitives/core/src/hash.rs @@ -31,7 +31,7 @@ pub fn convert_hash, H2: AsRef<[u8]>>(src: &H2) -> H1 #[cfg(test)] mod tests { use super::*; - use substrate_serializer as ser; + use sp_serializer as ser; #[test] fn test_h160() { diff --git a/primitives/core/src/hashing.rs b/primitives/core/src/hashing.rs index c3f7ddf9f5a5993c15e5ce44b54553d2dd4956aa..8fce710230aae5facebfe766e720ffa9f004506f 100644 --- a/primitives/core/src/hashing.rs +++ b/primitives/core/src/hashing.rs @@ -17,6 +17,7 @@ //! Hashing functions. use blake2_rfc; +use sha2::{Digest, Sha256}; use tiny_keccak::{Hasher, Keccak}; use twox_hash; @@ -123,7 +124,7 @@ pub fn twox_256(data: &[u8]) -> [u8; 32] { r } -/// Do a keccak 256 hash and return result. +/// Do a keccak 256-bit hash and return result. pub fn keccak_256(data: &[u8]) -> [u8; 32] { let mut keccak = Keccak::v256(); keccak.update(data); @@ -131,3 +132,12 @@ pub fn keccak_256(data: &[u8]) -> [u8; 32] { keccak.finalize(&mut output); output } + +/// Do a sha2 256-bit hash and return result. +pub fn sha2_256(data: &[u8]) -> [u8; 32] { + let mut hasher = Sha256::new(); + hasher.input(data); + let mut output = [0u8; 32]; + output.copy_from_slice(&hasher.result()); + output +} diff --git a/primitives/core/src/hexdisplay.rs b/primitives/core/src/hexdisplay.rs index 2c8533e25b5f88808d2e973bc2223fe3dc534ae4..104aaf812e6449e8b00221014f33018c4061b255 100644 --- a/primitives/core/src/hexdisplay.rs +++ b/primitives/core/src/hexdisplay.rs @@ -24,8 +24,8 @@ impl<'a> HexDisplay<'a> { pub fn from(d: &'a R) -> Self { HexDisplay(d.as_bytes_ref()) } } -impl<'a> rstd::fmt::Display for HexDisplay<'a> { - fn fmt(&self, f: &mut rstd::fmt::Formatter) -> Result<(), rstd::fmt::Error> { +impl<'a> sp_std::fmt::Display for HexDisplay<'a> { + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> Result<(), sp_std::fmt::Error> { if self.0.len() < 1027 { for byte in self.0 { f.write_fmt(format_args!("{:02x}", byte))?; @@ -43,8 +43,8 @@ impl<'a> rstd::fmt::Display for HexDisplay<'a> { } } -impl<'a> rstd::fmt::Debug for HexDisplay<'a> { - fn fmt(&self, f: &mut rstd::fmt::Formatter) -> Result<(), rstd::fmt::Error> { +impl<'a> sp_std::fmt::Debug for HexDisplay<'a> { + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> Result<(), sp_std::fmt::Error> { for byte in self.0 { f.write_fmt(format_args!("{:02x}", byte))?; } diff --git a/primitives/core/src/lib.rs b/primitives/core/src/lib.rs index 900728afbfb4456a6cdbd8685cfbcdde58477be4..00343c0e7fd74c3273d9999cb792b85166745f72 100644 --- a/primitives/core/src/lib.rs +++ b/primitives/core/src/lib.rs @@ -31,8 +31,8 @@ macro_rules! map { ); } -use rstd::prelude::*; -use rstd::ops::Deref; +use sp_std::prelude::*; +use sp_std::ops::Deref; #[cfg(feature = "std")] use std::borrow::Cow; #[cfg(feature = "std")] @@ -42,7 +42,7 @@ pub use serde; #[doc(hidden)] pub use codec::{Encode, Decode}; -pub use substrate_debug_derive::RuntimeDebug; +pub use sp_debug_derive::RuntimeDebug; #[cfg(feature = "std")] pub use impl_serde::serialize as bytes; @@ -84,10 +84,10 @@ pub use hash_db::Hasher; // pub use self::hasher::blake::BlakeHasher; pub use self::hasher::blake2::Blake2Hasher; -pub use primitives_storage as storage; +pub use sp_storage as storage; #[doc(hidden)] -pub use rstd; +pub use sp_std; /// Context for executing a call into the runtime. pub enum ExecutionContext { @@ -147,7 +147,7 @@ impl OpaqueMetadata { } } -impl rstd::ops::Deref for OpaqueMetadata { +impl sp_std::ops::Deref for OpaqueMetadata { type Target = Vec; fn deref(&self) -> &Self::Target { @@ -165,8 +165,8 @@ pub enum NativeOrEncoded { } #[cfg(feature = "std")] -impl rstd::fmt::Debug for NativeOrEncoded { - fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { +impl sp_std::fmt::Debug for NativeOrEncoded { + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { hexdisplay::HexDisplay::from(&self.as_encoded().as_ref()).fmt(f) } } @@ -235,8 +235,8 @@ pub trait TypeId { /// A log level matching the one from `log` crate. /// -/// Used internally by `runtime_io::log` method. -#[derive(Encode, Decode, runtime_interface::pass_by::PassByEnum, Copy, Clone)] +/// Used internally by `sp_io::log` method. +#[derive(Encode, Decode, sp_runtime_interface::pass_by::PassByEnum, Copy, Clone)] pub enum LogLevel { /// `Error` log level. Error = 1, @@ -305,7 +305,7 @@ pub fn to_substrate_wasm_fn_return_value(value: &impl Encode) -> u64 { // Leak the output vector to avoid it being freed. // This is fine in a WASM context since the heap // will be discarded after the call. - rstd::mem::forget(encoded); + sp_std::mem::forget(encoded); res } diff --git a/primitives/core/src/offchain/mod.rs b/primitives/core/src/offchain/mod.rs index 8afabc0392a2a3f9c2607de8b4ed28549ec88fe9..9c33abb7c108f6d32c928a2b094b7c4d42b9804f 100644 --- a/primitives/core/src/offchain/mod.rs +++ b/primitives/core/src/offchain/mod.rs @@ -17,9 +17,9 @@ //! Offchain workers types use codec::{Encode, Decode}; -use rstd::{prelude::{Vec, Box}, convert::TryFrom}; +use sp_std::{prelude::{Vec, Box}, convert::TryFrom}; use crate::RuntimeDebug; -use runtime_interface::pass_by::{PassByCodec, PassByInner, PassByEnum}; +use sp_runtime_interface::pass_by::{PassByCodec, PassByInner, PassByEnum}; pub use crate::crypto::KeyTypeId; @@ -669,7 +669,7 @@ impl Externalities for LimitedExternalities { } #[cfg(feature = "std")] -externalities::decl_extension! { +sp_externalities::decl_extension! { /// The offchain extension that will be registered at the Substrate externalities. pub struct OffchainExt(Box); } @@ -696,7 +696,7 @@ pub trait TransactionPool { } #[cfg(feature = "std")] -externalities::decl_extension! { +sp_externalities::decl_extension! { /// An externalities extension to submit transactions to the pool. pub struct TransactionPoolExt(Box); } diff --git a/primitives/core/src/sandbox.rs b/primitives/core/src/sandbox.rs index dd91ad6a1f5c0ef00966c57b4a20ab93359118af..cc82b4bd4c819e0c3cd93a3303754bcb47244208 100644 --- a/primitives/core/src/sandbox.rs +++ b/primitives/core/src/sandbox.rs @@ -17,7 +17,7 @@ //! Definition of a sandbox environment. use codec::{Encode, Decode}; -use rstd::vec::Vec; +use sp_std::vec::Vec; /// Error error that can be returned from host function. #[derive(Encode, Decode)] diff --git a/primitives/core/src/sr25519.rs b/primitives/core/src/sr25519.rs index 9521e3bb6c003c4a1589ecf682819213a47b3460..c0f71ea83b437d809ca6bb21ee7f5c7749d85b2d 100644 --- a/primitives/core/src/sr25519.rs +++ b/primitives/core/src/sr25519.rs @@ -21,7 +21,7 @@ //! for this to work. // end::description[] #[cfg(feature = "full_crypto")] -use rstd::vec::Vec; +use sp_std::vec::Vec; #[cfg(feature = "full_crypto")] use schnorrkel::{signing_context, ExpansionMode, Keypair, SecretKey, MiniSecretKey, PublicKey, derive::{Derivation, ChainCode, CHAIN_CODE_LENGTH} @@ -42,13 +42,13 @@ use crate::crypto::Ss58Codec; use crate::{crypto::{Public as TraitPublic, UncheckedFrom, CryptoType, Derive}}; use crate::hash::{H256, H512}; use codec::{Encode, Decode}; -use rstd::ops::Deref; +use sp_std::ops::Deref; #[cfg(feature = "std")] use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; #[cfg(feature = "full_crypto")] use schnorrkel::keys::{MINI_SECRET_KEY_LENGTH, SECRET_KEY_LENGTH}; -use runtime_interface::pass_by::PassByInner; +use sp_runtime_interface::pass_by::PassByInner; // signing context #[cfg(feature = "full_crypto")] @@ -121,7 +121,7 @@ impl std::str::FromStr for Public { } } -impl rstd::convert::TryFrom<&[u8]> for Public { +impl sp_std::convert::TryFrom<&[u8]> for Public { type Error = (); fn try_from(data: &[u8]) -> Result { @@ -154,15 +154,15 @@ impl std::fmt::Display for Public { } } -impl rstd::fmt::Debug for Public { +impl sp_std::fmt::Debug for Public { #[cfg(feature = "std")] - fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { let s = self.to_ss58check(); write!(f, "{} ({}...)", crate::hexdisplay::HexDisplay::from(&self.0), &s[0..8]) } #[cfg(not(feature = "std"))] - fn fmt(&self, _: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { Ok(()) } } @@ -188,7 +188,7 @@ impl<'de> Deserialize<'de> for Public { #[derive(Encode, Decode, PassByInner)] pub struct Signature(pub [u8; 64]); -impl rstd::convert::TryFrom<&[u8]> for Signature { +impl sp_std::convert::TryFrom<&[u8]> for Signature { type Error = (); fn try_from(data: &[u8]) -> Result { @@ -278,22 +278,22 @@ impl From for Signature { } } -impl rstd::fmt::Debug for Signature { +impl sp_std::fmt::Debug for Signature { #[cfg(feature = "std")] - fn fmt(&self, f: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { write!(f, "{}", crate::hexdisplay::HexDisplay::from(&self.0)) } #[cfg(not(feature = "std"))] - fn fmt(&self, _: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { Ok(()) } } #[cfg(feature = "full_crypto")] -impl rstd::hash::Hash for Signature { - fn hash(&self, state: &mut H) { - rstd::hash::Hash::hash(&self.0[..], state); +impl sp_std::hash::Hash for Signature { + fn hash(&self, state: &mut H) { + sp_std::hash::Hash::hash(&self.0[..], state); } } diff --git a/primitives/core/src/testing.rs b/primitives/core/src/testing.rs index e5d301008e3d4fb3344ad7306b797f9b70727964..b5a8c0aad65dfea9b990eed705f360f9d0a458b0 100644 --- a/primitives/core/src/testing.rs +++ b/primitives/core/src/testing.rs @@ -141,7 +141,7 @@ impl crate::traits::BareCryptoStore for KeyStore { /// # Example /// /// ``` -/// # use substrate_primitives::wasm_export_functions; +/// # use sp_core::wasm_export_functions; /// /// wasm_export_functions! { /// fn test_in_wasm(value: bool, another_value: Vec) -> bool { @@ -184,7 +184,7 @@ macro_rules! wasm_export_functions { &[0u8; 0] } else { unsafe { - $crate::rstd::slice::from_raw_parts(input_data, input_len) + $crate::sp_std::slice::from_raw_parts(input_data, input_len) } }; @@ -212,7 +212,7 @@ macro_rules! wasm_export_functions { &[0u8; 0] } else { unsafe { - $crate::rstd::slice::from_raw_parts(input_data, input_len) + $crate::sp_std::slice::from_raw_parts(input_data, input_len) } }; diff --git a/primitives/core/src/traits.rs b/primitives/core/src/traits.rs index f1b13408d1f0c307566b2e86e530bef63b946f34..2f78c8a708f5775362d71c458824bf05e2eff4b5 100644 --- a/primitives/core/src/traits.rs +++ b/primitives/core/src/traits.rs @@ -24,7 +24,7 @@ use std::{ sync::Arc, }; -pub use externalities::{Externalities, ExternalitiesExt}; +pub use sp_externalities::{Externalities, ExternalitiesExt}; /// Something that generates, stores and provides access to keys. pub trait BareCryptoStore: Send + Sync { @@ -74,7 +74,7 @@ pub trait BareCryptoStore: Send + Sync { /// A pointer to the key store. pub type BareCryptoStorePtr = Arc>; -externalities::decl_extension! { +sp_externalities::decl_extension! { /// The keystore extension to register/retrieve from the externalities. pub struct KeystoreExt(BareCryptoStorePtr); } diff --git a/primitives/core/src/uint.rs b/primitives/core/src/uint.rs index c835cf5773518adc6bc30e503e309a98a1760b2f..330fffb9f12f43c74ba3d426fa8f2b46e37a3ee7 100644 --- a/primitives/core/src/uint.rs +++ b/primitives/core/src/uint.rs @@ -22,7 +22,7 @@ pub use primitive_types::U256; mod tests { use super::*; use codec::{Encode, Decode}; - use substrate_serializer as ser; + use sp_serializer as ser; macro_rules! test { ($name: ident, $test_name: ident) => { diff --git a/primitives/core/debug-derive/Cargo.toml b/primitives/debug-derive/Cargo.toml similarity index 87% rename from primitives/core/debug-derive/Cargo.toml rename to primitives/debug-derive/Cargo.toml index a7bf90695ab932e7fe2e5f44b3437f13bb3cd2ca..9c65cb34f5fa93b828e75e7a1190657dd4813c24 100644 --- a/primitives/core/debug-derive/Cargo.toml +++ b/primitives/debug-derive/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "substrate-debug-derive" +name = "sp-debug-derive" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" diff --git a/primitives/core/debug-derive/src/impls.rs b/primitives/debug-derive/src/impls.rs similarity index 100% rename from primitives/core/debug-derive/src/impls.rs rename to primitives/debug-derive/src/impls.rs diff --git a/primitives/core/debug-derive/src/lib.rs b/primitives/debug-derive/src/lib.rs similarity index 96% rename from primitives/core/debug-derive/src/lib.rs rename to primitives/debug-derive/src/lib.rs index 5e6cf6098b30e4f0b69c7a3dd4c1a26b86e0832d..ac63441124ec655dc698467402148bd64dae849e 100644 --- a/primitives/core/debug-derive/src/lib.rs +++ b/primitives/debug-derive/src/lib.rs @@ -25,7 +25,7 @@ //! blob from unneeded code. //! //! ```rust -//! #[derive(substrate_debug_derive::RuntimeDebug)] +//! #[derive(sp_debug_derive::RuntimeDebug)] //! struct MyStruct; //! //! assert_eq!(format!("{:?}", MyStruct), "MyStruct"); diff --git a/primitives/core/debug-derive/tests/tests.rs b/primitives/debug-derive/tests/tests.rs similarity index 97% rename from primitives/core/debug-derive/tests/tests.rs rename to primitives/debug-derive/tests/tests.rs index 63ad6a3e8d49718f8db818ee9cb4cd3370a9a8c6..11f45fcc45cda50b1237f5b8a39e3a468b073758 100644 --- a/primitives/core/debug-derive/tests/tests.rs +++ b/primitives/debug-derive/tests/tests.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use substrate_debug_derive::RuntimeDebug; +use sp_debug_derive::RuntimeDebug; #[derive(RuntimeDebug)] struct Unnamed(u64, String); diff --git a/primitives/externalities/Cargo.toml b/primitives/externalities/Cargo.toml index 0b806ecee0494ab4c78e6d998cbc6f6f96a4c05e..09ce3253f2d9822adfe0a5b25755e5f3cd029b29 100644 --- a/primitives/externalities/Cargo.toml +++ b/primitives/externalities/Cargo.toml @@ -1,12 +1,11 @@ [package] -name = "substrate-externalities" +name = "sp-externalities" version = "2.0.0" license = "GPL-3.0" authors = ["Parity Technologies "] edition = "2018" [dependencies] -primitive-types = { version = "0.6", features = ["codec"] } -primitives-storage = { package = "substrate-primitives-storage", path = "../core/storage" } -rstd = { package = "sr-std", path = "../sr-std" } +sp-storage = { version = "2.0.0", path = "../storage" } +sp-std = { version = "2.0.0", path = "../std" } environmental = { version = "1.0.2" } diff --git a/primitives/externalities/src/extensions.rs b/primitives/externalities/src/extensions.rs index a1a83cb197d4f55075abff855dd0227787a1ad8d..c5535d0bab46dde7dc34fda5519aa64d30c7a6e8 100644 --- a/primitives/externalities/src/extensions.rs +++ b/primitives/externalities/src/extensions.rs @@ -41,7 +41,7 @@ pub trait Extension: Send + Any { /// /// # Example /// ``` -/// # use substrate_externalities::decl_extension; +/// # use sp_externalities::decl_extension; /// decl_extension! { /// /// Some test extension /// struct TestExt(String); diff --git a/primitives/externalities/src/lib.rs b/primitives/externalities/src/lib.rs index 4efbc54a4edc98c752b2cac5c7732a3fba92a184..52be547e25abf1a57f9d963505c7ca99760d8271 100644 --- a/primitives/externalities/src/lib.rs +++ b/primitives/externalities/src/lib.rs @@ -22,11 +22,9 @@ //! //! This crate exposes the main [`Externalities`] trait. -use primitive_types::H256; - use std::any::{Any, TypeId}; -use primitives_storage::ChildStorageKey; +use sp_storage::{ChildStorageKey, ChildInfo}; pub use scope_limited::{set_and_run_with_externalities, with_externalities}; pub use extensions::{Extension, Extensions, ExtensionStore}; @@ -42,27 +40,57 @@ pub trait Externalities: ExtensionStore { fn storage(&self, key: &[u8]) -> Option>; /// Get storage value hash. This may be optimized for large values. - fn storage_hash(&self, key: &[u8]) -> Option; + fn storage_hash(&self, key: &[u8]) -> Option>; /// Get child storage value hash. This may be optimized for large values. - fn child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option; + /// + /// Returns an `Option` that holds the SCALE encoded hash. + fn child_storage_hash( + &self, + storage_key: ChildStorageKey, + child_info: ChildInfo, + key: &[u8], + ) -> Option>; /// Read original runtime storage, ignoring any overlayed changes. fn original_storage(&self, key: &[u8]) -> Option>; /// Read original runtime child storage, ignoring any overlayed changes. - fn original_child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option>; + /// + /// Returns an `Option` that holds the SCALE encoded hash. + fn original_child_storage( + &self, + storage_key: ChildStorageKey, + child_info: ChildInfo, + key: &[u8], + ) -> Option>; /// Get original storage value hash, ignoring any overlayed changes. /// This may be optimized for large values. - fn original_storage_hash(&self, key: &[u8]) -> Option; + /// + /// Returns an `Option` that holds the SCALE encoded hash. + fn original_storage_hash(&self, key: &[u8]) -> Option>; /// Get original child storage value hash, ignoring any overlayed changes. /// This may be optimized for large values. - fn original_child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option; + /// + /// Returns an `Option` that holds the SCALE encoded hash. + fn original_child_storage_hash( + &self, + storage_key: ChildStorageKey, + child_info: ChildInfo, + key: &[u8], + ) -> Option>; /// Read child runtime storage. - fn child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option>; + /// + /// Returns an `Option` that holds the SCALE encoded hash. + fn child_storage( + &self, + storage_key: ChildStorageKey, + child_info: ChildInfo, + key: &[u8], + ) -> Option>; /// Set storage entry `key` of current contract being called (effective immediately). fn set_storage(&mut self, key: Vec, value: Vec) { @@ -70,8 +98,14 @@ pub trait Externalities: ExtensionStore { } /// Set child storage entry `key` of current contract being called (effective immediately). - fn set_child_storage(&mut self, storage_key: ChildStorageKey, key: Vec, value: Vec) { - self.place_child_storage(storage_key, key, Some(value)) + fn set_child_storage( + &mut self, + storage_key: ChildStorageKey, + child_info: ChildInfo, + key: Vec, + value: Vec, + ) { + self.place_child_storage(storage_key, child_info, key, Some(value)) } /// Clear a storage entry (`key`) of current contract being called (effective immediately). @@ -80,8 +114,13 @@ pub trait Externalities: ExtensionStore { } /// Clear a child storage entry (`key`) of current contract being called (effective immediately). - fn clear_child_storage(&mut self, storage_key: ChildStorageKey, key: &[u8]) { - self.place_child_storage(storage_key, key.to_vec(), None) + fn clear_child_storage( + &mut self, + storage_key: ChildStorageKey, + child_info: ChildInfo, + key: &[u8], + ) { + self.place_child_storage(storage_key, child_info, key.to_vec(), None) } /// Whether a storage entry exists. @@ -90,40 +129,79 @@ pub trait Externalities: ExtensionStore { } /// Whether a child storage entry exists. - fn exists_child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> bool { - self.child_storage(storage_key, key).is_some() + fn exists_child_storage( + &self, + storage_key: ChildStorageKey, + child_info: ChildInfo, + key: &[u8], + ) -> bool { + self.child_storage(storage_key, child_info, key).is_some() } + /// Returns the key immediately following the given key, if it exists. + fn next_storage_key(&self, key: &[u8]) -> Option>; + + /// Returns the key immediately following the given key, if it exists, in child storage. + fn next_child_storage_key( + &self, + storage_key: ChildStorageKey, + child_info: ChildInfo, + key: &[u8], + ) -> Option>; + /// Clear an entire child storage. - fn kill_child_storage(&mut self, storage_key: ChildStorageKey); + fn kill_child_storage(&mut self, storage_key: ChildStorageKey, child_info: ChildInfo); /// Clear storage entries which keys are start with the given prefix. fn clear_prefix(&mut self, prefix: &[u8]); /// Clear child storage entries which keys are start with the given prefix. - fn clear_child_prefix(&mut self, storage_key: ChildStorageKey, prefix: &[u8]); + fn clear_child_prefix( + &mut self, + storage_key: ChildStorageKey, + child_info: ChildInfo, + prefix: &[u8], + ); /// Set or clear a storage entry (`key`) of current contract being called (effective immediately). fn place_storage(&mut self, key: Vec, value: Option>); /// Set or clear a child storage entry. Return whether the operation succeeds. - fn place_child_storage(&mut self, storage_key: ChildStorageKey, key: Vec, value: Option>); + fn place_child_storage( + &mut self, + storage_key: ChildStorageKey, + child_info: ChildInfo, + key: Vec, + value: Option>, + ); /// Get the identity of the chain. fn chain_id(&self) -> u64; /// Get the trie root of the current storage map. This will also update all child storage keys /// in the top-level storage map. - fn storage_root(&mut self) -> H256; + /// + /// The hash is defined by the `Block`. + /// + /// Returns the SCALE encoded hash. + fn storage_root(&mut self) -> Vec; /// Get the trie root of a child storage map. This will also update the value of the child /// storage keys in the top-level storage map. /// If the storage root equals the default hash as defined by the trie, the key in the top-level /// storage map will be removed. - fn child_storage_root(&mut self, storage_key: ChildStorageKey) -> Vec; + fn child_storage_root( + &mut self, + storage_key: ChildStorageKey, + ) -> Vec; /// Get the change trie root of the current storage overlay at a block with given parent. - fn storage_changes_root(&mut self, parent: H256) -> Result, ()>; + /// `parent` is expects a SCALE endcoded hash. + /// + /// The hash is defined by the `Block`. + /// + /// Returns the SCALE encoded hash. + fn storage_changes_root(&mut self, parent: &[u8]) -> Result>, ()>; } /// Extension for the [`Externalities`] trait. diff --git a/primitives/finality-grandpa/Cargo.toml b/primitives/finality-grandpa/Cargo.toml index e9a166d2875bb37c56ece67a9a0ec077bbe16b78..c2856e524ff212e038c4d9b55005062c961d6b76 100644 --- a/primitives/finality-grandpa/Cargo.toml +++ b/primitives/finality-grandpa/Cargo.toml @@ -1,24 +1,24 @@ [package] -name = "substrate-finality-grandpa-primitives" +name = "sp-finality-grandpa" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" [dependencies] -app-crypto = { package = "substrate-application-crypto", path = "../application-crypto", default-features = false } +app-crypto = { version = "2.0.0", default-features = false, package = "sp-application-crypto", path = "../application-crypto" } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -rstd = { package = "sr-std", path = "../sr-std", default-features = false } +sp-std = { version = "2.0.0", default-features = false, path = "../std" } serde = { version = "1.0.101", optional = true, features = ["derive"] } -sr-api = { path = "../sr-api", default-features = false } -sr-primitives = { path = "../sr-primitives", default-features = false } +sp-api = { version = "2.0.0", default-features = false, path = "../api" } +sp-runtime = { version = "2.0.0", default-features = false, path = "../runtime" } [features] default = ["std"] std = [ "app-crypto/std", "codec/std", - "rstd/std", + "sp-std/std", "serde", - "sr-api/std", - "sr-primitives/std", + "sp-api/std", + "sp-runtime/std", ] diff --git a/primitives/finality-grandpa/src/lib.rs b/primitives/finality-grandpa/src/lib.rs index ff26b6a68ac2d006d7c815ccfd097ad6836e0c32..ef61092b9c6607e2be81b2254ef2b59b4762fe3b 100644 --- a/primitives/finality-grandpa/src/lib.rs +++ b/primitives/finality-grandpa/src/lib.rs @@ -24,9 +24,9 @@ extern crate alloc; #[cfg(feature = "std")] use serde::Serialize; use codec::{Encode, Decode, Input, Codec}; -use sr_primitives::{ConsensusEngineId, RuntimeDebug}; -use rstd::borrow::Cow; -use rstd::vec::Vec; +use sp_runtime::{ConsensusEngineId, RuntimeDebug}; +use sp_std::borrow::Cow; +use sp_std::vec::Vec; mod app { use app_crypto::{app_crypto, key_types::GRANDPA, ed25519}; @@ -210,7 +210,7 @@ impl<'a> Decode for VersionedAuthorityList<'a> { } } -sr_api::decl_runtime_apis! { +sp_api::decl_runtime_apis! { /// APIs for integrating the GRANDPA finality gadget into runtimes. /// This should be implemented on the runtime side. /// diff --git a/primitives/finality-tracker/Cargo.toml b/primitives/finality-tracker/Cargo.toml index 2f7ddf916b67eb15bbd94a977bcf7afeb9e8bb70..32458039458fd70bdccfe45a5804bab79d8bb5e4 100644 --- a/primitives/finality-tracker/Cargo.toml +++ b/primitives/finality-tracker/Cargo.toml @@ -6,13 +6,13 @@ edition = "2018" [dependencies] codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false } -inherents = { package = "substrate-inherents", path = "../../primitives/inherents", default-features = false } -rstd = { package = "sr-std", path = "../../primitives/sr-std", default-features = false } +sp-inherents = { version = "2.0.0", default-features = false, path = "../../primitives/inherents" } +sp-std = { version = "2.0.0", default-features = false, path = "../../primitives/std" } [features] default = ["std"] std = [ "codec/std", - "rstd/std", - "inherents/std", + "sp-std/std", + "sp-inherents/std", ] diff --git a/primitives/finality-tracker/src/lib.rs b/primitives/finality-tracker/src/lib.rs index 7b81a300c494188763ed8d5d7d31d35ef8519bc9..677be24ef5cdfd21aa928cb3691cad517ab29cd7 100644 --- a/primitives/finality-tracker/src/lib.rs +++ b/primitives/finality-tracker/src/lib.rs @@ -18,7 +18,7 @@ #![cfg_attr(not(feature = "std"), no_std)] -use inherents::{InherentIdentifier, InherentData, Error}; +use sp_inherents::{InherentIdentifier, InherentData, Error}; use codec::Decode; #[cfg(feature = "std")] @@ -55,7 +55,7 @@ impl InherentDataProvider { } #[cfg(feature = "std")] -impl inherents::ProvideInherentData for InherentDataProvider +impl sp_inherents::ProvideInherentData for InherentDataProvider where F: Fn() -> Result { fn inherent_identifier(&self) -> &'static InherentIdentifier { diff --git a/primitives/inherents/Cargo.toml b/primitives/inherents/Cargo.toml index 108cb15e9cce508702d870a6c66c5aa402ceedd3..0dc465e2883d1c851057177d5d7c40c0fc42708d 100644 --- a/primitives/inherents/Cargo.toml +++ b/primitives/inherents/Cargo.toml @@ -1,22 +1,22 @@ [package] -name = "substrate-inherents" +name = "sp-inherents" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" [dependencies] parking_lot = { version = "0.9.0", optional = true } -rstd = { package = "sr-std", path = "../sr-std", default-features = false } -primitives = { package = "substrate-primitives", path = "../core", default-features = false } +sp-std = { version = "2.0.0", default-features = false, path = "../std" } +sp-core = { version = "2.0.0", default-features = false, path = "../core" } codec = { package = "parity-scale-codec", version = "1.0.6", default-features = false, features = ["derive"] } -derive_more = { version = "0.15.0", optional = true } +derive_more = { version = "0.99.2", optional = true } [features] default = [ "std" ] std = [ "parking_lot", - "rstd/std", + "sp-std/std", "codec/std", - "primitives/std", + "sp-core/std", "derive_more", ] diff --git a/primitives/inherents/src/lib.rs b/primitives/inherents/src/lib.rs index 25512f4fcae2ab8790484db89c21a982d80530d0..b777b64e5eb06367aa422a33c200ced7f3721459 100644 --- a/primitives/inherents/src/lib.rs +++ b/primitives/inherents/src/lib.rs @@ -35,7 +35,7 @@ use codec::{Encode, Decode}; -use rstd::{collections::btree_map::{BTreeMap, IntoIter, Entry}, vec::Vec}; +use sp_std::{collections::btree_map::{BTreeMap, IntoIter, Entry}, vec::Vec}; #[cfg(feature = "std")] use parking_lot::RwLock; @@ -44,8 +44,8 @@ use parking_lot::RwLock; use std::{sync::Arc, format}; /// An error that can occur within the inherent data system. -#[derive(Debug, Encode, Decode, derive_more::Display)] #[cfg(feature = "std")] +#[derive(Debug, Encode, Decode, derive_more::Display)] pub struct Error(String); #[cfg(feature = "std")] @@ -64,7 +64,7 @@ impl Error { } /// An error that can occur within the inherent data system. -#[derive(Encode, primitives::RuntimeDebug)] +#[derive(Encode, sp_core::RuntimeDebug)] #[cfg(not(feature = "std"))] pub struct Error(&'static str); diff --git a/primitives/sr-io/Cargo.toml b/primitives/io/Cargo.toml similarity index 51% rename from primitives/sr-io/Cargo.toml rename to primitives/io/Cargo.toml index 52e175d2b80cd997b2df4814669a050b19e67690..a89b2d4c200818326e8b22e09e6ded04dbc770e1 100644 --- a/primitives/sr-io/Cargo.toml +++ b/primitives/io/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "sr-io" +name = "sp-io" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" @@ -7,27 +7,27 @@ edition = "2018" [dependencies] codec = { package = "parity-scale-codec", version = "1.0.6", default-features = false } hash-db = { version = "0.15.2", default-features = false } -primitives = { package = "substrate-primitives", path = "../core", default-features = false } -rstd = { package = "sr-std", path = "../sr-std", default-features = false } +sp-core = { version = "2.0.0", default-features = false, path = "../core" } +sp-std = { version = "2.0.0", default-features = false, path = "../std" } libsecp256k1 = { version = "0.3.0", optional = true } -substrate-state-machine = { path = "../../primitives/state-machine", optional = true } -runtime-interface = { package = "substrate-runtime-interface", path = "../runtime-interface", default-features = false } -trie = { package = "substrate-trie", path = "../../primitives/trie", optional = true } -externalities = { package = "substrate-externalities", path = "../externalities", optional = true } +sp-state-machine = { version = "2.0.0", optional = true, path = "../../primitives/state-machine" } +sp-runtime-interface = { version = "2.0.0", default-features = false, path = "../runtime-interface" } +sp-trie = { version = "2.0.0", optional = true, path = "../../primitives/trie" } +sp-externalities = { version = "2.0.0", optional = true, path = "../externalities" } log = { version = "0.4.8", optional = true } [features] default = ["std"] std = [ - "primitives/std", + "sp-core/std", "codec/std", - "rstd/std", + "sp-std/std", "hash-db/std", - "trie", - "substrate-state-machine", + "sp-trie", + "sp-state-machine", "libsecp256k1", - "runtime-interface/std", - "externalities", + "sp-runtime-interface/std", + "sp-externalities", "log", ] diff --git a/primitives/sr-io/src/lib.rs b/primitives/io/src/lib.rs similarity index 79% rename from primitives/sr-io/src/lib.rs rename to primitives/io/src/lib.rs index 2b40670c450cb02cb1a79e7346cca65ae35ef715..be88907cde228148df3f7c88514e44c0ad2d8df0 100644 --- a/primitives/sr-io/src/lib.rs +++ b/primitives/io/src/lib.rs @@ -28,21 +28,21 @@ #![cfg_attr(not(feature = "std"), doc = "Substrate's runtime standard library as compiled without Rust's standard library.")] -use rstd::vec::Vec; +use sp_std::vec::Vec; #[cfg(feature = "std")] -use rstd::ops::Deref; +use sp_std::ops::Deref; #[cfg(feature = "std")] -use primitives::{ +use sp_core::{ crypto::Pair, traits::KeystoreExt, offchain::{OffchainExt, TransactionPoolExt}, hexdisplay::HexDisplay, - storage::ChildStorageKey, + storage::{ChildStorageKey, ChildInfo}, }; -use primitives::{ +use sp_core::{ crypto::KeyTypeId, ed25519, sr25519, H256, LogLevel, offchain::{ Timestamp, HttpRequestId, HttpRequestStatus, HttpError, StorageKind, OpaqueNetworkState, @@ -50,14 +50,14 @@ use primitives::{ }; #[cfg(feature = "std")] -use trie::{TrieConfiguration, trie_types::Layout}; +use ::sp_trie::{TrieConfiguration, trie_types::Layout}; -use runtime_interface::{runtime_interface, Pointer}; +use sp_runtime_interface::{runtime_interface, Pointer}; use codec::{Encode, Decode}; #[cfg(feature = "std")] -use externalities::{ExternalitiesExt, Externalities}; +use sp_externalities::{ExternalitiesExt, Externalities}; /// Error verifying ECDSA signature #[derive(Encode, Decode)] @@ -91,10 +91,28 @@ pub trait Storage { self.storage(key).map(|s| s.to_vec()) } - /// Returns the data for `key` in the child storage or `None` if the key can not be found. - fn child_get(&self, child_storage_key: &[u8], key: &[u8]) -> Option> { + /// All Child api uses : + /// - A `child_storage_key` to define the anchor point for the child proof + /// (commonly the location where the child root is stored in its parent trie). + /// - A `child_storage_types` to identify the kind of the child type and how its + /// `child definition` parameter is encoded. + /// - A `child_definition_parameter` which is the additional information required + /// to use the child trie. For instance defaults child tries requires this to + /// contain a collision free unique id. + /// + /// This function specifically returns the data for `key` in the child storage or `None` + /// if the key can not be found. + fn child_get( + &self, + child_storage_key: &[u8], + child_definition: &[u8], + child_type: u32, + key: &[u8], + ) -> Option> { let storage_key = child_storage_key_or_panic(child_storage_key); - self.child_storage(storage_key, key).map(|s| s.to_vec()) + let child_info = ChildInfo::resolve_child_info(child_type, child_definition) + .expect("Invalid child definition"); + self.child_storage(storage_key, child_info, key).map(|s| s.to_vec()) } /// Get `key` from storage, placing the value into `value_out` and return the number of @@ -117,15 +135,21 @@ pub trait Storage { /// doesn't exist at all. /// If `value_out` length is smaller than the returned length, only `value_out` length bytes /// are copied into `value_out`. + /// + /// See `child_get` for common child api parameters. fn child_read( &self, child_storage_key: &[u8], + child_definition: &[u8], + child_type: u32, key: &[u8], value_out: &mut [u8], value_offset: u32, ) -> Option { let storage_key = child_storage_key_or_panic(child_storage_key); - self.child_storage(storage_key, key) + let child_info = ChildInfo::resolve_child_info(child_type, child_definition) + .expect("Invalid child definition"); + self.child_storage(storage_key, child_info, key) .map(|value| { let value_offset = value_offset as usize; let data = &value[value_offset.min(value.len())..]; @@ -141,9 +165,20 @@ pub trait Storage { } /// Set `key` to `value` in the child storage denoted by `child_storage_key`. - fn child_set(&mut self, child_storage_key: &[u8], key: &[u8], value: &[u8]) { + /// + /// See `child_get` for common child api parameters. + fn child_set( + &mut self, + child_storage_key: &[u8], + child_definition: &[u8], + child_type: u32, + key: &[u8], + value: &[u8], + ) { let storage_key = child_storage_key_or_panic(child_storage_key); - self.set_child_storage(storage_key, key.to_vec(), value.to_vec()); + let child_info = ChildInfo::resolve_child_info(child_type, child_definition) + .expect("Invalid child definition"); + self.set_child_storage(storage_key, child_info, key.to_vec(), value.to_vec()); } /// Clear the storage of the given `key` and its value. @@ -152,15 +187,34 @@ pub trait Storage { } /// Clear the given child storage of the given `key` and its value. - fn child_clear(&mut self, child_storage_key: &[u8], key: &[u8]) { + /// + /// See `child_get` for common child api parameters. + fn child_clear( + &mut self, + child_storage_key: &[u8], + child_definition: &[u8], + child_type: u32, + key: &[u8], + ) { let storage_key = child_storage_key_or_panic(child_storage_key); - self.clear_child_storage(storage_key, key); + let child_info = ChildInfo::resolve_child_info(child_type, child_definition) + .expect("Invalid child definition"); + self.clear_child_storage(storage_key, child_info, key); } /// Clear an entire child storage. - fn child_storage_kill(&mut self, child_storage_key: &[u8]) { + /// + /// See `child_get` for common child api parameters. + fn child_storage_kill( + &mut self, + child_storage_key: &[u8], + child_definition: &[u8], + child_type: u32, + ) { let storage_key = child_storage_key_or_panic(child_storage_key); - self.kill_child_storage(storage_key); + let child_info = ChildInfo::resolve_child_info(child_type, child_definition) + .expect("Invalid child definition"); + self.kill_child_storage(storage_key, child_info); } /// Check whether the given `key` exists in storage. @@ -169,9 +223,19 @@ pub trait Storage { } /// Check whether the given `key` exists in storage. - fn child_exists(&self, child_storage_key: &[u8], key: &[u8]) -> bool { + /// + /// See `child_get` for common child api parameters. + fn child_exists( + &self, + child_storage_key: &[u8], + child_definition: &[u8], + child_type: u32, + key: &[u8], + ) -> bool { let storage_key = child_storage_key_or_panic(child_storage_key); - self.exists_child_storage(storage_key, key) + let child_info = ChildInfo::resolve_child_info(child_type, child_definition) + .expect("Invalid child definition"); + self.exists_child_storage(storage_key, child_info, key) } /// Clear the storage of each key-value pair where the key starts with the given `prefix`. @@ -180,35 +244,86 @@ pub trait Storage { } /// Clear the child storage of each key-value pair where the key starts with the given `prefix`. - fn child_clear_prefix(&mut self, child_storage_key: &[u8], prefix: &[u8]) { + /// + /// See `child_get` for common child api parameters. + fn child_clear_prefix( + &mut self, + child_storage_key: &[u8], + child_definition: &[u8], + child_type: u32, + prefix: &[u8], + ) { let storage_key = child_storage_key_or_panic(child_storage_key); - self.clear_child_prefix(storage_key, prefix); + let child_info = ChildInfo::resolve_child_info(child_type, child_definition) + .expect("Invalid child definition"); + self.clear_child_prefix(storage_key, child_info, prefix); } /// "Commit" all existing operations and compute the resulting storage root. - fn root(&mut self) -> H256 { + /// + /// The hashing algorithm is defined by the `Block`. + /// + /// Returns the SCALE encoded hash. + fn root(&mut self) -> Vec { self.storage_root() } /// "Commit" all existing operations and compute the resulting child storage root. - fn child_root(&mut self, child_storage_key: &[u8]) -> Vec { + /// + /// The hashing algorithm is defined by the `Block`. + /// + /// Returns the SCALE encoded hash. + /// + /// See `child_get` for common child api parameters. + fn child_root( + &mut self, + child_storage_key: &[u8], + ) -> Vec { let storage_key = child_storage_key_or_panic(child_storage_key); self.child_storage_root(storage_key) } /// "Commit" all existing operations and get the resulting storage change root. - fn changes_root(&mut self, parent_hash: [u8; 32]) -> Option { - self.storage_changes_root(parent_hash.into()).ok().and_then(|h| h) + /// `parent_hash` is a SCALE encoded hash. + /// + /// The hashing algorithm is defined by the `Block`. + /// + /// Returns an `Option` that holds the SCALE encoded hash. + fn changes_root(&mut self, parent_hash: &[u8]) -> Option> { + self.storage_changes_root(parent_hash).ok().and_then(|h| h) + } + + /// Get the next key in storage after the given one in lexicographic order. + fn next_key(&mut self, key: &[u8]) -> Option> { + self.next_storage_key(&key) + } + + /// Get the next key in storage after the given one in lexicographic order in child storage. + fn child_next_key( + &mut self, + child_storage_key: &[u8], + child_definition: &[u8], + child_type: u32, + key: &[u8], + ) -> Option> { + let storage_key = child_storage_key_or_panic(child_storage_key); + let child_info = ChildInfo::resolve_child_info(child_type, child_definition) + .expect("Invalid child definition"); + self.next_child_storage_key(storage_key, child_info, key) } +} +/// Interface that provides trie related functionality. +#[runtime_interface] +pub trait Trie { /// A trie root formed from the iterated items. - fn blake2_256_trie_root(input: Vec<(Vec, Vec)>) -> H256 { - Layout::::trie_root(input) + fn blake2_256_root(input: Vec<(Vec, Vec)>) -> H256 { + Layout::::trie_root(input) } /// A trie root formed from the enumerated items. - fn blake2_256_ordered_trie_root(input: Vec>) -> H256 { - Layout::::ordered_trie_root(input) + fn blake2_256_ordered_root(input: Vec>) -> H256 { + Layout::::ordered_trie_root(input) } } @@ -217,7 +332,7 @@ pub trait Storage { pub trait Misc { /// The current relay chain identifier. fn chain_id(&self) -> u64 { - externalities::Externalities::chain_id(*self) + sp_externalities::Externalities::chain_id(*self) } /// Print a number. @@ -381,32 +496,37 @@ pub trait Crypto { pub trait Hashing { /// Conduct a 256-bit Keccak hash. fn keccak_256(data: &[u8]) -> [u8; 32] { - primitives::hashing::keccak_256(data) + sp_core::hashing::keccak_256(data) + } + + /// Conduct a 256-bit Sha2 hash. + fn sha2_256(data: &[u8]) -> [u8; 32] { + sp_core::hashing::sha2_256(data) } /// Conduct a 128-bit Blake2 hash. fn blake2_128(data: &[u8]) -> [u8; 16] { - primitives::hashing::blake2_128(data) + sp_core::hashing::blake2_128(data) } /// Conduct a 256-bit Blake2 hash. fn blake2_256(data: &[u8]) -> [u8; 32] { - primitives::hashing::blake2_256(data) + sp_core::hashing::blake2_256(data) } /// Conduct four XX hashes to give a 256-bit result. fn twox_256(data: &[u8]) -> [u8; 32] { - primitives::hashing::twox_256(data) + sp_core::hashing::twox_256(data) } /// Conduct two XX hashes to give a 128-bit result. fn twox_128(data: &[u8]) -> [u8; 16] { - primitives::hashing::twox_128(data) + sp_core::hashing::twox_128(data) } /// Conduct two XX hashes to give a 64-bit result. fn twox_64(data: &[u8]) -> [u8; 8] { - primitives::hashing::twox_64(data) + sp_core::hashing::twox_64(data) } } @@ -717,7 +837,7 @@ pub trait Sandbox { #[cfg(not(feature = "std"))] struct WasmAllocator; -#[cfg(all(not(feature = "disable_global_allocator"), not(feature = "std")))] +#[cfg(all(not(feature = "disable_allocator"), not(feature = "std")))] #[global_allocator] static ALLOCATOR: WasmAllocator = WasmAllocator; @@ -737,31 +857,31 @@ mod allocator_impl { } } +/// A default panic handler for WASM environment. #[cfg(all(not(feature = "disable_panic_handler"), not(feature = "std")))] #[panic_handler] #[no_mangle] pub fn panic(info: &core::panic::PanicInfo) -> ! { unsafe { - let message = rstd::alloc::format!("{}", info); - misc::print_utf8(message.as_bytes()); + let message = sp_std::alloc::format!("{}", info); + logging::log(LogLevel::Error, "runtime", message.as_bytes()); core::intrinsics::abort() } } +/// A default OOM handler for WASM environment. #[cfg(all(not(feature = "disable_oom"), not(feature = "std")))] #[alloc_error_handler] -pub extern fn oom(_: core::alloc::Layout) -> ! { - static OOM_MSG: &str = "Runtime memory exhausted. Aborting"; - +pub fn oom(_: core::alloc::Layout) -> ! { unsafe { - misc::print_utf8(OOM_MSG.as_bytes()); + logging::log(LogLevel::Error, "runtime", b"Runtime memory exhausted. Aborting"); core::intrinsics::abort(); } } /// Type alias for Externalities implementation used in tests. #[cfg(feature = "std")] -pub type TestExternalities = substrate_state_machine::TestExternalities; +pub type TestExternalities = sp_state_machine::TestExternalities; /// The host functions Substrate provides for the Wasm runtime environment. /// @@ -776,13 +896,15 @@ pub type SubstrateHostFunctions = ( allocator::HostFunctions, logging::HostFunctions, sandbox::HostFunctions, + crate::trie::HostFunctions, ); #[cfg(test)] mod tests { use super::*; - use primitives::map; - use substrate_state_machine::BasicExternalities; + use sp_core::map; + use sp_state_machine::BasicExternalities; + use sp_core::storage::Storage; #[test] fn storage_works() { @@ -795,7 +917,10 @@ mod tests { storage::set(b"foo", &[1, 2, 3][..]); }); - t = BasicExternalities::new(map![b"foo".to_vec() => b"bar".to_vec()], map![]); + t = BasicExternalities::new(Storage { + top: map![b"foo".to_vec() => b"bar".to_vec()], + children: map![], + }); t.execute_with(|| { assert_eq!(storage::get(b"hello"), None); @@ -805,10 +930,10 @@ mod tests { #[test] fn read_storage_works() { - let mut t = BasicExternalities::new( - map![b":test".to_vec() => b"\x0b\0\0\0Hello world".to_vec()], - map![], - ); + let mut t = BasicExternalities::new(Storage { + top: map![b":test".to_vec() => b"\x0b\0\0\0Hello world".to_vec()], + children: map![], + }); t.execute_with(|| { let mut v = [0u8; 4]; @@ -822,15 +947,15 @@ mod tests { #[test] fn clear_prefix_works() { - let mut t = BasicExternalities::new( - map![ + let mut t = BasicExternalities::new(Storage { + top: map![ b":a".to_vec() => b"\x0b\0\0\0Hello world".to_vec(), b":abcd".to_vec() => b"\x0b\0\0\0Hello world".to_vec(), b":abc".to_vec() => b"\x0b\0\0\0Hello world".to_vec(), b":abdd".to_vec() => b"\x0b\0\0\0Hello world".to_vec() ], - map![], - ); + children: map![], + }); t.execute_with(|| { storage::clear_prefix(b":abc"); diff --git a/primitives/keyring/Cargo.toml b/primitives/keyring/Cargo.toml index cc0e2836bacea52b119b80cd0830d0f7f0ae7c06..61ebf89ad2464b572232bc674a4995ea7e0d2bb9 100644 --- a/primitives/keyring/Cargo.toml +++ b/primitives/keyring/Cargo.toml @@ -1,12 +1,11 @@ [package] -name = "substrate-keyring" +name = "sp-keyring" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" [dependencies] -primitives = { package = "substrate-primitives", path = "../core" } -sr-primitives = { path = "../sr-primitives" } +sp-core = { version = "2.0.0", path = "../core" } +sp-runtime = { version = "2.0.0", path = "../runtime" } lazy_static = "1.4.0" -strum = "0.15.0" -strum_macros = "0.15.0" +strum = { version = "0.16.0", features = ["derive"] } diff --git a/primitives/keyring/src/ed25519.rs b/primitives/keyring/src/ed25519.rs index c1a357fc0e427f16f58e39fd502ed7e2a56f8e33..3b882bfea8886c4b216809a98aa2414604e515e1 100644 --- a/primitives/keyring/src/ed25519.rs +++ b/primitives/keyring/src/ed25519.rs @@ -18,12 +18,12 @@ use std::{collections::HashMap, ops::Deref}; use lazy_static::lazy_static; -use primitives::{ed25519::{Pair, Public, Signature}, Pair as PairT, Public as PublicT, H256}; -pub use primitives::ed25519; -use sr_primitives::AccountId32; +use sp_core::{ed25519::{Pair, Public, Signature}, Pair as PairT, Public as PublicT, H256}; +pub use sp_core::ed25519; +use sp_runtime::AccountId32; /// Set of test accounts. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, strum_macros::Display, strum_macros::EnumIter)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, strum::Display, strum::EnumIter)] pub enum Keyring { Alice, Bob, @@ -106,9 +106,9 @@ impl From for &'static str { } } -impl From for sr_primitives::MultiSigner { +impl From for sp_runtime::MultiSigner { fn from(x: Keyring) -> Self { - sr_primitives::MultiSigner::Ed25519(x.into()) + sp_runtime::MultiSigner::Ed25519(x.into()) } } @@ -180,7 +180,7 @@ impl Deref for Keyring { #[cfg(test)] mod tests { use super::*; - use primitives::{ed25519::Pair, Pair as PairT}; + use sp_core::{ed25519::Pair, Pair as PairT}; #[test] fn should_work() { diff --git a/primitives/keyring/src/sr25519.rs b/primitives/keyring/src/sr25519.rs index b37b2bdf9b22a2f1e3f02c799f72eda5f447d719..533a21f55a45e28ee6d51894600f8d42a50eb555 100644 --- a/primitives/keyring/src/sr25519.rs +++ b/primitives/keyring/src/sr25519.rs @@ -19,12 +19,12 @@ use std::collections::HashMap; use std::ops::Deref; use lazy_static::lazy_static; -use primitives::{sr25519::{Pair, Public, Signature}, Pair as PairT, Public as PublicT, H256}; -pub use primitives::sr25519; -use sr_primitives::AccountId32; +use sp_core::{sr25519::{Pair, Public, Signature}, Pair as PairT, Public as PublicT, H256}; +pub use sp_core::sr25519; +use sp_runtime::AccountId32; /// Set of test accounts. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, strum_macros::Display, strum_macros::EnumIter)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, strum::Display, strum::EnumIter)] pub enum Keyring { Alice, Bob, @@ -107,9 +107,9 @@ impl From for &'static str { } } -impl From for sr_primitives::MultiSigner { +impl From for sp_runtime::MultiSigner { fn from(x: Keyring) -> Self { - sr_primitives::MultiSigner::Sr25519(x.into()) + sp_runtime::MultiSigner::Sr25519(x.into()) } } @@ -181,7 +181,7 @@ impl Deref for Keyring { #[cfg(test)] mod tests { use super::*; - use primitives::{sr25519::Pair, Pair as PairT}; + use sp_core::{sr25519::Pair, Pair as PairT}; #[test] fn should_work() { diff --git a/primitives/offchain/Cargo.toml b/primitives/offchain/Cargo.toml index 5b451ee6d105351b3a6c6a9f7cad1c337538325d..ef6d0a6d2c7ee86783479b0082ffa112279875d9 100644 --- a/primitives/offchain/Cargo.toml +++ b/primitives/offchain/Cargo.toml @@ -1,18 +1,18 @@ [package] description = "Substrate offchain workers primitives" -name = "substrate-offchain-primitives" +name = "sp-offchain" version = "2.0.0" license = "GPL-3.0" authors = ["Parity Technologies "] edition = "2018" [dependencies] -sr-api = { path = "../sr-api", default-features = false } -sr-primitives = { path = "../sr-primitives", default-features = false } +sp-api = { version = "2.0.0", default-features = false, path = "../api" } +sp-runtime = { version = "2.0.0", default-features = false, path = "../runtime" } [features] default = ["std"] std = [ - "sr-api/std", - "sr-primitives/std" + "sp-api/std", + "sp-runtime/std" ] diff --git a/primitives/offchain/src/lib.rs b/primitives/offchain/src/lib.rs index 876fcf49a2e74429489a2e6826c229986bf22658..db7efcd0ccc2d7415480de9fbe9823281373828f 100644 --- a/primitives/offchain/src/lib.rs +++ b/primitives/offchain/src/lib.rs @@ -19,12 +19,12 @@ #![cfg_attr(not(feature = "std"), no_std)] #![warn(missing_docs)] -use sr_primitives::traits::NumberFor; +use sp_runtime::traits::NumberFor; /// Local Storage Prefix used by the Offchain Worker API to pub const STORAGE_PREFIX: &[u8] = b"storage"; -sr_api::decl_runtime_apis! { +sp_api::decl_runtime_apis! { /// The offchain worker api. pub trait OffchainWorkerApi { /// Starts the off-chain task for given block number. diff --git a/primitives/panic-handler/Cargo.toml b/primitives/panic-handler/Cargo.toml index 9724b9291926a8098a0124b247f6f8feb0c7ab3e..19e34352cf80696eb2113c5288a574b9e3f867ce 100644 --- a/primitives/panic-handler/Cargo.toml +++ b/primitives/panic-handler/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "substrate-panic-handler" +name = "sp-panic-handler" version = "2.0.0" authors = ["Parity Technologies "] description = "Substrate panic handler." diff --git a/primitives/phragmen/Cargo.toml b/primitives/phragmen/Cargo.toml index c1465628e56c7ac634dd7d8a6b65c544cf30ff94..92807376de3b5941151c090b2862f40e2b0ecd22 100644 --- a/primitives/phragmen/Cargo.toml +++ b/primitives/phragmen/Cargo.toml @@ -1,23 +1,23 @@ [package] -name = "substrate-phragmen" +name = "sp-phragmen" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } -rstd = { package = "sr-std", path = "../sr-std", default-features = false } -sr-primitives = { path = "../../primitives/sr-primitives", default-features = false } +sp-std = { version = "2.0.0", default-features = false, path = "../std" } +sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" } [dev-dependencies] -runtime-io ={ package = "sr-io", path = "../../primitives/sr-io" } -support = { package = "frame-support", path = "../../frame/support" } +substrate-test-utils = { version = "2.0.0", path = "../../test-utils" } +sp-io ={ version = "2.0.0", path = "../../primitives/io" } rand = "0.7.2" [features] default = ["std"] std = [ "serde", - "rstd/std", - "sr-primitives/std", + "sp-std/std", + "sp-runtime/std", ] diff --git a/primitives/phragmen/benches/phragmen.rs b/primitives/phragmen/benches/phragmen.rs index b73811b33fa55065e44e71a9a269e8db7d1b1088..33b80ed5a6b5470c4c3487a03e79774246920cb2 100644 --- a/primitives/phragmen/benches/phragmen.rs +++ b/primitives/phragmen/benches/phragmen.rs @@ -23,11 +23,11 @@ extern crate test; use test::Bencher; use rand::{self, Rng}; -extern crate substrate_phragmen as phragmen; +extern crate sp_phragmen as phragmen; use phragmen::{Support, SupportMap, PhragmenStakedAssignment}; use std::collections::BTreeMap; -use sr_primitives::traits::{Convert, SaturatedConversion}; +use sp_runtime::traits::{Convert, SaturatedConversion}; const VALIDATORS: u64 = 1000; const NOMINATORS: u64 = 10_000; diff --git a/primitives/phragmen/src/lib.rs b/primitives/phragmen/src/lib.rs index 67ea6077adf58613c343ee8a59712f5bd84cd22a..a06ef9497b21604323bdb5b363fd64aa5e746259 100644 --- a/primitives/phragmen/src/lib.rs +++ b/primitives/phragmen/src/lib.rs @@ -33,12 +33,14 @@ #![cfg_attr(not(feature = "std"), no_std)] -use rstd::{prelude::*, collections::btree_map::BTreeMap}; -use sr_primitives::RuntimeDebug; -use sr_primitives::{helpers_128bit::multiply_by_rational, Perbill, Rational128}; -use sr_primitives::traits::{Zero, Convert, Member, SimpleArithmetic, Saturating, Bounded}; +use sp_std::{prelude::*, collections::btree_map::BTreeMap}; +use sp_runtime::RuntimeDebug; +use sp_runtime::{helpers_128bit::multiply_by_rational, Perbill, Rational128}; +use sp_runtime::traits::{Zero, Convert, Member, SimpleArithmetic, Saturating, Bounded}; +#[cfg(test)] mod mock; +#[cfg(test)] mod tests; /// A type in which performing operations on balances and stakes of candidates and voters are safe. diff --git a/primitives/phragmen/src/mock.rs b/primitives/phragmen/src/mock.rs index a0ab23db34040d79d5aa64d029942668c7d0b0b3..3074258bbbe66817eb9d73f183f261b59a2219ee 100644 --- a/primitives/phragmen/src/mock.rs +++ b/primitives/phragmen/src/mock.rs @@ -19,11 +19,11 @@ #![cfg(test)] use crate::{elect, PhragmenResult, PhragmenAssignment}; -use sr_primitives::{ +use sp_runtime::{ assert_eq_error_rate, Perbill, traits::{Convert, Member, SaturatedConversion} }; -use rstd::collections::btree_map::BTreeMap; +use sp_std::collections::btree_map::BTreeMap; pub(crate) struct TestCurrencyToVote; impl Convert for TestCurrencyToVote { @@ -149,7 +149,7 @@ pub(crate) fn elect_float( if let Some(winner) = candidates .iter_mut() .filter(|c| !c.elected) - .min_by(|x, y| x.score.partial_cmp(&y.score).unwrap_or(rstd::cmp::Ordering::Equal)) + .min_by(|x, y| x.score.partial_cmp(&y.score).unwrap_or(sp_std::cmp::Ordering::Equal)) { winner.elected = true; for n in &mut voters { @@ -250,10 +250,10 @@ pub(crate) fn do_equalize_float( if backing_backed_stake.len() > 0 { let max_stake = backing_backed_stake .iter() - .max_by(|x, y| x.partial_cmp(&y).unwrap_or(rstd::cmp::Ordering::Equal)) + .max_by(|x, y| x.partial_cmp(&y).unwrap_or(sp_std::cmp::Ordering::Equal)) .expect("vector with positive length will have a max; qed"); let min_stake = backed_stakes_iter - .min_by(|x, y| x.partial_cmp(&y).unwrap_or(rstd::cmp::Ordering::Equal)) + .min_by(|x, y| x.partial_cmp(&y).unwrap_or(sp_std::cmp::Ordering::Equal)) .expect("iterator with positive length will have a min; qed"); difference = max_stake - min_stake; @@ -274,17 +274,10 @@ pub(crate) fn do_equalize_float( e.1 = 0.0; }); - // todo: rewrite. elected_edges.sort_unstable_by(|x, y| - if let Some(x) = support_map.get(&x.0) { - if let Some(y) = support_map.get(&y.0) { - x.total.partial_cmp(&y.total).unwrap_or(rstd::cmp::Ordering::Equal) - } else { - rstd::cmp::Ordering::Equal - } - } else { - rstd::cmp::Ordering::Equal - } + support_map.get(&x.0) + .and_then(|x| support_map.get(&y.0).and_then(|y| x.total.partial_cmp(&y.total))) + .unwrap_or(sp_std::cmp::Ordering::Equal) ); let mut cumulative_stake = 0.0; diff --git a/primitives/phragmen/src/tests.rs b/primitives/phragmen/src/tests.rs index aaeac27c1411c39218d4fcb3c78868654cd2a7a7..09491b3b903ff90030ecdad6d68e21be5f0232a7 100644 --- a/primitives/phragmen/src/tests.rs +++ b/primitives/phragmen/src/tests.rs @@ -20,8 +20,8 @@ use crate::mock::*; use crate::{elect, PhragmenResult}; -use support::assert_eq_uvec; -use sr_primitives::Perbill; +use substrate_test_utils::assert_eq_uvec; +use sp_runtime::Perbill; #[test] fn float_phragmen_poc_works() { @@ -354,3 +354,54 @@ fn phragmen_linear_equalize() { run_and_compare(candidates, voters, stake_of, 2, 2); } + +#[test] +fn elect_has_no_entry_barrier() { + let candidates = vec![10, 20, 30]; + let voters = vec![ + (1, vec![10]), + (2, vec![20]), + ]; + let stake_of = create_stake_of(&[ + (1, 10), + (2, 10), + ]); + + let PhragmenResult { winners, assignments: _ } = elect::<_, _, _, TestCurrencyToVote>( + 3, + 3, + candidates, + voters, + stake_of, + ).unwrap(); + + // 30 is elected with stake 0. The caller is responsible for stripping this. + assert_eq_uvec!(winners, vec![ + (10, 10), + (20, 10), + (30, 0), + ]); +} + +#[test] +fn minimum_to_elect_is_respected() { + let candidates = vec![10, 20, 30]; + let voters = vec![ + (1, vec![10]), + (2, vec![20]), + ]; + let stake_of = create_stake_of(&[ + (1, 10), + (2, 10), + ]); + + let maybe_result = elect::<_, _, _, TestCurrencyToVote>( + 10, + 10, + candidates, + voters, + stake_of, + ); + + assert!(maybe_result.is_none()); +} diff --git a/primitives/rpc/Cargo.toml b/primitives/rpc/Cargo.toml index 5216882b1a22e344f08828f113ed7800bd5a6e87..33a854e6b79f1eb1118ec3b5d4c566486b70f2fd 100644 --- a/primitives/rpc/Cargo.toml +++ b/primitives/rpc/Cargo.toml @@ -1,9 +1,12 @@ [package] -name = "substrate-rpc-primitives" +name = "sp-rpc" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" [dependencies] serde = { version = "1.0.101", features = ["derive"] } -primitives = { package = "substrate-primitives", path = "../core" } +sp-core = { version = "2.0.0", path = "../core" } + +[dev-dependencies] +serde_json = "1.0.41" diff --git a/primitives/rpc/src/lib.rs b/primitives/rpc/src/lib.rs index 667b1b1b4b4f9619b2a3823a9dca0cac92f73c61..74007bea8e935daceadad52fb280ec4ed40258e5 100644 --- a/primitives/rpc/src/lib.rs +++ b/primitives/rpc/src/lib.rs @@ -19,3 +19,20 @@ #![warn(missing_docs)] pub mod number; +pub mod list; + +/// A util function to assert the result of serialization and deserialization is the same. +#[cfg(test)] +pub(crate) fn assert_deser(s: &str, expected: T) where + T: std::fmt::Debug + serde::ser::Serialize + serde::de::DeserializeOwned + PartialEq +{ + assert_eq!( + serde_json::from_str::(s).unwrap(), + expected + ); + assert_eq!( + serde_json::to_string(&expected).unwrap(), + s + ); +} + diff --git a/primitives/rpc/src/list.rs b/primitives/rpc/src/list.rs new file mode 100644 index 0000000000000000000000000000000000000000..5cd7b18705a68b4070132acf7a1bbbbdc341d25d --- /dev/null +++ b/primitives/rpc/src/list.rs @@ -0,0 +1,75 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! RPC a lenient list or value type. + +use serde::{Serialize, Deserialize}; + +/// RPC list or value wrapper. +/// +/// For some RPCs it's convenient to call them with either +/// a single value or a whole list of values to get a proper response. +/// In theory you could do a batch query, but it's: +/// 1. Less convient in client libraries +/// 2. If the response value is small, the protocol overhead might be dominant. +/// +/// Also it's nice to be able to maintain backward compatibility for methods that +/// were initially taking a value and now we want to expand them to take a list. +#[derive(Serialize, Deserialize, Debug, PartialEq)] +#[serde(untagged)] +pub enum ListOrValue { + /// A list of values of given type. + List(Vec), + /// A single value of given type. + Value(T), +} + +impl ListOrValue { + /// Map every contained value using function `F`. + /// + /// This allows to easily convert all values in any of the variants. + pub fn map X, X>(self, f: F) -> ListOrValue { + match self { + ListOrValue::List(v) => ListOrValue::List(v.into_iter().map(f).collect()), + ListOrValue::Value(v) => ListOrValue::Value(f(v)), + } + } +} + +impl From for ListOrValue { + fn from(n: T) -> Self { + ListOrValue::Value(n) + } +} + +impl From> for ListOrValue { + fn from(n: Vec) -> Self { + ListOrValue::List(n) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::assert_deser; + + #[test] + fn should_serialize_and_deserialize() { + assert_deser(r#"5"#, ListOrValue::Value(5_u64)); + assert_deser(r#""str""#, ListOrValue::Value("str".to_string())); + assert_deser(r#"[1,2,3]"#, ListOrValue::List(vec![1_u64, 2_u64, 3_u64])); + } +} diff --git a/primitives/rpc/src/number.rs b/primitives/rpc/src/number.rs index 0637e3decf39645b3561a61d7d8881451ce142a3..220b221b66e9c876c06a40afd084bc923a0b5d3d 100644 --- a/primitives/rpc/src/number.rs +++ b/primitives/rpc/src/number.rs @@ -18,7 +18,7 @@ use serde::{Serialize, Deserialize}; use std::{convert::TryFrom, fmt::Debug}; -use primitives::U256; +use sp_core::U256; /// RPC Block number type /// @@ -27,7 +27,7 @@ use primitives::U256; /// or we attempt to parse given hex value. /// We do that for consistency with the returned type, default generic header /// serializes block number as hex to avoid overflows in JavaScript. -#[derive(Serialize, Deserialize)] +#[derive(Serialize, Deserialize, Debug, PartialEq)] #[serde(untagged)] pub enum NumberOrHex { /// The original header number type of block. @@ -72,3 +72,18 @@ impl From for NumberOrHex { NumberOrHex::Hex(n) } } + +#[cfg(test)] +mod tests { + use super::*; + use crate::assert_deser; + + #[test] + fn should_serialize_and_deserialize() { + assert_deser(r#""0x1234""#, NumberOrHex::::Hex(0x1234.into())); + assert_deser(r#""0x0""#, NumberOrHex::::Hex(0.into())); + assert_deser(r#"5"#, NumberOrHex::Number(5_u64)); + assert_deser(r#"10000"#, NumberOrHex::Number(10000_u32)); + assert_deser(r#"0"#, NumberOrHex::Number(0_u16)); + } +} diff --git a/primitives/runtime-interface/Cargo.toml b/primitives/runtime-interface/Cargo.toml index 7af9b8b0887e526dbd4ca5e2912d516f4b67164f..cdc94b6a2f2266349e6d884e8814d5f332def289 100644 --- a/primitives/runtime-interface/Cargo.toml +++ b/primitives/runtime-interface/Cargo.toml @@ -1,33 +1,34 @@ [package] -name = "substrate-runtime-interface" +name = "sp-runtime-interface" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" [dependencies] -wasm-interface = { package = "substrate-wasm-interface", path = "../wasm-interface", optional = true } -rstd = { package = "sr-std", path = "../sr-std", default-features = false } -substrate-runtime-interface-proc-macro = { path = "proc-macro" } -externalities = { package = "substrate-externalities", path = "../externalities", optional = true } +sp-wasm-interface = { version = "2.0.0", optional = true, path = "../wasm-interface" } +sp-std = { version = "2.0.0", default-features = false, path = "../std" } +sp-runtime-interface-proc-macro = { version = "2.0.0", path = "proc-macro" } +sp-externalities = { version = "2.0.0", optional = true, path = "../externalities" } codec = { package = "parity-scale-codec", version = "1.0.6", default-features = false } environmental = { version = "1.0.2", optional = true } static_assertions = "1.0.0" primitive-types = { version = "0.6.1", default-features = false } [dev-dependencies] -executor = { package = "substrate-executor", path = "../../client/executor" } -test-wasm = { package = "substrate-runtime-interface-test-wasm", path = "test-wasm" } -state_machine = { package = "substrate-state-machine", path = "../../primitives/state-machine" } -primitives = { package = "substrate-primitives", path = "../core" } -runtime-io = { package = "sr-io", path = "../sr-io" } +sp-runtime-interface-test-wasm = { version = "2.0.0", path = "test-wasm" } +sp-state-machine = { version = "2.0.0", path = "../../primitives/state-machine" } +sp-core = { version = "2.0.0", path = "../core" } +sp-io = { version = "2.0.0", path = "../io" } +rustversion = "1.0.0" +trybuild = "1.0.17" [features] default = [ "std" ] std = [ - "wasm-interface", - "rstd/std", + "sp-wasm-interface", + "sp-std/std", "codec/std", - "externalities", + "sp-externalities", "environmental", "primitive-types/std", ] diff --git a/primitives/runtime-interface/proc-macro/Cargo.toml b/primitives/runtime-interface/proc-macro/Cargo.toml index 0b073b854749de95d9bf88516a84bf7c04ba9d92..a5d12de0a648bf22ceef845f9823d7f24bc289a6 100644 --- a/primitives/runtime-interface/proc-macro/Cargo.toml +++ b/primitives/runtime-interface/proc-macro/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "substrate-runtime-interface-proc-macro" +name = "sp-runtime-interface-proc-macro" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" @@ -8,20 +8,8 @@ edition = "2018" proc-macro = true [dependencies] -syn = { version = "1.0.5", features = [ "full", "visit", "fold", "extra-traits" ] } +syn = { version = "1.0.5", features = ["full", "visit", "fold", "extra-traits"] } quote = "1.0.2" proc-macro2 = "1.0.3" Inflector = "0.11.4" proc-macro-crate = "0.1.4" - -[dev-dependencies] -runtime-interface = { package = "substrate-runtime-interface", path = ".." } -codec = { package = "parity-scale-codec", version = "1.0.6", features = [ "derive" ] } -externalities = { package = "substrate-externalities", path = "../../externalities" } -rustversion = "1.0.0" -trybuild = "1.0.17" - -# We actually don't need the `std` feature in this crate, but the tests require it. -[features] -default = [ "std" ] -std = [] diff --git a/primitives/runtime-interface/proc-macro/src/lib.rs b/primitives/runtime-interface/proc-macro/src/lib.rs index 991fab756938855a4d6c5a0d3de7e56ae119d383..af181654573eeade2624fe7aa0ee6f872fcf16ad 100644 --- a/primitives/runtime-interface/proc-macro/src/lib.rs +++ b/primitives/runtime-interface/proc-macro/src/lib.rs @@ -33,148 +33,6 @@ mod pass_by; mod runtime_interface; mod utils; -/// Attribute macro for transforming a trait declaration into a runtime interface. -/// -/// A runtime interface is a fixed interface between a Substrate compatible runtime and the native -/// node. This interface is callable from a native and a wasm runtime. The macro will generate the -/// corresponding code for the native implementation and the code for calling from the wasm -/// side to the native implementation. -/// -/// The macro expects the runtime interface declaration as trait declaration: -/// -/// ``` -/// # use runtime_interface::runtime_interface; -/// -/// #[runtime_interface] -/// trait Interface { -/// /// A function that can be called from native/wasm. -/// /// -/// /// The implementation given to this function is only compiled on native. -/// fn call_some_complex_code(data: &[u8]) -> Vec { -/// // Here you could call some rather complex code that only compiles on native or -/// // is way faster in native than executing it in wasm. -/// Vec::new() -/// } -/// -/// /// A function can take a `&self` or `&mut self` argument to get access to the -/// /// `Externalities`. (The generated method does not require -/// /// this argument, so the function can be called just with the `optional` argument) -/// fn set_or_clear(&mut self, optional: Option>) { -/// match optional { -/// Some(value) => self.set_storage([1, 2, 3, 4].to_vec(), value), -/// None => self.clear_storage(&[1, 2, 3, 4]), -/// } -/// } -/// } -/// ``` -/// -/// -/// The given example will generate roughly the following code for native: -/// -/// ``` -/// // The name of the trait is converted to snake case and used as mod name. -/// // -/// // Be aware that this module is not `public`, the visibility of the module is determined based -/// // on the visibility of the trait declaration. -/// mod interface { -/// trait Interface { -/// fn call_some_complex_code(data: &[u8]) -> Vec; -/// fn set_or_clear(&mut self, optional: Option>); -/// } -/// -/// impl Interface for &mut dyn externalities::Externalities { -/// fn call_some_complex_code(data: &[u8]) -> Vec { Vec::new() } -/// fn set_or_clear(&mut self, optional: Option>) { -/// match optional { -/// Some(value) => self.set_storage([1, 2, 3, 4].to_vec(), value), -/// None => self.clear_storage(&[1, 2, 3, 4]), -/// } -/// } -/// } -/// -/// pub fn call_some_complex_code(data: &[u8]) -> Vec { -/// <&mut dyn externalities::Externalities as Interface>::call_some_complex_code(data) -/// } -/// -/// pub fn set_or_clear(optional: Option>) { -/// externalities::with_externalities(|mut ext| Interface::set_or_clear(&mut ext, optional)) -/// .expect("`set_or_clear` called outside of an Externalities-provided environment.") -/// } -/// -/// /// This type implements the `HostFunctions` trait (from `substrate-wasm-interface`) and -/// /// provides the host implementation for the wasm side. The host implementation converts the -/// /// arguments from wasm to native and calls the corresponding native function. -/// /// -/// /// This type needs to be passed to the wasm executor, so that the host functions will be -/// /// registered in the executor. -/// pub struct HostFunctions; -/// } -/// ``` -/// -/// -/// The given example will generate roughly the following code for wasm: -/// -/// ``` -/// mod interface { -/// mod extern_host_functions_impls { -/// extern "C" { -/// /// Every function is exported as `ext_TRAIT_NAME_FUNCTION_NAME_version_VERSION`. -/// /// -/// /// `TRAIT_NAME` is converted into snake case. -/// /// -/// /// The type for each argument of the exported function depends on -/// /// `::FFIType`. -/// /// -/// /// `data` holds the pointer and the length to the `[u8]` slice. -/// pub fn ext_Interface_call_some_complex_code_version_1(data: u64) -> u64; -/// /// `optional` holds the pointer and the length of the encoded value. -/// pub fn ext_Interface_set_or_clear_version_1(optional: u64); -/// } -/// } -/// -/// /// The type is actually `ExchangeableFunction` (from `substrate-runtime-interface`). -/// /// -/// /// This can be used to replace the implementation of the `call_some_complex_code` function. -/// /// Instead of calling into the host, the callee will automatically call the other -/// /// implementation. -/// /// -/// /// To replace the implementation: -/// /// -/// /// `host_call_some_complex_code.replace_implementation(some_other_impl)` -/// pub static host_call_some_complex_code: () = (); -/// pub static host_set_or_clear: () = (); -/// -/// pub fn call_some_complex_code(data: &[u8]) -> Vec { -/// // This is the actual call: `host_call_some_complex_code.get()(data)` -/// // -/// // But that does not work for several reasons in this example, so we just return an -/// // empty vector. -/// Vec::new() -/// } -/// -/// pub fn set_or_clear(optional: Option>) { -/// // Same as above -/// } -/// } -/// ``` -/// -/// # Argument types -/// -/// The macro supports any kind of argument type, as long as it implements `RIType` and the required -/// `FromFFIValue`/`IntoFFIValue` from `substrate-runtime-interface`. The macro will convert each -/// argument to the corresponding FFI representation and will call into the host using this FFI -/// representation. On the host each argument is converted back to the native representation and -/// the native implementation is called. Any return value is handled in the same way. -/// -/// # Wasm only interfaces -/// -/// Some interfaces are only required from within the wasm runtime e.g. the allocator interface. -/// To support this, the macro can be called like `#[runtime_interface(wasm_only)]`. This instructs -/// the macro to make two significant changes to the generated code: -/// -/// 1. The generated functions are not callable from the native side. -/// 2. The trait as shown above is not implemented for `Externalities` and is instead implemented -/// for `FunctionExecutor` (from `substrate-wasm-interface`). #[proc_macro_attribute] pub fn runtime_interface( attrs: proc_macro::TokenStream, @@ -188,76 +46,18 @@ pub fn runtime_interface( .into() } -/// Derive macro for implementing `PassBy` with the `Codec` strategy. -/// -/// This requires that the type implements `Encode` and `Decode` from `parity-scale-codec`. -/// -/// # Example -/// -/// ``` -/// # use runtime_interface::pass_by::PassByCodec; -/// # use codec::{Encode, Decode}; -/// #[derive(PassByCodec, Encode, Decode)] -/// struct EncodableType { -/// name: Vec, -/// param: u32, -/// } -/// ``` #[proc_macro_derive(PassByCodec)] pub fn pass_by_codec(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let input = parse_macro_input!(input as DeriveInput); pass_by::codec_derive_impl(input).unwrap_or_else(|e| e.to_compile_error()).into() } -/// Derive macro for implementing `PassBy` with the `Inner` strategy. -/// -/// Besides implementing `PassBy`, this derive also implements the helper trait `PassByInner`. -/// -/// The type is required to be a struct with just one field. The field type needs to implement -/// the required traits to pass it between the wasm and the native side. (See the runtime interface -/// crate for more information about these traits.) -/// -/// # Example -/// -/// ``` -/// # use runtime_interface::pass_by::PassByInner; -/// #[derive(PassByInner)] -/// struct Data([u8; 32]); -/// ``` -/// -/// ``` -/// # use runtime_interface::pass_by::PassByInner; -/// #[derive(PassByInner)] -/// struct Data { -/// data: [u8; 32], -/// } -/// ``` #[proc_macro_derive(PassByInner)] pub fn pass_by_inner(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let input = parse_macro_input!(input as DeriveInput); pass_by::inner_derive_impl(input).unwrap_or_else(|e| e.to_compile_error()).into() } -/// Derive macro for implementing `PassBy` with the `Enum` strategy. -/// -/// Besides implementing `PassBy`, this derive also implements `TryFrom` and `From for u8` -/// for the type. -/// -/// The type is required to be an enum with only unit variants and at maximum `256` variants. Also -/// it is required that the type implements `Copy`. -/// -/// # Example -/// -/// ``` -/// # use runtime_interface::pass_by::PassByEnum; -/// #[derive(PassByEnum, Copy, Clone)] -/// enum Data { -/// Okay, -/// NotOkay, -/// // This will not work with the derive. -/// //Why(u32), -/// } -/// ``` #[proc_macro_derive(PassByEnum)] pub fn pass_by_enum(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let input = parse_macro_input!(input as DeriveInput); diff --git a/primitives/runtime-interface/proc-macro/src/pass_by/enum_.rs b/primitives/runtime-interface/proc-macro/src/pass_by/enum_.rs index ac5e67552083b61c9647d154735963ec9c3151b5..c650a8cb5cc2e0d9a0a65fba02c2f7c062a002fc 100644 --- a/primitives/runtime-interface/proc-macro/src/pass_by/enum_.rs +++ b/primitives/runtime-interface/proc-macro/src/pass_by/enum_.rs @@ -50,10 +50,10 @@ pub fn derive_impl(input: DeriveInput) -> Result { type PassBy = #crate_::pass_by::Enum<#ident>; } - impl #crate_::rstd::convert::TryFrom for #ident { + impl #crate_::sp_std::convert::TryFrom for #ident { type Error = (); - fn try_from(inner: u8) -> #crate_::rstd::result::Result { + fn try_from(inner: u8) -> #crate_::sp_std::result::Result { match inner { #( #try_from_variants, )* _ => Err(()), diff --git a/primitives/runtime-interface/proc-macro/src/runtime_interface/bare_function_interface.rs b/primitives/runtime-interface/proc-macro/src/runtime_interface/bare_function_interface.rs index dbedba000e2627ceb1e9b4adefa291a53c08b718..1c662f8802efea1c5b805abeb9c1df141c3d6e1b 100644 --- a/primitives/runtime-interface/proc-macro/src/runtime_interface/bare_function_interface.rs +++ b/primitives/runtime-interface/proc-macro/src/runtime_interface/bare_function_interface.rs @@ -106,7 +106,7 @@ fn function_std_impl( if is_wasm_only { Some( parse_quote!( - mut __function_context__: &mut dyn #crate_::wasm_interface::FunctionContext + mut __function_context__: &mut dyn #crate_::sp_wasm_interface::FunctionContext ) ) } else { @@ -164,7 +164,7 @@ fn generate_call_to_trait( } else { // The name of the trait the interface trait is implemented for let impl_trait_name = if is_wasm_only { - quote!( #crate_::wasm_interface::FunctionContext ) + quote!( #crate_::sp_wasm_interface::FunctionContext ) } else { quote!( #crate_::Externalities ) }; diff --git a/primitives/runtime-interface/proc-macro/src/runtime_interface/host_function_interface.rs b/primitives/runtime-interface/proc-macro/src/runtime_interface/host_function_interface.rs index f710e9b60cbf4636b38f4081b1ebf5809acde809..63cb75f66789ca625f5ea85e80586218558ab18f 100644 --- a/primitives/runtime-interface/proc-macro/src/runtime_interface/host_function_interface.rs +++ b/primitives/runtime-interface/proc-macro/src/runtime_interface/host_function_interface.rs @@ -174,8 +174,8 @@ fn generate_host_functions_struct(trait_def: &ItemTrait, is_wasm_only: bool) -> pub struct HostFunctions; #[cfg(feature = "std")] - impl #crate_::wasm_interface::HostFunctions for HostFunctions { - fn host_functions() -> Vec<&'static dyn #crate_::wasm_interface::Function> { + impl #crate_::sp_wasm_interface::HostFunctions for HostFunctions { + fn host_functions() -> Vec<&'static dyn #crate_::sp_wasm_interface::Function> { vec![ #( #host_functions ),* ] } } @@ -212,20 +212,20 @@ fn generate_host_function_implementation( struct #struct_name; #[allow(unused)] - impl #crate_::wasm_interface::Function for #struct_name { + impl #crate_::sp_wasm_interface::Function for #struct_name { fn name(&self) -> &str { #name } - fn signature(&self) -> #crate_::wasm_interface::Signature { + fn signature(&self) -> #crate_::sp_wasm_interface::Signature { #signature } fn execute( &self, - __function_context__: &mut dyn #crate_::wasm_interface::FunctionContext, - args: &mut dyn Iterator, - ) -> std::result::Result, String> { + __function_context__: &mut dyn #crate_::sp_wasm_interface::FunctionContext, + args: &mut dyn Iterator, + ) -> std::result::Result, String> { #( #wasm_to_ffi_values )* #( #ffi_to_host_values )* #host_function_call @@ -234,7 +234,7 @@ fn generate_host_function_implementation( } } - &#struct_name as &dyn #crate_::wasm_interface::Function + &#struct_name as &dyn #crate_::sp_wasm_interface::Function } } ) @@ -246,18 +246,18 @@ fn generate_wasm_interface_signature_for_host_function(sig: &Signature) -> Resul let return_value = match &sig.output { ReturnType::Type(_, ty) => quote! { - Some( <<#ty as #crate_::RIType>::FFIType as #crate_::wasm_interface::IntoValue>::VALUE_TYPE ) + Some( <<#ty as #crate_::RIType>::FFIType as #crate_::sp_wasm_interface::IntoValue>::VALUE_TYPE ) }, ReturnType::Default => quote!( None ), }; let arg_types = get_function_argument_types_without_ref(sig) .map(|ty| quote! { - <<#ty as #crate_::RIType>::FFIType as #crate_::wasm_interface::IntoValue>::VALUE_TYPE + <<#ty as #crate_::RIType>::FFIType as #crate_::sp_wasm_interface::IntoValue>::VALUE_TYPE }); Ok( quote! { - #crate_::wasm_interface::Signature { + #crate_::sp_wasm_interface::Signature { args: std::borrow::Cow::Borrowed(&[ #( #arg_types ),* ][..]), return_value: #return_value, } @@ -292,7 +292,7 @@ fn generate_wasm_to_ffi_values<'a>( Ok(quote! { let val = args.next().ok_or_else(|| #error_message)?; let #var_name = < - <#ty as #crate_::RIType>::FFIType as #crate_::wasm_interface::TryFromValue + <#ty as #crate_::RIType>::FFIType as #crate_::sp_wasm_interface::TryFromValue >::try_from_value(val).ok_or_else(|| #try_from_error)?; }) }) @@ -408,7 +408,7 @@ fn generate_return_value_into_wasm_value(sig: &Signature) -> TokenStream { <#ty as #crate_::host::IntoFFIValue>::into_ffi_value( #result_var_name, __function_context__, - ).map(#crate_::wasm_interface::IntoValue::into_value).map(Some) + ).map(#crate_::sp_wasm_interface::IntoValue::into_value).map(Some) } } } diff --git a/primitives/runtime-interface/proc-macro/src/runtime_interface/trait_decl_impl.rs b/primitives/runtime-interface/proc-macro/src/runtime_interface/trait_decl_impl.rs index 0e5ae906ab680de520d2dc07052c8e79843b27c6..e76daf71bd11721cdad3f629699736f9d9c8b84c 100644 --- a/primitives/runtime-interface/proc-macro/src/runtime_interface/trait_decl_impl.rs +++ b/primitives/runtime-interface/proc-macro/src/runtime_interface/trait_decl_impl.rs @@ -130,7 +130,7 @@ fn impl_trait_for_externalities(trait_def: &ItemTrait, is_wasm_only: bool) -> Re }); let impl_type = if is_wasm_only { - quote!( &mut dyn #crate_::wasm_interface::FunctionContext ) + quote!( &mut dyn #crate_::sp_wasm_interface::FunctionContext ) } else { quote!( &mut dyn #crate_::Externalities ) }; diff --git a/primitives/runtime-interface/proc-macro/src/utils.rs b/primitives/runtime-interface/proc-macro/src/utils.rs index d868452dcec2a2d0771577dfa64f057be3515f96..d5ae107e0b431ad5df562ce1d4d6b645cb5d6534 100644 --- a/primitives/runtime-interface/proc-macro/src/utils.rs +++ b/primitives/runtime-interface/proc-macro/src/utils.rs @@ -33,10 +33,10 @@ use inflector::Inflector; /// Generates the include for the runtime-interface crate. pub fn generate_runtime_interface_include() -> TokenStream { - if env::var("CARGO_PKG_NAME").unwrap() == "substrate-runtime-interface" { + if env::var("CARGO_PKG_NAME").unwrap() == "sp-runtime-interface" { TokenStream::new() } else { - match crate_name("substrate-runtime-interface") { + match crate_name("sp-runtime-interface") { Ok(crate_name) => { let crate_name = Ident::new(&crate_name, Span::call_site()); quote!( @@ -52,10 +52,10 @@ pub fn generate_runtime_interface_include() -> TokenStream { } } -/// Generates the access to the `substrate-runtime-interface` crate. +/// Generates the access to the `sp-runtime-interface` crate. pub fn generate_crate_access() -> TokenStream { - if env::var("CARGO_PKG_NAME").unwrap() == "substrate-runtime-interface" { - quote!( substrate_runtime_interface ) + if env::var("CARGO_PKG_NAME").unwrap() == "sp-runtime-interface" { + quote!( sp_runtime_interface ) } else { quote!( proc_macro_runtime_interface ) } diff --git a/primitives/runtime-interface/src/host.rs b/primitives/runtime-interface/src/host.rs index 313aba3d855d694ccec41dc6f1a5eddd359f1167..10ebd1beec3bd503c6d37a72d3a37a2cd5657f6f 100644 --- a/primitives/runtime-interface/src/host.rs +++ b/primitives/runtime-interface/src/host.rs @@ -18,7 +18,7 @@ use crate::RIType; -use wasm_interface::{FunctionContext, Result}; +use sp_wasm_interface::{FunctionContext, Result}; /// Something that can be converted into a ffi value. pub trait IntoFFIValue: RIType { diff --git a/primitives/runtime-interface/src/impls.rs b/primitives/runtime-interface/src/impls.rs index c2821ce6ec8ac9e1bce0cf5cd73bef396b559fdd..97dfcb769a7c83baa01ffe8c7d5fab28f88b9710 100644 --- a/primitives/runtime-interface/src/impls.rs +++ b/primitives/runtime-interface/src/impls.rs @@ -26,17 +26,17 @@ use crate::wasm::*; use static_assertions::assert_eq_size; #[cfg(feature = "std")] -use wasm_interface::{FunctionContext, Result}; +use sp_wasm_interface::{FunctionContext, Result}; use codec::{Encode, Decode}; -use rstd::{any::TypeId, mem, vec::Vec}; +use sp_std::{any::TypeId, mem, vec::Vec}; #[cfg(feature = "std")] -use rstd::borrow::Cow; +use sp_std::borrow::Cow; #[cfg(not(feature = "std"))] -use rstd::{slice, boxed::Box}; +use sp_std::{slice, boxed::Box}; // Make sure that our assumptions for storing a pointer + its size in `u64` is valid. #[cfg(all(not(feature = "std"), not(feature = "disable_target_static_assertions")))] @@ -48,7 +48,7 @@ assert_eq_size!(*const u8, u32); pub fn pointer_and_len_to_u64(ptr: u32, len: u32) -> u64 { // The static assertions from above are changed into a runtime check. #[cfg(all(not(feature = "std"), feature = "disable_target_static_assertions"))] - assert_eq!(4, rstd::mem::size_of::()); + assert_eq!(4, sp_std::mem::size_of::()); (u64::from(len) << 32) | u64::from(ptr) } @@ -57,7 +57,7 @@ pub fn pointer_and_len_to_u64(ptr: u32, len: u32) -> u64 { pub fn pointer_and_len_from_u64(val: u64) -> (u32, u32) { // The static assertions from above are changed into a runtime check. #[cfg(all(not(feature = "std"), feature = "disable_target_static_assertions"))] - assert_eq!(4, rstd::mem::size_of::()); + assert_eq!(4, sp_std::mem::size_of::()); let ptr = (val & (!0u32 as u64)) as u32; let len = (val >> 32) as u32; @@ -373,7 +373,7 @@ impl_traits_for_arrays! { 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, } -impl PassBy for rstd::result::Result { +impl PassBy for sp_std::result::Result { type PassBy = Codec; } @@ -448,7 +448,7 @@ impl IntoFFIValue for str { } #[cfg(feature = "std")] -impl RIType for Pointer { +impl RIType for Pointer { type FFIType = u32; } @@ -475,7 +475,7 @@ impl FromFFIValue for Pointer { } #[cfg(feature = "std")] -impl FromFFIValue for Pointer { +impl FromFFIValue for Pointer { type SelfInstance = Self; fn from_ffi_value(_: &mut dyn FunctionContext, arg: u32) -> Result { @@ -484,7 +484,7 @@ impl FromFFIValue for Pointer { } #[cfg(feature = "std")] -impl IntoFFIValue for Pointer { +impl IntoFFIValue for Pointer { fn into_ffi_value(self, _: &mut dyn FunctionContext) -> Result { Ok(self.into()) } diff --git a/primitives/runtime-interface/src/lib.rs b/primitives/runtime-interface/src/lib.rs index fb70d252a67720f0dd51ea2a36601b64c1a39ff9..b02ccc6ab26caa5ca2e5c364d03f9e1eea4491a2 100644 --- a/primitives/runtime-interface/src/lib.rs +++ b/primitives/runtime-interface/src/lib.rs @@ -59,7 +59,7 @@ //! Declaring a runtime interface is similar to declaring a trait in Rust: //! //! ``` -//! #[substrate_runtime_interface::runtime_interface] +//! #[sp_runtime_interface::runtime_interface] //! trait RuntimeInterface { //! fn some_function(value: &[u8]) -> bool { //! value.iter().all(|v| *v > 125) @@ -72,18 +72,162 @@ #![cfg_attr(not(feature = "std"), no_std)] +extern crate self as sp_runtime_interface; + #[doc(hidden)] #[cfg(feature = "std")] -pub use wasm_interface; +pub use sp_wasm_interface; #[doc(hidden)] -pub use rstd; +pub use sp_std; -pub use substrate_runtime_interface_proc_macro::runtime_interface; +/// Attribute macro for transforming a trait declaration into a runtime interface. +/// +/// A runtime interface is a fixed interface between a Substrate compatible runtime and the native +/// node. This interface is callable from a native and a wasm runtime. The macro will generate the +/// corresponding code for the native implementation and the code for calling from the wasm +/// side to the native implementation. +/// +/// The macro expects the runtime interface declaration as trait declaration: +/// +/// ``` +/// # use sp_runtime_interface::runtime_interface; +/// +/// #[runtime_interface] +/// trait Interface { +/// /// A function that can be called from native/wasm. +/// /// +/// /// The implementation given to this function is only compiled on native. +/// fn call_some_complex_code(data: &[u8]) -> Vec { +/// // Here you could call some rather complex code that only compiles on native or +/// // is way faster in native than executing it in wasm. +/// Vec::new() +/// } +/// +/// /// A function can take a `&self` or `&mut self` argument to get access to the +/// /// `Externalities`. (The generated method does not require +/// /// this argument, so the function can be called just with the `optional` argument) +/// fn set_or_clear(&mut self, optional: Option>) { +/// match optional { +/// Some(value) => self.set_storage([1, 2, 3, 4].to_vec(), value), +/// None => self.clear_storage(&[1, 2, 3, 4]), +/// } +/// } +/// } +/// ``` +/// +/// +/// The given example will generate roughly the following code for native: +/// +/// ``` +/// // The name of the trait is converted to snake case and used as mod name. +/// // +/// // Be aware that this module is not `public`, the visibility of the module is determined based +/// // on the visibility of the trait declaration. +/// mod interface { +/// trait Interface { +/// fn call_some_complex_code(data: &[u8]) -> Vec; +/// fn set_or_clear(&mut self, optional: Option>); +/// } +/// +/// impl Interface for &mut dyn sp_externalities::Externalities { +/// fn call_some_complex_code(data: &[u8]) -> Vec { Vec::new() } +/// fn set_or_clear(&mut self, optional: Option>) { +/// match optional { +/// Some(value) => self.set_storage([1, 2, 3, 4].to_vec(), value), +/// None => self.clear_storage(&[1, 2, 3, 4]), +/// } +/// } +/// } +/// +/// pub fn call_some_complex_code(data: &[u8]) -> Vec { +/// <&mut dyn sp_externalities::Externalities as Interface>::call_some_complex_code(data) +/// } +/// +/// pub fn set_or_clear(optional: Option>) { +/// sp_externalities::with_externalities(|mut ext| Interface::set_or_clear(&mut ext, optional)) +/// .expect("`set_or_clear` called outside of an Externalities-provided environment.") +/// } +/// +/// /// This type implements the `HostFunctions` trait (from `sp-wasm-interface`) and +/// /// provides the host implementation for the wasm side. The host implementation converts the +/// /// arguments from wasm to native and calls the corresponding native function. +/// /// +/// /// This type needs to be passed to the wasm executor, so that the host functions will be +/// /// registered in the executor. +/// pub struct HostFunctions; +/// } +/// ``` +/// +/// +/// The given example will generate roughly the following code for wasm: +/// +/// ``` +/// mod interface { +/// mod extern_host_functions_impls { +/// extern "C" { +/// /// Every function is exported as `ext_TRAIT_NAME_FUNCTION_NAME_version_VERSION`. +/// /// +/// /// `TRAIT_NAME` is converted into snake case. +/// /// +/// /// The type for each argument of the exported function depends on +/// /// `::FFIType`. +/// /// +/// /// `data` holds the pointer and the length to the `[u8]` slice. +/// pub fn ext_Interface_call_some_complex_code_version_1(data: u64) -> u64; +/// /// `optional` holds the pointer and the length of the encoded value. +/// pub fn ext_Interface_set_or_clear_version_1(optional: u64); +/// } +/// } +/// +/// /// The type is actually `ExchangeableFunction` (from `sp-runtime-interface`). +/// /// +/// /// This can be used to replace the implementation of the `call_some_complex_code` function. +/// /// Instead of calling into the host, the callee will automatically call the other +/// /// implementation. +/// /// +/// /// To replace the implementation: +/// /// +/// /// `host_call_some_complex_code.replace_implementation(some_other_impl)` +/// pub static host_call_some_complex_code: () = (); +/// pub static host_set_or_clear: () = (); +/// +/// pub fn call_some_complex_code(data: &[u8]) -> Vec { +/// // This is the actual call: `host_call_some_complex_code.get()(data)` +/// // +/// // But that does not work for several reasons in this example, so we just return an +/// // empty vector. +/// Vec::new() +/// } +/// +/// pub fn set_or_clear(optional: Option>) { +/// // Same as above +/// } +/// } +/// ``` +/// +/// # Argument types +/// +/// The macro supports any kind of argument type, as long as it implements [`RIType`] and the +/// required `FromFFIValue`/`IntoFFIValue`. The macro will convert each +/// argument to the corresponding FFI representation and will call into the host using this FFI +/// representation. On the host each argument is converted back to the native representation and +/// the native implementation is called. Any return value is handled in the same way. +/// +/// # Wasm only interfaces +/// +/// Some interfaces are only required from within the wasm runtime e.g. the allocator interface. +/// To support this, the macro can be called like `#[runtime_interface(wasm_only)]`. This instructs +/// the macro to make two significant changes to the generated code: +/// +/// 1. The generated functions are not callable from the native side. +/// 2. The trait as shown above is not implemented for `Externalities` and is instead implemented +/// for `FunctionExecutor` (from `sp-wasm-interface`). +pub use sp_runtime_interface_proc_macro::runtime_interface; #[doc(hidden)] #[cfg(feature = "std")] -pub use externalities::{ +pub use sp_externalities::{ set_and_run_with_externalities, with_externalities, Externalities, ExternalitiesExt, ExtensionStore, }; @@ -105,7 +249,7 @@ pub mod pass_by; pub trait RIType { /// The ffi type that is used to represent `Self`. #[cfg(feature = "std")] - type FFIType: wasm_interface::IntoValue + wasm_interface::TryFromValue; + type FFIType: sp_wasm_interface::IntoValue + sp_wasm_interface::TryFromValue; #[cfg(not(feature = "std"))] type FFIType; } @@ -116,97 +260,4 @@ pub type Pointer = *mut T; /// A pointer that can be used in a runtime interface function signature. #[cfg(feature = "std")] -pub type Pointer = wasm_interface::Pointer; - -#[cfg(test)] -mod tests { - use super::*; - use test_wasm::{WASM_BINARY, test_api::HostFunctions}; - use wasm_interface::HostFunctions as HostFunctionsT; - - type TestExternalities = state_machine::TestExternalities; - - fn call_wasm_method(method: &str) -> TestExternalities { - let mut ext = TestExternalities::default(); - let mut ext_ext = ext.ext(); - - executor::call_in_wasm::< - _, - ( - HF, - runtime_io::SubstrateHostFunctions, - executor::deprecated_host_interface::SubstrateExternals - ) - >( - method, - &[], - executor::WasmExecutionMethod::Interpreted, - &mut ext_ext, - &WASM_BINARY[..], - 8, - ).expect(&format!("Executes `{}`", method)); - - ext - } - - #[test] - fn test_return_data() { - call_wasm_method::("test_return_data"); - } - - #[test] - fn test_return_option_data() { - call_wasm_method::("test_return_option_data"); - } - - #[test] - fn test_set_storage() { - let mut ext = call_wasm_method::("test_set_storage"); - - let expected = "world"; - assert_eq!(expected.as_bytes(), &ext.ext().storage("hello".as_bytes()).unwrap()[..]); - } - - #[test] - fn test_return_value_into_mutable_reference() { - call_wasm_method::("test_return_value_into_mutable_reference"); - } - - #[test] - fn test_get_and_return_array() { - call_wasm_method::("test_get_and_return_array"); - } - - #[test] - fn test_array_as_mutable_reference() { - call_wasm_method::("test_array_as_mutable_reference"); - } - - #[test] - fn test_return_input_public_key() { - call_wasm_method::("test_return_input_public_key"); - } - - #[test] - #[should_panic( - expected = "Other(\"Instantiation: Export ext_test_api_return_input_version_1 not found\")" - )] - fn host_function_not_found() { - call_wasm_method::<()>("test_return_data"); - } - - #[test] - #[should_panic( - expected = - "FunctionExecution(\"ext_test_api_invalid_utf8_data_version_1\", \ - \"Invalid utf8 data provided\")" - )] - fn test_invalid_utf8_data_should_return_an_error() { - call_wasm_method::("test_invalid_utf8_data_should_return_an_error"); - } - - #[test] - fn test_overwrite_native_function_implementation() { - call_wasm_method::("test_overwrite_native_function_implementation"); - } -} +pub type Pointer = sp_wasm_interface::Pointer; \ No newline at end of file diff --git a/primitives/runtime-interface/src/pass_by.rs b/primitives/runtime-interface/src/pass_by.rs index 46265237c0c4742c58b729d65368f86ce279aecb..dd38a4f80f3c830955231f9526d1fd8d5c48ed72 100644 --- a/primitives/runtime-interface/src/pass_by.rs +++ b/primitives/runtime-interface/src/pass_by.rs @@ -28,14 +28,77 @@ use crate::host::*; use crate::wasm::*; #[cfg(feature = "std")] -use wasm_interface::{FunctionContext, Pointer, Result}; +use sp_wasm_interface::{FunctionContext, Pointer, Result}; -use rstd::{marker::PhantomData, convert::TryFrom}; +use sp_std::{marker::PhantomData, convert::TryFrom}; #[cfg(not(feature = "std"))] -use rstd::{slice, vec::Vec}; +use sp_std::{slice, vec::Vec}; -pub use substrate_runtime_interface_proc_macro::{PassByCodec, PassByInner, PassByEnum}; +/// Derive macro for implementing [`PassBy`] with the [`Codec`] strategy. +/// +/// This requires that the type implements [`Encode`](codec::Encode) and [`Decode`](codec::Decode) +/// from `parity-scale-codec`. +/// +/// # Example +/// +/// ``` +/// # use sp_runtime_interface::pass_by::PassByCodec; +/// # use codec::{Encode, Decode}; +/// #[derive(PassByCodec, Encode, Decode)] +/// struct EncodableType { +/// name: Vec, +/// param: u32, +/// } +/// ``` +pub use sp_runtime_interface_proc_macro::PassByCodec; + +/// Derive macro for implementing [`PassBy`] with the [`Inner`] strategy. +/// +/// Besides implementing [`PassBy`], this derive also implements the helper trait [`PassByInner`]. +/// +/// The type is required to be a struct with just one field. The field type needs to implement +/// the required traits to pass it between the wasm and the native side. (See the runtime interface +/// crate for more information about these traits.) +/// +/// # Example +/// +/// ``` +/// # use sp_runtime_interface::pass_by::PassByInner; +/// #[derive(PassByInner)] +/// struct Data([u8; 32]); +/// ``` +/// +/// ``` +/// # use sp_runtime_interface::pass_by::PassByInner; +/// #[derive(PassByInner)] +/// struct Data { +/// data: [u8; 32], +/// } +/// ``` +pub use sp_runtime_interface_proc_macro::PassByInner; + +/// Derive macro for implementing [`PassBy`] with the [`Enum`] strategy. +/// +/// Besides implementing [`PassBy`], this derive also implements `TryFrom` and +/// `From for u8` for the type. +/// +/// The type is required to be an enum with only unit variants and at maximum `256` variants. Also +/// it is required that the type implements `Copy`. +/// +/// # Example +/// +/// ``` +/// # use sp_runtime_interface::pass_by::PassByEnum; +/// #[derive(PassByEnum, Copy, Clone)] +/// enum Data { +/// Okay, +/// NotOkay, +/// // This will not work with the derive. +/// //Why(u32), +/// } +/// ``` +pub use sp_runtime_interface_proc_macro::PassByEnum; /// Something that should be passed between wasm and the host using the given strategy. /// @@ -145,7 +208,7 @@ impl FromFFIValue for T { /// /// # Example /// ``` -/// # use substrate_runtime_interface::pass_by::{PassBy, Codec}; +/// # use sp_runtime_interface::pass_by::{PassBy, Codec}; /// #[derive(codec::Encode, codec::Decode)] /// struct Test; /// @@ -237,7 +300,7 @@ pub trait PassByInner: Sized { /// /// # Example /// ``` -/// # use substrate_runtime_interface::pass_by::{PassBy, Inner, PassByInner}; +/// # use sp_runtime_interface::pass_by::{PassBy, Inner, PassByInner}; /// struct Test([u8; 32]); /// /// impl PassBy for Test { @@ -311,7 +374,7 @@ impl, I: RIType> RIType for Inner { /// /// # Example /// ``` -/// # use substrate_runtime_interface::pass_by::{PassBy, Enum}; +/// # use sp_runtime_interface::pass_by::{PassBy, Enum}; /// #[derive(Clone, Copy)] /// enum Test { /// Test1, diff --git a/primitives/runtime-interface/src/wasm.rs b/primitives/runtime-interface/src/wasm.rs index 7ac890a3ca3bac3841761b390b5443557b1dd4e7..508f0c4f267f7916af277334245ec5c03f04c27f 100644 --- a/primitives/runtime-interface/src/wasm.rs +++ b/primitives/runtime-interface/src/wasm.rs @@ -18,7 +18,7 @@ use crate::RIType; -use rstd::cell::Cell; +use sp_std::cell::Cell; /// Something that can be created from a ffi value. /// diff --git a/primitives/runtime-interface/test-wasm/Cargo.toml b/primitives/runtime-interface/test-wasm/Cargo.toml index 13d6e2591421b47822de7a4c2ed087ed04c28162..b3a400a12d39382d249fed80bb7392ef40803024 100644 --- a/primitives/runtime-interface/test-wasm/Cargo.toml +++ b/primitives/runtime-interface/test-wasm/Cargo.toml @@ -1,19 +1,19 @@ [package] -name = "substrate-runtime-interface-test-wasm" +name = "sp-runtime-interface-test-wasm" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" build = "build.rs" [dependencies] -runtime-interface = { package = "substrate-runtime-interface", path = "../", default-features = false } -rstd = { package = "sr-std", path = "../../sr-std", default-features = false } -runtime-io = { package = "sr-io", path = "../../sr-io", default-features = false } -primitives = { package = "substrate-primitives", path = "../../core", default-features = false } +sp-runtime-interface = { version = "2.0.0", default-features = false, path = "../" } +sp-std = { version = "2.0.0", default-features = false, path = "../../std" } +sp-io = { version = "2.0.0", default-features = false, path = "../../io" } +sp-core = { version = "2.0.0", default-features = false, path = "../../core" } [build-dependencies] -wasm-builder-runner = { package = "substrate-wasm-builder-runner", version = "1.0.3", path = "../../../client/utils/wasm-builder-runner" } +wasm-builder-runner = { version = "1.0.3", package = "substrate-wasm-builder-runner", path = "../../../utils/wasm-builder-runner" } [features] default = [ "std" ] -std = [ "runtime-interface/std", "rstd/std", "primitives/std", "runtime-io/std" ] +std = [ "sp-runtime-interface/std", "sp-std/std", "sp-core/std", "sp-io/std" ] diff --git a/primitives/runtime-interface/test-wasm/src/lib.rs b/primitives/runtime-interface/test-wasm/src/lib.rs index d61315c521b685733387c9d0971f28fc71c69be0..f3535180195967ddca5a8d1f1188c2ded6d5cbf2 100644 --- a/primitives/runtime-interface/test-wasm/src/lib.rs +++ b/primitives/runtime-interface/test-wasm/src/lib.rs @@ -18,12 +18,12 @@ #![cfg_attr(not(feature = "std"), no_std)] -use runtime_interface::runtime_interface; +use sp_runtime_interface::runtime_interface; #[cfg(not(feature = "std"))] -use rstd::{vec, vec::Vec, mem, convert::TryFrom}; +use sp_std::{vec, vec::Vec, mem, convert::TryFrom}; -use primitives::{sr25519::Public, wasm_export_functions}; +use sp_core::{sr25519::Public, wasm_export_functions}; // Inlucde the WASM binary #[cfg(feature = "std")] @@ -95,15 +95,15 @@ extern "C" { /// Make sure the old runtime interface needs to be imported. #[no_mangle] pub fn force_old_runtime_interface_import() { - unsafe { ext_clear_storage(rstd::ptr::null(), 0); } - unsafe { ext_keccak_256(rstd::ptr::null(), 0, rstd::ptr::null_mut()); } + unsafe { ext_clear_storage(sp_std::ptr::null(), 0); } + unsafe { ext_keccak_256(sp_std::ptr::null(), 0, sp_std::ptr::null_mut()); } } -/// This function is not used, but we require it for the compiler to include `runtime-io`. -/// `runtime-io` is required for its panic and oom handler. +/// This function is not used, but we require it for the compiler to include `sp-io`. +/// `sp-io` is required for its panic and oom handler. #[no_mangle] -pub fn import_runtime_io() { - runtime_io::misc::print_utf8(&[]); +pub fn import_sp_io() { + sp_io::misc::print_utf8(&[]); } wasm_export_functions! { @@ -173,7 +173,7 @@ wasm_export_functions! { fn test_invalid_utf8_data_should_return_an_error() { let data = vec![0, 159, 146, 150]; // I'm an evil hacker, trying to hack! - let data_str = unsafe { rstd::str::from_utf8_unchecked(&data) }; + let data_str = unsafe { sp_std::str::from_utf8_unchecked(&data) }; test_api::invalid_utf8_data(data_str); } diff --git a/primitives/runtime-interface/test/Cargo.toml b/primitives/runtime-interface/test/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..35eb8cb8e1f56cd4545164d0f0b42db558391a8c --- /dev/null +++ b/primitives/runtime-interface/test/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "sp-runtime-interface-test" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" +publish = false + +[dependencies] +sp-runtime-interface = { version = "2.0.0", path = "../" } +sc-executor = { version = "2.0.0", path = "../../../client/executor" } +sp-runtime-interface-test-wasm = { version = "2.0.0", path = "../test-wasm" } +sp-state-machine = { version = "2.0.0", path = "../../../primitives/state-machine" } +sp-core = { version = "2.0.0", path = "../../core" } +sp-io = { version = "2.0.0", path = "../../io" } diff --git a/primitives/runtime-interface/test/src/lib.rs b/primitives/runtime-interface/test/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..a791442fc4364c6a70c2c1a145753280498899e0 --- /dev/null +++ b/primitives/runtime-interface/test/src/lib.rs @@ -0,0 +1,107 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Integration tests for runtime interface primitives + +use sp_runtime_interface::*; +use sp_runtime_interface_test_wasm::{WASM_BINARY, test_api::HostFunctions}; +use sp_wasm_interface::HostFunctions as HostFunctionsT; + +type TestExternalities = sp_state_machine::TestExternalities; + +fn call_wasm_method(method: &str) -> TestExternalities { + let mut ext = TestExternalities::default(); + let mut ext_ext = ext.ext(); + + sc_executor::call_in_wasm::< + _, + ( + HF, + sp_io::SubstrateHostFunctions, + sc_executor::deprecated_host_interface::SubstrateExternals + ) + >( + method, + &[], + sc_executor::WasmExecutionMethod::Interpreted, + &mut ext_ext, + &WASM_BINARY[..], + 8, + ).expect(&format!("Executes `{}`", method)); + + ext +} + +#[test] +fn test_return_data() { + call_wasm_method::("test_return_data"); +} + +#[test] +fn test_return_option_data() { + call_wasm_method::("test_return_option_data"); +} + +#[test] +fn test_set_storage() { + let mut ext = call_wasm_method::("test_set_storage"); + + let expected = "world"; + assert_eq!(expected.as_bytes(), &ext.ext().storage("hello".as_bytes()).unwrap()[..]); +} + +#[test] +fn test_return_value_into_mutable_reference() { + call_wasm_method::("test_return_value_into_mutable_reference"); +} + +#[test] +fn test_get_and_return_array() { + call_wasm_method::("test_get_and_return_array"); +} + +#[test] +fn test_array_as_mutable_reference() { + call_wasm_method::("test_array_as_mutable_reference"); +} + +#[test] +fn test_return_input_public_key() { + call_wasm_method::("test_return_input_public_key"); +} + +#[test] +#[should_panic( + expected = "Other(\"Instantiation: Export ext_test_api_return_input_version_1 not found\")" +)] +fn host_function_not_found() { + call_wasm_method::<()>("test_return_data"); +} + +#[test] +#[should_panic( + expected = + "FunctionExecution(\"ext_test_api_invalid_utf8_data_version_1\", \ + \"Invalid utf8 data provided\")" +)] +fn test_invalid_utf8_data_should_return_an_error() { + call_wasm_method::("test_invalid_utf8_data_should_return_an_error"); +} + +#[test] +fn test_overwrite_native_function_implementation() { + call_wasm_method::("test_overwrite_native_function_implementation"); +} diff --git a/primitives/runtime-interface/proc-macro/tests/ui.rs b/primitives/runtime-interface/tests/ui.rs similarity index 100% rename from primitives/runtime-interface/proc-macro/tests/ui.rs rename to primitives/runtime-interface/tests/ui.rs diff --git a/primitives/runtime-interface/proc-macro/tests/ui/no_generic_parameters.rs b/primitives/runtime-interface/tests/ui/no_generic_parameters.rs similarity index 61% rename from primitives/runtime-interface/proc-macro/tests/ui/no_generic_parameters.rs rename to primitives/runtime-interface/tests/ui/no_generic_parameters.rs index 489fe5d9b4f91983caec0a4a899f0995c8edc4b8..17ddb00fab3b7a6c576518e452c6b4484ab8ed4d 100644 --- a/primitives/runtime-interface/proc-macro/tests/ui/no_generic_parameters.rs +++ b/primitives/runtime-interface/tests/ui/no_generic_parameters.rs @@ -1,4 +1,4 @@ -use runtime_interface::runtime_interface; +use sp_runtime_interface::runtime_interface; #[runtime_interface] trait Test { diff --git a/primitives/runtime-interface/proc-macro/tests/ui/no_generic_parameters.stderr b/primitives/runtime-interface/tests/ui/no_generic_parameters.stderr similarity index 100% rename from primitives/runtime-interface/proc-macro/tests/ui/no_generic_parameters.stderr rename to primitives/runtime-interface/tests/ui/no_generic_parameters.stderr diff --git a/primitives/runtime-interface/proc-macro/tests/ui/no_method_implementation.rs b/primitives/runtime-interface/tests/ui/no_method_implementation.rs similarity index 58% rename from primitives/runtime-interface/proc-macro/tests/ui/no_method_implementation.rs rename to primitives/runtime-interface/tests/ui/no_method_implementation.rs index 5291942420fd5b0a2eb64c0931428adbe86591cf..e3cd93e4a97b224857fa34949896d7d53f67a28a 100644 --- a/primitives/runtime-interface/proc-macro/tests/ui/no_method_implementation.rs +++ b/primitives/runtime-interface/tests/ui/no_method_implementation.rs @@ -1,4 +1,4 @@ -use runtime_interface::runtime_interface; +use sp_runtime_interface::runtime_interface; #[runtime_interface] trait Test { diff --git a/primitives/runtime-interface/proc-macro/tests/ui/no_method_implementation.stderr b/primitives/runtime-interface/tests/ui/no_method_implementation.stderr similarity index 100% rename from primitives/runtime-interface/proc-macro/tests/ui/no_method_implementation.stderr rename to primitives/runtime-interface/tests/ui/no_method_implementation.stderr diff --git a/primitives/runtime-interface/proc-macro/tests/ui/pass_by_enum_with_struct.rs b/primitives/runtime-interface/tests/ui/pass_by_enum_with_struct.rs similarity index 51% rename from primitives/runtime-interface/proc-macro/tests/ui/pass_by_enum_with_struct.rs rename to primitives/runtime-interface/tests/ui/pass_by_enum_with_struct.rs index a729e0a99adca67d75a39479de172bcc50cf9be3..6f4ae37ea466e1f2f603929c557633c6d2059fcb 100644 --- a/primitives/runtime-interface/proc-macro/tests/ui/pass_by_enum_with_struct.rs +++ b/primitives/runtime-interface/tests/ui/pass_by_enum_with_struct.rs @@ -1,4 +1,4 @@ -use runtime_interface::pass_by::PassByEnum; +use sp_runtime_interface::pass_by::PassByEnum; #[derive(PassByEnum)] struct Test; diff --git a/primitives/runtime-interface/proc-macro/tests/ui/pass_by_enum_with_struct.stderr b/primitives/runtime-interface/tests/ui/pass_by_enum_with_struct.stderr similarity index 100% rename from primitives/runtime-interface/proc-macro/tests/ui/pass_by_enum_with_struct.stderr rename to primitives/runtime-interface/tests/ui/pass_by_enum_with_struct.stderr diff --git a/primitives/runtime-interface/proc-macro/tests/ui/pass_by_enum_with_value_variant.rs b/primitives/runtime-interface/tests/ui/pass_by_enum_with_value_variant.rs similarity index 57% rename from primitives/runtime-interface/proc-macro/tests/ui/pass_by_enum_with_value_variant.rs rename to primitives/runtime-interface/tests/ui/pass_by_enum_with_value_variant.rs index d2558e797770b8c7bfacfca9642662160d5826a3..a03bfdc1aed814f180d6822a74efcc93b05a316c 100644 --- a/primitives/runtime-interface/proc-macro/tests/ui/pass_by_enum_with_value_variant.rs +++ b/primitives/runtime-interface/tests/ui/pass_by_enum_with_value_variant.rs @@ -1,4 +1,4 @@ -use runtime_interface::pass_by::PassByEnum; +use sp_runtime_interface::pass_by::PassByEnum; #[derive(PassByEnum)] enum Test { diff --git a/primitives/runtime-interface/proc-macro/tests/ui/pass_by_enum_with_value_variant.stderr b/primitives/runtime-interface/tests/ui/pass_by_enum_with_value_variant.stderr similarity index 100% rename from primitives/runtime-interface/proc-macro/tests/ui/pass_by_enum_with_value_variant.stderr rename to primitives/runtime-interface/tests/ui/pass_by_enum_with_value_variant.stderr diff --git a/primitives/runtime-interface/proc-macro/tests/ui/pass_by_inner_with_two_fields.rs b/primitives/runtime-interface/tests/ui/pass_by_inner_with_two_fields.rs similarity index 62% rename from primitives/runtime-interface/proc-macro/tests/ui/pass_by_inner_with_two_fields.rs rename to primitives/runtime-interface/tests/ui/pass_by_inner_with_two_fields.rs index eab79eae1910cacf39803774cba70e04ccee1520..f496bc3700106b27de4c72d0a3226174e751b03e 100644 --- a/primitives/runtime-interface/proc-macro/tests/ui/pass_by_inner_with_two_fields.rs +++ b/primitives/runtime-interface/tests/ui/pass_by_inner_with_two_fields.rs @@ -1,4 +1,4 @@ -use runtime_interface::pass_by::PassByInner; +use sp_runtime_interface::pass_by::PassByInner; #[derive(PassByInner)] struct Test { diff --git a/primitives/runtime-interface/proc-macro/tests/ui/pass_by_inner_with_two_fields.stderr b/primitives/runtime-interface/tests/ui/pass_by_inner_with_two_fields.stderr similarity index 100% rename from primitives/runtime-interface/proc-macro/tests/ui/pass_by_inner_with_two_fields.stderr rename to primitives/runtime-interface/tests/ui/pass_by_inner_with_two_fields.stderr diff --git a/primitives/runtime-interface/proc-macro/tests/ui/take_self_by_value.rs b/primitives/runtime-interface/tests/ui/take_self_by_value.rs similarity index 60% rename from primitives/runtime-interface/proc-macro/tests/ui/take_self_by_value.rs rename to primitives/runtime-interface/tests/ui/take_self_by_value.rs index f01c2de21ef6157a0a05e4b6c7ff0a54ea51aff9..9c12614d9307726c01c8e3acfcb59bbd5b926abd 100644 --- a/primitives/runtime-interface/proc-macro/tests/ui/take_self_by_value.rs +++ b/primitives/runtime-interface/tests/ui/take_self_by_value.rs @@ -1,4 +1,4 @@ -use runtime_interface::runtime_interface; +use sp_runtime_interface::runtime_interface; #[runtime_interface] trait Test { diff --git a/primitives/runtime-interface/proc-macro/tests/ui/take_self_by_value.stderr b/primitives/runtime-interface/tests/ui/take_self_by_value.stderr similarity index 100% rename from primitives/runtime-interface/proc-macro/tests/ui/take_self_by_value.stderr rename to primitives/runtime-interface/tests/ui/take_self_by_value.stderr diff --git a/primitives/runtime/Cargo.toml b/primitives/runtime/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..2b3829529dd0e50b97929fdbd542c57d28fb4d5a --- /dev/null +++ b/primitives/runtime/Cargo.toml @@ -0,0 +1,39 @@ +[package] +name = "sp-runtime" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +serde = { version = "1.0.101", optional = true, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } +sp-core = { version = "2.0.0", default-features = false, path = "../core" } +sp-application-crypto = { version = "2.0.0", default-features = false, path = "../application-crypto" } +sp-arithmetic = { version = "2.0.0", default-features = false, path = "../arithmetic" } +sp-std = { version = "2.0.0", default-features = false, path = "../std" } +sp-io = { version = "2.0.0", default-features = false, path = "../io" } +log = { version = "0.4.8", optional = true } +paste = "0.1.6" +rand = { version = "0.7.2", optional = true } +impl-trait-for-tuples = "0.1.3" +sp-inherents = { version = "2.0.0", default-features = false, path = "../inherents" } + +[dev-dependencies] +serde_json = "1.0.41" +rand = "0.7.2" + +[features] +bench = [] +default = ["std"] +std = [ + "sp-application-crypto/std", + "sp-arithmetic/std", + "codec/std", + "log", + "sp-core/std", + "rand", + "sp-std/std", + "sp-io/std", + "serde", + "sp-inherents/std", +] diff --git a/primitives/sr-primitives/src/curve.rs b/primitives/runtime/src/curve.rs similarity index 99% rename from primitives/sr-primitives/src/curve.rs rename to primitives/runtime/src/curve.rs index 52a6ddd33b8c44aeddad376dbd2ac371d67088f0..f2e1a8b7d5ca3448a2c155a5f5971fa526b6d170 100644 --- a/primitives/sr-primitives/src/curve.rs +++ b/primitives/runtime/src/curve.rs @@ -20,7 +20,7 @@ use crate::{Perbill, traits::{SimpleArithmetic, SaturatedConversion}}; use core::ops::Sub; /// Piecewise Linear function in [0, 1] -> [0, 1]. -#[derive(PartialEq, Eq, primitives::RuntimeDebug)] +#[derive(PartialEq, Eq, sp_core::RuntimeDebug)] pub struct PiecewiseLinear<'a> { /// Array of points. Must be in order from the lowest abscissas to the highest. pub points: &'a [(Perbill, Perbill)], diff --git a/primitives/sr-primitives/src/generic/block.rs b/primitives/runtime/src/generic/block.rs similarity index 98% rename from primitives/sr-primitives/src/generic/block.rs rename to primitives/runtime/src/generic/block.rs index 3383e257605aa7498f35b39384c59bf86a3c50a1..cad166e80ccccfa9eb26801f62a0ce5ff9e95a31 100644 --- a/primitives/sr-primitives/src/generic/block.rs +++ b/primitives/runtime/src/generic/block.rs @@ -22,8 +22,8 @@ use std::fmt; #[cfg(feature = "std")] use serde::{Deserialize, Serialize}; -use rstd::prelude::*; -use primitives::RuntimeDebug; +use sp_std::prelude::*; +use sp_core::RuntimeDebug; use crate::codec::{Codec, Encode, Decode}; use crate::traits::{self, Member, Block as BlockT, Header as HeaderT, MaybeSerialize}; use crate::Justification; diff --git a/primitives/sr-primitives/src/generic/checked_extrinsic.rs b/primitives/runtime/src/generic/checked_extrinsic.rs similarity index 98% rename from primitives/sr-primitives/src/generic/checked_extrinsic.rs rename to primitives/runtime/src/generic/checked_extrinsic.rs index 929d7026617c9009ee648b2c6d178d80de199d7c..3940943a5971fdcd523d575942e0f03e9c216a95 100644 --- a/primitives/sr-primitives/src/generic/checked_extrinsic.rs +++ b/primitives/runtime/src/generic/checked_extrinsic.rs @@ -27,7 +27,7 @@ use crate::transaction_validity::TransactionValidity; /// Definition of something that the external world might want to say; its /// existence implies that it has been checked and is good, particularly with /// regards to the signature. -#[derive(PartialEq, Eq, Clone, primitives::RuntimeDebug)] +#[derive(PartialEq, Eq, Clone, sp_core::RuntimeDebug)] pub struct CheckedExtrinsic { /// Who this purports to be from and the number of extrinsics have come before /// from the same signer, if anyone (note this is not a signature). diff --git a/primitives/sr-primitives/src/generic/digest.rs b/primitives/runtime/src/generic/digest.rs similarity index 98% rename from primitives/sr-primitives/src/generic/digest.rs rename to primitives/runtime/src/generic/digest.rs index 83f2c6f1745dedd5092b28c2f013fd3caa0fa9a9..9e241d9a480008834d627f32577460447ebcf556 100644 --- a/primitives/sr-primitives/src/generic/digest.rs +++ b/primitives/runtime/src/generic/digest.rs @@ -19,11 +19,11 @@ #[cfg(feature = "std")] use serde::{Deserialize, Serialize}; -use rstd::prelude::*; +use sp_std::prelude::*; use crate::ConsensusEngineId; use crate::codec::{Decode, Encode, Input, Error}; -use primitives::RuntimeDebug; +use sp_core::RuntimeDebug; /// Generic header digest. #[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] @@ -105,7 +105,7 @@ pub enum DigestItem { impl serde::Serialize for DigestItem { fn serialize(&self, seq: S) -> Result where S: serde::Serializer { self.using_encoded(|bytes| { - primitives::bytes::serialize(bytes, seq) + sp_core::bytes::serialize(bytes, seq) }) } } @@ -115,7 +115,7 @@ impl<'a, Hash: Decode> serde::Deserialize<'a> for DigestItem { fn deserialize(de: D) -> Result where D: serde::Deserializer<'a>, { - let r = primitives::bytes::deserialize(de)?; + let r = sp_core::bytes::deserialize(de)?; Decode::decode(&mut &r[..]) .map_err(|e| serde::de::Error::custom(format!("Decode error: {}", e))) } diff --git a/primitives/sr-primitives/src/generic/era.rs b/primitives/runtime/src/generic/era.rs similarity index 98% rename from primitives/sr-primitives/src/generic/era.rs rename to primitives/runtime/src/generic/era.rs index 305951b1ee3914e3ae2fc93839dd155090d12db3..c72e8f8b0f3911a2459b76fd723082beae40f021 100644 --- a/primitives/sr-primitives/src/generic/era.rs +++ b/primitives/runtime/src/generic/era.rs @@ -28,7 +28,7 @@ pub type Period = u64; pub type Phase = u64; /// An era to describe the longevity of a transaction. -#[derive(PartialEq, Eq, Clone, Copy, primitives::RuntimeDebug)] +#[derive(PartialEq, Eq, Clone, Copy, sp_core::RuntimeDebug)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub enum Era { /// The transaction is valid forever. The genesis hash must be present in the signed content. diff --git a/primitives/sr-primitives/src/generic/header.rs b/primitives/runtime/src/generic/header.rs similarity index 91% rename from primitives/sr-primitives/src/generic/header.rs rename to primitives/runtime/src/generic/header.rs index 75994749c572e3a5c144ce738608902dde91e2a0..35f2e91afca1cd076a80ad559ccb7e6066309d44 100644 --- a/primitives/sr-primitives/src/generic/header.rs +++ b/primitives/runtime/src/generic/header.rs @@ -24,14 +24,14 @@ use crate::traits::{ MaybeSerializeDeserialize, MaybeSerialize, MaybeDisplay, }; use crate::generic::Digest; -use primitives::U256; -use rstd::{ +use sp_core::U256; +use sp_std::{ convert::TryFrom, fmt::Debug, }; /// Abstraction over a block header for a substrate chain. -#[derive(PartialEq, Eq, Clone, primitives::RuntimeDebug)] +#[derive(PartialEq, Eq, Clone, sp_core::RuntimeDebug)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] #[cfg_attr(feature = "std", serde(rename_all = "camelCase"))] #[cfg_attr(feature = "std", serde(deny_unknown_fields))] @@ -104,10 +104,10 @@ impl codec::EncodeLike for Header where {} impl traits::Header for Header where - Number: Member + MaybeSerializeDeserialize + Debug + rstd::hash::Hash + MaybeDisplay + - SimpleArithmetic + Codec + Copy + Into + TryFrom, + Number: Member + MaybeSerializeDeserialize + Debug + sp_std::hash::Hash + MaybeDisplay + + SimpleArithmetic + Codec + Copy + Into + TryFrom + sp_std::str::FromStr, Hash: HashT, - Hash::Output: Default + rstd::hash::Hash + Copy + Member + + Hash::Output: Default + sp_std::hash::Hash + Copy + Member + MaybeSerialize + Debug + MaybeDisplay + SimpleBitOps + Codec, { type Number = Number; @@ -152,9 +152,9 @@ impl traits::Header for Header where } impl Header where - Number: Member + rstd::hash::Hash + Copy + MaybeDisplay + SimpleArithmetic + Codec + Into + TryFrom, + Number: Member + sp_std::hash::Hash + Copy + MaybeDisplay + SimpleArithmetic + Codec + Into + TryFrom, Hash: HashT, - Hash::Output: Default + rstd::hash::Hash + Copy + Member + MaybeDisplay + SimpleBitOps + Codec, + Hash::Output: Default + sp_std::hash::Hash + Copy + Member + MaybeDisplay + SimpleBitOps + Codec, { /// Convenience helper for computing the hash of the header without having /// to import the trait. diff --git a/primitives/sr-primitives/src/generic/mod.rs b/primitives/runtime/src/generic/mod.rs similarity index 96% rename from primitives/sr-primitives/src/generic/mod.rs rename to primitives/runtime/src/generic/mod.rs index 0138a15aee21a2e7259a54cfaefc02ce4b519145..79e0d912b99f1b1dd4741544565ac2d134724622 100644 --- a/primitives/sr-primitives/src/generic/mod.rs +++ b/primitives/runtime/src/generic/mod.rs @@ -37,10 +37,10 @@ pub use self::digest::{ }; use crate::codec::Encode; -use rstd::prelude::*; +use sp_std::prelude::*; fn encode_with_vec_prefix)>(encoder: F) -> Vec { - let size = ::rstd::mem::size_of::(); + let size = ::sp_std::mem::size_of::(); let reserve = match size { 0..=0b00111111 => 1, 0..=0b00111111_11111111 => 2, diff --git a/primitives/sr-primitives/src/generic/tests.rs b/primitives/runtime/src/generic/tests.rs similarity index 98% rename from primitives/sr-primitives/src/generic/tests.rs rename to primitives/runtime/src/generic/tests.rs index 67e85da374533f67ae3f004ae88497e675e3ab8c..fed9f6ec60f52a437e69e58fb8716c38ce73eaec 100644 --- a/primitives/sr-primitives/src/generic/tests.rs +++ b/primitives/runtime/src/generic/tests.rs @@ -17,7 +17,7 @@ //! Tests for the generic implementations of Extrinsic/Header/Block. use crate::codec::{Decode, Encode}; -use primitives::H256; +use sp_core::H256; use super::DigestItem; #[test] diff --git a/primitives/sr-primitives/src/generic/unchecked_extrinsic.rs b/primitives/runtime/src/generic/unchecked_extrinsic.rs similarity index 98% rename from primitives/sr-primitives/src/generic/unchecked_extrinsic.rs rename to primitives/runtime/src/generic/unchecked_extrinsic.rs index e2bda54a313b97e529027c2abc1f2fee2cef0060..5b760ba7d1b4da807dac39f9775e71ccf6e895ba 100644 --- a/primitives/sr-primitives/src/generic/unchecked_extrinsic.rs +++ b/primitives/runtime/src/generic/unchecked_extrinsic.rs @@ -16,8 +16,8 @@ //! Generic implementation of an unchecked (pre-verification) extrinsic. -use rstd::{fmt, prelude::*}; -use runtime_io::hashing::blake2_256; +use sp_std::{fmt, prelude::*}; +use sp_io::hashing::blake2_256; use codec::{Decode, Encode, EncodeLike, Input, Error}; use crate::{ traits::{self, Member, MaybeDisplay, SignedExtension, Checkable, Extrinsic, IdentifyAccount}, @@ -282,7 +282,7 @@ where #[cfg(test)] mod tests { use super::*; - use runtime_io::hashing::blake2_256; + use sp_io::hashing::blake2_256; use crate::codec::{Encode, Decode}; use crate::traits::{SignedExtension, IdentifyAccount, IdentityLookup}; use serde::{Serialize, Deserialize}; @@ -322,7 +322,7 @@ mod tests { type DispatchInfo = (); type Pre = (); - fn additional_signed(&self) -> rstd::result::Result<(), TransactionValidityError> { Ok(()) } + fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { Ok(()) } } type Ex = UncheckedExtrinsic; diff --git a/primitives/sr-primitives/src/lib.rs b/primitives/runtime/src/lib.rs similarity index 80% rename from primitives/sr-primitives/src/lib.rs rename to primitives/runtime/src/lib.rs index f98a06fbef2e90ea5b525e7fa96c8b30761dbba0..986b4bf660e77f5a9c81621c0623bf28644fa9ab 100644 --- a/primitives/sr-primitives/src/lib.rs +++ b/primitives/runtime/src/lib.rs @@ -29,20 +29,20 @@ pub use codec; #[doc(hidden)] pub use serde; #[doc(hidden)] -pub use rstd; +pub use sp_std; #[doc(hidden)] pub use paste; #[doc(hidden)] -pub use app_crypto; +pub use sp_application_crypto as app_crypto; #[cfg(feature = "std")] -pub use primitives::storage::{StorageOverlay, ChildrenStorageOverlay}; +pub use sp_core::storage::{Storage, StorageChild}; -use rstd::prelude::*; -use rstd::convert::TryFrom; -use primitives::{crypto, ed25519, sr25519, ecdsa, hash::{H256, H512}}; +use sp_std::prelude::*; +use sp_std::convert::TryFrom; +use sp_core::{crypto, ed25519, sr25519, ecdsa, hash::{H256, H512}}; use codec::{Encode, Decode}; pub mod curve; @@ -52,23 +52,26 @@ pub mod offchain; pub mod testing; pub mod traits; pub mod transaction_validity; +pub mod random_number_generator; /// Re-export these since they're only "kind of" generic. pub use generic::{DigestItem, Digest}; /// Re-export this since it's part of the API of this crate. -pub use primitives::{TypeId, crypto::{key_types, KeyTypeId, CryptoType, AccountId32}}; -pub use app_crypto::{RuntimeAppPublic, BoundToRuntimeAppPublic}; +pub use sp_core::{TypeId, crypto::{key_types, KeyTypeId, CryptoType, AccountId32}}; +pub use sp_application_crypto::{RuntimeAppPublic, BoundToRuntimeAppPublic}; /// Re-export `RuntimeDebug`, to avoid dependency clutter. -pub use primitives::RuntimeDebug; +pub use sp_core::RuntimeDebug; /// Re-export top-level arithmetic stuff. -pub use arithmetic::{Perquintill, Perbill, Permill, Percent, Rational128, Fixed64}; +pub use sp_arithmetic::{Perquintill, Perbill, Permill, Percent, Rational128, Fixed64}; /// Re-export 128 bit helpers. -pub use arithmetic::helpers_128bit; +pub use sp_arithmetic::helpers_128bit; /// Re-export big_uint stuff. -pub use arithmetic::biguint; +pub use sp_arithmetic::biguint; + +pub use random_number_generator::RandomNumberGenerator; /// An abstraction over justification for a block's validity under a consensus algorithm. /// @@ -118,15 +121,15 @@ use crate::traits::IdentifyAccount; #[cfg(feature = "std")] pub trait BuildStorage: Sized { /// Build the storage out of this builder. - fn build_storage(&self) -> Result<(StorageOverlay, ChildrenStorageOverlay), String> { - let mut storage = (Default::default(), Default::default()); + fn build_storage(&self) -> Result { + let mut storage = Default::default(); self.assimilate_storage(&mut storage)?; Ok(storage) } /// Assimilate the storage for this module into pre-existing overlays. fn assimilate_storage( &self, - storage: &mut (StorageOverlay, ChildrenStorageOverlay), + storage: &mut sp_core::storage::Storage, ) -> Result<(), String>; } @@ -136,23 +139,26 @@ pub trait BuildModuleGenesisStorage: Sized { /// Create the module genesis storage into the given `storage` and `child_storage`. fn build_module_genesis_storage( &self, - storage: &mut (StorageOverlay, ChildrenStorageOverlay), + storage: &mut sp_core::storage::Storage, ) -> Result<(), String>; } #[cfg(feature = "std")] -impl BuildStorage for (StorageOverlay, ChildrenStorageOverlay) { +impl BuildStorage for sp_core::storage::Storage { fn assimilate_storage( &self, - storage: &mut (StorageOverlay, ChildrenStorageOverlay), + storage: &mut sp_core::storage::Storage, )-> Result<(), String> { - storage.0.extend(self.0.iter().map(|(k, v)| (k.clone(), v.clone()))); - for (k, other_map) in self.1.iter() { + storage.top.extend(self.top.iter().map(|(k, v)| (k.clone(), v.clone()))); + for (k, other_map) in self.children.iter() { let k = k.clone(); - if let Some(map) = storage.1.get_mut(&k) { - map.extend(other_map.iter().map(|(k, v)| (k.clone(), v.clone()))); + if let Some(map) = storage.children.get_mut(&k) { + map.data.extend(other_map.data.iter().map(|(k, v)| (k.clone(), v.clone()))); + if !map.child_info.try_update(other_map.child_info.as_ref()) { + return Err("Incompatible child info update".to_string()); + } } else { - storage.1.insert(k, other_map.clone()); + storage.children.insert(k, other_map.clone()); } } Ok(()) @@ -240,7 +246,7 @@ impl traits::IdentifyAccount for MultiSigner { match self { MultiSigner::Ed25519(who) => <[u8; 32]>::from(who).into(), MultiSigner::Sr25519(who) => <[u8; 32]>::from(who).into(), - MultiSigner::Ecdsa(who) => runtime_io::hashing::blake2_256(who.as_ref()).into(), + MultiSigner::Ecdsa(who) => sp_io::hashing::blake2_256(who.as_ref()).into(), } } } @@ -298,15 +304,15 @@ impl std::fmt::Display for MultiSigner { impl Verify for MultiSignature { type Signer = MultiSigner; fn verify>(&self, mut msg: L, signer: &AccountId32) -> bool { - use primitives::crypto::Public; + use sp_core::crypto::Public; match (self, signer) { (MultiSignature::Ed25519(ref sig), who) => sig.verify(msg, &ed25519::Public::from_slice(who.as_ref())), (MultiSignature::Sr25519(ref sig), who) => sig.verify(msg, &sr25519::Public::from_slice(who.as_ref())), (MultiSignature::Ecdsa(ref sig), who) => { - let m = runtime_io::hashing::blake2_256(msg.get()); - match runtime_io::crypto::secp256k1_ecdsa_recover_compressed(sig.as_ref(), &m) { + let m = sp_io::hashing::blake2_256(msg.get()); + match sp_io::crypto::secp256k1_ecdsa_recover_compressed(sig.as_ref(), &m) { Ok(pubkey) => - &runtime_io::hashing::blake2_256(pubkey.as_ref()) + &sp_io::hashing::blake2_256(pubkey.as_ref()) == >::as_ref(who), _ => false, } @@ -323,7 +329,7 @@ pub struct AnySignature(H512); impl Verify for AnySignature { type Signer = sr25519::Public; fn verify>(&self, mut msg: L, signer: &sr25519::Public) -> bool { - use primitives::crypto::Public; + use sp_core::crypto::Public; let msg = msg.get(); sr25519::Signature::try_from(self.0.as_fixed_bytes().as_ref()) .map(|s| s.verify(msg, signer)) @@ -352,56 +358,76 @@ impl From for DispatchOutcome { } } +/// Result of a module function call; either nothing (functions are only called for "side effects") +/// or an error message. +pub type DispatchResult = sp_std::result::Result<(), DispatchError>; + +/// Reason why a dispatch call failed #[derive(Eq, PartialEq, Clone, Copy, Encode, Decode, RuntimeDebug)] #[cfg_attr(feature = "std", derive(Serialize))] -/// Reason why a dispatch call failed -pub struct DispatchError { - /// Module index, matching the metadata module index - pub module: Option, - /// Module specific error value - pub error: u8, - /// Optional error message. - #[codec(skip)] - pub message: Option<&'static str>, -} - -impl DispatchError { - /// Create a new instance of `DispatchError`. - pub fn new(module: Option, error: u8, message: Option<&'static str>) -> Self { - Self { - module, - error, - message, - } +pub enum DispatchError { + /// Some error occurred. + Other(#[codec(skip)] &'static str), + /// Failed to lookup some data. + CannotLookup, + /// A bad origin. + BadOrigin, + /// A custom error in a module + Module { + /// Module index, matching the metadata module index + index: u8, + /// Module specific error value + error: u8, + /// Optional error message. + #[codec(skip)] + message: Option<&'static str>, + }, +} + +impl From for DispatchError { + fn from(_: crate::traits::LookupError) -> Self { + Self::CannotLookup } } -impl traits::Printable for DispatchError { - fn print(&self) { - "DispatchError".print(); - if let Some(module) = self.module { - module.print(); - } - self.error.print(); - if let Some(msg) = self.message { - msg.print(); - } +impl From for DispatchError { + fn from(_: crate::traits::BadOrigin) -> Self { + Self::BadOrigin } } -impl traits::ModuleDispatchError for &'static str { - fn as_u8(&self) -> u8 { - 0 +impl From<&'static str> for DispatchError { + fn from(err: &'static str) -> DispatchError { + DispatchError::Other(err) } +} - fn as_str(&self) -> &'static str { - self +impl Into<&'static str> for DispatchError { + fn into(self) -> &'static str { + match self { + Self::Other(msg) => msg, + Self::CannotLookup => "Can not lookup", + Self::BadOrigin => "Bad origin", + Self::Module { message, .. } => message.unwrap_or("Unknown module error"), + } } } -impl From<&'static str> for DispatchError { - fn from(err: &'static str) -> DispatchError { - DispatchError::new(None, 0, Some(err)) +impl traits::Printable for DispatchError { + fn print(&self) { + "DispatchError".print(); + match self { + Self::Other(err) => err.print(), + Self::CannotLookup => "Can not lookup".print(), + Self::BadOrigin => "Bad origin".print(), + Self::Module { index, error, message } => { + index.print(); + error.print(); + if let Some(msg) = message { + msg.print(); + } + } + } } } @@ -529,7 +555,7 @@ macro_rules! impl_outer_config { impl $crate::BuildStorage for $main { fn assimilate_storage( &self, - storage: &mut ($crate::StorageOverlay, $crate::ChildrenStorageOverlay), + storage: &mut $crate::Storage, ) -> std::result::Result<(), String> { $( if let Some(ref extra) = self.[< $snake $(_ $instance )? >] { @@ -580,15 +606,15 @@ macro_rules! impl_outer_config { /// /// ```rust /// # fn main() { -/// sr_primitives::assert_eq_error_rate!(10, 10, 0); -/// sr_primitives::assert_eq_error_rate!(10, 11, 1); -/// sr_primitives::assert_eq_error_rate!(12, 10, 2); +/// sp_runtime::assert_eq_error_rate!(10, 10, 0); +/// sp_runtime::assert_eq_error_rate!(10, 11, 1); +/// sp_runtime::assert_eq_error_rate!(12, 10, 2); /// # } /// ``` /// /// ```rust,should_panic /// # fn main() { -/// sr_primitives::assert_eq_error_rate!(12, 10, 1); +/// sp_runtime::assert_eq_error_rate!(12, 10, 1); /// # } /// ``` #[macro_export] @@ -610,14 +636,14 @@ macro_rules! assert_eq_error_rate { #[derive(PartialEq, Eq, Clone, Default, Encode, Decode)] pub struct OpaqueExtrinsic(pub Vec); -impl rstd::fmt::Debug for OpaqueExtrinsic { +impl sp_std::fmt::Debug for OpaqueExtrinsic { #[cfg(feature = "std")] - fn fmt(&self, fmt: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { - write!(fmt, "{}", primitives::hexdisplay::HexDisplay::from(&self.0)) + fn fmt(&self, fmt: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { + write!(fmt, "{}", sp_core::hexdisplay::HexDisplay::from(&self.0)) } #[cfg(not(feature = "std"))] - fn fmt(&self, _fmt: &mut rstd::fmt::Formatter) -> rstd::fmt::Result { + fn fmt(&self, _fmt: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { Ok(()) } } @@ -626,14 +652,14 @@ impl rstd::fmt::Debug for OpaqueExtrinsic { #[cfg(feature = "std")] impl ::serde::Serialize for OpaqueExtrinsic { fn serialize(&self, seq: S) -> Result where S: ::serde::Serializer { - codec::Encode::using_encoded(&self.0, |bytes| ::primitives::bytes::serialize(bytes, seq)) + codec::Encode::using_encoded(&self.0, |bytes| ::sp_core::bytes::serialize(bytes, seq)) } } #[cfg(feature = "std")] impl<'a> ::serde::Deserialize<'a> for OpaqueExtrinsic { fn deserialize(de: D) -> Result where D: ::serde::Deserializer<'a> { - let r = ::primitives::bytes::deserialize(de)?; + let r = ::sp_core::bytes::deserialize(de)?; Decode::decode(&mut &r[..]) .map_err(|e| ::serde::de::Error::custom(format!("Decode error: {}", e))) } @@ -662,18 +688,18 @@ mod tests { #[test] fn dispatch_error_encoding() { - let error = DispatchError { - module: Some(1), + let error = DispatchError::Module { + index: 1, error: 2, message: Some("error message"), }; let encoded = error.encode(); let decoded = DispatchError::decode(&mut &encoded[..]).unwrap(); - assert_eq!(encoded, vec![1, 1, 2]); + assert_eq!(encoded, vec![3, 1, 2]); assert_eq!( decoded, - DispatchError { - module: Some(1), + DispatchError::Module { + index: 1, error: 2, message: None, }, diff --git a/primitives/sr-primitives/src/offchain/http.rs b/primitives/runtime/src/offchain/http.rs similarity index 94% rename from primitives/sr-primitives/src/offchain/http.rs rename to primitives/runtime/src/offchain/http.rs index 50d536fc14dbb06a4313bdaba105129958cbdae6..968d50daee8d87b7d3a80dce695496a547a5454e 100644 --- a/primitives/sr-primitives/src/offchain/http.rs +++ b/primitives/runtime/src/offchain/http.rs @@ -16,7 +16,7 @@ //! A high-level helpers for making HTTP requests from Offchain Workers. //! -//! `sr-io` crate exposes a low level methods to make and control HTTP requests +//! `sp-io` crate exposes a low level methods to make and control HTTP requests //! available only for Offchain Workers. Those might be hard to use //! and usually that level of control is not really necessary. //! This module aims to provide high-level wrappers for those APIs @@ -25,7 +25,7 @@ //! //! Example: //! ```rust,no_run -//! use sr_primitives::offchain::http::Request; +//! use sp_runtime::offchain::http::Request; //! //! // initiate a GET request to localhost:1234 //! let request: Request = Request::get("http://localhost:1234"); @@ -47,12 +47,12 @@ //! assert_eq!(body.error(), &None); //! ``` -use rstd::str; -use rstd::prelude::Vec; +use sp_std::str; +use sp_std::prelude::Vec; #[cfg(not(feature = "std"))] -use rstd::prelude::vec; -use primitives::RuntimeDebug; -use primitives::offchain::{ +use sp_std::prelude::vec; +use sp_core::RuntimeDebug; +use sp_core::offchain::{ Timestamp, HttpRequestId as RequestId, HttpRequestStatus as RequestStatus, @@ -111,7 +111,7 @@ mod header { /// Returns the name of this header. pub fn name(&self) -> &str { // Header keys are always produced from `&str` so this is safe. - // we don't store them as `Strings` to avoid bringing `alloc::String` to rstd + // we don't store them as `Strings` to avoid bringing `alloc::String` to sp-std // or here. unsafe { str::from_utf8_unchecked(&self.name) } } @@ -119,7 +119,7 @@ mod header { /// Returns the value of this header. pub fn value(&self) -> &str { // Header values are always produced from `&str` so this is safe. - // we don't store them as `Strings` to avoid bringing `alloc::String` to rstd + // we don't store them as `Strings` to avoid bringing `alloc::String` to sp-std // or here. unsafe { str::from_utf8_unchecked(&self.value) } } @@ -221,7 +221,7 @@ impl<'a, I: AsRef<[u8]>, T: IntoIterator> Request<'a, T> { let meta = &[]; // start an http request. - let id = runtime_io::offchain::http_request_start( + let id = sp_io::offchain::http_request_start( self.method.as_ref(), self.url, meta, @@ -229,7 +229,7 @@ impl<'a, I: AsRef<[u8]>, T: IntoIterator> Request<'a, T> { // add custom headers for header in &self.headers { - runtime_io::offchain::http_request_add_header( + sp_io::offchain::http_request_add_header( id, header.name(), header.value(), @@ -238,11 +238,11 @@ impl<'a, I: AsRef<[u8]>, T: IntoIterator> Request<'a, T> { // write body for chunk in self.body { - runtime_io::offchain::http_request_write_body(id, chunk.as_ref(), self.deadline)?; + sp_io::offchain::http_request_write_body(id, chunk.as_ref(), self.deadline)?; } // finalise the request - runtime_io::offchain::http_request_write_body(id, &[], self.deadline)?; + sp_io::offchain::http_request_write_body(id, &[], self.deadline)?; Ok(PendingRequest { id, @@ -307,7 +307,7 @@ impl PendingRequest { deadline: impl Into> ) -> Vec> { let ids = requests.iter().map(|r| r.id).collect::>(); - let statuses = runtime_io::offchain::http_response_wait(&ids, deadline.into()); + let statuses = sp_io::offchain::http_response_wait(&ids, deadline.into()); statuses .into_iter() @@ -346,7 +346,7 @@ impl Response { pub fn headers(&mut self) -> &Headers { if self.headers.is_none() { self.headers = Some( - Headers { raw: runtime_io::offchain::http_response_headers(self.id) }, + Headers { raw: sp_io::offchain::http_response_headers(self.id) }, ); } self.headers.as_ref().expect("Headers were just set; qed") @@ -426,7 +426,7 @@ impl Iterator for ResponseBody { } if self.filled_up_to.is_none() { - let result = runtime_io::offchain::http_response_read_body( + let result = sp_io::offchain::http_response_read_body( self.id, &mut self.buffer, self.deadline); @@ -515,8 +515,8 @@ impl<'a> HeadersIterator<'a> { #[cfg(test)] mod tests { use super::*; - use runtime_io::TestExternalities; - use primitives::offchain::{ + use sp_io::TestExternalities; + use sp_core::offchain::{ OffchainExt, testing, }; diff --git a/client/network/src/legacy_proto/mod.rs b/primitives/runtime/src/offchain/mod.rs similarity index 86% rename from client/network/src/legacy_proto/mod.rs rename to primitives/runtime/src/offchain/mod.rs index bbe795528be9d854217dc23a622b7bbe5fd8da36..07c25570eef8c0e7f610eb10768ad94344113fd6 100644 --- a/client/network/src/legacy_proto/mod.rs +++ b/primitives/runtime/src/offchain/mod.rs @@ -14,9 +14,6 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -pub use self::behaviour::{LegacyProto, LegacyProtoOut}; +//! A collection of higher lever helpers for offchain calls. -mod behaviour; -mod handler; -mod upgrade; -mod tests; +pub mod http; diff --git a/primitives/runtime/src/random_number_generator.rs b/primitives/runtime/src/random_number_generator.rs new file mode 100644 index 0000000000000000000000000000000000000000..487d3b95275c714f691a45502f23f8f99b1709a7 --- /dev/null +++ b/primitives/runtime/src/random_number_generator.rs @@ -0,0 +1,103 @@ +// Copyright 2017-2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! A simple pseudo random number generator that allows a stream of random numbers to be efficiently +//! created from a single initial seed hash. + +use codec::{Encode, Decode}; +use crate::traits::{Hash, TrailingZeroInput}; + +/// Pseudo-random number streamer. This retains the state of the random number stream. It's as +/// secure as the combination of the seed with which it is constructed and the hash function it uses +/// to cycle elements. +/// +/// It can be saved and later reloaded using the Codec traits. +/// +/// Example: +/// ``` +/// use sp_runtime::traits::{Hash, BlakeTwo256}; +/// use sp_runtime::RandomNumberGenerator; +/// let random_seed = BlakeTwo256::hash(b"Sixty-nine"); +/// let mut rng = >::new(random_seed); +/// assert_eq!(rng.pick_u32(100), 59); +/// assert_eq!(rng.pick_item(&[1, 2, 3]), Some(&1)); +/// ``` +/// +/// This can use any cryptographic `Hash` function as the means of entropy-extension, and avoids +/// needless extensions of entropy. +/// +/// If you're persisting it over blocks, be aware that the sequence will start to repeat. This won't +/// be a practical issue unless you're using tiny hash types (e.g. 64-bit) and pulling hundred of +/// megabytes of data from it. +#[derive(Encode, Decode)] +pub struct RandomNumberGenerator { + current: Hashing::Output, + offset: u32, +} + +impl RandomNumberGenerator { + /// A new source of random data. + pub fn new(seed: Hashing::Output) -> Self { + Self { + current: seed, + offset: 0, + } + } + + fn offset(&self) -> usize { self.offset as usize } + + /// Returns a number at least zero, at most `max`. + pub fn pick_u32(&mut self, max: u32) -> u32 { + let needed = (4 - max.leading_zeros() / 8) as usize; + let top = ((1 << (needed as u64 * 8)) / ((max + 1) as u64) * ((max + 1) as u64) - 1) as u32; + loop { + if self.offset() + needed > self.current.as_ref().len() { + // rehash + self.current = Hashing::hash(self.current.as_ref()); + self.offset = 0; + } + let data = &self.current.as_ref()[self.offset()..self.offset() + needed]; + self.offset += needed as u32; + let raw = u32::decode(&mut TrailingZeroInput::new(data)).unwrap_or(0); + if raw <= top { + break if max < u32::max_value() { + raw % (max + 1) + } else { + raw + } + } + } + } + + /// Returns a number at least zero, at most `max`. + /// + /// This returns a `usize`, but internally it only uses `u32` so avoid consensus problems. + pub fn pick_usize(&mut self, max: usize) -> usize { + self.pick_u32(max as u32) as usize + } + + /// Pick a random element from an array of `items`. + /// + /// This is guaranteed to return `Some` except in the case that the given array `items` is + /// empty. + pub fn pick_item<'a, T>(&mut self, items: &'a [T]) -> Option<&'a T> { + if items.is_empty() { + None + } else { + Some(&items[self.pick_usize(items.len() - 1)]) + } + } +} diff --git a/primitives/sr-primitives/src/testing.rs b/primitives/runtime/src/testing.rs similarity index 98% rename from primitives/sr-primitives/src/testing.rs rename to primitives/runtime/src/testing.rs index e77b7c23b4fd9219468eabefe66b655bee78c28d..4fb7ccade7d8c14d07a4b76349d038ece894eb0a 100644 --- a/primitives/sr-primitives/src/testing.rs +++ b/primitives/runtime/src/testing.rs @@ -26,8 +26,8 @@ use crate::traits::{ #[allow(deprecated)] use crate::traits::ValidateUnsigned; use crate::{generic, KeyTypeId, ApplyExtrinsicResult}; -pub use primitives::{H256, sr25519}; -use primitives::{crypto::{CryptoType, Dummy, key_types, Public}, U256}; +pub use sp_core::{H256, sr25519}; +use sp_core::{crypto::{CryptoType, Dummy, key_types, Public}, U256}; use crate::transaction_validity::{TransactionValidity, TransactionValidityError}; /// Authority Id @@ -80,7 +80,7 @@ impl UintAuthorityId { } } -impl app_crypto::RuntimeAppPublic for UintAuthorityId { +impl sp_application_crypto::RuntimeAppPublic for UintAuthorityId { const ID: KeyTypeId = key_types::DUMMY; type Signature = u64; diff --git a/primitives/sr-primitives/src/traits.rs b/primitives/runtime/src/traits.rs similarity index 87% rename from primitives/sr-primitives/src/traits.rs rename to primitives/runtime/src/traits.rs index 2b2bed53a467ee9dfa2c86a0876faf17d84b0056..22cd2814e73cb56f1184227fa175a7adb82e702d 100644 --- a/primitives/sr-primitives/src/traits.rs +++ b/primitives/runtime/src/traits.rs @@ -16,25 +16,25 @@ //! Primitives for the runtime modules. -use rstd::prelude::*; -use rstd::{self, result, marker::PhantomData, convert::{TryFrom, TryInto}, fmt::Debug}; -use runtime_io; +use sp_std::prelude::*; +use sp_std::{self, result, marker::PhantomData, convert::{TryFrom, TryInto}, fmt::Debug}; +use sp_io; #[cfg(feature = "std")] use std::fmt::Display; #[cfg(feature = "std")] use serde::{Serialize, Deserialize, de::DeserializeOwned}; -use primitives::{self, Hasher, Blake2Hasher, TypeId}; +use sp_core::{self, Hasher, Blake2Hasher, TypeId}; use crate::codec::{Codec, Encode, Decode}; use crate::transaction_validity::{ ValidTransaction, TransactionValidity, TransactionValidityError, UnknownTransaction, }; use crate::generic::{Digest, DigestItem}; -pub use arithmetic::traits::{ +pub use sp_arithmetic::traits::{ SimpleArithmetic, UniqueSaturatedInto, UniqueSaturatedFrom, Saturating, SaturatedConversion, Zero, One, Bounded, CheckedAdd, CheckedSub, CheckedMul, CheckedDiv, CheckedShl, CheckedShr, IntegerSquareRoot }; -use app_crypto::AppKey; +use sp_application_crypto::AppKey; use impl_trait_for_tuples::impl_for_tuples; /// A lazy value. @@ -49,8 +49,8 @@ impl<'a> Lazy<[u8]> for &'a [u8] { fn get(&mut self) -> &[u8] { &**self } } -/// Some type that is able to be collapsed into an account ID. It is not possible to recreate the original value from -/// the account ID. +/// Some type that is able to be collapsed into an account ID. It is not possible to recreate the +/// original value from the account ID. pub trait IdentifyAccount { /// The account ID that this can be transformed into. type AccountId; @@ -58,17 +58,17 @@ pub trait IdentifyAccount { fn into_account(self) -> Self::AccountId; } -impl IdentifyAccount for primitives::ed25519::Public { +impl IdentifyAccount for sp_core::ed25519::Public { type AccountId = Self; fn into_account(self) -> Self { self } } -impl IdentifyAccount for primitives::sr25519::Public { +impl IdentifyAccount for sp_core::sr25519::Public { type AccountId = Self; fn into_account(self) -> Self { self } } -impl IdentifyAccount for primitives::ecdsa::Public { +impl IdentifyAccount for sp_core::ecdsa::Public { type AccountId = Self; fn into_account(self) -> Self { self } } @@ -81,26 +81,26 @@ pub trait Verify { fn verify>(&self, msg: L, signer: &::AccountId) -> bool; } -impl Verify for primitives::ed25519::Signature { - type Signer = primitives::ed25519::Public; - fn verify>(&self, mut msg: L, signer: &primitives::ed25519::Public) -> bool { - runtime_io::crypto::ed25519_verify(self, msg.get(), signer) +impl Verify for sp_core::ed25519::Signature { + type Signer = sp_core::ed25519::Public; + fn verify>(&self, mut msg: L, signer: &sp_core::ed25519::Public) -> bool { + sp_io::crypto::ed25519_verify(self, msg.get(), signer) } } -impl Verify for primitives::sr25519::Signature { - type Signer = primitives::sr25519::Public; - fn verify>(&self, mut msg: L, signer: &primitives::sr25519::Public) -> bool { - runtime_io::crypto::sr25519_verify(self, msg.get(), signer) +impl Verify for sp_core::sr25519::Signature { + type Signer = sp_core::sr25519::Public; + fn verify>(&self, mut msg: L, signer: &sp_core::sr25519::Public) -> bool { + sp_io::crypto::sr25519_verify(self, msg.get(), signer) } } -impl Verify for primitives::ecdsa::Signature { - type Signer = primitives::ecdsa::Public; - fn verify>(&self, mut msg: L, signer: &primitives::ecdsa::Public) -> bool { - match runtime_io::crypto::secp256k1_ecdsa_recover_compressed( +impl Verify for sp_core::ecdsa::Signature { + type Signer = sp_core::ecdsa::Public; + fn verify>(&self, mut msg: L, signer: &sp_core::ecdsa::Public) -> bool { + match sp_io::crypto::secp256k1_ecdsa_recover_compressed( self.as_ref(), - &runtime_io::hashing::blake2_256(msg.get()), + &sp_io::hashing::blake2_256(msg.get()), ) { Ok(pubkey) => >::as_ref(signer) == &pubkey[..], _ => false, @@ -117,30 +117,30 @@ pub trait AppVerify { } impl< - S: Verify::Public as app_crypto::AppPublic>::Generic> + From, - T: app_crypto::Wraps + app_crypto::AppKey + app_crypto::AppSignature + + S: Verify::Public as sp_application_crypto::AppPublic>::Generic> + From, + T: sp_application_crypto::Wraps + sp_application_crypto::AppKey + sp_application_crypto::AppSignature + AsRef + AsMut + From, > AppVerify for T where ::Signer: IdentifyAccount::Signer>, - <::Public as app_crypto::AppPublic>::Generic: - IdentifyAccount::Public as app_crypto::AppPublic>::Generic>, + <::Public as sp_application_crypto::AppPublic>::Generic: + IdentifyAccount::Public as sp_application_crypto::AppPublic>::Generic>, { type AccountId = ::Public; fn verify>(&self, msg: L, signer: &::Public) -> bool { - use app_crypto::IsWrappedBy; + use sp_application_crypto::IsWrappedBy; let inner: &S = self.as_ref(); - let inner_pubkey = <::Public as app_crypto::AppPublic>::Generic::from_ref(&signer); + let inner_pubkey = <::Public as sp_application_crypto::AppPublic>::Generic::from_ref(&signer); Verify::verify(inner, msg, inner_pubkey) } } /// An error type that indicates that the origin is invalid. #[derive(Encode, Decode)] -pub struct InvalidOrigin; +pub struct BadOrigin; -impl From for &'static str { - fn from(_: InvalidOrigin) -> &'static str { - "Invalid origin" +impl From for &'static str { + fn from(_: BadOrigin) -> &'static str { + "Bad origin" } } @@ -149,8 +149,8 @@ pub trait EnsureOrigin { /// A return type. type Success; /// Perform the origin check. - fn ensure_origin(o: OuterOrigin) -> result::Result { - Self::try_origin(o).map_err(|_| InvalidOrigin) + fn ensure_origin(o: OuterOrigin) -> result::Result { + Self::try_origin(o).map_err(|_| BadOrigin) } /// Perform the origin check. fn try_origin(o: OuterOrigin) -> result::Result; @@ -316,15 +316,15 @@ impl Clear for T { /// A meta trait for all bit ops. pub trait SimpleBitOps: Sized + Clear + - rstd::ops::BitOr + - rstd::ops::BitXor + - rstd::ops::BitAnd + sp_std::ops::BitOr + + sp_std::ops::BitXor + + sp_std::ops::BitAnd {} impl + - rstd::ops::BitXor + - rstd::ops::BitAnd + sp_std::ops::BitOr + + sp_std::ops::BitXor + + sp_std::ops::BitAnd > SimpleBitOps for T {} /// The block finalization trait. Implementing this lets you express what should happen @@ -346,18 +346,22 @@ pub trait OnInitialize { /// Off-chain computation trait. /// /// Implementing this trait on a module allows you to perform long-running tasks -/// that make validators generate extrinsics (either transactions or inherents) -/// with the results of those long-running computations. +/// that make (by default) validators generate transactions that feed results +/// of those long-running computations back on chain. /// /// NOTE: This function runs off-chain, so it can access the block state, -/// but cannot preform any alterations. +/// but cannot preform any alterations. More specifically alterations are +/// not forbidden, but they are not persisted in any way after the worker +/// has finished. #[impl_for_tuples(30)] pub trait OffchainWorker { - /// This function is being called on every block. + /// This function is being called after every block import (when fully synced). /// - /// Implement this and use special `extern`s to generate transactions or inherents. + /// Implement this and use any of the `Offchain` `sp_io` set of APIs + /// to perform off-chain computations, calls and submit transactions + /// with results to trigger any on-chain changes. /// Any state alterations are lost and are not persisted. - fn generate_extrinsics(_n: BlockNumber) {} + fn offchain_worker(_n: BlockNumber) {} } /// Abstraction around hashing @@ -365,7 +369,7 @@ pub trait OffchainWorker { // traits must be fulfilled by all type parameters. pub trait Hash: 'static + MaybeSerializeDeserialize + Debug + Clone + Eq + PartialEq { /// The hash type produced. - type Output: Member + MaybeSerializeDeserialize + Debug + rstd::hash::Hash + type Output: Member + MaybeSerializeDeserialize + Debug + sp_std::hash::Hash + AsRef<[u8]> + AsMut<[u8]> + Copy + Default + Encode + Decode; /// The associated hash_db Hasher type. @@ -384,40 +388,26 @@ pub trait Hash: 'static + MaybeSerializeDeserialize + Debug + Clone + Eq + Parti /// The Patricia tree root of the given mapping. fn trie_root(input: Vec<(Vec, Vec)>) -> Self::Output; - - /// Acquire the global storage root. - fn storage_root() -> Self::Output; - - /// Acquire the global storage changes root. - fn storage_changes_root(parent_hash: Self::Output) -> Option; } /// Blake2-256 Hash implementation. -#[derive(PartialEq, Eq, Clone, primitives::RuntimeDebug)] +#[derive(PartialEq, Eq, Clone, sp_core::RuntimeDebug)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub struct BlakeTwo256; impl Hash for BlakeTwo256 { - type Output = primitives::H256; + type Output = sp_core::H256; type Hasher = Blake2Hasher; fn hash(s: &[u8]) -> Self::Output { - runtime_io::hashing::blake2_256(s).into() + sp_io::hashing::blake2_256(s).into() } fn trie_root(input: Vec<(Vec, Vec)>) -> Self::Output { - runtime_io::storage::blake2_256_trie_root(input) + sp_io::trie::blake2_256_root(input) } fn ordered_trie_root(input: Vec>) -> Self::Output { - runtime_io::storage::blake2_256_ordered_trie_root(input) - } - - fn storage_root() -> Self::Output { - runtime_io::storage::root().into() - } - - fn storage_changes_root(parent_hash: Self::Output) -> Option { - runtime_io::storage::changes_root(parent_hash.into()).map(Into::into) + sp_io::trie::blake2_256_ordered_root(input) } } @@ -427,10 +417,10 @@ pub trait CheckEqual { fn check_equal(&self, other: &Self); } -impl CheckEqual for primitives::H256 { +impl CheckEqual for sp_core::H256 { #[cfg(feature = "std")] fn check_equal(&self, other: &Self) { - use primitives::hexdisplay::HexDisplay; + use sp_core::hexdisplay::HexDisplay; if self != other { println!( "Hash: given={}, expected={}", @@ -491,7 +481,7 @@ impl_maybe_marker!( MaybeDisplay: Display; /// A type that implements Hash when in std environment. - MaybeHash: rstd::hash::Hash; + MaybeHash: sp_std::hash::Hash; /// A type that implements Serialize when in std environment. MaybeSerialize: Serialize; @@ -508,9 +498,9 @@ pub trait RandomnessBeacon { /// # Security /// /// This MUST NOT be used for gambling, as it can be influenced by a - /// malicious validator in the short term. It MAY be used in many + /// malicious validator in the short term. It MAY be used in many /// cryptographic protocols, however, so long as one remembers that this - /// (like everything else on-chain) is public. For example, it can be + /// (like everything else on-chain) is public. For example, it can be /// used where a number is needed that cannot have been chosen by an /// adversary, for purposes such as public-coin zero-knowledge proofs. fn random() -> [u8; 32]; @@ -533,10 +523,10 @@ pub trait IsMember { /// You can also create a `new` one from those fields. pub trait Header: Clone + Send + Sync + Codec + Eq + MaybeSerialize + Debug + 'static { /// Header number. - type Number: Member + MaybeSerializeDeserialize + Debug + rstd::hash::Hash - + Copy + MaybeDisplay + SimpleArithmetic + Codec; + type Number: Member + MaybeSerializeDeserialize + Debug + sp_std::hash::Hash + + Copy + MaybeDisplay + SimpleArithmetic + Codec + sp_std::str::FromStr; /// Header hash type - type Hash: Member + MaybeSerializeDeserialize + Debug + rstd::hash::Hash + type Hash: Member + MaybeSerializeDeserialize + Debug + sp_std::hash::Hash + Copy + MaybeDisplay + Default + SimpleBitOps + Codec + AsRef<[u8]> + AsMut<[u8]>; /// Hashing algorithm type Hashing: Hash; @@ -581,17 +571,17 @@ pub trait Header: Clone + Send + Sync + Codec + Eq + MaybeSerialize + Debug + 's } } -/// Something which fulfills the abstract idea of a Substrate block. It has types for an -/// `Extrinsic` piece of information as well as a `Header`. +/// Something which fulfills the abstract idea of a Substrate block. It has types for +/// `Extrinsic` pieces of information as well as a `Header`. /// /// You can get an iterator over each of the `extrinsics` and retrieve the `header`. pub trait Block: Clone + Send + Sync + Codec + Eq + MaybeSerialize + Debug + 'static { - /// Type of extrinsics. + /// Type for extrinsics. type Extrinsic: Member + Codec + Extrinsic + MaybeSerialize; /// Header type. type Header: Header; /// Block hash type. - type Hash: Member + MaybeSerializeDeserialize + Debug + rstd::hash::Hash + type Hash: Member + MaybeSerializeDeserialize + Debug + sp_std::hash::Hash + Copy + MaybeDisplay + Default + SimpleBitOps + Codec + AsRef<[u8]> + AsMut<[u8]>; /// Returns a reference to the header. @@ -606,7 +596,8 @@ pub trait Block: Clone + Send + Sync + Codec + Eq + MaybeSerialize + Debug + 'st fn hash(&self) -> Self::Hash { <::Hashing as Hash>::hash_of(self.header()) } - /// Create an encoded block from the given `header` and `extrinsics` without requiring to create an instance. + /// Creates an encoded block from the given `header` and `extrinsics` without requiring the + /// creation of an instance. fn encode_from(header: &Self::Header, extrinsics: &[Self::Extrinsic]) -> Vec; } @@ -677,10 +668,6 @@ impl Checkable for T { } } -/// Result of a module function call; either nothing (functions are only called for "side effects") -/// or an error message. -pub type DispatchResult = result::Result<(), Error>; - /// A lazy call (module function and argument values) that can be executed via its `dispatch` /// method. pub trait Dispatchable { @@ -690,10 +677,8 @@ pub trait Dispatchable { type Origin; /// ... type Trait; - /// The error type returned by this dispatchable. - type Error: Into; /// Actually dispatch this call and result the result of it. - fn dispatch(self, origin: Self::Origin) -> DispatchResult; + fn dispatch(self, origin: Self::Origin) -> crate::DispatchResult; } /// Means by which a transaction may be extended. This type embodies both the data and the logic @@ -713,7 +698,7 @@ pub trait SignedExtension: Codec + Debug + Sync + Send + Clone + Eq + PartialEq type Pre: Default; /// An opaque set of information attached to the transaction. This could be constructed anywhere - /// down the line in a runtime. The current substrate runtime uses a struct with the same name + /// down the line in a runtime. The current Substrate runtime uses a struct with the same name /// to represent the dispatch class and weight. type DispatchInfo: Clone; @@ -726,7 +711,7 @@ pub trait SignedExtension: Codec + Debug + Sync + Send + Clone + Eq + PartialEq /// This function can be called frequently by the transaction queue, /// to obtain transaction validity against current state. /// It should perform all checks that determine a valid transaction, - /// that can pay for it's execution and quickly eliminate ones + /// that can pay for its execution and quickly eliminate ones /// that are stale or incorrect. /// /// Make sure to perform the same checks in `pre_dispatch` function. @@ -762,7 +747,7 @@ pub trait SignedExtension: Codec + Debug + Sync + Send + Clone + Eq + PartialEq /// Validate an unsigned transaction for the transaction queue. /// - /// This function can be called frequently by the transaction queue, + /// This function can be called frequently by the transaction queue /// to obtain transaction validity against current state. /// It should perform all checks that determine a valid unsigned transaction, /// and quickly eliminate ones that are stale or incorrect. @@ -798,17 +783,6 @@ pub trait SignedExtension: Codec + Debug + Sync + Send + Clone + Eq + PartialEq fn post_dispatch(_pre: Self::Pre, _info: Self::DispatchInfo, _len: usize) { } } -/// An error that is returned by a dispatchable function of a module. -pub trait ModuleDispatchError { - /// Convert this error to an `u8`. - /// - /// The `u8` corresponds to the index of the variant in the error enum. - fn as_u8(&self) -> u8; - - /// Convert the error to a `&'static str`. - fn as_str(&self) -> &'static str; -} - #[impl_for_tuples(1, 12)] impl SignedExtension for Tuple { for_tuples!( where #( Tuple: SignedExtension )* ); @@ -875,7 +849,7 @@ impl SignedExtension for () { type Call = (); type Pre = (); type DispatchInfo = (); - fn additional_signed(&self) -> rstd::result::Result<(), TransactionValidityError> { Ok(()) } + fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { Ok(()) } } /// An "executable" piece of information, used by the standard Substrate Executive in order to @@ -885,10 +859,10 @@ impl SignedExtension for () { /// Also provides information on to whom this information is attributable and an index that allows /// each piece of attributable information to be disambiguated. pub trait Applyable: Sized + Send + Sync { - /// Id of the account that is responsible for this piece of information (sender). + /// ID of the account that is responsible for this piece of information (sender). type AccountId: Member + MaybeDisplay; - /// Type by which we can dispatch. Restricts the UnsignedValidator type. + /// Type by which we can dispatch. Restricts the `UnsignedValidator` type. type Call; /// An opaque set of information attached to the transaction. @@ -916,7 +890,7 @@ pub trait Applyable: Sized + Send + Sync { } /// Auxiliary wrapper that holds an api instance and binds it to the given lifetime. -pub struct ApiRef<'a, T>(T, rstd::marker::PhantomData<&'a ()>); +pub struct ApiRef<'a, T>(T, sp_std::marker::PhantomData<&'a ()>); impl<'a, T> From for ApiRef<'a, T> { fn from(api: T) -> Self { @@ -924,7 +898,7 @@ impl<'a, T> From for ApiRef<'a, T> { } } -impl<'a, T> rstd::ops::Deref for ApiRef<'a, T> { +impl<'a, T> sp_std::ops::Deref for ApiRef<'a, T> { type Target = T; fn deref(&self) -> &Self::Target { @@ -932,7 +906,7 @@ impl<'a, T> rstd::ops::Deref for ApiRef<'a, T> { } } -impl<'a, T> rstd::ops::DerefMut for ApiRef<'a, T> { +impl<'a, T> sp_std::ops::DerefMut for ApiRef<'a, T> { fn deref_mut(&mut self) -> &mut T { &mut self.0 } @@ -1026,7 +1000,14 @@ pub trait OpaqueKeys: Clone { } /// Input that adds infinite number of zero after wrapped input. -struct TrailingZeroInput<'a>(&'a [u8]); +pub struct TrailingZeroInput<'a>(&'a [u8]); + +impl<'a> TrailingZeroInput<'a> { + /// Create a new instance from the given byte array. + pub fn new(data: &'a [u8]) -> Self { + Self(data) + } +} impl<'a> codec::Input for TrailingZeroInput<'a> { fn remaining_len(&mut self) -> Result, codec::Error> { @@ -1119,7 +1100,7 @@ macro_rules! count { /// `KeyTypeIdProviders` is set to the types given as fields. /// /// ```rust -/// use sr_primitives::{ +/// use sp_runtime::{ /// impl_opaque_keys, KeyTypeId, BoundToRuntimeAppPublic, app_crypto::{sr25519, ed25519} /// }; /// @@ -1164,7 +1145,7 @@ macro_rules! impl_opaque_keys { /// The generated key pairs are stored in the keystore. /// /// Returns the concatenated SCALE encoded public keys. - pub fn generate(seed: Option<$crate::rstd::vec::Vec>) -> $crate::rstd::vec::Vec { + pub fn generate(seed: Option<$crate::sp_std::vec::Vec>) -> $crate::sp_std::vec::Vec { let keys = Self{ $( $field: < @@ -1236,19 +1217,19 @@ impl Printable for usize { impl Printable for u64 { fn print(&self) { - runtime_io::misc::print_num(*self); + sp_io::misc::print_num(*self); } } impl Printable for &[u8] { fn print(&self) { - runtime_io::misc::print_hex(self); + sp_io::misc::print_hex(self); } } impl Printable for &str { fn print(&self) { - runtime_io::misc::print_utf8(self.as_bytes()); + sp_io::misc::print_utf8(self.as_bytes()); } } @@ -1284,8 +1265,8 @@ mod tests { use crate::codec::{Encode, Decode, Input}; mod t { - use primitives::crypto::KeyTypeId; - use app_crypto::{app_crypto, sr25519}; + use sp_core::crypto::KeyTypeId; + use sp_application_crypto::{app_crypto, sr25519}; app_crypto!(sr25519, KeyTypeId(*b"test")); } diff --git a/primitives/sr-primitives/src/transaction_validity.rs b/primitives/runtime/src/transaction_validity.rs similarity index 99% rename from primitives/sr-primitives/src/transaction_validity.rs rename to primitives/runtime/src/transaction_validity.rs index be9a1d0fd9f8ffebc8fdecd5f6dd860e0a1fcb76..b08455aab6d4254c9b43758672a063738311f047 100644 --- a/primitives/sr-primitives/src/transaction_validity.rs +++ b/primitives/runtime/src/transaction_validity.rs @@ -16,7 +16,7 @@ //! Transaction validity interface. -use rstd::prelude::*; +use sp_std::prelude::*; use crate::codec::{Encode, Decode}; use crate::RuntimeDebug; diff --git a/primitives/sr-sandbox/Cargo.toml b/primitives/sandbox/Cargo.toml similarity index 54% rename from primitives/sr-sandbox/Cargo.toml rename to primitives/sandbox/Cargo.toml index 97d391d794d652ef60e9c6ae2efb6c8f33023ba1..ff3b7662cd5a5dbd098ab7fedc5f59d471ef63da 100755 --- a/primitives/sr-sandbox/Cargo.toml +++ b/primitives/sandbox/Cargo.toml @@ -1,14 +1,14 @@ [package] -name = "sr-sandbox" +name = "sp-sandbox" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" [dependencies] wasmi = { version = "0.6.2", optional = true } -primitives = { package = "substrate-primitives", path = "../core", default-features = false } -rstd = { package = "sr-std", path = "../sr-std", default-features = false } -runtime-io = { package = "sr-io", path = "../sr-io", default-features = false } +sp-core = { version = "2.0.0", default-features = false, path = "../core" } +sp-std = { version = "2.0.0", default-features = false, path = "../std" } +sp-io = { version = "2.0.0", default-features = false, path = "../io" } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false } [dev-dependencies] @@ -19,9 +19,9 @@ assert_matches = "1.3.0" default = ["std"] std = [ "wasmi", - "primitives/std", - "rstd/std", + "sp-core/std", + "sp-std/std", "codec/std", - "runtime-io/std", + "sp-io/std", ] strict = [] diff --git a/primitives/sr-sandbox/src/lib.rs b/primitives/sandbox/src/lib.rs similarity index 98% rename from primitives/sr-sandbox/src/lib.rs rename to primitives/sandbox/src/lib.rs index 17b2cb7c1ebda8f4be270c63eee7c31a6a8a8212..448cadfe8046ba6592d2fa024d8e8ebba8e62950 100755 --- a/primitives/sr-sandbox/src/lib.rs +++ b/primitives/sandbox/src/lib.rs @@ -38,9 +38,9 @@ #![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), feature(core_intrinsics))] -use rstd::prelude::*; +use sp_std::prelude::*; -pub use primitives::sandbox::{TypedValue, ReturnValue, HostError}; +pub use sp_core::sandbox::{TypedValue, ReturnValue, HostError}; mod imp { #[cfg(feature = "std")] @@ -51,7 +51,7 @@ mod imp { } /// Error that can occur while using this crate. -#[derive(primitives::RuntimeDebug)] +#[derive(sp_core::RuntimeDebug)] pub enum Error { /// Module is not valid, couldn't be instantiated. Module, diff --git a/primitives/sr-sandbox/with_std.rs b/primitives/sandbox/with_std.rs similarity index 99% rename from primitives/sr-sandbox/with_std.rs rename to primitives/sandbox/with_std.rs index afc092686eeca4a498894b18983f3f19dfee751a..dacaa3a198df20432e3b89ca2f3da69988f2bd79 100755 --- a/primitives/sr-sandbox/with_std.rs +++ b/primitives/sandbox/with_std.rs @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use rstd::collections::btree_map::BTreeMap; -use rstd::fmt; +use sp_std::collections::btree_map::BTreeMap; +use sp_std::fmt; use wasmi::{ Externals, FuncInstance, FuncRef, GlobalDescriptor, GlobalRef, ImportResolver, diff --git a/primitives/sr-sandbox/without_std.rs b/primitives/sandbox/without_std.rs similarity index 98% rename from primitives/sr-sandbox/without_std.rs rename to primitives/sandbox/without_std.rs index d7fffbf88b27fb71621fa69f5985c4f6f1406c18..e76bbe72857a2e5a8ebf85175c7cd1878e4360de 100755 --- a/primitives/sr-sandbox/without_std.rs +++ b/primitives/sandbox/without_std.rs @@ -14,14 +14,14 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use rstd::{prelude::*, slice, marker, mem, vec, rc::Rc}; use codec::{Decode, Encode}; -use primitives::sandbox as sandbox_primitives; +use sp_core::sandbox as sandbox_primitives; +use sp_io::sandbox; +use sp_std::{prelude::*, slice, marker, mem, vec, rc::Rc}; use super::{Error, TypedValue, ReturnValue, HostFuncType}; -use runtime_io::sandbox; mod ffi { - use rstd::mem; + use sp_std::mem; use super::HostFuncType; /// Index into the default table that points to a `HostFuncType`. diff --git a/primitives/serializer/Cargo.toml b/primitives/serializer/Cargo.toml index 4e0e706e2fab232ff516ade2bfa22a2ed9ad598c..39fdeb0e7ee3c03329e59380f88bcba96386517b 100644 --- a/primitives/serializer/Cargo.toml +++ b/primitives/serializer/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "substrate-serializer" +name = "sp-serializer" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" diff --git a/primitives/session/Cargo.toml b/primitives/session/Cargo.toml index d1490905c200bfeecb3c3addeca9118142592a87..b7c72e0c681fec52e161a92048cbb8a2a966ae15 100644 --- a/primitives/session/Cargo.toml +++ b/primitives/session/Cargo.toml @@ -1,14 +1,14 @@ [package] -name = "substrate-session" +name = "sp-session" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" [dependencies] -sr-api = { path = "../sr-api", default-features = false } -rstd = { package = "sr-std", path = "../sr-std", default-features = false } -sr-primitives = { path = "../sr-primitives", optional = true } +sp-api = { version = "2.0.0", default-features = false, path = "../api" } +sp-std = { version = "2.0.0", default-features = false, path = "../std" } +sp-runtime = { version = "2.0.0", optional = true, path = "../runtime" } [features] default = [ "std" ] -std = [ "sr-api/std", "rstd/std", "sr-primitives" ] +std = [ "sp-api/std", "sp-std/std", "sp-runtime" ] diff --git a/primitives/session/src/lib.rs b/primitives/session/src/lib.rs index adc7629c368169ad813496d298188e4cedf7fcf6..f6be084a67942cc7fcbb37b327a950af2d7e62eb 100644 --- a/primitives/session/src/lib.rs +++ b/primitives/session/src/lib.rs @@ -18,12 +18,12 @@ #![cfg_attr(not(feature = "std"), no_std)] -use rstd::vec::Vec; +use sp_std::vec::Vec; #[cfg(feature = "std")] -use sr_primitives::{generic::BlockId, traits::{ProvideRuntimeApi, Block as BlockT}}; +use sp_runtime::{generic::BlockId, traits::{ProvideRuntimeApi, Block as BlockT}}; -sr_api::decl_runtime_apis! { +sp_api::decl_runtime_apis! { /// Session keys runtime api. pub trait SessionKeys { /// Generate a set of session keys with optionally using the given seed. @@ -44,7 +44,7 @@ pub fn generate_initial_session_keys( client: std::sync::Arc, at: &BlockId, seeds: Vec, -) -> Result<(), <::Api as sr_api::ApiExt>::Error> +) -> Result<(), <::Api as sp_api::ApiExt>::Error> where Block: BlockT, T: ProvideRuntimeApi, diff --git a/primitives/sr-api/Cargo.toml b/primitives/sr-api/Cargo.toml deleted file mode 100644 index a23a36284d8cb54356b33686559bd11e55f3c69a..0000000000000000000000000000000000000000 --- a/primitives/sr-api/Cargo.toml +++ /dev/null @@ -1,33 +0,0 @@ -[package] -name = "sr-api" -version = "2.0.0" -authors = ["Parity Technologies "] -edition = "2018" - -[dependencies] -codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false } -sr-api-proc-macro = { path = "proc-macro" } -primitives = { package = "substrate-primitives", path = "../core", default-features = false } -rstd = { package = "sr-std", path = "../sr-std", default-features = false } -sr-primitives = { path = "../sr-primitives", default-features = false } -sr-version = { path = "../sr-version", default-features = false } -state-machine = { package = "substrate-state-machine", path = "../../primitives/state-machine", optional = true } - -[dev-dependencies] -criterion = "0.3.0" -test-client = { package = "substrate-test-runtime-client", path = "../../test/utils/runtime/client" } - -[[bench]] -name = "bench" -harness = false - -[features] -default = [ "std" ] -std = [ - "codec/std", - "primitives/std", - "rstd/std", - "sr-primitives/std", - "state-machine", - "sr-version/std", -] diff --git a/primitives/sr-api/proc-macro/Cargo.toml b/primitives/sr-api/proc-macro/Cargo.toml deleted file mode 100644 index bd6418c458f0ae80f659740f92e17f401001eb61..0000000000000000000000000000000000000000 --- a/primitives/sr-api/proc-macro/Cargo.toml +++ /dev/null @@ -1,26 +0,0 @@ -[package] -name = "sr-api-proc-macro" -version = "2.0.0" -authors = ["Parity Technologies "] -edition = "2018" - -[lib] -proc-macro = true - -[dependencies] -quote = "1.0.2" -syn = { version = "1.0.8", features = [ "full", "fold", "extra-traits", "visit" ] } -proc-macro2 = "1.0.6" -blake2-rfc = "0.2.18" -proc-macro-crate = "0.1.4" - -[dev-dependencies] -sr-api = { path = ".." } -sr-primitives = { path = "../../sr-primitives" } -sr-version = { path = "../../sr-version" } -test-client = { package = "substrate-test-runtime-client", path = "../../../test/utils/runtime/client" } - -# Required for the doc tests -[features] -default = [ "std" ] -std = [] diff --git a/primitives/sr-api/proc-macro/src/lib.rs b/primitives/sr-api/proc-macro/src/lib.rs deleted file mode 100644 index 913e6e9d04bfb42e7473182fa04f92d19ee132c2..0000000000000000000000000000000000000000 --- a/primitives/sr-api/proc-macro/src/lib.rs +++ /dev/null @@ -1,189 +0,0 @@ -// Copyright 2018-2019 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate 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. - -// Substrate 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 Substrate. If not, see . - -//! Macros for declaring and implementing runtime apis. - -#![recursion_limit = "512"] -extern crate proc_macro; - -use proc_macro::TokenStream; - -mod impl_runtime_apis; -mod decl_runtime_apis; -mod utils; - -/// Tags given trait implementations as runtime apis. -/// -/// All traits given to this macro, need to be declared with the `decl_runtime_apis!` macro. -/// The implementation of the trait should follow the declaration given to the `decl_runtime_apis!` -/// macro, besides the `Block` type that is required as first generic parameter for each runtime -/// api trait. When implementing a runtime api trait, it is required that the trait is referenced -/// by a path, e.g. `impl my_trait::MyTrait for Runtime`. The macro will use this path to access -/// the declaration of the trait for the runtime side. -/// -/// The macro also generates the api implementations for the client side and provides it through -/// the `RuntimeApi` type. The `RuntimeApi` is hidden behind a `feature` called `std`. -/// -/// To expose version information about all implemented api traits, the constant -/// `RUNTIME_API_VERSIONS` is generated. This constant should be used to instantiate the `apis` -/// field of `RuntimeVersion`. -/// -/// # Example -/// -/// ```rust -/// use sr_version::create_runtime_str; -/// # -/// # use sr_primitives::traits::GetNodeBlockType; -/// # use test_client::runtime::{Block, Header}; -/// # -/// # /// The declaration of the `Runtime` type and the implementation of the `GetNodeBlockType` -/// # /// trait are done by the `construct_runtime!` macro in a real runtime. -/// # pub struct Runtime {} -/// # impl GetNodeBlockType for Runtime { -/// # type NodeBlock = Block; -/// # } -/// # -/// # sr_api::decl_runtime_apis! { -/// # /// Declare the api trait. -/// # pub trait Balance { -/// # /// Get the balance. -/// # fn get_balance() -> u64; -/// # /// Set the balance. -/// # fn set_balance(val: u64); -/// # } -/// # pub trait BlockBuilder { -/// # fn build_block() -> Block; -/// # } -/// # } -/// -/// /// All runtime api implementations need to be done in one call of the macro! -/// sr_api::impl_runtime_apis! { -/// # impl sr_api::Core for Runtime { -/// # fn version() -> sr_version::RuntimeVersion { -/// # unimplemented!() -/// # } -/// # fn execute_block(_block: Block) {} -/// # fn initialize_block(_header: &Header) {} -/// # } -/// -/// impl self::Balance for Runtime { -/// fn get_balance() -> u64 { -/// 1 -/// } -/// fn set_balance(_bal: u64) { -/// // Store the balance -/// } -/// } -/// -/// impl self::BlockBuilder for Runtime { -/// fn build_block() -> Block { -/// unimplemented!("Please implement me!") -/// } -/// } -/// } -/// -/// /// Runtime version. This needs to be declared for each runtime. -/// pub const VERSION: sr_version::RuntimeVersion = sr_version::RuntimeVersion { -/// spec_name: create_runtime_str!("node"), -/// impl_name: create_runtime_str!("test-node"), -/// authoring_version: 1, -/// spec_version: 1, -/// impl_version: 0, -/// // Here we are exposing the runtime api versions. -/// apis: RUNTIME_API_VERSIONS, -/// }; -/// -/// # fn main() {} -/// ``` -#[proc_macro] -pub fn impl_runtime_apis(input: TokenStream) -> TokenStream { - impl_runtime_apis::impl_runtime_apis_impl(input) -} - -/// Declares given traits as runtime apis. -/// -/// The macro will create two declarations, one for using on the client side and one for using -/// on the runtime side. The declaration for the runtime side is hidden in its own module. -/// The client side declaration gets two extra parameters per function, -/// `&self` and `at: &BlockId`. The runtime side declaration will match the given trait -/// declaration. Besides one exception, the macro adds an extra generic parameter `Block: BlockT` -/// to the client side and the runtime side. This generic parameter is usable by the user. -/// -/// For implementing these macros you should use the `impl_runtime_apis!` macro. -/// -/// # Example -/// -/// ```rust -/// sr_api::decl_runtime_apis! { -/// /// Declare the api trait. -/// pub trait Balance { -/// /// Get the balance. -/// fn get_balance() -> u64; -/// /// Set the balance. -/// fn set_balance(val: u64); -/// } -/// -/// /// You can declare multiple api traits in one macro call. -/// /// In one module you can call the macro at maximum one time. -/// pub trait BlockBuilder { -/// /// The macro adds an explicit `Block: BlockT` generic parameter for you. -/// /// You can use this generic parameter as you would defined it manually. -/// fn build_block() -> Block; -/// } -/// } -/// -/// # fn main() {} -/// ``` -/// -/// # Runtime api trait versioning -/// -/// To support versioning of the traits, the macro supports the attribute `#[api_version(1)]`. -/// The attribute supports any `u32` as version. By default, each trait is at version `1`, if no -/// version is provided. We also support changing the signature of a method. This signature -/// change is highlighted with the `#[changed_in(2)]` attribute above a method. A method that is -/// tagged with this attribute is callable by the name `METHOD_before_version_VERSION`. This -/// method will only support calling into wasm, trying to call into native will fail (change the -/// spec version!). Such a method also does not need to be implemented in the runtime. -/// -/// ```rust -/// sr_api::decl_runtime_apis! { -/// /// Declare the api trait. -/// #[api_version(2)] -/// pub trait Balance { -/// /// Get the balance. -/// fn get_balance() -> u64; -/// /// Set balance. -/// fn set_balance(val: u64); -/// /// Set balance, old version. -/// /// -/// /// Is callable by `set_balance_before_version_2`. -/// #[changed_in(2)] -/// fn set_balance(val: u16); -/// /// In version 2, we added this new function. -/// fn increase_balance(val: u64); -/// } -/// } -/// -/// # fn main() {} -/// ``` -/// -/// To check if a given runtime implements a runtime api trait, the `RuntimeVersion` has the -/// function `has_api()`. Also the `ApiExt` provides a function `has_api(at: &BlockId)` to -/// check if the runtime at the given block id implements the requested runtime api trait. -#[proc_macro] -pub fn decl_runtime_apis(input: TokenStream) -> TokenStream { - decl_runtime_apis::decl_runtime_apis_impl(input) -} diff --git a/primitives/sr-api/test/Cargo.toml b/primitives/sr-api/test/Cargo.toml deleted file mode 100644 index 7915266cca107963a813cdf714be786f8a753c94..0000000000000000000000000000000000000000 --- a/primitives/sr-api/test/Cargo.toml +++ /dev/null @@ -1,21 +0,0 @@ -[package] -name = "sr-api-test" -version = "2.0.0" -authors = ["Parity Technologies "] -edition = "2018" - -[dependencies] -sr-api = { path = "../" } -test-client = { package = "substrate-test-runtime-client", path = "../../../test/utils/runtime/client" } -sr-version = { path = "../../sr-version" } -sr-primitives = { path = "../../sr-primitives" } -consensus_common = { package = "substrate-consensus-common", path = "../../../primitives/consensus/common" } -codec = { package = "parity-scale-codec", version = "1.0.0" } -state-machine = { package = "substrate-state-machine", path = "../../../primitives/state-machine" } -trybuild = "1.0.17" -rustversion = "1.0.0" - -# We only need this to generate the correct code. -[features] -default = [ "std" ] -std = [] diff --git a/primitives/sr-api/test/tests/ui/declaring_old_block.rs b/primitives/sr-api/test/tests/ui/declaring_old_block.rs deleted file mode 100644 index 962aae4506642da8232b8e45e02bf4005cbc218d..0000000000000000000000000000000000000000 --- a/primitives/sr-api/test/tests/ui/declaring_old_block.rs +++ /dev/null @@ -1,9 +0,0 @@ -use sr_primitives::traits::Block as BlockT; - -sr_api::decl_runtime_apis! { - pub trait Api { - fn test(); - } -} - -fn main() {} diff --git a/primitives/sr-api/test/tests/ui/declaring_own_block_with_different_name.rs b/primitives/sr-api/test/tests/ui/declaring_own_block_with_different_name.rs deleted file mode 100644 index 9a471482564937a1ce24826cfec88a9fe7e7fa25..0000000000000000000000000000000000000000 --- a/primitives/sr-api/test/tests/ui/declaring_own_block_with_different_name.rs +++ /dev/null @@ -1,9 +0,0 @@ -use sr_primitives::traits::Block as BlockT; - -sr_api::decl_runtime_apis! { - pub trait Api { - fn test(); - } -} - -fn main() {} diff --git a/primitives/sr-primitives/Cargo.toml b/primitives/sr-primitives/Cargo.toml deleted file mode 100644 index bd709c68bd4d96baa8832cc1d10a0a39de0daf39..0000000000000000000000000000000000000000 --- a/primitives/sr-primitives/Cargo.toml +++ /dev/null @@ -1,39 +0,0 @@ -[package] -name = "sr-primitives" -version = "2.0.0" -authors = ["Parity Technologies "] -edition = "2018" - -[dependencies] -serde = { version = "1.0.101", optional = true, features = ["derive"] } -codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -primitives = { package = "substrate-primitives", path = "../core", default-features = false } -app-crypto = { package = "substrate-application-crypto", path = "../application-crypto", default-features = false } -arithmetic = { package = "sr-arithmetic", path = "../sr-arithmetic", default-features = false } -rstd = { package = "sr-std", path = "../sr-std", default-features = false } -runtime_io = { package = "sr-io", path = "../sr-io", default-features = false } -log = { version = "0.4.8", optional = true } -paste = "0.1.6" -rand = { version = "0.7.2", optional = true } -impl-trait-for-tuples = "0.1.3" -inherents = { package = "substrate-inherents", path = "../inherents", default-features = false } - -[dev-dependencies] -serde_json = "1.0.41" -rand = "0.7.2" - -[features] -bench = [] -default = ["std"] -std = [ - "app-crypto/std", - "arithmetic/std", - "codec/std", - "log", - "primitives/std", - "rand", - "rstd/std", - "runtime_io/std", - "serde", - "inherents/std", -] diff --git a/primitives/sr-primitives/src/offchain/mod.rs b/primitives/sr-primitives/src/offchain/mod.rs deleted file mode 100644 index 51dc19bc12d606a6ff14ab2ceaaefd5e27035298..0000000000000000000000000000000000000000 --- a/primitives/sr-primitives/src/offchain/mod.rs +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2019 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate 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. - -// Substrate 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 Substrate. If not, see . - -//! A collection of higher lever helpers for offchain calls. - -use crate::{ - traits, - generic::BlockId, -}; - -pub mod http; - -/// An abstraction for transaction pool. -/// -/// This trait is used by offchain calls to be able to submit transactions. -/// The main use case is for offchain workers, to feed back the results of computations, -/// but since the transaction pool access is a separate `ExternalitiesExtension` it can -/// be also used in context of other offchain calls. For one may generate and submit -/// a transaction for some misbehavior reports (say equivocation). -pub trait TransactionPool: Send + Sync { - /// Submit transaction. - /// - /// The transaction will end up in the pool and be propagated to others. - fn submit_at( - &self, - at: &BlockId, - extrinsic: Block::Extrinsic, - ) -> Result<(), ()>; -} diff --git a/primitives/sr-staking-primitives/Cargo.toml b/primitives/staking/Cargo.toml similarity index 56% rename from primitives/sr-staking-primitives/Cargo.toml rename to primitives/staking/Cargo.toml index 25e8f4ccf1529576e5d34111445d57b947f04f37..35725c72e334baeaca061819338873d3e11a1922 100644 --- a/primitives/sr-staking-primitives/Cargo.toml +++ b/primitives/staking/Cargo.toml @@ -1,18 +1,18 @@ [package] -name = "sr-staking-primitives" +name = "sp-staking" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" [dependencies] codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -sr-primitives = { path = "../sr-primitives", default-features = false } -rstd = { package = "sr-std", path = "../sr-std", default-features = false } +sp-runtime = { version = "2.0.0", default-features = false, path = "../runtime" } +sp-std = { version = "2.0.0", default-features = false, path = "../std" } [features] default = ["std"] std = [ "codec/std", - "sr-primitives/std", - "rstd/std", + "sp-runtime/std", + "sp-std/std", ] diff --git a/primitives/sr-staking-primitives/src/lib.rs b/primitives/staking/src/lib.rs similarity index 100% rename from primitives/sr-staking-primitives/src/lib.rs rename to primitives/staking/src/lib.rs diff --git a/primitives/sr-staking-primitives/src/offence.rs b/primitives/staking/src/offence.rs similarity index 95% rename from primitives/sr-staking-primitives/src/offence.rs rename to primitives/staking/src/offence.rs index db51f75df1bf3c973c8989446404b0fb8178182e..33170193ec53fc0f38513c2c60db2aca735f2c4f 100644 --- a/primitives/sr-staking-primitives/src/offence.rs +++ b/primitives/staking/src/offence.rs @@ -17,10 +17,10 @@ //! Common traits and types that are useful for describing offences for usage in environments //! that use staking. -use rstd::vec::Vec; +use sp_std::vec::Vec; use codec::{Encode, Decode}; -use sr_primitives::Perbill; +use sp_runtime::Perbill; use crate::SessionIndex; @@ -117,9 +117,12 @@ pub trait OnOffenceHandler { /// the authorities should be slashed and is computed /// according to the `OffenceCount` already. This is of the same length as `offenders.` /// Zero is a valid value for a fraction. + /// + /// The `session` parameter is the session index of the offence. fn on_offence( offenders: &[OffenceDetails], slash_fraction: &[Perbill], + session: SessionIndex, ); } @@ -127,11 +130,12 @@ impl OnOffenceHandler for () { fn on_offence( _offenders: &[OffenceDetails], _slash_fraction: &[Perbill], + _session: SessionIndex, ) {} } /// A details about an offending authority for a particular kind of offence. -#[derive(Clone, PartialEq, Eq, Encode, Decode, sr_primitives::RuntimeDebug)] +#[derive(Clone, PartialEq, Eq, Encode, Decode, sp_runtime::RuntimeDebug)] pub struct OffenceDetails { /// The offending authority id pub offender: Offender, diff --git a/primitives/state-machine/Cargo.toml b/primitives/state-machine/Cargo.toml index 36557803e10e893f202d4cbdc3ddcedb9e3ea1c4..777830d5eab3cad562d2347c06daf7045a383add 100644 --- a/primitives/state-machine/Cargo.toml +++ b/primitives/state-machine/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "substrate-state-machine" +name = "sp-state-machine" version = "2.0.0" authors = ["Parity Technologies "] description = "Substrate State Machine" @@ -11,13 +11,13 @@ parking_lot = "0.9.0" hash-db = "0.15.2" trie-db = "0.16.0" trie-root = "0.15.2" -trie = { package = "substrate-trie", path = "../trie" } -primitives = { package = "substrate-primitives", path = "../core" } -panic-handler = { package = "substrate-panic-handler", path = "../panic-handler" } +sp-trie = { version = "2.0.0", path = "../trie" } +sp-core = { version = "2.0.0", path = "../core" } +sp-panic-handler = { version = "2.0.0", path = "../panic-handler" } codec = { package = "parity-scale-codec", version = "1.0.0" } num-traits = "0.2.8" rand = "0.7.2" -externalities = { package = "substrate-externalities", path = "../externalities" } +sp-externalities = { version = "2.0.0", path = "../externalities" } [dev-dependencies] hex-literal = "0.2.1" diff --git a/primitives/state-machine/src/backend.rs b/primitives/state-machine/src/backend.rs index 5fbda1aa32f4543662737209633d6135890cc244..7a5357c398eb87a10fe8bdb7ad1ea846568a20db 100644 --- a/primitives/state-machine/src/backend.rs +++ b/primitives/state-machine/src/backend.rs @@ -16,15 +16,17 @@ //! State machine backends. These manage the code and storage of contracts. -use std::{error, fmt, cmp::Ord, collections::HashMap, marker::PhantomData}; +use std::{error, fmt, cmp::Ord, collections::{HashMap, BTreeMap}, marker::PhantomData, ops}; use log::warn; use hash_db::Hasher; use crate::trie_backend::TrieBackend; use crate::trie_backend_essence::TrieBackendStorage; -use trie::{ +use sp_trie::{ TrieMut, MemoryDB, child_trie_root, default_child_trie_root, TrieConfiguration, trie_types::{TrieDBMut, Layout}, }; +use codec::{Encode, Codec}; +use sp_core::storage::{ChildInfo, OwnedChildInfo, Storage}; /// A state backend is used to read state data and can have changes committed /// to it. @@ -49,11 +51,21 @@ pub trait Backend: std::fmt::Debug { } /// Get keyed child storage or None if there is nothing associated. - fn child_storage(&self, storage_key: &[u8], key: &[u8]) -> Result>, Self::Error>; + fn child_storage( + &self, + storage_key: &[u8], + child_info: ChildInfo, + key: &[u8], + ) -> Result>, Self::Error>; /// Get child keyed storage value hash or None if there is nothing associated. - fn child_storage_hash(&self, storage_key: &[u8], key: &[u8]) -> Result, Self::Error> { - self.child_storage(storage_key, key).map(|v| v.map(|v| H::hash(&v))) + fn child_storage_hash( + &self, + storage_key: &[u8], + child_info: ChildInfo, + key: &[u8], + ) -> Result, Self::Error> { + self.child_storage(storage_key, child_info, key).map(|v| v.map(|v| H::hash(&v))) } /// true if a key exists in storage. @@ -62,12 +74,33 @@ pub trait Backend: std::fmt::Debug { } /// true if a key exists in child storage. - fn exists_child_storage(&self, storage_key: &[u8], key: &[u8]) -> Result { - Ok(self.child_storage(storage_key, key)?.is_some()) + fn exists_child_storage( + &self, + storage_key: &[u8], + child_info: ChildInfo, + key: &[u8], + ) -> Result { + Ok(self.child_storage(storage_key, child_info, key)?.is_some()) } + /// Return the next key in storage in lexicographic order or `None` if there is no value. + fn next_storage_key(&self, key: &[u8]) -> Result>, Self::Error>; + + /// Return the next key in child storage in lexicographic order or `None` if there is no value. + fn next_child_storage_key( + &self, + storage_key: &[u8], + child_info: ChildInfo, + key: &[u8] + ) -> Result>, Self::Error>; + /// Retrieve all entries keys of child storage and call `f` for each of those keys. - fn for_keys_in_child_storage(&self, storage_key: &[u8], f: F); + fn for_keys_in_child_storage( + &self, + storage_key: &[u8], + child_info: ChildInfo, + f: F, + ); /// Retrieve all entries keys which start with the given prefix and /// call `f` for each of those keys. @@ -82,7 +115,13 @@ pub trait Backend: std::fmt::Debug { /// Retrieve all child entries keys which start with the given prefix and /// call `f` for each of those keys. - fn for_child_keys_with_prefix(&self, storage_key: &[u8], prefix: &[u8], f: F); + fn for_child_keys_with_prefix( + &self, + storage_key: &[u8], + child_info: ChildInfo, + prefix: &[u8], + f: F, + ); /// Calculate the storage root, with given delta over what is already stored in /// the backend, and produce a "transaction" that can be used to commit. @@ -95,7 +134,12 @@ pub trait Backend: std::fmt::Debug { /// Calculate the child storage root, with given delta over what is already stored in /// the backend, and produce a "transaction" that can be used to commit. The second argument /// is true if child storage root equals default storage root. - fn child_storage_root(&self, storage_key: &[u8], delta: I) -> (Vec, bool, Self::Transaction) + fn child_storage_root( + &self, + storage_key: &[u8], + child_info: ChildInfo, + delta: I, + ) -> (H::Out, bool, Self::Transaction) where I: IntoIterator, Option>)>, H::Out: Ord; @@ -111,9 +155,14 @@ pub trait Backend: std::fmt::Debug { } /// Get all keys of child storage with given prefix - fn child_keys(&self, child_storage_key: &[u8], prefix: &[u8]) -> Vec> { + fn child_keys( + &self, + storage_key: &[u8], + child_info: ChildInfo, + prefix: &[u8], + ) -> Vec> { let mut all = Vec::new(); - self.for_child_keys_with_prefix(child_storage_key, prefix, |k| all.push(k.to_vec())); + self.for_child_keys_with_prefix(storage_key, child_info, prefix, |k| all.push(k.to_vec())); all } @@ -133,20 +182,20 @@ pub trait Backend: std::fmt::Debug { where I1: IntoIterator, Option>)>, I2i: IntoIterator, Option>)>, - I2: IntoIterator, I2i)>, - ::Out: Ord, + I2: IntoIterator, I2i, OwnedChildInfo)>, + H::Out: Ord + Encode, { let mut txs: Self::Transaction = Default::default(); let mut child_roots: Vec<_> = Default::default(); // child first - for (storage_key, child_delta) in child_deltas { + for (storage_key, child_delta, child_info) in child_deltas { let (child_root, empty, child_txs) = - self.child_storage_root(&storage_key[..], child_delta); + self.child_storage_root(&storage_key[..], child_info.as_ref(), child_delta); txs.consolidate(child_txs); if empty { child_roots.push((storage_key, None)); } else { - child_roots.push((storage_key, Some(child_root))); + child_roots.push((storage_key, Some(child_root.encode()))); } } let (root, parent_txs) = self.storage_root( @@ -166,20 +215,49 @@ impl<'a, T: Backend, H: Hasher> Backend for &'a T { (*self).storage(key) } - fn child_storage(&self, storage_key: &[u8], key: &[u8]) -> Result>, Self::Error> { - (*self).child_storage(storage_key, key) + fn child_storage( + &self, + storage_key: &[u8], + child_info: ChildInfo, + key: &[u8], + ) -> Result>, Self::Error> { + (*self).child_storage(storage_key, child_info, key) } - fn for_keys_in_child_storage(&self, storage_key: &[u8], f: F) { - (*self).for_keys_in_child_storage(storage_key, f) + fn for_keys_in_child_storage( + &self, + storage_key: &[u8], + child_info: ChildInfo, + f: F, + ) { + (*self).for_keys_in_child_storage(storage_key, child_info, f) + } + + fn next_storage_key(&self, key: &[u8]) -> Result>, Self::Error> { + (*self).next_storage_key(key) + } + + fn next_child_storage_key( + &self, + storage_key: &[u8], + child_info: ChildInfo, + key: &[u8], + ) -> Result>, Self::Error> { + (*self).next_child_storage_key(storage_key, child_info, key) } fn for_keys_with_prefix(&self, prefix: &[u8], f: F) { (*self).for_keys_with_prefix(prefix, f) } - fn for_child_keys_with_prefix(&self, storage_key: &[u8], prefix: &[u8], f: F) { - (*self).for_child_keys_with_prefix(storage_key, prefix, f) + fn for_child_keys_with_prefix( + &self, + storage_key: &[u8], + child_info: ChildInfo, + prefix: &[u8], + f: F, + ) { + (*self).for_child_keys_with_prefix(storage_key, child_info, prefix, f) } fn storage_root(&self, delta: I) -> (H::Out, Self::Transaction) @@ -190,12 +268,17 @@ impl<'a, T: Backend, H: Hasher> Backend for &'a T { (*self).storage_root(delta) } - fn child_storage_root(&self, storage_key: &[u8], delta: I) -> (Vec, bool, Self::Transaction) + fn child_storage_root( + &self, + storage_key: &[u8], + child_info: ChildInfo, + delta: I, + ) -> (H::Out, bool, Self::Transaction) where I: IntoIterator, Option>)>, H::Out: Ord, { - (*self).child_storage_root(storage_key, delta) + (*self).child_storage_root(storage_key, child_info, delta) } fn pairs(&self) -> Vec<(Vec, Vec)> { @@ -219,15 +302,18 @@ impl Consolidate for () { } } -impl Consolidate for Vec<(Option>, Vec, Option>)> { +impl Consolidate for Vec<( + Option<(Vec, OwnedChildInfo)>, + Vec<(Vec, Option>)>, + )> { fn consolidate(&mut self, mut other: Self) { self.append(&mut other); } } -impl> Consolidate for trie::GenericMemoryDB { +impl> Consolidate for sp_trie::GenericMemoryDB { fn consolidate(&mut self, other: Self) { - trie::GenericMemoryDB::consolidate(self, other) + sp_trie::GenericMemoryDB::consolidate(self, other) } } @@ -249,7 +335,7 @@ impl error::Error for Void { /// In-memory backend. Fully recomputes tries each time `as_trie_backend` is called but useful for /// tests and proof checking. pub struct InMemory { - inner: HashMap>, HashMap, Vec>>, + inner: HashMap, OwnedChildInfo)>, BTreeMap, Vec>>, // This field is only needed for returning reference in `as_trie_backend`. trie: Option, H>>, _hasher: PhantomData, @@ -287,23 +373,25 @@ impl PartialEq for InMemory { } } -impl InMemory { +impl InMemory where H::Out: Codec { /// Copy the state, with applied updates pub fn update(&self, changes: >::Transaction) -> Self { - let mut inner: HashMap<_, _> = self.inner.clone(); - for (storage_key, key, val) in changes { - match val { - Some(v) => { inner.entry(storage_key).or_default().insert(key, v); }, - None => { inner.entry(storage_key).or_default().remove(&key); }, + let mut inner = self.inner.clone(); + for (child_info, key_values) in changes { + let entry = inner.entry(child_info).or_default(); + for (key, val) in key_values { + match val { + Some(v) => { entry.insert(key, v); }, + None => { entry.remove(&key); }, + } } } - inner.into() } } -impl From>, HashMap, Vec>>> for InMemory { - fn from(inner: HashMap>, HashMap, Vec>>) -> Self { +impl From, OwnedChildInfo)>, BTreeMap, Vec>>> for InMemory { + fn from(inner: HashMap, OwnedChildInfo)>, BTreeMap, Vec>>) -> Self { InMemory { inner: inner, trie: None, @@ -312,17 +400,11 @@ impl From>, HashMap, Vec>>> for In } } -impl From<( - HashMap, Vec>, - HashMap, HashMap, Vec>>, -)> for InMemory { - fn from(inners: ( - HashMap, Vec>, - HashMap, HashMap, Vec>>, - )) -> Self { - let mut inner: HashMap>, HashMap, Vec>> - = inners.1.into_iter().map(|(k, v)| (Some(k), v)).collect(); - inner.insert(None, inners.0); +impl From for InMemory { + fn from(inners: Storage) -> Self { + let mut inner: HashMap, OwnedChildInfo)>, BTreeMap, Vec>> + = inners.children.into_iter().map(|(k, c)| (Some((k, c.child_info)), c.data)).collect(); + inner.insert(None, inners.top); InMemory { inner: inner, trie: None, @@ -331,8 +413,8 @@ impl From<( } } -impl From, Vec>> for InMemory { - fn from(inner: HashMap, Vec>) -> Self { +impl From, Vec>> for InMemory { + fn from(inner: BTreeMap, Vec>) -> Self { let mut expanded = HashMap::new(); expanded.insert(None, inner); InMemory { @@ -343,12 +425,19 @@ impl From, Vec>> for InMemory { } } -impl From>, Vec, Option>)>> for InMemory { - fn from(inner: Vec<(Option>, Vec, Option>)>) -> Self { - let mut expanded: HashMap>, HashMap, Vec>> = HashMap::new(); - for (child_key, key, value) in inner { - if let Some(value) = value { - expanded.entry(child_key).or_default().insert(key, value); +impl From, OwnedChildInfo)>, Vec<(Vec, Option>)>)>> + for InMemory { + fn from( + inner: Vec<(Option<(Vec, OwnedChildInfo)>, Vec<(Vec, Option>)>)>, + ) -> Self { + let mut expanded: HashMap, OwnedChildInfo)>, BTreeMap, Vec>> + = HashMap::new(); + for (child_info, key_values) in inner { + let entry = expanded.entry(child_info).or_default(); + for (key, value) in key_values { + if let Some(value) = value { + entry.insert(key, value); + } } } expanded.into() @@ -357,28 +446,60 @@ impl From>, Vec, Option>)>> for InMem impl InMemory { /// child storage key iterator - pub fn child_storage_keys(&self) -> impl Iterator { - self.inner.iter().filter_map(|item| item.0.as_ref().map(|v|&v[..])) + pub fn child_storage_keys(&self) -> impl Iterator { + self.inner.iter().filter_map(|item| + item.0.as_ref().map(|v|(&v.0[..], v.1.as_ref())) + ) } } -impl Backend for InMemory { +impl Backend for InMemory where H::Out: Codec { type Error = Void; - type Transaction = Vec<(Option>, Vec, Option>)>; + type Transaction = Vec<( + Option<(Vec, OwnedChildInfo)>, + Vec<(Vec, Option>)>, + )>; type TrieBackendStorage = MemoryDB; fn storage(&self, key: &[u8]) -> Result>, Self::Error> { Ok(self.inner.get(&None).and_then(|map| map.get(key).map(Clone::clone))) } - fn child_storage(&self, storage_key: &[u8], key: &[u8]) -> Result>, Self::Error> { - Ok(self.inner.get(&Some(storage_key.to_vec())).and_then(|map| map.get(key).map(Clone::clone))) + fn child_storage( + &self, + storage_key: &[u8], + child_info: ChildInfo, + key: &[u8], + ) -> Result>, Self::Error> { + Ok(self.inner.get(&Some((storage_key.to_vec(), child_info.to_owned()))) + .and_then(|map| map.get(key).map(Clone::clone))) } fn exists_storage(&self, key: &[u8]) -> Result { Ok(self.inner.get(&None).map(|map| map.get(key).is_some()).unwrap_or(false)) } + fn next_storage_key(&self, key: &[u8]) -> Result>, Self::Error> { + let range = (ops::Bound::Excluded(key), ops::Bound::Unbounded); + let next_key = self.inner.get(&None) + .and_then(|map| map.range::<[u8], _>(range).next().map(|(k, _)| k).cloned()); + + Ok(next_key) + } + + fn next_child_storage_key( + &self, + storage_key: &[u8], + child_info: ChildInfo, + key: &[u8], + ) -> Result>, Self::Error> { + let range = (ops::Bound::Excluded(key), ops::Bound::Unbounded); + let next_key = self.inner.get(&Some((storage_key.to_vec(), child_info.to_owned()))) + .and_then(|map| map.range::<[u8], _>(range).next().map(|(k, _)| k).cloned()); + + Ok(next_key) + } + fn for_keys_with_prefix(&self, prefix: &[u8], f: F) { self.inner.get(&None).map(|map| map.keys().filter(|key| key.starts_with(prefix)).map(|k| &**k).for_each(f)); } @@ -388,12 +509,24 @@ impl Backend for InMemory { .for_each(|(k, v)| f(k, v))); } - fn for_keys_in_child_storage(&self, storage_key: &[u8], mut f: F) { - self.inner.get(&Some(storage_key.to_vec())).map(|map| map.keys().for_each(|k| f(&k))); + fn for_keys_in_child_storage( + &self, + storage_key: &[u8], + child_info: ChildInfo, + mut f: F, + ) { + self.inner.get(&Some((storage_key.to_vec(), child_info.to_owned()))) + .map(|map| map.keys().for_each(|k| f(&k))); } - fn for_child_keys_with_prefix(&self, storage_key: &[u8], prefix: &[u8], f: F) { - self.inner.get(&Some(storage_key.to_vec())) + fn for_child_keys_with_prefix( + &self, + storage_key: &[u8], + child_info: ChildInfo, + prefix: &[u8], + f: F, + ) { + self.inner.get(&Some((storage_key.to_vec(), child_info.to_owned()))) .map(|map| map.keys().filter(|key| key.starts_with(prefix)).map(|k| &**k).for_each(f)); } @@ -413,19 +546,26 @@ impl Backend for InMemory { .filter_map(|(k, maybe_val)| maybe_val.map(|val| (k, val))) ); - let full_transaction = transaction.into_iter().map(|(k, v)| (None, k, v)).collect(); + let full_transaction = transaction.into_iter().collect(); - (root, full_transaction) + (root, vec![(None, full_transaction)]) } - fn child_storage_root(&self, storage_key: &[u8], delta: I) -> (Vec, bool, Self::Transaction) + fn child_storage_root( + &self, + storage_key: &[u8], + child_info: ChildInfo, + delta: I, + ) -> (H::Out, bool, Self::Transaction) where I: IntoIterator, Option>)>, H::Out: Ord { let storage_key = storage_key.to_vec(); + let child_info = Some((storage_key.clone(), child_info.to_owned())); - let existing_pairs = self.inner.get(&Some(storage_key.clone())) + + let existing_pairs = self.inner.get(&child_info) .into_iter() .flat_map(|map| map.iter().map(|(k, v)| (k.clone(), Some(v.clone())))); @@ -438,11 +578,11 @@ impl Backend for InMemory { .filter_map(|(k, maybe_val)| maybe_val.map(|val| (k, val))) ); - let full_transaction = transaction.into_iter().map(|(k, v)| (Some(storage_key.clone()), k, v)).collect(); + let full_transaction = transaction.into_iter().collect(); let is_default = root == default_child_trie_root::>(&storage_key); - (root, is_default, full_transaction) + (root, is_default, vec![(child_info, full_transaction)]) } fn pairs(&self) -> Vec<(Vec, Vec)> { @@ -459,8 +599,13 @@ impl Backend for InMemory { .collect() } - fn child_keys(&self, storage_key: &[u8], prefix: &[u8]) -> Vec> { - self.inner.get(&Some(storage_key.to_vec())) + fn child_keys( + &self, + storage_key: &[u8], + child_info: ChildInfo, + prefix: &[u8], + ) -> Vec> { + self.inner.get(&Some((storage_key.to_vec(), child_info.to_owned()))) .into_iter() .flat_map(|map| map.keys().filter(|k| k.starts_with(prefix)).cloned()) .collect() @@ -470,8 +615,10 @@ impl Backend for InMemory { let mut mdb = MemoryDB::default(); let mut new_child_roots = Vec::new(); let mut root_map = None; - for (storage_key, map) in &self.inner { - if let Some(storage_key) = storage_key.as_ref() { + for (child_info, map) in &self.inner { + if let Some((storage_key, _child_info)) = child_info.as_ref() { + // no need to use child_info at this point because we use a MemoryDB for + // proof (with PrefixedMemoryDB it would be needed). let ch = insert_into_memory_db::(&mut mdb, map.clone().into_iter())?; new_child_roots.push((storage_key.clone(), ch.as_ref().into())); } else { @@ -520,12 +667,17 @@ mod tests { /// Assert in memory backend with only child trie keys works as trie backend. #[test] fn in_memory_with_child_trie_only() { - let storage = InMemory::::default(); + let storage = InMemory::::default(); + let child_info = OwnedChildInfo::new_default(b"unique_id_1".to_vec()); let mut storage = storage.update( - vec![(Some(b"1".to_vec()), b"2".to_vec(), Some(b"3".to_vec()))] + vec![( + Some((b"1".to_vec(), child_info.clone())), + vec![(b"2".to_vec(), Some(b"3".to_vec()))] + )] ); let trie_backend = storage.as_trie_backend().unwrap(); - assert_eq!(trie_backend.child_storage(b"1", b"2").unwrap(), Some(b"3".to_vec())); + assert_eq!(trie_backend.child_storage(b"1", child_info.as_ref(), b"2").unwrap(), + Some(b"3".to_vec())); assert!(trie_backend.storage(b"1").unwrap().is_some()); } } diff --git a/primitives/state-machine/src/basic.rs b/primitives/state-machine/src/basic.rs index e758b3dd3b8147e5b17de77e7cf8e8258b60f226..641d3b531c290d8b285cac6713d633afd4edd509 100644 --- a/primitives/state-machine/src/basic.rs +++ b/primitives/state-machine/src/basic.rs @@ -16,60 +16,56 @@ //! Basic implementation for Externalities. -use std::{collections::HashMap, any::{TypeId, Any}, iter::FromIterator}; +use std::{ + collections::BTreeMap, any::{TypeId, Any}, iter::FromIterator, ops::Bound +}; use crate::backend::{Backend, InMemory}; use hash_db::Hasher; -use trie::{TrieConfiguration, default_child_trie_root}; -use trie::trie_types::Layout; -use primitives::{ +use sp_trie::{TrieConfiguration, default_child_trie_root}; +use sp_trie::trie_types::Layout; +use sp_core::{ storage::{ - well_known_keys::is_child_storage_key, ChildStorageKey, StorageOverlay, - ChildrenStorageOverlay + well_known_keys::is_child_storage_key, ChildStorageKey, Storage, + ChildInfo, StorageChild, }, - traits::Externalities, Blake2Hasher, hash::H256, + traits::Externalities, Blake2Hasher, }; use log::warn; +use codec::Encode; -/// Simple HashMap-based Externalities impl. +/// Simple Map-based Externalities impl. #[derive(Debug)] pub struct BasicExternalities { - top: StorageOverlay, - children: ChildrenStorageOverlay, + inner: Storage, } impl BasicExternalities { /// Create a new instance of `BasicExternalities` - pub fn new(top: StorageOverlay, children: ChildrenStorageOverlay) -> Self { - BasicExternalities { - top, - children, - } + pub fn new(inner: Storage) -> Self { + BasicExternalities { inner } } /// Insert key/value pub fn insert(&mut self, k: Vec, v: Vec) -> Option> { - self.top.insert(k, v) + self.inner.top.insert(k, v) } /// Consume self and returns inner storages - pub fn into_storages(self) -> ( - HashMap, Vec>, - HashMap, HashMap, Vec>>, - ) { - (self.top, self.children) + pub fn into_storages(self) -> Storage { + self.inner } /// Execute the given closure `f` with the externalities set and initialized with `storage`. /// /// Returns the result of the closure and updates `storage` with all changes. pub fn execute_with_storage( - storage: &mut (StorageOverlay, ChildrenStorageOverlay), + storage: &mut sp_core::storage::Storage, f: impl FnOnce() -> R, ) -> R { - let mut ext = Self { - top: storage.0.drain().collect(), - children: storage.1.drain().collect(), - }; + let mut ext = Self { inner: Storage { + top: std::mem::replace(&mut storage.top, Default::default()), + children: std::mem::replace(&mut storage.children, Default::default()), + }}; let r = ext.execute_with(f); @@ -82,68 +78,105 @@ impl BasicExternalities { /// /// Returns the result of the given closure. pub fn execute_with(&mut self, f: impl FnOnce() -> R) -> R { - externalities::set_and_run_with_externalities(self, f) + sp_externalities::set_and_run_with_externalities(self, f) } } impl PartialEq for BasicExternalities { fn eq(&self, other: &BasicExternalities) -> bool { - self.top.eq(&other.top) && self.children.eq(&other.children) + self.inner.top.eq(&other.inner.top) + && self.inner.children.eq(&other.inner.children) } } impl FromIterator<(Vec, Vec)> for BasicExternalities { fn from_iter, Vec)>>(iter: I) -> Self { let mut t = Self::default(); - t.top.extend(iter); + t.inner.top.extend(iter); t } } impl Default for BasicExternalities { - fn default() -> Self { Self::new(Default::default(), Default::default()) } + fn default() -> Self { Self::new(Default::default()) } } -impl From, Vec>> for BasicExternalities { - fn from(hashmap: HashMap, Vec>) -> Self { - BasicExternalities { +impl From, Vec>> for BasicExternalities { + fn from(hashmap: BTreeMap, Vec>) -> Self { + BasicExternalities { inner: Storage { top: hashmap, children: Default::default(), - } + }} } } impl Externalities for BasicExternalities { fn storage(&self, key: &[u8]) -> Option> { - self.top.get(key).cloned() + self.inner.top.get(key).cloned() } - fn storage_hash(&self, key: &[u8]) -> Option { - self.storage(key).map(|v| Blake2Hasher::hash(&v)) + fn storage_hash(&self, key: &[u8]) -> Option> { + self.storage(key).map(|v| Blake2Hasher::hash(&v).encode()) } fn original_storage(&self, key: &[u8]) -> Option> { self.storage(key) } - fn original_storage_hash(&self, key: &[u8]) -> Option { + fn original_storage_hash(&self, key: &[u8]) -> Option> { self.storage_hash(key) } - fn child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option> { - self.children.get(storage_key.as_ref()).and_then(|child| child.get(key)).cloned() + fn child_storage( + &self, + storage_key: ChildStorageKey, + _child_info: ChildInfo, + key: &[u8], + ) -> Option> { + self.inner.children.get(storage_key.as_ref()).and_then(|child| child.data.get(key)).cloned() } - fn child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option { - self.child_storage(storage_key, key).map(|v| Blake2Hasher::hash(&v)) + fn child_storage_hash( + &self, + storage_key: ChildStorageKey, + child_info: ChildInfo, + key: &[u8], + ) -> Option> { + self.child_storage(storage_key, child_info, key).map(|v| Blake2Hasher::hash(&v).encode()) } - fn original_child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option { - self.child_storage_hash(storage_key, key) + fn original_child_storage_hash( + &self, + storage_key: ChildStorageKey, + child_info: ChildInfo, + key: &[u8], + ) -> Option> { + self.child_storage_hash(storage_key, child_info, key) } - fn original_child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option> { - Externalities::child_storage(self, storage_key, key) + fn original_child_storage( + &self, + storage_key: ChildStorageKey, + child_info: ChildInfo, + key: &[u8], + ) -> Option> { + Externalities::child_storage(self, storage_key, child_info, key) + } + + fn next_storage_key(&self, key: &[u8]) -> Option> { + let range = (Bound::Excluded(key), Bound::Unbounded); + self.inner.top.range::<[u8], _>(range).next().map(|(k, _)| k).cloned() + } + + fn next_child_storage_key( + &self, + storage_key: ChildStorageKey, + _child_info: ChildInfo, + key: &[u8], + ) -> Option> { + let range = (Bound::Excluded(key), Bound::Unbounded); + self.inner.children.get(storage_key.as_ref()) + .and_then(|child| child.data.range::<[u8], _>(range).next().map(|(k, _)| k).cloned()) } fn place_storage(&mut self, key: Vec, maybe_value: Option>) { @@ -153,27 +186,36 @@ impl Externalities for BasicExternalities { } match maybe_value { - Some(value) => { self.top.insert(key, value); } - None => { self.top.remove(&key); } + Some(value) => { self.inner.top.insert(key, value); } + None => { self.inner.top.remove(&key); } } } fn place_child_storage( &mut self, storage_key: ChildStorageKey, + child_info: ChildInfo, key: Vec, value: Option>, ) { - let child_map = self.children.entry(storage_key.into_owned()).or_default(); + let child_map = self.inner.children.entry(storage_key.into_owned()) + .or_insert_with(|| StorageChild { + data: Default::default(), + child_info: child_info.to_owned(), + }); if let Some(value) = value { - child_map.insert(key, value); + child_map.data.insert(key, value); } else { - child_map.remove(&key); + child_map.data.remove(&key); } } - fn kill_child_storage(&mut self, storage_key: ChildStorageKey) { - self.children.remove(storage_key.as_ref()); + fn kill_child_storage( + &mut self, + storage_key: ChildStorageKey, + _child_info: ChildInfo, + ) { + self.inner.children.remove(storage_key.as_ref()); } fn clear_prefix(&mut self, prefix: &[u8]) { @@ -185,20 +227,41 @@ impl Externalities for BasicExternalities { return; } - self.top.retain(|key, _| !key.starts_with(prefix)); + let to_remove = self.inner.top.range::<[u8], _>((Bound::Included(prefix), Bound::Unbounded)) + .map(|(k, _)| k) + .take_while(|k| k.starts_with(prefix)) + .cloned() + .collect::>(); + + for key in to_remove { + self.inner.top.remove(&key); + } } - fn clear_child_prefix(&mut self, storage_key: ChildStorageKey, prefix: &[u8]) { - if let Some(child) = self.children.get_mut(storage_key.as_ref()) { - child.retain(|key, _| !key.starts_with(prefix)); + fn clear_child_prefix( + &mut self, + storage_key: ChildStorageKey, + _child_info: ChildInfo, + prefix: &[u8], + ) { + if let Some(child) = self.inner.children.get_mut(storage_key.as_ref()) { + let to_remove = child.data.range::<[u8], _>((Bound::Included(prefix), Bound::Unbounded)) + .map(|(k, _)| k) + .take_while(|k| k.starts_with(prefix)) + .cloned() + .collect::>(); + + for key in to_remove { + child.data.remove(&key); + } } } fn chain_id(&self) -> u64 { 42 } - fn storage_root(&mut self) -> H256 { - let mut top = self.top.clone(); - let keys: Vec<_> = self.children.keys().map(|k| k.to_vec()).collect(); + fn storage_root(&mut self) -> Vec { + let mut top = self.inner.top.clone(); + let keys: Vec<_> = self.inner.children.keys().map(|k| k.to_vec()).collect(); // Single child trie implementation currently allows using the same child // empty root for all child trie. Using null storage key until multiple // type of child trie support. @@ -209,31 +272,35 @@ impl Externalities for BasicExternalities { .expect("Map only feed by valid keys; qed"), ); if &empty_hash[..] == &child_root[..] { - top.remove(&storage_key); + top.remove(storage_key.as_slice()); } else { top.insert(storage_key, child_root); } } - Layout::::trie_root(self.top.clone()) + Layout::::trie_root(self.inner.top.clone()).as_ref().into() } - fn child_storage_root(&mut self, storage_key: ChildStorageKey) -> Vec { - if let Some(child) = self.children.get(storage_key.as_ref()) { - let delta = child.clone().into_iter().map(|(k, v)| (k, Some(v))); + fn child_storage_root( + &mut self, + storage_key: ChildStorageKey, + ) -> Vec { + if let Some(child) = self.inner.children.get(storage_key.as_ref()) { + let delta = child.data.clone().into_iter().map(|(k, v)| (k, Some(v))); - InMemory::::default().child_storage_root(storage_key.as_ref(), delta).0 + InMemory::::default() + .child_storage_root(storage_key.as_ref(), child.child_info.as_ref(), delta).0 } else { default_child_trie_root::>(storage_key.as_ref()) - } + }.encode() } - fn storage_changes_root(&mut self, _parent: H256) -> Result, ()> { + fn storage_changes_root(&mut self, _parent: &[u8]) -> Result>, ()> { Ok(None) } } -impl externalities::ExtensionStore for BasicExternalities { +impl sp_externalities::ExtensionStore for BasicExternalities { fn extension_by_type_id(&mut self, _: TypeId) -> Option<&mut dyn Any> { warn!("Extensions are not supported by `BasicExternalities`."); None @@ -243,10 +310,13 @@ impl externalities::ExtensionStore for BasicExternalities { #[cfg(test)] mod tests { use super::*; - use primitives::{H256, map}; - use primitives::storage::well_known_keys::CODE; + use sp_core::map; + use sp_core::storage::{Storage, StorageChild}; + use sp_core::storage::well_known_keys::CODE; use hex_literal::hex; + const CHILD_INFO_1: ChildInfo<'static> = ChildInfo::new_default(b"unique_id_1"); + #[test] fn commit_should_work() { let mut ext = BasicExternalities::default(); @@ -255,7 +325,7 @@ mod tests { ext.set_storage(b"dogglesworth".to_vec(), b"cat".to_vec()); const ROOT: [u8; 32] = hex!("39245109cef3758c2eed2ccba8d9b370a917850af3824bc8348d505df2c298fa"); - assert_eq!(ext.storage_root(), H256::from(ROOT)); + assert_eq!(&ext.storage_root()[..], &ROOT); } #[test] @@ -272,37 +342,35 @@ mod tests { fn children_works() { let child_storage = b":child_storage:default:test".to_vec(); - let mut ext = BasicExternalities::new( - Default::default(), - map![ - child_storage.clone() => map![ - b"doe".to_vec() => b"reindeer".to_vec() - ] + let mut ext = BasicExternalities::new(Storage { + top: Default::default(), + children: map![ + child_storage.clone() => StorageChild { + data: map![ b"doe".to_vec() => b"reindeer".to_vec() ], + child_info: CHILD_INFO_1.to_owned(), + } ] - ); + }); let child = || ChildStorageKey::from_vec(child_storage.clone()).unwrap(); - assert_eq!(ext.child_storage(child(), b"doe"), Some(b"reindeer".to_vec())); + assert_eq!(ext.child_storage(child(), CHILD_INFO_1, b"doe"), Some(b"reindeer".to_vec())); - ext.set_child_storage(child(), b"dog".to_vec(), b"puppy".to_vec()); - assert_eq!(ext.child_storage(child(), b"dog"), Some(b"puppy".to_vec())); + ext.set_child_storage(child(), CHILD_INFO_1, b"dog".to_vec(), b"puppy".to_vec()); + assert_eq!(ext.child_storage(child(), CHILD_INFO_1, b"dog"), Some(b"puppy".to_vec())); - ext.clear_child_storage(child(), b"dog"); - assert_eq!(ext.child_storage(child(), b"dog"), None); + ext.clear_child_storage(child(), CHILD_INFO_1, b"dog"); + assert_eq!(ext.child_storage(child(), CHILD_INFO_1, b"dog"), None); - ext.kill_child_storage(child()); - assert_eq!(ext.child_storage(child(), b"doe"), None); + ext.kill_child_storage(child(), CHILD_INFO_1); + assert_eq!(ext.child_storage(child(), CHILD_INFO_1, b"doe"), None); } #[test] fn basic_externalities_is_empty() { // Make sure no values are set by default in `BasicExternalities`. - let (storage, child_storage) = BasicExternalities::new( - Default::default(), - Default::default(), - ).into_storages(); - assert!(storage.is_empty()); - assert!(child_storage.is_empty()); + let storage = BasicExternalities::new(Default::default()).into_storages(); + assert!(storage.top.is_empty()); + assert!(storage.children.is_empty()); } } diff --git a/primitives/state-machine/src/changes_trie/build.rs b/primitives/state-machine/src/changes_trie/build.rs index 10c38a41e26509173543a456a2ee233901604155..356c8614e2edb20cb1b1c40beeacdc106f1336a4 100644 --- a/primitives/state-machine/src/changes_trie/build.rs +++ b/primitives/state-machine/src/changes_trie/build.rs @@ -18,7 +18,7 @@ use std::collections::{BTreeMap, BTreeSet}; use std::collections::btree_map::Entry; -use codec::Decode; +use codec::{Decode, Encode}; use hash_db::Hasher; use num_traits::One; use crate::backend::Backend; @@ -47,6 +47,7 @@ pub(crate) fn prepare_input<'a, B, H, Number>( where B: Backend, H: Hasher + 'a, + H::Out: Encode, Number: BlockNumber, { let number = parent.number.clone() + One::one(); @@ -132,10 +133,15 @@ fn prepare_extrinsics_input_inner<'a, B, H, Number>( H: Hasher, Number: BlockNumber, { - let (committed, prospective) = if let Some(sk) = storage_key.as_ref() { - (changes.committed.children.get(sk), changes.prospective.children.get(sk)) + let (committed, prospective, child_info) = if let Some(sk) = storage_key.as_ref() { + let child_info = changes.child_info(sk).cloned(); + ( + changes.committed.children.get(sk).map(|c| &c.0), + changes.prospective.children.get(sk).map(|c| &c.0), + child_info, + ) } else { - (Some(&changes.committed.top), Some(&changes.prospective.top)) + (Some(&changes.committed.top), Some(&changes.prospective.top), None) }; committed.iter().flat_map(|c| c.iter()) .chain(prospective.iter().flat_map(|c| c.iter())) @@ -147,8 +153,11 @@ fn prepare_extrinsics_input_inner<'a, B, H, Number>( // AND are not in storage at the beginning of operation if let Some(sk) = storage_key.as_ref() { if !changes.child_storage(sk, k).map(|v| v.is_some()).unwrap_or_default() { - if !backend.exists_child_storage(sk, k).map_err(|e| format!("{}", e))? { - return Ok(map); + if let Some(child_info) = child_info.as_ref() { + if !backend.exists_child_storage(sk, child_info.as_ref(), k) + .map_err(|e| format!("{}", e))? { + return Ok(map); + } } } } else { @@ -200,7 +209,7 @@ fn prepare_digest_input<'a, H, Number>( ), String> where H: Hasher, - H::Out: 'a, + H::Out: 'a + Encode, Number: BlockNumber, { let build_skewed_digest = config.end.as_ref() == Some(&block); @@ -329,14 +338,18 @@ fn prepare_digest_input<'a, H, Number>( #[cfg(test)] mod test { use codec::Encode; - use primitives::Blake2Hasher; - use primitives::storage::well_known_keys::{EXTRINSIC_INDEX}; + use sp_core::Blake2Hasher; + use sp_core::storage::well_known_keys::{EXTRINSIC_INDEX}; + use sp_core::storage::ChildInfo; use crate::backend::InMemory; use crate::changes_trie::{RootsStorage, Configuration, storage::InMemoryStorage}; use crate::changes_trie::build_cache::{IncompleteCacheAction, IncompleteCachedBuildData}; use crate::overlayed_changes::{OverlayedValue, OverlayedChangeSet}; use super::*; + const CHILD_INFO_1: ChildInfo<'static> = ChildInfo::new_default(b"unique_id_1"); + const CHILD_INFO_2: ChildInfo<'static> = ChildInfo::new_default(b"unique_id_2"); + fn prepare_for_build(zero: u64) -> ( InMemory, InMemoryStorage, @@ -351,7 +364,7 @@ mod test { (vec![103], vec![255]), (vec![104], vec![255]), (vec![105], vec![255]), - ].into_iter().collect::<::std::collections::HashMap<_, _>>().into(); + ].into_iter().collect::<::std::collections::BTreeMap<_, _>>().into(); let child_trie_key1 = b"1".to_vec(); let child_trie_key2 = b"2".to_vec(); let storage = InMemoryStorage::with_inputs(vec![ @@ -415,18 +428,18 @@ mod test { }), ].into_iter().collect(), children: vec![ - (child_trie_key1.clone(), vec![ + (child_trie_key1.clone(), (vec![ (vec![100], OverlayedValue { value: Some(vec![200]), extrinsics: Some(vec![0, 2].into_iter().collect()) }) - ].into_iter().collect()), - (child_trie_key2, vec![ + ].into_iter().collect(), CHILD_INFO_1.to_owned())), + (child_trie_key2, (vec![ (vec![100], OverlayedValue { value: Some(vec![200]), extrinsics: Some(vec![0, 2].into_iter().collect()) }) - ].into_iter().collect()), + ].into_iter().collect(), CHILD_INFO_2.to_owned())), ].into_iter().collect() }, committed: OverlayedChangeSet { top: vec![ @@ -444,12 +457,12 @@ mod test { }), ].into_iter().collect(), children: vec![ - (child_trie_key1, vec![ + (child_trie_key1, (vec![ (vec![100], OverlayedValue { value: Some(vec![202]), extrinsics: Some(vec![3].into_iter().collect()) }) - ].into_iter().collect()), + ].into_iter().collect(), CHILD_INFO_1.to_owned())), ].into_iter().collect(), }, changes_trie_config: Some(config.clone()), diff --git a/primitives/state-machine/src/changes_trie/changes_iterator.rs b/primitives/state-machine/src/changes_trie/changes_iterator.rs index 2f61b87fe21991f0e3d6f72870432a68a71a1c1e..f62575f451810024e228161ab01cb2b110cd1063 100644 --- a/primitives/state-machine/src/changes_trie/changes_iterator.rs +++ b/primitives/state-machine/src/changes_trie/changes_iterator.rs @@ -19,10 +19,10 @@ use std::cell::RefCell; use std::collections::VecDeque; -use codec::{Decode, Encode}; +use codec::{Decode, Encode, Codec}; use hash_db::Hasher; use num_traits::Zero; -use trie::Recorder; +use sp_trie::Recorder; use crate::changes_trie::{AnchorBlockId, ConfigurationRange, RootsStorage, Storage, BlockNumber}; use crate::changes_trie::input::{DigestIndex, ExtrinsicIndex, DigestIndexValue, ExtrinsicIndexValue}; use crate::changes_trie::storage::{TrieBackendAdapter, InMemoryStorage}; @@ -81,7 +81,7 @@ pub fn key_changes_proof<'a, H: Hasher, Number: BlockNumber>( max: Number, storage_key: Option<&[u8]>, key: &[u8], -) -> Result>, String> { +) -> Result>, String> where H::Out: Codec { // we can't query any roots before root let max = ::std::cmp::min(max.clone(), end.number.clone()); @@ -129,7 +129,7 @@ pub fn key_changes_proof_check<'a, H: Hasher, Number: BlockNumber>( max: Number, storage_key: Option<&[u8]>, key: &[u8] -) -> Result, String> { +) -> Result, String> where H::Out: Encode { key_changes_proof_check_with_db( config, roots_storage, @@ -152,7 +152,7 @@ pub fn key_changes_proof_check_with_db<'a, H: Hasher, Number: BlockNumber>( max: Number, storage_key: Option<&[u8]>, key: &[u8] -) -> Result, String> { +) -> Result, String> where H::Out: Encode { // we can't query any roots before root let max = ::std::cmp::min(max.clone(), end.number.clone()); @@ -316,8 +316,8 @@ pub struct DrilldownIterator<'a, H, Number> essence: DrilldownIteratorEssence<'a, H, Number>, } -impl<'a, H: Hasher, Number: BlockNumber> Iterator - for DrilldownIterator<'a, H, Number> +impl<'a, H: Hasher, Number: BlockNumber> Iterator for DrilldownIterator<'a, H, Number> + where H::Out: Encode { type Item = Result<(Number, u32), String>; @@ -358,7 +358,7 @@ impl<'a, H, Number> Iterator for ProvingDrilldownIterator<'a, H, Number> where Number: BlockNumber, H: Hasher, - H::Out: 'a, + H::Out: 'a + Codec, { type Item = Result<(Number, u32), String>; @@ -376,7 +376,7 @@ impl<'a, H, Number> Iterator for ProvingDrilldownIterator<'a, H, Number> #[cfg(test)] mod tests { use std::iter::FromIterator; - use primitives::Blake2Hasher; + use sp_core::Blake2Hasher; use crate::changes_trie::Configuration; use crate::changes_trie::input::InputPair; use crate::changes_trie::storage::InMemoryStorage; diff --git a/primitives/state-machine/src/changes_trie/mod.rs b/primitives/state-machine/src/changes_trie/mod.rs index f771fddf6196415ce53e0176633bdbb5149e8ba9..54eaa967c7d443422dd817e403c3c63426e85365 100644 --- a/primitives/state-machine/src/changes_trie/mod.rs +++ b/primitives/state-machine/src/changes_trie/mod.rs @@ -71,12 +71,12 @@ use hash_db::{Hasher, Prefix}; use crate::backend::Backend; use num_traits::{One, Zero}; use codec::{Decode, Encode}; -use primitives; +use sp_core; use crate::changes_trie::build::prepare_input; use crate::changes_trie::build_cache::{IncompleteCachedBuildData, IncompleteCacheAction}; use crate::overlayed_changes::OverlayedChanges; -use trie::{MemoryDB, DBValue, TrieMut}; -use trie::trie_types::TrieDBMut; +use sp_trie::{MemoryDB, DBValue, TrieMut}; +use sp_trie::trie_types::TrieDBMut; /// Changes that are made outside of extrinsics are marked with this index; pub const NO_EXTRINSIC_INDEX: u32 = 0xffffffff; @@ -149,7 +149,7 @@ pub trait Storage: RootsStorage { pub struct TrieBackendStorageAdapter<'a, H: Hasher, Number: BlockNumber>(pub &'a dyn Storage); impl<'a, H: Hasher, N: BlockNumber> crate::TrieBackendStorage for TrieBackendStorageAdapter<'a, H, N> { - type Overlay = trie::MemoryDB; + type Overlay = sp_trie::MemoryDB; fn get(&self, key: &H::Out, prefix: Prefix) -> Result, String> { self.0.get(key, prefix) @@ -157,7 +157,7 @@ impl<'a, H: Hasher, N: BlockNumber> crate::TrieBackendStorage for TrieBackend } /// Changes trie configuration. -pub type Configuration = primitives::ChangesTrieConfiguration; +pub type Configuration = sp_core::ChangesTrieConfiguration; /// Blocks range where configuration has been constant. #[derive(Clone)] @@ -181,7 +181,7 @@ pub fn build_changes_trie<'a, B: Backend, S: Storage, H: Hasher, N parent_hash: H::Out, ) -> Result, H::Out, CacheAction)>, ()> where - H::Out: Ord + 'static, + H::Out: Ord + 'static + Encode, { let (storage, config) = match (storage, changes.changes_trie_config.as_ref()) { (Some(storage), Some(config)) => (storage, config), diff --git a/primitives/state-machine/src/changes_trie/prune.rs b/primitives/state-machine/src/changes_trie/prune.rs index fccd177e60a2f16b3c8b7df3501aad01372239a5..c6d305ddf9d4cfefc19553da9ab3ee10ab08bb32 100644 --- a/primitives/state-machine/src/changes_trie/prune.rs +++ b/primitives/state-machine/src/changes_trie/prune.rs @@ -17,7 +17,7 @@ //! Changes trie pruning-related functions. use hash_db::Hasher; -use trie::Recorder; +use sp_trie::Recorder; use log::warn; use num_traits::{One, Zero}; use crate::proving_backend::ProvingBackendRecorder; @@ -25,7 +25,7 @@ use crate::trie_backend_essence::TrieBackendEssence; use crate::changes_trie::{AnchorBlockId, Configuration, Storage, BlockNumber}; use crate::changes_trie::storage::TrieBackendAdapter; use crate::changes_trie::input::{ChildIndex, InputKey}; -use codec::Decode; +use codec::{Decode, Codec}; /// Get number of oldest block for which changes trie is not pruned /// given changes trie configuration, pruning parameter and number of @@ -55,7 +55,7 @@ pub fn prune, H: Hasher, Number: BlockNumber, F: FnMut(H:: min_blocks_to_keep: Number, current_block: &AnchorBlockId, mut remove_trie_node: F, -) { +) where H::Out: Codec { // select range for pruning let (first, last) = match pruning_range(config, min_blocks_to_keep, current_block.number.clone()) { @@ -116,7 +116,7 @@ fn prune_trie, H: Hasher, Number: BlockNumber, F: FnMut(H: storage: &S, root: H::Out, remove_trie_node: &mut F, -) { +) where H::Out: Codec { // enumerate all changes trie' keys, recording all nodes that have been 'touched' // (effectively - all changes trie nodes) @@ -202,8 +202,8 @@ fn max_digest_intervals_to_keep( #[cfg(test)] mod tests { use std::collections::HashSet; - use trie::MemoryDB; - use primitives::Blake2Hasher; + use sp_trie::MemoryDB; + use sp_core::Blake2Hasher; use crate::backend::insert_into_memory_db; use crate::changes_trie::storage::InMemoryStorage; use codec::Encode; @@ -221,13 +221,15 @@ mod tests { storage: &S, min_blocks_to_keep: u64, current_block: u64, - ) -> HashSet { + ) -> HashSet where H::Out: Codec { let mut pruned_trie_nodes = HashSet::new(); - prune(config, + prune( + config, storage, min_blocks_to_keep, &AnchorBlockId { hash: Default::default(), number: current_block }, - |node| { pruned_trie_nodes.insert(node); }); + |node| { pruned_trie_nodes.insert(node); }, + ); pruned_trie_nodes } diff --git a/primitives/state-machine/src/changes_trie/storage.rs b/primitives/state-machine/src/changes_trie/storage.rs index a82477bdc393310089329b070af3d7c0d1603f02..f9a03b6c2eb1d3e9c3ee109c7764137fdfaa894d 100644 --- a/primitives/state-machine/src/changes_trie/storage.rs +++ b/primitives/state-machine/src/changes_trie/storage.rs @@ -18,8 +18,8 @@ use std::collections::{BTreeMap, HashSet, HashMap}; use hash_db::{Hasher, Prefix, EMPTY_PREFIX}; -use trie::DBValue; -use trie::MemoryDB; +use sp_trie::DBValue; +use sp_trie::MemoryDB; use parking_lot::RwLock; use crate::changes_trie::{BuildCache, RootsStorage, Storage, AnchorBlockId, BlockNumber}; use crate::trie_backend_essence::TrieBackendStorage; diff --git a/primitives/state-machine/src/ext.rs b/primitives/state-machine/src/ext.rs index 0e93302a95a547edf66cd498af701677642b5531..32dcba634ed95372fda91136b8663ed59ca586ff 100644 --- a/primitives/state-machine/src/ext.rs +++ b/primitives/state-machine/src/ext.rs @@ -24,12 +24,13 @@ use crate::{ }; use hash_db::Hasher; -use primitives::{ - storage::{ChildStorageKey, well_known_keys::is_child_storage_key}, +use sp_core::{ + storage::{ChildStorageKey, well_known_keys::is_child_storage_key, ChildInfo}, traits::Externalities, hexdisplay::HexDisplay, hash::H256, }; -use trie::{trie_types::Layout, MemoryDB, default_child_trie_root}; -use externalities::Extensions; +use sp_trie::{trie_types::Layout, MemoryDB, default_child_trie_root}; +use sp_externalities::Extensions; +use codec::{Decode, Encode}; use std::{error, fmt, any::{Any, TypeId}}; use log::{warn, trace}; @@ -178,7 +179,7 @@ where N: crate::changes_trie::BlockNumber, { fn storage(&self, key: &[u8]) -> Option> { - let _guard = panic_handler::AbortGuard::force_abort(); + let _guard = sp_panic_handler::AbortGuard::force_abort(); let result = self.overlay.storage(key).map(|x| x.map(|x| x.to_vec())).unwrap_or_else(|| self.backend.storage(key).expect(EXT_NOT_ALLOWED_TO_FAIL)); trace!(target: "state-trace", "{:04x}: Get {}={:?}", @@ -189,25 +190,25 @@ where result } - fn storage_hash(&self, key: &[u8]) -> Option { - let _guard = panic_handler::AbortGuard::force_abort(); + fn storage_hash(&self, key: &[u8]) -> Option> { + let _guard = sp_panic_handler::AbortGuard::force_abort(); let result = self.overlay .storage(key) .map(|x| x.map(|x| H::hash(x))) - .unwrap_or_else(|| - self.backend.storage_hash(key).expect(EXT_NOT_ALLOWED_TO_FAIL) - ); + .unwrap_or_else(|| self.backend.storage_hash(key).expect(EXT_NOT_ALLOWED_TO_FAIL)); + trace!(target: "state-trace", "{:04x}: Hash {}={:?}", self.id, HexDisplay::from(&key), result, ); - result + result.map(|r| r.encode()) } fn original_storage(&self, key: &[u8]) -> Option> { - let _guard = panic_handler::AbortGuard::force_abort(); + let _guard = sp_panic_handler::AbortGuard::force_abort(); let result = self.backend.storage(key).expect(EXT_NOT_ALLOWED_TO_FAIL); + trace!(target: "state-trace", "{:04x}: GetOriginal {}={:?}", self.id, HexDisplay::from(&key), @@ -216,24 +217,31 @@ where result } - fn original_storage_hash(&self, key: &[u8]) -> Option { - let _guard = panic_handler::AbortGuard::force_abort(); + fn original_storage_hash(&self, key: &[u8]) -> Option> { + let _guard = sp_panic_handler::AbortGuard::force_abort(); let result = self.backend.storage_hash(key).expect(EXT_NOT_ALLOWED_TO_FAIL); + trace!(target: "state-trace", "{:04x}: GetOriginalHash {}={:?}", self.id, HexDisplay::from(&key), result, ); - result + result.map(|r| r.encode()) } - fn child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option> { - let _guard = panic_handler::AbortGuard::force_abort(); + fn child_storage( + &self, + storage_key: ChildStorageKey, + child_info: ChildInfo, + key: &[u8], + ) -> Option> { + let _guard = sp_panic_handler::AbortGuard::force_abort(); let result = self.overlay .child_storage(storage_key.as_ref(), key) .map(|x| x.map(|x| x.to_vec())) .unwrap_or_else(|| - self.backend.child_storage(storage_key.as_ref(), key).expect(EXT_NOT_ALLOWED_TO_FAIL) + self.backend.child_storage(storage_key.as_ref(), child_info, key) + .expect(EXT_NOT_ALLOWED_TO_FAIL) ); trace!(target: "state-trace", "{:04x}: GetChild({}) {}={:?}", @@ -246,8 +254,13 @@ where result } - fn child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option { - let _guard = panic_handler::AbortGuard::force_abort(); + fn child_storage_hash( + &self, + storage_key: ChildStorageKey, + _child_info: ChildInfo, + key: &[u8], + ) -> Option> { + let _guard = sp_panic_handler::AbortGuard::force_abort(); let result = self.overlay .child_storage(storage_key.as_ref(), key) .map(|x| x.map(|x| H::hash(x))) @@ -262,13 +275,18 @@ where result, ); - result + result.map(|r| r.encode()) } - fn original_child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option> { - let _guard = panic_handler::AbortGuard::force_abort(); + fn original_child_storage( + &self, + storage_key: ChildStorageKey, + child_info: ChildInfo, + key: &[u8], + ) -> Option> { + let _guard = sp_panic_handler::AbortGuard::force_abort(); let result = self.backend - .child_storage(storage_key.as_ref(), key) + .child_storage(storage_key.as_ref(), child_info, key) .expect(EXT_NOT_ALLOWED_TO_FAIL); trace!(target: "state-trace", "{:04x}: ChildOriginal({}) {}={:?}", @@ -280,10 +298,15 @@ where result } - fn original_child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option { - let _guard = panic_handler::AbortGuard::force_abort(); + fn original_child_storage_hash( + &self, + storage_key: ChildStorageKey, + child_info: ChildInfo, + key: &[u8], + ) -> Option> { + let _guard = sp_panic_handler::AbortGuard::force_abort(); let result = self.backend - .child_storage_hash(storage_key.as_ref(), key) + .child_storage_hash(storage_key.as_ref(), child_info, key) .expect(EXT_NOT_ALLOWED_TO_FAIL); trace!(target: "state-trace", "{}: ChildHashOriginal({}) {}={:?}", @@ -292,11 +315,11 @@ where HexDisplay::from(&key), result, ); - result + result.map(|r| r.encode()) } fn exists_storage(&self, key: &[u8]) -> bool { - let _guard = panic_handler::AbortGuard::force_abort(); + let _guard = sp_panic_handler::AbortGuard::force_abort(); let result = match self.overlay.storage(key) { Some(x) => x.is_some(), _ => self.backend.exists_storage(key).expect(EXT_NOT_ALLOWED_TO_FAIL), @@ -311,13 +334,18 @@ where } - fn exists_child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> bool { - let _guard = panic_handler::AbortGuard::force_abort(); + fn exists_child_storage( + &self, + storage_key: ChildStorageKey, + child_info: ChildInfo, + key: &[u8], + ) -> bool { + let _guard = sp_panic_handler::AbortGuard::force_abort(); let result = match self.overlay.child_storage(storage_key.as_ref(), key) { Some(x) => x.is_some(), _ => self.backend - .exists_child_storage(storage_key.as_ref(), key) + .exists_child_storage(storage_key.as_ref(), child_info, key) .expect(EXT_NOT_ALLOWED_TO_FAIL), }; @@ -330,13 +358,57 @@ where result } + fn next_storage_key(&self, key: &[u8]) -> Option> { + let next_backend_key = self.backend.next_storage_key(key).expect(EXT_NOT_ALLOWED_TO_FAIL); + let next_overlay_key_change = self.overlay.next_storage_key_change(key); + + match (next_backend_key, next_overlay_key_change) { + (Some(backend_key), Some(overlay_key)) if &backend_key[..] < overlay_key.0 => Some(backend_key), + (backend_key, None) => backend_key, + (_, Some(overlay_key)) => if overlay_key.1.value.is_some() { + Some(overlay_key.0.to_vec()) + } else { + self.next_storage_key(&overlay_key.0[..]) + }, + } + } + + fn next_child_storage_key( + &self, + storage_key: ChildStorageKey, + child_info: ChildInfo, + key: &[u8], + ) -> Option> { + let next_backend_key = self.backend + .next_child_storage_key(storage_key.as_ref(), child_info, key) + .expect(EXT_NOT_ALLOWED_TO_FAIL); + let next_overlay_key_change = self.overlay.next_child_storage_key_change( + storage_key.as_ref(), + key + ); + + match (next_backend_key, next_overlay_key_change) { + (Some(backend_key), Some(overlay_key)) if &backend_key[..] < overlay_key.0 => Some(backend_key), + (backend_key, None) => backend_key, + (_, Some(overlay_key)) => if overlay_key.1.value.is_some() { + Some(overlay_key.0.to_vec()) + } else { + self.next_child_storage_key( + storage_key, + child_info, + &overlay_key.0[..], + ) + }, + } + } + fn place_storage(&mut self, key: Vec, value: Option>) { trace!(target: "state-trace", "{:04x}: Put {}={:?}", self.id, HexDisplay::from(&key), value.as_ref().map(HexDisplay::from) ); - let _guard = panic_handler::AbortGuard::force_abort(); + let _guard = sp_panic_handler::AbortGuard::force_abort(); if is_child_storage_key(&key) { warn!(target: "trie", "Refuse to directly set child storage key"); return; @@ -349,6 +421,7 @@ where fn place_child_storage( &mut self, storage_key: ChildStorageKey, + child_info: ChildInfo, key: Vec, value: Option>, ) { @@ -358,23 +431,27 @@ where HexDisplay::from(&key), value.as_ref().map(HexDisplay::from) ); - let _guard = panic_handler::AbortGuard::force_abort(); + let _guard = sp_panic_handler::AbortGuard::force_abort(); self.mark_dirty(); - self.overlay.set_child_storage(storage_key.into_owned(), key, value); + self.overlay.set_child_storage(storage_key.into_owned(), child_info, key, value); } - fn kill_child_storage(&mut self, storage_key: ChildStorageKey) { + fn kill_child_storage( + &mut self, + storage_key: ChildStorageKey, + child_info: ChildInfo, + ) { trace!(target: "state-trace", "{:04x}: KillChild({})", self.id, HexDisplay::from(&storage_key.as_ref()), ); - let _guard = panic_handler::AbortGuard::force_abort(); + let _guard = sp_panic_handler::AbortGuard::force_abort(); self.mark_dirty(); - self.overlay.clear_child_storage(storage_key.as_ref()); - self.backend.for_keys_in_child_storage(storage_key.as_ref(), |key| { - self.overlay.set_child_storage(storage_key.as_ref().to_vec(), key.to_vec(), None); + self.overlay.clear_child_storage(storage_key.as_ref(), child_info); + self.backend.for_keys_in_child_storage(storage_key.as_ref(), child_info, |key| { + self.overlay.set_child_storage(storage_key.as_ref().to_vec(), child_info, key.to_vec(), None); }); } @@ -383,7 +460,7 @@ where self.id, HexDisplay::from(&prefix), ); - let _guard = panic_handler::AbortGuard::force_abort(); + let _guard = sp_panic_handler::AbortGuard::force_abort(); if is_child_storage_key(prefix) { warn!(target: "trie", "Refuse to directly clear prefix that is part of child storage key"); return; @@ -396,18 +473,23 @@ where }); } - fn clear_child_prefix(&mut self, storage_key: ChildStorageKey, prefix: &[u8]) { + fn clear_child_prefix( + &mut self, + storage_key: ChildStorageKey, + child_info: ChildInfo, + prefix: &[u8], + ) { trace!(target: "state-trace", "{:04x}: ClearChildPrefix({}) {}", self.id, HexDisplay::from(&storage_key.as_ref()), HexDisplay::from(&prefix), ); - let _guard = panic_handler::AbortGuard::force_abort(); + let _guard = sp_panic_handler::AbortGuard::force_abort(); self.mark_dirty(); - self.overlay.clear_child_prefix(storage_key.as_ref(), prefix); - self.backend.for_child_keys_with_prefix(storage_key.as_ref(), prefix, |key| { - self.overlay.set_child_storage(storage_key.as_ref().to_vec(), key.to_vec(), None); + self.overlay.clear_child_prefix(storage_key.as_ref(), child_info, prefix); + self.backend.for_child_keys_with_prefix(storage_key.as_ref(), child_info, prefix, |key| { + self.overlay.set_child_storage(storage_key.as_ref().to_vec(), child_info, key.to_vec(), None); }); } @@ -415,26 +497,33 @@ where 42 } - fn storage_root(&mut self) -> H256 { - let _guard = panic_handler::AbortGuard::force_abort(); + fn storage_root(&mut self) -> Vec { + let _guard = sp_panic_handler::AbortGuard::force_abort(); if let Some((_, ref root)) = self.storage_transaction { trace!(target: "state-trace", "{:04x}: Root (cached) {}", self.id, HexDisplay::from(&root.as_ref()), ); - return root.clone(); + return root.encode(); } - let child_storage_keys = - self.overlay.prospective.children.keys() + let child_storage_keys = self.overlay.prospective.children.keys() .chain(self.overlay.committed.children.keys()); let child_delta_iter = child_storage_keys.map(|storage_key| - (storage_key.clone(), self.overlay.committed.children.get(storage_key) - .into_iter() - .flat_map(|map| map.iter().map(|(k, v)| (k.clone(), v.value.clone()))) - .chain(self.overlay.prospective.children.get(storage_key) + ( + storage_key.clone(), + self.overlay.committed.children.get(storage_key) .into_iter() - .flat_map(|map| map.iter().map(|(k, v)| (k.clone(), v.value.clone())))))); + .flat_map(|(map, _)| map.iter().map(|(k, v)| (k.clone(), v.value.clone()))) + .chain( + self.overlay.prospective.children.get(storage_key) + .into_iter() + .flat_map(|(map, _)| map.iter().map(|(k, v)| (k.clone(), v.value.clone()))) + ), + self.overlay.child_info(storage_key).cloned() + .expect("child info initialized in either committed or prospective"), + ) + ); // compute and memoize @@ -447,14 +536,18 @@ where self.id, HexDisplay::from(&root.as_ref()), ); - root + root.encode() } - fn child_storage_root(&mut self, storage_key: ChildStorageKey) -> Vec { - let _guard = panic_handler::AbortGuard::force_abort(); + fn child_storage_root( + &mut self, + storage_key: ChildStorageKey, + ) -> Vec { + let _guard = sp_panic_handler::AbortGuard::force_abort(); if self.storage_transaction.is_some() { let root = self .storage(storage_key.as_ref()) + .and_then(|k| Decode::decode(&mut &k[..]).ok()) .unwrap_or( default_child_trie_root::>(storage_key.as_ref()) ); @@ -463,46 +556,79 @@ where HexDisplay::from(&storage_key.as_ref()), HexDisplay::from(&root.as_ref()), ); - root + root.encode() } else { let storage_key = storage_key.as_ref(); - let (root, is_empty, _) = { - let delta = self.overlay.committed.children.get(storage_key) - .into_iter() - .flat_map(|map| map.clone().into_iter().map(|(k, v)| (k, v.value))) - .chain(self.overlay.prospective.children.get(storage_key) - .into_iter() - .flat_map(|map| map.clone().into_iter().map(|(k, v)| (k, v.value)))); - - self.backend.child_storage_root(storage_key, delta) - }; - - if is_empty { - self.overlay.set_storage(storage_key.into(), None); + if let Some(child_info) = self.overlay.child_info(storage_key).cloned() { + let (root, is_empty, _) = { + let delta = self.overlay.committed.children.get(storage_key) + .into_iter() + .flat_map(|(map, _)| map.clone().into_iter().map(|(k, v)| (k, v.value))) + .chain( + self.overlay.prospective.children.get(storage_key) + .into_iter() + .flat_map(|(map, _)| map.clone().into_iter().map(|(k, v)| (k, v.value))) + ); + + self.backend.child_storage_root(storage_key, child_info.as_ref(), delta) + }; + + let root = root.encode(); + // We store update in the overlay in order to be able to use 'self.storage_transaction' + // cache. This is brittle as it rely on Ext only querying the trie backend for + // storage root. + // A better design would be to manage 'child_storage_transaction' in a + // similar way as 'storage_transaction' but for each child trie. + if is_empty { + self.overlay.set_storage(storage_key.into(), None); + } else { + self.overlay.set_storage(storage_key.into(), Some(root.clone())); + } + + trace!(target: "state-trace", "{:04x}: ChildRoot({}) {}", + self.id, + HexDisplay::from(&storage_key.as_ref()), + HexDisplay::from(&root.as_ref()), + ); + root } else { - self.overlay.set_storage(storage_key.into(), Some(root.clone())); + // empty overlay + let root = self + .storage(storage_key.as_ref()) + .and_then(|k| Decode::decode(&mut &k[..]).ok()) + .unwrap_or( + default_child_trie_root::>(storage_key.as_ref()) + ); + trace!(target: "state-trace", "{:04x}: ChildRoot({}) (no change) {}", + self.id, + HexDisplay::from(&storage_key.as_ref()), + HexDisplay::from(&root.as_ref()), + ); + root.encode() } - - trace!(target: "state-trace", "{:04x}: ChildRoot({}) {}", - self.id, - HexDisplay::from(&storage_key.as_ref()), - HexDisplay::from(&root.as_ref()), - ); - root - } } - fn storage_changes_root(&mut self, parent_hash: H256) -> Result, ()> { - let _guard = panic_handler::AbortGuard::force_abort(); + fn storage_changes_root(&mut self, parent_hash: &[u8]) -> Result>, ()> { + let _guard = sp_panic_handler::AbortGuard::force_abort(); + self.changes_trie_transaction = build_changes_trie::<_, T, H, N>( self.backend, self.changes_trie_storage.clone(), self.overlay, - parent_hash, + H256::decode(&mut &parent_hash[..]).map_err(|e| + trace!( + target: "state-trace", + "Failed to decode changes root parent hash: {}", + e, + ) + )?, )?; - let result = Ok(self.changes_trie_transaction.as_ref().map(|(_, root, _)| root.clone())); + let result = Ok( + self.changes_trie_transaction.as_ref().map(|(_, root, _)| root.encode()) + ); + trace!(target: "state-trace", "{:04x}: ChangesRoot({}) {:?}", self.id, HexDisplay::from(&parent_hash.as_ref()), @@ -512,7 +638,7 @@ where } } -impl<'a, H, B, T, N> externalities::ExtensionStore for Ext<'a, H, N, B, T> +impl<'a, H, B, T, N> sp_externalities::ExtensionStore for Ext<'a, H, N, B, T> where H: Hasher, B: 'a + Backend, @@ -529,13 +655,14 @@ mod tests { use super::*; use hex_literal::hex; use codec::Encode; - use primitives::{Blake2Hasher, storage::well_known_keys::EXTRINSIC_INDEX}; + use sp_core::{Blake2Hasher, storage::well_known_keys::EXTRINSIC_INDEX, map}; use crate::{ changes_trie::{ Configuration as ChangesTrieConfiguration, InMemoryStorage as InMemoryChangesTrieStorage, }, backend::InMemory, overlayed_changes::OverlayedValue, }; + use sp_core::storage::{Storage, StorageChild}; type TestBackend = InMemory; type TestChangesTrieStorage = InMemoryChangesTrieStorage; @@ -566,7 +693,7 @@ mod tests { let mut overlay = prepare_overlay_with_changes(); let backend = TestBackend::default(); let mut ext = TestExt::new(&mut overlay, &backend, None, None); - assert_eq!(ext.storage_changes_root(Default::default()).unwrap(), None); + assert_eq!(ext.storage_changes_root(&H256::default().encode()).unwrap(), None); } #[test] @@ -576,7 +703,7 @@ mod tests { let storage = TestChangesTrieStorage::with_blocks(vec![(100, Default::default())]); let backend = TestBackend::default(); let mut ext = TestExt::new(&mut overlay, &backend, Some(&storage), None); - assert_eq!(ext.storage_changes_root(Default::default()).unwrap(), None); + assert_eq!(ext.storage_changes_root(&H256::default().encode()).unwrap(), None); } #[test] @@ -586,8 +713,8 @@ mod tests { let backend = TestBackend::default(); let mut ext = TestExt::new(&mut overlay, &backend, Some(&storage), None); assert_eq!( - ext.storage_changes_root(Default::default()).unwrap(), - Some(hex!("bb0c2ef6e1d36d5490f9766cfcc7dfe2a6ca804504c3bb206053890d6dd02376").into()), + ext.storage_changes_root(&H256::default().encode()).unwrap(), + Some(hex!("bb0c2ef6e1d36d5490f9766cfcc7dfe2a6ca804504c3bb206053890d6dd02376").to_vec()), ); } @@ -599,8 +726,93 @@ mod tests { let backend = TestBackend::default(); let mut ext = TestExt::new(&mut overlay, &backend, Some(&storage), None); assert_eq!( - ext.storage_changes_root(Default::default()).unwrap(), - Some(hex!("96f5aae4690e7302737b6f9b7f8567d5bbb9eac1c315f80101235a92d9ec27f4").into()), + ext.storage_changes_root(&H256::default().encode()).unwrap(), + Some(hex!("96f5aae4690e7302737b6f9b7f8567d5bbb9eac1c315f80101235a92d9ec27f4").to_vec()), ); } + + #[test] + fn next_storage_key_works() { + let mut overlay = OverlayedChanges::default(); + overlay.set_storage(vec![20], None); + overlay.set_storage(vec![30], Some(vec![31])); + let backend = Storage { + top: map![ + vec![10] => vec![10], + vec![20] => vec![20], + vec![40] => vec![40] + ], + children: map![] + }.into(); + + let ext = TestExt::new(&mut overlay, &backend, None, None); + + // next_backend < next_overlay + assert_eq!(ext.next_storage_key(&[5]), Some(vec![10])); + + // next_backend == next_overlay but next_overlay is a delete + assert_eq!(ext.next_storage_key(&[10]), Some(vec![30])); + + // next_overlay < next_backend + assert_eq!(ext.next_storage_key(&[20]), Some(vec![30])); + + // next_backend exist but next_overlay doesn't exist + assert_eq!(ext.next_storage_key(&[30]), Some(vec![40])); + + drop(ext); + overlay.set_storage(vec![50], Some(vec![50])); + let ext = TestExt::new(&mut overlay, &backend, None, None); + + // next_overlay exist but next_backend doesn't exist + assert_eq!(ext.next_storage_key(&[40]), Some(vec![50])); + } + + #[test] + fn next_child_storage_key_works() { + const CHILD_KEY_1: &[u8] = b":child_storage:default:Child1"; + + const CHILD_UUID_1: &[u8] = b"unique_id_1"; + const CHILD_INFO_1: ChildInfo<'static> = ChildInfo::new_default(CHILD_UUID_1); + + + let child = || ChildStorageKey::from_slice(CHILD_KEY_1).unwrap(); + let mut overlay = OverlayedChanges::default(); + overlay.set_child_storage(child().as_ref().to_vec(), CHILD_INFO_1, vec![20], None); + overlay.set_child_storage(child().as_ref().to_vec(), CHILD_INFO_1, vec![30], Some(vec![31])); + let backend = Storage { + top: map![], + children: map![ + child().as_ref().to_vec() => StorageChild { + data: map![ + vec![10] => vec![10], + vec![20] => vec![20], + vec![40] => vec![40] + ], + child_info: CHILD_INFO_1.to_owned(), + } + ], + }.into(); + + + let ext = TestExt::new(&mut overlay, &backend, None, None); + + // next_backend < next_overlay + assert_eq!(ext.next_child_storage_key(child(), CHILD_INFO_1, &[5]), Some(vec![10])); + + // next_backend == next_overlay but next_overlay is a delete + assert_eq!(ext.next_child_storage_key(child(), CHILD_INFO_1, &[10]), Some(vec![30])); + + // next_overlay < next_backend + assert_eq!(ext.next_child_storage_key(child(), CHILD_INFO_1, &[20]), Some(vec![30])); + + // next_backend exist but next_overlay doesn't exist + assert_eq!(ext.next_child_storage_key(child(), CHILD_INFO_1, &[30]), Some(vec![40])); + + drop(ext); + overlay.set_child_storage(child().as_ref().to_vec(), CHILD_INFO_1, vec![50], Some(vec![50])); + let ext = TestExt::new(&mut overlay, &backend, None, None); + + // next_overlay exist but next_backend doesn't exist + assert_eq!(ext.next_child_storage_key(child(), CHILD_INFO_1, &[40]), Some(vec![50])); + } } diff --git a/primitives/state-machine/src/lib.rs b/primitives/state-machine/src/lib.rs index 9095be1877b37b972d3ee5df5d50e86eeb94ad29..86cae2dfbbcaf64737b7911a72f9d9839fc11870 100644 --- a/primitives/state-machine/src/lib.rs +++ b/primitives/state-machine/src/lib.rs @@ -21,13 +21,13 @@ use std::{fmt, result, collections::HashMap, panic::UnwindSafe, marker::PhantomData}; use log::{warn, trace}; use hash_db::Hasher; -use codec::{Decode, Encode}; -use primitives::{ - storage::well_known_keys, NativeOrEncoded, NeverNativeValue, - traits::{KeystoreExt, CodeExecutor}, hexdisplay::HexDisplay, hash::H256, +use codec::{Decode, Encode, Codec}; +use sp_core::{ + storage::{well_known_keys, ChildInfo}, NativeOrEncoded, NeverNativeValue, + traits::CodeExecutor, hexdisplay::HexDisplay, hash::H256, }; use overlayed_changes::OverlayedChangeSet; -use externalities::Extensions; +use sp_externalities::Extensions; pub mod backend; mod changes_trie; @@ -40,7 +40,7 @@ mod proving_backend; mod trie_backend; mod trie_backend_essence; -pub use trie::{trie_types::{Layout, TrieDBMut}, TrieMut, DBValue, MemoryDB}; +pub use sp_trie::{trie_types::{Layout, TrieDBMut}, TrieMut, DBValue, MemoryDB}; pub use testing::TestExternalities; pub use basic::BasicExternalities; pub use ext::Ext; @@ -424,7 +424,7 @@ impl<'a, B, H, N, T, Exec> StateMachine<'a, B, H, N, T, Exec> where ExecutionManager::AlwaysWasm(trust_level) => { let _abort_guard = match trust_level { BackendTrustLevel::Trusted => None, - BackendTrustLevel::Untrusted => Some(panic_handler::AbortGuard::never_abort()), + BackendTrustLevel::Untrusted => Some(sp_panic_handler::AbortGuard::never_abort()), }; let res = self.execute_aux(compute_tx, false, native_call); (res.0, res.2, res.3) @@ -452,7 +452,6 @@ pub fn prove_execution( exec: &Exec, method: &str, call_data: &[u8], - keystore: Option, ) -> Result<(Vec, StorageProof), Box> where B: Backend, @@ -461,7 +460,7 @@ where { let trie_backend = backend.as_trie_backend() .ok_or_else(|| Box::new(ExecutionError::UnableToGenerateProof) as Box)?; - prove_execution_on_trie_backend(trie_backend, overlay, exec, method, call_data, keystore) + prove_execution_on_trie_backend(trie_backend, overlay, exec, method, call_data) } /// Prove execution using the given trie backend, overlayed changes, and call executor. @@ -479,7 +478,6 @@ pub fn prove_execution_on_trie_backend( exec: &Exec, method: &str, call_data: &[u8], - keystore: Option, ) -> Result<(Vec, StorageProof), Box> where S: trie_backend_essence::TrieBackendStorage, @@ -487,12 +485,8 @@ where Exec: CodeExecutor, { let proving_backend = proving_backend::ProvingBackend::new(trie_backend); - let mut extensions = Extensions::new(); - if let Some(keystore) = keystore { - extensions.register(keystore); - } let mut sm = StateMachine::<_, H, _, InMemoryChangesTrieStorage, Exec>::new( - &proving_backend, None, overlay, exec, method, call_data, extensions, + &proving_backend, None, overlay, exec, method, call_data, Extensions::default(), ); let (result, _, _) = sm.execute_using_consensus_failure_handler::<_, NeverNativeValue, fn() -> _>( @@ -512,7 +506,6 @@ pub fn execution_proof_check( exec: &Exec, method: &str, call_data: &[u8], - keystore: Option, ) -> Result, Box> where H: Hasher, @@ -520,7 +513,7 @@ where H::Out: Ord + 'static, { let trie_backend = create_proof_check_backend::(root.into(), proof)?; - execution_proof_check_on_trie_backend(&trie_backend, overlay, exec, method, call_data, keystore) + execution_proof_check_on_trie_backend(&trie_backend, overlay, exec, method, call_data) } /// Check execution proof on proving backend, generated by `prove_execution` call. @@ -530,18 +523,13 @@ pub fn execution_proof_check_on_trie_backend( exec: &Exec, method: &str, call_data: &[u8], - keystore: Option, ) -> Result, Box> where H: Hasher, Exec: CodeExecutor, { - let mut extensions = Extensions::new(); - if let Some(keystore) = keystore { - extensions.register(keystore); - } let mut sm = StateMachine::<_, H, _, InMemoryChangesTrieStorage, Exec>::new( - trie_backend, None, overlay, exec, method, call_data, extensions, + trie_backend, None, overlay, exec, method, call_data, Extensions::default(), ); sm.execute_using_consensus_failure_handler::<_, NeverNativeValue, fn() -> _>( @@ -574,18 +562,19 @@ where pub fn prove_child_read( mut backend: B, storage_key: &[u8], + child_info: ChildInfo, keys: I, ) -> Result> where B: Backend, H: Hasher, - H::Out: Ord, + H::Out: Ord + Codec, I: IntoIterator, I::Item: AsRef<[u8]>, { let trie_backend = backend.as_trie_backend() .ok_or_else(|| Box::new(ExecutionError::UnableToGenerateProof) as Box)?; - prove_child_read_on_trie_backend(trie_backend, storage_key, keys) + prove_child_read_on_trie_backend(trie_backend, storage_key, child_info, keys) } /// Generate storage read proof on pre-created trie backend. @@ -596,7 +585,7 @@ pub fn prove_read_on_trie_backend( where S: trie_backend_essence::TrieBackendStorage, H: Hasher, - H::Out: Ord, + H::Out: Ord + Codec, I: IntoIterator, I::Item: AsRef<[u8]>, { @@ -613,19 +602,20 @@ where pub fn prove_child_read_on_trie_backend( trie_backend: &TrieBackend, storage_key: &[u8], + child_info: ChildInfo, keys: I, ) -> Result> where S: trie_backend_essence::TrieBackendStorage, H: Hasher, - H::Out: Ord, + H::Out: Ord + Codec, I: IntoIterator, I::Item: AsRef<[u8]>, { let proving_backend = proving_backend::ProvingBackend::<_, H>::new(trie_backend); for key in keys.into_iter() { proving_backend - .child_storage(storage_key, key.as_ref()) + .child_storage(storage_key, child_info.clone(), key.as_ref()) .map_err(|e| Box::new(e) as Box)?; } Ok(proving_backend.extract_proof()) @@ -639,7 +629,7 @@ pub fn read_proof_check( ) -> Result, Option>>, Box> where H: Hasher, - H::Out: Ord, + H::Out: Ord + Codec, I: IntoIterator, I::Item: AsRef<[u8]>, { @@ -661,7 +651,7 @@ pub fn read_child_proof_check( ) -> Result, Option>>, Box> where H: Hasher, - H::Out: Ord, + H::Out: Ord + Codec, I: IntoIterator, I::Item: AsRef<[u8]>, { @@ -685,7 +675,7 @@ pub fn read_proof_check_on_proving_backend( ) -> Result>, Box> where H: Hasher, - H::Out: Ord, + H::Out: Ord + Codec, { proving_backend.storage(key).map_err(|e| Box::new(e) as Box) } @@ -698,9 +688,11 @@ pub fn read_child_proof_check_on_proving_backend( ) -> Result>, Box> where H: Hasher, - H::Out: Ord, + H::Out: Ord + Codec, { - proving_backend.child_storage(storage_key, key).map_err(|e| Box::new(e) as Box) + // Not a prefixed memory db, using empty unique id and include root resolution. + proving_backend.child_storage(storage_key, ChildInfo::new_default(&[]), key) + .map_err(|e| Box::new(e) as Box) } /// Sets overlayed changes' changes trie configuration. Returns error if configuration @@ -743,7 +735,7 @@ fn try_read_overlay_value( #[cfg(test)] mod tests { - use std::collections::HashMap; + use std::collections::BTreeMap; use codec::Encode; use overlayed_changes::OverlayedValue; use super::*; @@ -753,7 +745,7 @@ mod tests { InMemoryStorage as InMemoryChangesTrieStorage, Configuration as ChangesTrieConfig, }; - use primitives::{Blake2Hasher, map, traits::Externalities, storage::ChildStorageKey}; + use sp_core::{Blake2Hasher, map, traits::Externalities, storage::ChildStorageKey}; struct DummyCodeExecutor { change_changes_trie_config: bool, @@ -762,6 +754,8 @@ mod tests { fallback_succeeds: bool, } + const CHILD_INFO_1: ChildInfo<'static> = ChildInfo::new_default(b"unique_id_1"); + impl CodeExecutor for DummyCodeExecutor { type Error = u8; @@ -914,7 +908,6 @@ mod tests { &executor, "test", &[], - None, ).unwrap(); // check proof locally @@ -925,7 +918,6 @@ mod tests { &executor, "test", &[], - None, ).unwrap(); // check that both results are correct @@ -935,7 +927,7 @@ mod tests { #[test] fn clear_prefix_in_ext_works() { - let initial: HashMap<_, _> = map![ + let initial: BTreeMap<_, _> = map![ b"aaa".to_vec() => b"0".to_vec(), b"abb".to_vec() => b"1".to_vec(), b"abc".to_vec() => b"2".to_vec(), @@ -996,22 +988,26 @@ mod tests { ext.set_child_storage( ChildStorageKey::from_slice(b":child_storage:default:testchild").unwrap(), + CHILD_INFO_1, b"abc".to_vec(), b"def".to_vec() ); assert_eq!( ext.child_storage( ChildStorageKey::from_slice(b":child_storage:default:testchild").unwrap(), + CHILD_INFO_1, b"abc" ), Some(b"def".to_vec()) ); ext.kill_child_storage( - ChildStorageKey::from_slice(b":child_storage:default:testchild").unwrap() + ChildStorageKey::from_slice(b":child_storage:default:testchild").unwrap(), + CHILD_INFO_1, ); assert_eq!( ext.child_storage( ChildStorageKey::from_slice(b":child_storage:default:testchild").unwrap(), + CHILD_INFO_1, b"abc" ), None @@ -1047,6 +1043,7 @@ mod tests { let remote_proof = prove_child_read( remote_backend, b":child_storage:default:sub1", + CHILD_INFO_1, &[b"value3"], ).unwrap(); let local_result1 = read_child_proof_check::( @@ -1095,6 +1092,40 @@ mod tests { assert!(state_machine.execute(ExecutionStrategy::NativeWhenPossible).is_err()); } + #[test] + fn child_storage_uuid() { + const CHILD_INFO_1: ChildInfo<'static> = ChildInfo::new_default(b"unique_id_1"); + const CHILD_INFO_2: ChildInfo<'static> = ChildInfo::new_default(b"unique_id_2"); + use crate::trie_backend::tests::test_trie; + let mut overlay = OverlayedChanges::default(); + + let subtrie1 = ChildStorageKey::from_slice(b":child_storage:default:sub_test1").unwrap(); + let subtrie2 = ChildStorageKey::from_slice(b":child_storage:default:sub_test2").unwrap(); + let mut transaction = { + let backend = test_trie(); + let changes_trie_storage = InMemoryChangesTrieStorage::::new(); + let mut ext = Ext::new( + &mut overlay, + &backend, + Some(&changes_trie_storage), + None, + ); + ext.set_child_storage(subtrie1, CHILD_INFO_1, b"abc".to_vec(), b"def".to_vec()); + ext.set_child_storage(subtrie2, CHILD_INFO_2, b"abc".to_vec(), b"def".to_vec()); + ext.storage_root(); + (ext.transaction().0).0 + }; + let mut duplicate = false; + for (k, (value, rc)) in transaction.drain().iter() { + // look for a key inserted twice: transaction rc is 2 + if *rc == 2 { + duplicate = true; + println!("test duplicate for {:?} {:?}", k, value); + } + } + assert!(!duplicate); + } + #[test] fn cannot_change_changes_trie_config_with_native_else_wasm() { let backend = trie_backend::tests::test_trie(); diff --git a/primitives/state-machine/src/overlayed_changes.rs b/primitives/state-machine/src/overlayed_changes.rs index 73cb8b604a1c267133551f51a52e4bccda26a229..f4e0de504547871e9c686241247807e1f907b0ea 100644 --- a/primitives/state-machine/src/overlayed_changes.rs +++ b/primitives/state-machine/src/overlayed_changes.rs @@ -18,10 +18,11 @@ #[cfg(test)] use std::iter::FromIterator; -use std::collections::{HashMap, BTreeSet}; +use std::collections::{HashMap, BTreeMap, BTreeSet}; use codec::Decode; use crate::changes_trie::{NO_EXTRINSIC_INDEX, Configuration as ChangesTrieConfig}; -use primitives::storage::well_known_keys::EXTRINSIC_INDEX; +use sp_core::storage::{well_known_keys::EXTRINSIC_INDEX, OwnedChildInfo, ChildInfo}; +use std::{mem, ops}; /// The overlayed changes to state to be queried on top of the backend. /// @@ -54,9 +55,9 @@ pub struct OverlayedValue { #[cfg_attr(test, derive(PartialEq))] pub struct OverlayedChangeSet { /// Top level storage changes. - pub top: HashMap, OverlayedValue>, + pub top: BTreeMap, OverlayedValue>, /// Child storage changes. - pub children: HashMap, HashMap, OverlayedValue>>, + pub children: HashMap, (BTreeMap, OverlayedValue>, OwnedChildInfo)>, } #[cfg(test)] @@ -118,13 +119,13 @@ impl OverlayedChanges { /// value has been set. pub fn child_storage(&self, storage_key: &[u8], key: &[u8]) -> Option> { if let Some(map) = self.prospective.children.get(storage_key) { - if let Some(val) = map.get(key) { + if let Some(val) = map.0.get(key) { return Some(val.value.as_ref().map(AsRef::as_ref)); } } if let Some(map) = self.committed.children.get(storage_key) { - if let Some(val) = map.get(key) { + if let Some(val) = map.0.get(key) { return Some(val.value.as_ref().map(AsRef::as_ref)); } } @@ -149,10 +150,20 @@ impl OverlayedChanges { /// Inserts the given key-value pair into the prospective child change set. /// /// `None` can be used to delete a value specified by the given key. - pub(crate) fn set_child_storage(&mut self, storage_key: Vec, key: Vec, val: Option>) { + pub(crate) fn set_child_storage( + &mut self, + storage_key: Vec, + child_info: ChildInfo, + key: Vec, + val: Option>, + ) { let extrinsic_index = self.extrinsic_index(); - let map_entry = self.prospective.children.entry(storage_key).or_default(); - let entry = map_entry.entry(key).or_default(); + let map_entry = self.prospective.children.entry(storage_key) + .or_insert_with(|| (Default::default(), child_info.to_owned())); + let updatable = map_entry.1.try_update(child_info); + debug_assert!(updatable); + + let entry = map_entry.0.entry(key).or_default(); entry.value = val; if let Some(extrinsic) = extrinsic_index { @@ -167,11 +178,18 @@ impl OverlayedChanges { /// change set, and still can be reverted by [`discard_prospective`]. /// /// [`discard_prospective`]: #method.discard_prospective - pub(crate) fn clear_child_storage(&mut self, storage_key: &[u8]) { + pub(crate) fn clear_child_storage( + &mut self, + storage_key: &[u8], + child_info: ChildInfo, + ) { let extrinsic_index = self.extrinsic_index(); - let map_entry = self.prospective.children.entry(storage_key.to_vec()).or_default(); + let map_entry = self.prospective.children.entry(storage_key.to_vec()) + .or_insert_with(|| (Default::default(), child_info.to_owned())); + let updatable = map_entry.1.try_update(child_info); + debug_assert!(updatable); - map_entry.values_mut().for_each(|e| { + map_entry.0.values_mut().for_each(|e| { if let Some(extrinsic) = extrinsic_index { e.extrinsics.get_or_insert_with(Default::default) .insert(extrinsic); @@ -180,10 +198,10 @@ impl OverlayedChanges { e.value = None; }); - if let Some(committed_map) = self.committed.children.get(storage_key) { + if let Some((committed_map, _child_info)) = self.committed.children.get(storage_key) { for (key, value) in committed_map.iter() { - if !map_entry.contains_key(key) { - map_entry.insert(key.clone(), OverlayedValue { + if !map_entry.0.contains_key(key) { + map_entry.0.insert(key.clone(), OverlayedValue { value: None, extrinsics: extrinsic_index.map(|i| { let mut e = value.extrinsics.clone() @@ -234,11 +252,19 @@ impl OverlayedChanges { } } - pub(crate) fn clear_child_prefix(&mut self, storage_key: &[u8], prefix: &[u8]) { + pub(crate) fn clear_child_prefix( + &mut self, + storage_key: &[u8], + child_info: ChildInfo, + prefix: &[u8], + ) { let extrinsic_index = self.extrinsic_index(); - let map_entry = self.prospective.children.entry(storage_key.to_vec()).or_default(); + let map_entry = self.prospective.children.entry(storage_key.to_vec()) + .or_insert_with(|| (Default::default(), child_info.to_owned())); + let updatable = map_entry.1.try_update(child_info); + debug_assert!(updatable); - for (key, entry) in map_entry.iter_mut() { + for (key, entry) in map_entry.0.iter_mut() { if key.starts_with(prefix) { entry.value = None; @@ -249,12 +275,12 @@ impl OverlayedChanges { } } - if let Some(child_committed) = self.committed.children.get(storage_key) { + if let Some((child_committed, _child_info)) = self.committed.children.get(storage_key) { // Then do the same with keys from commited changes. // NOTE that we are making changes in the prospective change set. for key in child_committed.keys() { if key.starts_with(prefix) { - let entry = map_entry.entry(key.clone()).or_default(); + let entry = map_entry.0.entry(key.clone()).or_default(); entry.value = None; if let Some(extrinsic) = extrinsic_index { @@ -274,9 +300,10 @@ impl OverlayedChanges { /// Commit prospective changes to state. pub fn commit_prospective(&mut self) { if self.committed.is_empty() { - ::std::mem::swap(&mut self.prospective, &mut self.committed); + mem::swap(&mut self.prospective, &mut self.committed); } else { - for (key, val) in self.prospective.top.drain() { + let top_to_commit = mem::replace(&mut self.prospective.top, BTreeMap::new()); + for (key, val) in top_to_commit.into_iter() { let entry = self.committed.top.entry(key).or_default(); entry.value = val.value; @@ -285,10 +312,12 @@ impl OverlayedChanges { .extend(prospective_extrinsics); } } - for (storage_key, mut map) in self.prospective.children.drain() { - let map_dest = self.committed.children.entry(storage_key).or_default(); - for (key, val) in map.drain() { - let entry = map_dest.entry(key).or_default(); + for (storage_key, (map, child_info)) in self.prospective.children.drain() { + let child_content = self.committed.children.entry(storage_key) + .or_insert_with(|| (Default::default(), child_info)); + // No update to child info at this point (will be needed for deletion). + for (key, val) in map.into_iter() { + let entry = child_content.0.entry(key).or_default(); entry.value = val.value; if let Some(prospective_extrinsics) = val.extrinsics { @@ -306,12 +335,12 @@ impl OverlayedChanges { /// Will panic if there are any uncommitted prospective changes. pub fn into_committed(self) -> ( impl Iterator, Option>)>, - impl Iterator, impl Iterator, Option>)>)>, + impl Iterator, (impl Iterator, Option>)>, OwnedChildInfo))>, ){ assert!(self.prospective.is_empty()); (self.committed.top.into_iter().map(|(k, v)| (k, v.value)), self.committed.children.into_iter() - .map(|(sk, v)| (sk, v.into_iter().map(|(k, v)| (k, v.value))))) + .map(|(sk, (v, ci))| (sk, (v.into_iter().map(|(k, v)| (k, v.value)), ci)))) } /// Inserts storage entry responsible for current extrinsic index. @@ -339,6 +368,68 @@ impl OverlayedChanges { false => None, } } + + /// Get child info for a storage key. + /// Take the latest value so prospective first. + pub fn child_info(&self, storage_key: &[u8]) -> Option<&OwnedChildInfo> { + if let Some((_, ci)) = self.prospective.children.get(storage_key) { + return Some(&ci); + } + if let Some((_, ci)) = self.committed.children.get(storage_key) { + return Some(&ci); + } + None + } + + /// Returns the next (in lexicographic order) storage key in the overlayed alongside its value. + /// If no value is next then `None` is returned. + pub fn next_storage_key_change(&self, key: &[u8]) -> Option<(&[u8], &OverlayedValue)> { + let range = (ops::Bound::Excluded(key), ops::Bound::Unbounded); + + let next_prospective_key = self.prospective.top + .range::<[u8], _>(range) + .next() + .map(|(k, v)| (&k[..], v)); + + let next_committed_key = self.committed.top + .range::<[u8], _>(range) + .next() + .map(|(k, v)| (&k[..], v)); + + match (next_committed_key, next_prospective_key) { + // Committed is strictly less than prospective + (Some(committed_key), Some(prospective_key)) if committed_key.0 < prospective_key.0 => + Some(committed_key), + (committed_key, None) => committed_key, + // Prospective key is less or equal to committed or committed doesn't exist + (_, prospective_key) => prospective_key, + } + } + + /// Returns the next (in lexicographic order) child storage key in the overlayed alongside its + /// value. If no value is next then `None` is returned. + pub fn next_child_storage_key_change( + &self, + storage_key: &[u8], + key: &[u8] + ) -> Option<(&[u8], &OverlayedValue)> { + let range = (ops::Bound::Excluded(key), ops::Bound::Unbounded); + + let next_prospective_key = self.prospective.children.get(storage_key) + .and_then(|(map, _)| map.range::<[u8], _>(range).next().map(|(k, v)| (&k[..], v))); + + let next_committed_key = self.committed.children.get(storage_key) + .and_then(|(map, _)| map.range::<[u8], _>(range).next().map(|(k, v)| (&k[..], v))); + + match (next_committed_key, next_prospective_key) { + // Committed is strictly less than prospective + (Some(committed_key), Some(prospective_key)) if committed_key.0 < prospective_key.0 => + Some(committed_key), + (committed_key, None) => committed_key, + // Prospective key is less or equal to committed or committed doesn't exist + (_, prospective_key) => prospective_key, + } + } } #[cfg(test)] @@ -351,16 +442,16 @@ impl From>> for OverlayedValue { #[cfg(test)] mod tests { use hex_literal::hex; - use primitives::{ - Blake2Hasher, H256, traits::Externalities, storage::well_known_keys::EXTRINSIC_INDEX, + use sp_core::{ + Blake2Hasher, traits::Externalities, storage::well_known_keys::EXTRINSIC_INDEX, }; use crate::backend::InMemory; use crate::changes_trie::InMemoryStorage as InMemoryChangesTrieStorage; use crate::ext::Ext; use super::*; - fn strip_extrinsic_index(map: &HashMap, OverlayedValue>) - -> HashMap, OverlayedValue> + fn strip_extrinsic_index(map: &BTreeMap, OverlayedValue>) + -> BTreeMap, OverlayedValue> { let mut clone = map.clone(); clone.remove(&EXTRINSIC_INDEX.to_vec()); @@ -397,7 +488,7 @@ mod tests { #[test] fn overlayed_storage_root_works() { - let initial: HashMap<_, _> = vec![ + let initial: BTreeMap<_, _> = vec![ (b"doe".to_vec(), b"reindeer".to_vec()), (b"dog".to_vec(), b"puppyXXX".to_vec()), (b"dogglesworth".to_vec(), b"catXXX".to_vec()), @@ -426,7 +517,7 @@ mod tests { ); const ROOT: [u8; 32] = hex!("39245109cef3758c2eed2ccba8d9b370a917850af3824bc8348d505df2c298fa"); - assert_eq!(ext.storage_root(), H256::from(ROOT)); + assert_eq!(&ext.storage_root()[..], &ROOT); } #[test] @@ -543,4 +634,80 @@ mod tests { assert_eq!(overlay.prospective, Default::default()); } + + #[test] + fn next_storage_key_change_works() { + let mut overlay = OverlayedChanges::default(); + overlay.set_storage(vec![20], Some(vec![20])); + overlay.set_storage(vec![30], Some(vec![30])); + overlay.set_storage(vec![40], Some(vec![40])); + overlay.commit_prospective(); + overlay.set_storage(vec![10], Some(vec![10])); + overlay.set_storage(vec![30], None); + + // next_prospective < next_committed + let next_to_5 = overlay.next_storage_key_change(&[5]).unwrap(); + assert_eq!(next_to_5.0.to_vec(), vec![10]); + assert_eq!(next_to_5.1.value, Some(vec![10])); + + // next_committed < next_prospective + let next_to_10 = overlay.next_storage_key_change(&[10]).unwrap(); + assert_eq!(next_to_10.0.to_vec(), vec![20]); + assert_eq!(next_to_10.1.value, Some(vec![20])); + + // next_committed == next_prospective + let next_to_20 = overlay.next_storage_key_change(&[20]).unwrap(); + assert_eq!(next_to_20.0.to_vec(), vec![30]); + assert_eq!(next_to_20.1.value, None); + + // next_committed, no next_prospective + let next_to_30 = overlay.next_storage_key_change(&[30]).unwrap(); + assert_eq!(next_to_30.0.to_vec(), vec![40]); + assert_eq!(next_to_30.1.value, Some(vec![40])); + + overlay.set_storage(vec![50], Some(vec![50])); + // next_prospective, no next_committed + let next_to_40 = overlay.next_storage_key_change(&[40]).unwrap(); + assert_eq!(next_to_40.0.to_vec(), vec![50]); + assert_eq!(next_to_40.1.value, Some(vec![50])); + } + + #[test] + fn next_child_storage_key_change_works() { + let child = b"Child1".to_vec(); + let child_info = ChildInfo::new_default(b"uniqueid"); + let mut overlay = OverlayedChanges::default(); + overlay.set_child_storage(child.clone(), child_info, vec![20], Some(vec![20])); + overlay.set_child_storage(child.clone(), child_info, vec![30], Some(vec![30])); + overlay.set_child_storage(child.clone(), child_info, vec![40], Some(vec![40])); + overlay.commit_prospective(); + overlay.set_child_storage(child.clone(), child_info, vec![10], Some(vec![10])); + overlay.set_child_storage(child.clone(), child_info, vec![30], None); + + // next_prospective < next_committed + let next_to_5 = overlay.next_child_storage_key_change(&child, &[5]).unwrap(); + assert_eq!(next_to_5.0.to_vec(), vec![10]); + assert_eq!(next_to_5.1.value, Some(vec![10])); + + // next_committed < next_prospective + let next_to_10 = overlay.next_child_storage_key_change(&child, &[10]).unwrap(); + assert_eq!(next_to_10.0.to_vec(), vec![20]); + assert_eq!(next_to_10.1.value, Some(vec![20])); + + // next_committed == next_prospective + let next_to_20 = overlay.next_child_storage_key_change(&child, &[20]).unwrap(); + assert_eq!(next_to_20.0.to_vec(), vec![30]); + assert_eq!(next_to_20.1.value, None); + + // next_committed, no next_prospective + let next_to_30 = overlay.next_child_storage_key_change(&child, &[30]).unwrap(); + assert_eq!(next_to_30.0.to_vec(), vec![40]); + assert_eq!(next_to_30.1.value, Some(vec![40])); + + overlay.set_child_storage(child.clone(), child_info, vec![50], Some(vec![50])); + // next_prospective, no next_committed + let next_to_40 = overlay.next_child_storage_key_change(&child, &[40]).unwrap(); + assert_eq!(next_to_40.0.to_vec(), vec![50]); + assert_eq!(next_to_40.1.value, Some(vec![50])); + } } diff --git a/primitives/state-machine/src/proving_backend.rs b/primitives/state-machine/src/proving_backend.rs index 2ebd82f0c43c0d104081e5fa08bfd256ead0b2af..92ad2047a5e5327ad0be2c0753fdaca41f109f52 100644 --- a/primitives/state-machine/src/proving_backend.rs +++ b/primitives/state-machine/src/proving_backend.rs @@ -18,20 +18,21 @@ use std::sync::Arc; use parking_lot::RwLock; -use codec::{Decode, Encode}; +use codec::{Decode, Encode, Codec}; use log::debug; use hash_db::{Hasher, HashDB, EMPTY_PREFIX, Prefix}; -use trie::{ +use sp_trie::{ MemoryDB, PrefixedMemoryDB, default_child_trie_root, read_trie_value_with, read_child_trie_value_with, record_all_keys }; -pub use trie::Recorder; -pub use trie::trie_types::{Layout, TrieError}; +pub use sp_trie::Recorder; +pub use sp_trie::trie_types::{Layout, TrieError}; use crate::trie_backend::TrieBackend; use crate::trie_backend_essence::{Ephemeral, TrieBackendEssence, TrieBackendStorage}; use crate::{Error, ExecutionError, Backend}; use std::collections::{HashMap, HashSet}; use crate::DBValue; +use sp_core::storage::ChildInfo; /// Patricia trie-based backend specialized in get value proofs. pub struct ProvingBackendRecorder<'a, S: 'a + TrieBackendStorage, H: 'a + Hasher> { @@ -119,6 +120,7 @@ impl<'a, S, H> ProvingBackendRecorder<'a, S, H> where S: TrieBackendStorage, H: Hasher, + H::Out: Codec, { /// Produce proof for a key query. pub fn storage(&mut self, key: &[u8]) -> Result>, String> { @@ -142,9 +144,11 @@ impl<'a, S, H> ProvingBackendRecorder<'a, S, H> pub fn child_storage( &mut self, storage_key: &[u8], + child_info: ChildInfo, key: &[u8] ) -> Result>, String> { let root = self.storage(storage_key)? + .and_then(|r| Decode::decode(&mut &r[..]).ok()) .unwrap_or(default_child_trie_root::>(storage_key)); let mut read_overlay = S::Overlay::default(); @@ -157,8 +161,9 @@ impl<'a, S, H> ProvingBackendRecorder<'a, S, H> read_child_trie_value_with::, _, _>( storage_key, + child_info.keyspace(), &eph, - &root, + &root.as_ref(), key, &mut *self.proof_recorder ).map_err(map_e) @@ -199,7 +204,9 @@ pub struct ProofRecorderBackend<'a, S: 'a + TrieBackendStorage, H: 'a + Hashe proof_recorder: ProofRecorder, } -impl<'a, S: 'a + TrieBackendStorage, H: 'a + Hasher> ProvingBackend<'a, S, H> { +impl<'a, S: 'a + TrieBackendStorage, H: 'a + Hasher> ProvingBackend<'a, S, H> + where H::Out: Codec +{ /// Create new proving backend. pub fn new(backend: &'a TrieBackend) -> Self { let proof_recorder = Default::default(); @@ -254,7 +261,7 @@ impl<'a, S, H> Backend for ProvingBackend<'a, S, H> where S: 'a + TrieBackendStorage, H: 'a + Hasher, - H::Out: Ord, + H::Out: Ord + Codec, { type Error = String; type Transaction = S::Overlay; @@ -264,12 +271,35 @@ impl<'a, S, H> Backend for ProvingBackend<'a, S, H> self.0.storage(key) } - fn child_storage(&self, storage_key: &[u8], key: &[u8]) -> Result>, Self::Error> { - self.0.child_storage(storage_key, key) + fn child_storage( + &self, + storage_key: &[u8], + child_info: ChildInfo, + key: &[u8], + ) -> Result>, Self::Error> { + self.0.child_storage(storage_key, child_info, key) } - fn for_keys_in_child_storage(&self, storage_key: &[u8], f: F) { - self.0.for_keys_in_child_storage(storage_key, f) + fn for_keys_in_child_storage( + &self, + storage_key: &[u8], + child_info: ChildInfo, + f: F, + ) { + self.0.for_keys_in_child_storage(storage_key, child_info, f) + } + + fn next_storage_key(&self, key: &[u8]) -> Result>, Self::Error> { + self.0.next_storage_key(key) + } + + fn next_child_storage_key( + &self, + storage_key: &[u8], + child_info: ChildInfo, + key: &[u8], + ) -> Result>, Self::Error> { + self.0.next_child_storage_key(storage_key, child_info, key) } fn for_keys_with_prefix(&self, prefix: &[u8], f: F) { @@ -280,8 +310,14 @@ impl<'a, S, H> Backend for ProvingBackend<'a, S, H> self.0.for_key_values_with_prefix(prefix, f) } - fn for_child_keys_with_prefix(&self, storage_key: &[u8], prefix: &[u8], f: F) { - self.0.for_child_keys_with_prefix(storage_key, prefix, f) + fn for_child_keys_with_prefix( + &self, + storage_key: &[u8], + child_info: ChildInfo, + prefix: &[u8], + f: F, + ) { + self.0.for_child_keys_with_prefix(storage_key, child_info, prefix, f) } fn pairs(&self) -> Vec<(Vec, Vec)> { @@ -292,8 +328,13 @@ impl<'a, S, H> Backend for ProvingBackend<'a, S, H> self.0.keys(prefix) } - fn child_keys(&self, child_storage_key: &[u8], prefix: &[u8]) -> Vec> { - self.0.child_keys(child_storage_key, prefix) + fn child_keys( + &self, + storage_key: &[u8], + child_info: ChildInfo, + prefix: &[u8], + ) -> Vec> { + self.0.child_keys(storage_key, child_info, prefix) } fn storage_root(&self, delta: I) -> (H::Out, Self::Transaction) @@ -302,12 +343,17 @@ impl<'a, S, H> Backend for ProvingBackend<'a, S, H> self.0.storage_root(delta) } - fn child_storage_root(&self, storage_key: &[u8], delta: I) -> (Vec, bool, Self::Transaction) + fn child_storage_root( + &self, + storage_key: &[u8], + child_info: ChildInfo, + delta: I, + ) -> (H::Out, bool, Self::Transaction) where I: IntoIterator, Option>)>, H::Out: Ord { - self.0.child_storage_root(storage_key, delta) + self.0.child_storage_root(storage_key, child_info, delta) } } @@ -318,6 +364,7 @@ pub fn create_proof_check_backend( ) -> Result, H>, Box> where H: Hasher, + H::Out: Codec, { let db = create_proof_check_backend_storage(proof); @@ -347,9 +394,12 @@ mod tests { use crate::backend::{InMemory}; use crate::trie_backend::tests::test_trie; use super::*; - use primitives::{Blake2Hasher, storage::ChildStorageKey}; + use sp_core::{Blake2Hasher, storage::ChildStorageKey}; use crate::proving_backend::create_proof_check_backend; + const CHILD_INFO_1: ChildInfo<'static> = ChildInfo::new_default(b"unique_id_1"); + const CHILD_INFO_2: ChildInfo<'static> = ChildInfo::new_default(b"unique_id_2"); + fn test_proving<'a>( trie_backend: &'a TrieBackend,Blake2Hasher>, ) -> ProvingBackend<'a, PrefixedMemoryDB, Blake2Hasher> { @@ -372,7 +422,7 @@ mod tests { #[test] fn proof_is_invalid_when_does_not_contains_root() { - use primitives::H256; + use sp_core::H256; let result = create_proof_check_backend::( H256::from_low_u64_be(1), StorageProof::empty() @@ -395,9 +445,9 @@ mod tests { #[test] fn proof_recorded_and_checked() { - let contents = (0..64).map(|i| (None, vec![i], Some(vec![i]))).collect::>(); + let contents = (0..64).map(|i| (vec![i], Some(vec![i]))).collect::>(); let in_memory = InMemory::::default(); - let mut in_memory = in_memory.update(contents); + let mut in_memory = in_memory.update(vec![(None, contents)]); let in_memory_root = in_memory.storage_root(::std::iter::empty()).0; (0..64).for_each(|i| assert_eq!(in_memory.storage(&[i]).unwrap().unwrap(), vec![i])); @@ -421,26 +471,29 @@ mod tests { let subtrie2 = ChildStorageKey::from_slice(b":child_storage:default:sub2").unwrap(); let own1 = subtrie1.into_owned(); let own2 = subtrie2.into_owned(); - let contents = (0..64).map(|i| (None, vec![i], Some(vec![i]))) - .chain((28..65).map(|i| (Some(own1.clone()), vec![i], Some(vec![i])))) - .chain((10..15).map(|i| (Some(own2.clone()), vec![i], Some(vec![i])))) - .collect::>(); + let contents = vec![ + (None, (0..64).map(|i| (vec![i], Some(vec![i]))).collect()), + (Some((own1.clone(), CHILD_INFO_1.to_owned())), + (28..65).map(|i| (vec![i], Some(vec![i]))).collect()), + (Some((own2.clone(), CHILD_INFO_2.to_owned())), + (10..15).map(|i| (vec![i], Some(vec![i]))).collect()), + ]; let in_memory = InMemory::::default(); let mut in_memory = in_memory.update(contents); let in_memory_root = in_memory.full_storage_root::<_, Vec<_>, _>( ::std::iter::empty(), - in_memory.child_storage_keys().map(|k|(k.to_vec(), Vec::new())) + in_memory.child_storage_keys().map(|k|(k.0.to_vec(), Vec::new(), k.1.to_owned())) ).0; (0..64).for_each(|i| assert_eq!( in_memory.storage(&[i]).unwrap().unwrap(), vec![i] )); (28..65).for_each(|i| assert_eq!( - in_memory.child_storage(&own1[..], &[i]).unwrap().unwrap(), + in_memory.child_storage(&own1[..], CHILD_INFO_1, &[i]).unwrap().unwrap(), vec![i] )); (10..15).for_each(|i| assert_eq!( - in_memory.child_storage(&own2[..], &[i]).unwrap().unwrap(), + in_memory.child_storage(&own2[..], CHILD_INFO_2, &[i]).unwrap().unwrap(), vec![i] )); @@ -468,7 +521,7 @@ mod tests { assert_eq!(proof_check.storage(&[64]).unwrap(), None); let proving = ProvingBackend::new(trie); - assert_eq!(proving.child_storage(&own1[..], &[64]), Ok(Some(vec![64]))); + assert_eq!(proving.child_storage(&own1[..], CHILD_INFO_1, &[64]), Ok(Some(vec![64]))); let proof = proving.extract_proof(); let proof_check = create_proof_check_backend::( @@ -476,7 +529,7 @@ mod tests { proof ).unwrap(); assert_eq!( - proof_check.child_storage(&own1[..], &[64]).unwrap().unwrap(), + proof_check.child_storage(&own1[..], CHILD_INFO_1, &[64]).unwrap().unwrap(), vec![64] ); } diff --git a/primitives/state-machine/src/testing.rs b/primitives/state-machine/src/testing.rs index 61b338bc81acd2fe1811ec56e3eb39f6211ad6b7..7bb7e7320b07ba8dc29b6c51a00eba04751ad45f 100644 --- a/primitives/state-machine/src/testing.rs +++ b/primitives/state-machine/src/testing.rs @@ -16,7 +16,7 @@ //! Test implementation for Externalities. -use std::{collections::HashMap, any::{Any, TypeId}}; +use std::any::{Any, TypeId}; use hash_db::Hasher; use crate::{ backend::{InMemory, Backend}, OverlayedChanges, @@ -26,16 +26,15 @@ use crate::{ }, ext::Ext, }; -use primitives::{ +use sp_core::{ storage::{ - well_known_keys::{CHANGES_TRIE_CONFIG, CODE, HEAP_PAGES, is_child_storage_key} + well_known_keys::{CHANGES_TRIE_CONFIG, CODE, HEAP_PAGES, is_child_storage_key}, + Storage, }, hash::H256, Blake2Hasher, }; use codec::Encode; -use externalities::{Extensions, Extension}; - -type StorageTuple = (HashMap, Vec>, HashMap, HashMap, Vec>>); +use sp_externalities::{Extensions, Extension}; /// Simple HashMap-based Externalities impl. pub struct TestExternalities=Blake2Hasher, N: ChangesTrieBlockNumber=u64> { @@ -57,42 +56,37 @@ impl, N: ChangesTrieBlockNumber> TestExternalities { } /// Create a new instance of `TestExternalities` with storage. - pub fn new(storage: StorageTuple) -> Self { + pub fn new(storage: Storage) -> Self { Self::new_with_code(&[], storage) } /// Create a new instance of `TestExternalities` with code and storage. - pub fn new_with_code(code: &[u8], mut storage: StorageTuple) -> Self { + pub fn new_with_code(code: &[u8], mut storage: Storage) -> Self { let mut overlay = OverlayedChanges::default(); - assert!(storage.0.keys().all(|key| !is_child_storage_key(key))); - assert!(storage.1.keys().all(|key| is_child_storage_key(key))); + assert!(storage.top.keys().all(|key| !is_child_storage_key(key))); + assert!(storage.children.keys().all(|key| is_child_storage_key(key))); super::set_changes_trie_config( &mut overlay, - storage.0.get(&CHANGES_TRIE_CONFIG.to_vec()).cloned(), + storage.top.get(&CHANGES_TRIE_CONFIG.to_vec()).cloned(), false, ).expect("changes trie configuration is correct in test env; qed"); - storage.0.insert(HEAP_PAGES.to_vec(), 8u64.encode()); - storage.0.insert(CODE.to_vec(), code.to_vec()); - - let backend: HashMap<_, _> = storage.1.into_iter() - .map(|(keyspace, map)| (Some(keyspace), map)) - .chain(Some((None, storage.0)).into_iter()) - .collect(); + storage.top.insert(HEAP_PAGES.to_vec(), 8u64.encode()); + storage.top.insert(CODE.to_vec(), code.to_vec()); TestExternalities { overlay, changes_trie_storage: ChangesTrieInMemoryStorage::new(), - backend: backend.into(), + backend: storage.into(), extensions: Default::default(), } } /// Insert key/value into backend pub fn insert(&mut self, k: Vec, v: Vec) { - self.backend = self.backend.update(vec![(None, k, Some(v))]); + self.backend = self.backend.update(vec![(None, vec![(k, Some(v))])]); } /// Registers the given extension for this instance. @@ -107,19 +101,23 @@ impl, N: ChangesTrieBlockNumber> TestExternalities { /// Return a new backend with all pending value. pub fn commit_all(&self) -> InMemory { - let top = self.overlay.committed.top.clone().into_iter() + let top: Vec<_> = self.overlay.committed.top.clone().into_iter() .chain(self.overlay.prospective.top.clone().into_iter()) - .map(|(k, v)| (None, k, v.value)); + .map(|(k, v)| (k, v.value)).collect(); + let mut transaction = vec![(None, top)]; - let children = self.overlay.committed.children.clone().into_iter() + self.overlay.committed.children.clone().into_iter() .chain(self.overlay.prospective.children.clone().into_iter()) - .flat_map(|(keyspace, map)| { - map.into_iter() - .map(|(k, v)| (Some(keyspace.clone()), k, v.value)) - .collect::>() + .for_each(|(keyspace, (map, child_info))| { + transaction.push(( + Some((keyspace, child_info)), + map.into_iter() + .map(|(k, v)| (k, v.value)) + .collect::>(), + )) }); - self.backend.update(top.chain(children).collect()) + self.backend.update(transaction) } /// Execute the given closure while `self` is set as externalities. @@ -127,7 +125,7 @@ impl, N: ChangesTrieBlockNumber> TestExternalities { /// Returns the result of the given closure. pub fn execute_with(&mut self, execute: impl FnOnce() -> R) -> R { let mut ext = self.ext(); - externalities::set_and_run_with_externalities(&mut ext, execute) + sp_externalities::set_and_run_with_externalities(&mut ext, execute) } } @@ -149,13 +147,13 @@ impl, N: ChangesTrieBlockNumber> Default for TestExternaliti fn default() -> Self { Self::new(Default::default()) } } -impl, N: ChangesTrieBlockNumber> From for TestExternalities { - fn from(storage: StorageTuple) -> Self { +impl, N: ChangesTrieBlockNumber> From for TestExternalities { + fn from(storage: Storage) -> Self { Self::new(storage) } } -impl externalities::ExtensionStore for TestExternalities where +impl sp_externalities::ExtensionStore for TestExternalities where H: Hasher, N: ChangesTrieBlockNumber, { @@ -167,7 +165,7 @@ impl externalities::ExtensionStore for TestExternalities where #[cfg(test)] mod tests { use super::*; - use primitives::traits::Externalities; + use sp_core::traits::Externalities; use hex_literal::hex; #[test] @@ -178,7 +176,7 @@ mod tests { ext.set_storage(b"dog".to_vec(), b"puppy".to_vec()); ext.set_storage(b"dogglesworth".to_vec(), b"cat".to_vec()); const ROOT: [u8; 32] = hex!("2a340d3dfd52f5992c6b117e9e45f479e6da5afffafeb26ab619cf137a95aeb8"); - assert_eq!(ext.storage_root(), H256::from(ROOT)); + assert_eq!(&ext.storage_root()[..], &ROOT); } #[test] diff --git a/primitives/state-machine/src/trie_backend.rs b/primitives/state-machine/src/trie_backend.rs index 432ccf3e75f0e47319a30c12daaf3c1a03c7747f..4b48bec31b65adda7ed9848c31b4a992f11969ba 100644 --- a/primitives/state-machine/src/trie_backend.rs +++ b/primitives/state-machine/src/trie_backend.rs @@ -18,17 +18,19 @@ use log::{warn, debug}; use hash_db::Hasher; -use trie::{Trie, delta_trie_root, default_child_trie_root, child_delta_trie_root}; -use trie::trie_types::{TrieDB, TrieError, Layout}; +use sp_trie::{Trie, delta_trie_root, default_child_trie_root, child_delta_trie_root}; +use sp_trie::trie_types::{TrieDB, TrieError, Layout}; use crate::trie_backend_essence::{TrieBackendEssence, TrieBackendStorage, Ephemeral}; use crate::Backend; +use sp_core::storage::ChildInfo; +use codec::{Codec, Decode}; /// Patricia trie-based backend. Transaction type is an overlay of changes to commit. pub struct TrieBackend, H: Hasher> { essence: TrieBackendEssence, } -impl, H: Hasher> TrieBackend { +impl, H: Hasher> TrieBackend where H::Out: Codec { /// Create new trie-based backend. pub fn new(storage: S, root: H::Out) -> Self { TrieBackend { @@ -64,7 +66,7 @@ impl, H: Hasher> std::fmt::Debug for TrieBackend } impl, H: Hasher> Backend for TrieBackend where - H::Out: Ord, + H::Out: Ord + Codec, { type Error = String; type Transaction = S::Overlay; @@ -74,8 +76,26 @@ impl, H: Hasher> Backend for TrieBackend where self.essence.storage(key) } - fn child_storage(&self, storage_key: &[u8], key: &[u8]) -> Result>, Self::Error> { - self.essence.child_storage(storage_key, key) + fn child_storage( + &self, + storage_key: &[u8], + child_info: ChildInfo, + key: &[u8], + ) -> Result>, Self::Error> { + self.essence.child_storage(storage_key, child_info, key) + } + + fn next_storage_key(&self, key: &[u8]) -> Result>, Self::Error> { + self.essence.next_storage_key(key) + } + + fn next_child_storage_key( + &self, + storage_key: &[u8], + child_info: ChildInfo, + key: &[u8], + ) -> Result>, Self::Error> { + self.essence.next_child_storage_key(storage_key, child_info, key) } fn for_keys_with_prefix(&self, prefix: &[u8], f: F) { @@ -86,12 +106,23 @@ impl, H: Hasher> Backend for TrieBackend where self.essence.for_key_values_with_prefix(prefix, f) } - fn for_keys_in_child_storage(&self, storage_key: &[u8], f: F) { - self.essence.for_keys_in_child_storage(storage_key, f) + fn for_keys_in_child_storage( + &self, + storage_key: &[u8], + child_info: ChildInfo, + f: F, + ) { + self.essence.for_keys_in_child_storage(storage_key, child_info, f) } - fn for_child_keys_with_prefix(&self, storage_key: &[u8], prefix: &[u8], f: F) { - self.essence.for_child_keys_with_prefix(storage_key, prefix, f) + fn for_child_keys_with_prefix( + &self, + storage_key: &[u8], + child_info: ChildInfo, + prefix: &[u8], + f: F, + ) { + self.essence.for_child_keys_with_prefix(storage_key, child_info, prefix, f) } fn pairs(&self) -> Vec<(Vec, Vec)> { @@ -159,16 +190,22 @@ impl, H: Hasher> Backend for TrieBackend where (root, write_overlay) } - fn child_storage_root(&self, storage_key: &[u8], delta: I) -> (Vec, bool, Self::Transaction) + fn child_storage_root( + &self, + storage_key: &[u8], + child_info: ChildInfo, + delta: I, + ) -> (H::Out, bool, Self::Transaction) where I: IntoIterator, Option>)>, - H::Out: Ord + H::Out: Ord, { let default_root = default_child_trie_root::>(storage_key); let mut write_overlay = S::Overlay::default(); let mut root = match self.storage(storage_key) { - Ok(value) => value.unwrap_or(default_root.clone()), + Ok(value) => + value.and_then(|r| Decode::decode(&mut &r[..]).ok()).unwrap_or(default_root.clone()), Err(e) => { warn!(target: "trie", "Failed to read child storage root: {}", e); default_root.clone() @@ -181,10 +218,11 @@ impl, H: Hasher> Backend for TrieBackend where &mut write_overlay, ); - match child_delta_trie_root::, _, _, _, _>( + match child_delta_trie_root::, _, _, _, _, _>( storage_key, + child_info.keyspace(), &mut eph, - root.clone(), + root, delta ) { Ok(ret) => root = ret, @@ -205,15 +243,21 @@ impl, H: Hasher> Backend for TrieBackend where #[cfg(test)] pub mod tests { use std::collections::HashSet; - use primitives::{Blake2Hasher, H256}; + use sp_core::{Blake2Hasher, H256}; use codec::Encode; - use trie::{TrieMut, PrefixedMemoryDB, trie_types::TrieDBMut}; + use sp_trie::{TrieMut, PrefixedMemoryDB, trie_types::TrieDBMut, KeySpacedDBMut}; use super::*; + const CHILD_KEY_1: &[u8] = b":child_storage:default:sub1"; + + const CHILD_UUID_1: &[u8] = b"unique_id_1"; + const CHILD_INFO_1: ChildInfo<'static> = ChildInfo::new_default(CHILD_UUID_1); + fn test_db() -> (PrefixedMemoryDB, H256) { let mut root = H256::default(); let mut mdb = PrefixedMemoryDB::::default(); { + let mut mdb = KeySpacedDBMut::new(&mut mdb, CHILD_UUID_1); let mut trie = TrieDBMut::new(&mut mdb, &mut root); trie.insert(b"value3", &[142]).expect("insert failed"); trie.insert(b"value4", &[124]).expect("insert failed"); @@ -223,7 +267,7 @@ pub mod tests { let mut sub_root = Vec::new(); root.encode_to(&mut sub_root); let mut trie = TrieDBMut::new(&mut mdb, &mut root); - trie.insert(b":child_storage:default:sub1", &sub_root).expect("insert failed"); + trie.insert(CHILD_KEY_1, &sub_root[..]).expect("insert failed"); trie.insert(b"key", b"value").expect("insert failed"); trie.insert(b"value1", &[42]).expect("insert failed"); trie.insert(b"value2", &[24]).expect("insert failed"); @@ -245,6 +289,15 @@ pub mod tests { assert_eq!(test_trie().storage(b"key").unwrap(), Some(b"value".to_vec())); } + #[test] + fn read_from_child_storage_returns_some() { + let test_trie = test_trie(); + assert_eq!( + test_trie.child_storage(CHILD_KEY_1, CHILD_INFO_1, b"value3").unwrap(), + Some(vec![142u8]), + ); + } + #[test] fn read_from_storage_returns_none() { assert_eq!(test_trie().storage(b"non-existing-key").unwrap(), None); diff --git a/primitives/state-machine/src/trie_backend_essence.rs b/primitives/state-machine/src/trie_backend_essence.rs index 5a5431963448cb285489cf64150469d44f135b05..75601373edffaa4f03accd1467ea5035ee57e9d6 100644 --- a/primitives/state-machine/src/trie_backend_essence.rs +++ b/primitives/state-machine/src/trie_backend_essence.rs @@ -21,11 +21,13 @@ use std::ops::Deref; use std::sync::Arc; use log::{debug, warn}; use hash_db::{self, Hasher, EMPTY_PREFIX, Prefix}; -use trie::{Trie, MemoryDB, PrefixedMemoryDB, DBValue, +use sp_trie::{Trie, MemoryDB, PrefixedMemoryDB, DBValue, default_child_trie_root, read_trie_value, read_child_trie_value, - for_keys_in_child_trie}; -use trie::trie_types::{TrieDB, TrieError, Layout}; + for_keys_in_child_trie, KeySpacedDB}; +use sp_trie::trie_types::{TrieDB, TrieError, Layout}; use crate::backend::Consolidate; +use sp_core::storage::ChildInfo; +use codec::Encode; /// Patricia trie-based storage trait. pub trait Storage: Send + Sync { @@ -39,7 +41,7 @@ pub struct TrieBackendEssence, H: Hasher> { root: H::Out, } -impl, H: Hasher> TrieBackendEssence { +impl, H: Hasher> TrieBackendEssence where H::Out: Encode { /// Create new trie-based backend. pub fn new(storage: S, root: H::Out) -> Self { TrieBackendEssence { @@ -63,6 +65,86 @@ impl, H: Hasher> TrieBackendEssence { self.storage } + /// Return the next key in the trie i.e. the minimum key that is strictly superior to `key` in + /// lexicographic order. + pub fn next_storage_key(&self, key: &[u8]) -> Result>, String> { + self.next_storage_key_from_root(&self.root, None, key) + } + + /// Return the next key in the child trie i.e. the minimum key that is strictly superior to + /// `key` in lexicographic order. + pub fn next_child_storage_key( + &self, + storage_key: &[u8], + child_info: ChildInfo, + key: &[u8], + ) -> Result>, String> { + let child_root = match self.storage(storage_key)? { + Some(child_root) => child_root, + None => return Ok(None), + }; + + let mut hash = H::Out::default(); + + if child_root.len() != hash.as_ref().len() { + return Err(format!("Invalid child storage hash at {:?}", storage_key)); + } + // note: child_root and hash must be same size, panics otherwise. + hash.as_mut().copy_from_slice(&child_root[..]); + + self.next_storage_key_from_root(&hash, Some(child_info), key) + } + + /// Return next key from main trie or child trie by providing corresponding root. + fn next_storage_key_from_root( + &self, + root: &H::Out, + child_info: Option, + key: &[u8], + ) -> Result>, String> { + let mut read_overlay = S::Overlay::default(); + let eph = Ephemeral { + storage: &self.storage, + overlay: &mut read_overlay, + }; + let dyn_eph: &dyn hash_db::HashDBRef<_, _>; + let keyspace_eph; + if let Some(child_info) = child_info.as_ref() { + keyspace_eph = KeySpacedDB::new(&eph, child_info.keyspace()); + dyn_eph = &keyspace_eph; + } else { + dyn_eph = &eph; + } + + let trie = TrieDB::::new(dyn_eph, root) + .map_err(|e| format!("TrieDB creation error: {}", e))?; + let mut iter = trie.iter() + .map_err(|e| format!("TrieDB iteration error: {}", e))?; + + // The key just after the one given in input, basically `key++0`. + // Note: We are sure this is the next key if: + // * size of key has no limit (i.e. we can always add 0 to the path), + // * and no keys can be inserted between `key` and `key++0` (this is ensured by sp-io). + let mut potential_next_key = Vec::with_capacity(key.len() + 1); + potential_next_key.extend_from_slice(key); + potential_next_key.push(0); + + iter.seek(&potential_next_key) + .map_err(|e| format!("TrieDB iterator seek error: {}", e))?; + + let next_element = iter.next(); + + let next_key = if let Some(next_element) = next_element { + let (next_key, _) = next_element + .map_err(|e| format!("TrieDB iterator next error: {}", e))?; + Some(next_key) + } else { + None + }; + + Ok(next_key) + } + /// Get the value of storage at given key. pub fn storage(&self, key: &[u8]) -> Result>, String> { let mut read_overlay = S::Overlay::default(); @@ -77,9 +159,14 @@ impl, H: Hasher> TrieBackendEssence { } /// Get the value of child storage at given key. - pub fn child_storage(&self, storage_key: &[u8], key: &[u8]) -> Result>, String> { + pub fn child_storage( + &self, + storage_key: &[u8], + child_info: ChildInfo, + key: &[u8], + ) -> Result>, String> { let root = self.storage(storage_key)? - .unwrap_or(default_child_trie_root::>(storage_key)); + .unwrap_or(default_child_trie_root::>(storage_key).encode()); let mut read_overlay = S::Overlay::default(); let eph = Ephemeral { @@ -89,13 +176,19 @@ impl, H: Hasher> TrieBackendEssence { let map_e = |e| format!("Trie lookup error: {}", e); - read_child_trie_value::, _>(storage_key, &eph, &root, key).map_err(map_e) + read_child_trie_value::, _>(storage_key, child_info.keyspace(), &eph, &root, key) + .map_err(map_e) } /// Retrieve all entries keys of child storage and call `f` for each of those keys. - pub fn for_keys_in_child_storage(&self, storage_key: &[u8], f: F) { + pub fn for_keys_in_child_storage( + &self, + storage_key: &[u8], + child_info: ChildInfo, + f: F, + ) { let root = match self.storage(storage_key) { - Ok(v) => v.unwrap_or(default_child_trie_root::>(storage_key)), + Ok(v) => v.unwrap_or(default_child_trie_root::>(storage_key).encode()), Err(e) => { debug!(target: "trie", "Error while iterating child storage: {}", e); return; @@ -110,6 +203,7 @@ impl, H: Hasher> TrieBackendEssence { if let Err(e) = for_keys_in_child_trie::, _, Ephemeral>( storage_key, + child_info.keyspace(), &eph, &root, f, @@ -119,9 +213,15 @@ impl, H: Hasher> TrieBackendEssence { } /// Execute given closure for all keys starting with prefix. - pub fn for_child_keys_with_prefix(&self, storage_key: &[u8], prefix: &[u8], mut f: F) { + pub fn for_child_keys_with_prefix( + &self, + storage_key: &[u8], + child_info: ChildInfo, + prefix: &[u8], + mut f: F, + ) { let root_vec = match self.storage(storage_key) { - Ok(v) => v.unwrap_or(default_child_trie_root::>(storage_key)), + Ok(v) => v.unwrap_or(default_child_trie_root::>(storage_key).encode()), Err(e) => { debug!(target: "trie", "Error while iterating child storage: {}", e); return; @@ -129,13 +229,12 @@ impl, H: Hasher> TrieBackendEssence { }; let mut root = H::Out::default(); root.as_mut().copy_from_slice(&root_vec); - - self.keys_values_with_prefix_inner(&root, prefix, |k, _v| f(k)) + self.keys_values_with_prefix_inner(&root, prefix, |k, _v| f(k), Some(child_info)) } /// Execute given closure for all keys starting with prefix. pub fn for_keys_with_prefix(&self, prefix: &[u8], mut f: F) { - self.keys_values_with_prefix_inner(&self.root, prefix, |k, _v| f(k)) + self.keys_values_with_prefix_inner(&self.root, prefix, |k, _v| f(k), None) } @@ -144,6 +243,7 @@ impl, H: Hasher> TrieBackendEssence { root: &H::Out, prefix: &[u8], mut f: F, + child_info: Option, ) { let mut read_overlay = S::Overlay::default(); let eph = Ephemeral { @@ -151,8 +251,8 @@ impl, H: Hasher> TrieBackendEssence { overlay: &mut read_overlay, }; - let mut iter = move || -> Result<(), Box>> { - let trie = TrieDB::::new(&eph, root)?; + let mut iter = move |db| -> Result<(), Box>> { + let trie = TrieDB::::new(db, root)?; let mut iter = trie.iter()?; iter.seek(prefix)?; @@ -170,14 +270,20 @@ impl, H: Hasher> TrieBackendEssence { Ok(()) }; - if let Err(e) = iter() { + let result = if let Some(child_info) = child_info { + let db = KeySpacedDB::new(&eph, child_info.keyspace()); + iter(&db) + } else { + iter(&eph) + }; + if let Err(e) = result { debug!(target: "trie", "Error while iterating by prefix: {}", e); } } /// Execute given closure for all key and values starting with prefix. pub fn for_key_values_with_prefix(&self, prefix: &[u8], f: F) { - self.keys_values_with_prefix_inner(&self.root, prefix, f) + self.keys_values_with_prefix_inner(&self.root, prefix, f, None) } } @@ -339,3 +445,67 @@ impl TrieBackendStorage for MemoryDB { Ok(hash_db::HashDB::get(self, key, prefix)) } } + +#[cfg(test)] +mod test { + use sp_core::{Blake2Hasher, H256}; + use sp_trie::{TrieMut, PrefixedMemoryDB, trie_types::TrieDBMut, KeySpacedDBMut}; + use super::*; + + #[test] + fn next_storage_key_and_next_child_storage_key_work() { + let child_info = ChildInfo::new_default(b"uniqueid"); + // Contains values + let mut root_1 = H256::default(); + // Contains child trie + let mut root_2 = H256::default(); + + let mut mdb = PrefixedMemoryDB::::default(); + { + let mut trie = TrieDBMut::new(&mut mdb, &mut root_1); + trie.insert(b"3", &[1]).expect("insert failed"); + trie.insert(b"4", &[1]).expect("insert failed"); + trie.insert(b"6", &[1]).expect("insert failed"); + } + { + let mut mdb = KeySpacedDBMut::new(&mut mdb, child_info.keyspace()); + // reuse of root_1 implicitly assert child trie root is same + // as top trie (contents must remain the same). + let mut trie = TrieDBMut::new(&mut mdb, &mut root_1); + trie.insert(b"3", &[1]).expect("insert failed"); + trie.insert(b"4", &[1]).expect("insert failed"); + trie.insert(b"6", &[1]).expect("insert failed"); + } + { + let mut trie = TrieDBMut::new(&mut mdb, &mut root_2); + trie.insert(b"MyChild", root_1.as_ref()).expect("insert failed"); + }; + + let essence_1 = TrieBackendEssence::new(mdb, root_1); + + assert_eq!(essence_1.next_storage_key(b"2"), Ok(Some(b"3".to_vec()))); + assert_eq!(essence_1.next_storage_key(b"3"), Ok(Some(b"4".to_vec()))); + assert_eq!(essence_1.next_storage_key(b"4"), Ok(Some(b"6".to_vec()))); + assert_eq!(essence_1.next_storage_key(b"5"), Ok(Some(b"6".to_vec()))); + assert_eq!(essence_1.next_storage_key(b"6"), Ok(None)); + + let mdb = essence_1.into_storage(); + let essence_2 = TrieBackendEssence::new(mdb, root_2); + + assert_eq!( + essence_2.next_child_storage_key(b"MyChild", child_info, b"2"), Ok(Some(b"3".to_vec())) + ); + assert_eq!( + essence_2.next_child_storage_key(b"MyChild", child_info, b"3"), Ok(Some(b"4".to_vec())) + ); + assert_eq!( + essence_2.next_child_storage_key(b"MyChild", child_info, b"4"), Ok(Some(b"6".to_vec())) + ); + assert_eq!( + essence_2.next_child_storage_key(b"MyChild", child_info, b"5"), Ok(Some(b"6".to_vec())) + ); + assert_eq!( + essence_2.next_child_storage_key(b"MyChild", child_info, b"6"), Ok(None) + ); + } +} diff --git a/primitives/sr-std/Cargo.toml b/primitives/std/Cargo.toml similarity index 89% rename from primitives/sr-std/Cargo.toml rename to primitives/std/Cargo.toml index 77021af935ae1b5f1a8aaa6bf6ac6630c22416de..7fdf7d1144b7b108208c2f6caaeb62720995e149 100644 --- a/primitives/sr-std/Cargo.toml +++ b/primitives/std/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "sr-std" +name = "sp-std" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" diff --git a/primitives/sr-std/src/lib.rs b/primitives/std/src/lib.rs similarity index 99% rename from primitives/sr-std/src/lib.rs rename to primitives/std/src/lib.rs index 5aa8e82235247a904f59d9781db3d803ac14b7f7..18533e041b99d17d8cc6e16861a2511274bff2c6 100644 --- a/primitives/sr-std/src/lib.rs +++ b/primitives/std/src/lib.rs @@ -37,7 +37,7 @@ macro_rules! map { /// # Example /// /// ``` -/// use sr_std::if_std; +/// use sp_std::if_std; /// /// if_std! { /// // This code is only being compiled and executed when the `std` feature is enabled. diff --git a/primitives/sr-std/with_std.rs b/primitives/std/with_std.rs similarity index 100% rename from primitives/sr-std/with_std.rs rename to primitives/std/with_std.rs diff --git a/primitives/sr-std/without_std.rs b/primitives/std/without_std.rs similarity index 100% rename from primitives/sr-std/without_std.rs rename to primitives/std/without_std.rs diff --git a/primitives/core/storage/Cargo.toml b/primitives/storage/Cargo.toml similarity index 57% rename from primitives/core/storage/Cargo.toml rename to primitives/storage/Cargo.toml index 1e5d7ee8b4548ff8641c75e220756f8d499287a2..384519cc1d69d99502b6e0cd115c85ccfe5ea8c7 100644 --- a/primitives/core/storage/Cargo.toml +++ b/primitives/storage/Cargo.toml @@ -1,16 +1,16 @@ [package] -name = "substrate-primitives-storage" +name = "sp-storage" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" description = "Storage related primitives" [dependencies] -rstd = { package = "sr-std", path = "../../sr-std", default-features = false } +sp-std = { version = "2.0.0", default-features = false, path = "../std" } serde = { version = "1.0.101", optional = true, features = ["derive"] } impl-serde = { version = "0.2.3", optional = true } -substrate-debug-derive = { version = "2.0.0", path = "../debug-derive" } +sp-debug-derive = { version = "2.0.0", path = "../debug-derive" } [features] default = [ "std" ] -std = [ "rstd/std", "serde", "impl-serde" ] +std = [ "sp-std/std", "serde", "impl-serde" ] diff --git a/primitives/core/storage/src/lib.rs b/primitives/storage/src/lib.rs similarity index 53% rename from primitives/core/storage/src/lib.rs rename to primitives/storage/src/lib.rs index ba36e2c80f81e923262bf14cc96077f60d5bdb2e..491a157ebe916fc0e40078c2c27fa0e75931bbd9 100644 --- a/primitives/core/storage/src/lib.rs +++ b/primitives/storage/src/lib.rs @@ -20,9 +20,9 @@ #[cfg(feature = "std")] use serde::{Serialize, Deserialize}; -use substrate_debug_derive::RuntimeDebug; +use sp_debug_derive::RuntimeDebug; -use rstd::{vec::Vec, borrow::Cow}; +use sp_std::{vec::Vec, borrow::Cow}; /// Storage key. #[derive(PartialEq, Eq, RuntimeDebug)] @@ -40,13 +40,31 @@ pub struct StorageData( pub Vec, ); -/// A set of key value pairs for storage. +/// Map of data to use in a storage, it is a collection of +/// byte key and values. #[cfg(feature = "std")] -pub type StorageOverlay = std::collections::HashMap, Vec>; +pub type StorageMap = std::collections::BTreeMap, Vec>; -/// A set of key value pairs for children storage; #[cfg(feature = "std")] -pub type ChildrenStorageOverlay = std::collections::HashMap, StorageOverlay>; +#[derive(Debug, PartialEq, Eq, Clone)] +/// Child trie storage data. +pub struct StorageChild { + /// Child data for storage. + pub data: StorageMap, + /// Associated child info for a child + /// trie. + pub child_info: OwnedChildInfo, +} + +#[cfg(feature = "std")] +#[derive(Default, Debug, Clone)] +/// Struct containing data needed for a storage. +pub struct Storage { + /// Top trie storage data. + pub top: StorageMap, + /// Children trie storage data by storage key. + pub children: std::collections::HashMap, StorageChild>, +} /// Storage change set #[derive(RuntimeDebug)] @@ -156,3 +174,132 @@ impl<'a> ChildStorageKey<'a> { self.storage_key.into_owned() } } + +#[derive(Clone, Copy)] +/// Information related to a child state. +pub enum ChildInfo<'a> { + Default(ChildTrie<'a>), +} + +/// Owned version of `ChildInfo`. +/// To be use in persistence layers. +#[derive(Debug, Clone)] +#[cfg_attr(feature = "std", derive(PartialEq, Eq, Hash, PartialOrd, Ord))] +pub enum OwnedChildInfo { + Default(OwnedChildTrie), +} + +impl<'a> ChildInfo<'a> { + /// Instantiates information for a default child trie. + pub const fn new_default(unique_id: &'a[u8]) -> Self { + ChildInfo::Default(ChildTrie { + data: unique_id, + }) + } + + /// Instantiates a owned version of this child info. + pub fn to_owned(&self) -> OwnedChildInfo { + match self { + ChildInfo::Default(ChildTrie { data }) + => OwnedChildInfo::Default(OwnedChildTrie { + data: data.to_vec(), + }), + } + } + + /// Create child info from a linear byte packed value and a given type. + pub fn resolve_child_info(child_type: u32, data: &'a[u8]) -> Option { + match child_type { + x if x == ChildType::CryptoUniqueId as u32 => Some(ChildInfo::new_default(data)), + _ => None, + } + } + + /// Return a single byte vector containing packed child info content and its child info type. + /// This can be use as input for `resolve_child_info`. + pub fn info(&self) -> (&[u8], u32) { + match self { + ChildInfo::Default(ChildTrie { + data, + }) => (data, ChildType::CryptoUniqueId as u32), + } + } + + /// Return byte sequence (keyspace) that can be use by underlying db to isolate keys. + /// This is a unique id of the child trie. The collision resistance of this value + /// depends on the type of child info use. For `ChildInfo::Default` it is and need to be. + pub fn keyspace(&self) -> &[u8] { + match self { + ChildInfo::Default(ChildTrie { + data, + }) => &data[..], + } + } +} + +/// Type of child. +/// It does not strictly define different child type, it can also +/// be related to technical consideration or api variant. +#[repr(u32)] +pub enum ChildType { + /// Default, it uses a cryptographic strong unique id as input. + CryptoUniqueId = 1, +} + +impl OwnedChildInfo { + /// Instantiates info for a default child trie. + pub fn new_default(unique_id: Vec) -> Self { + OwnedChildInfo::Default(OwnedChildTrie { + data: unique_id, + }) + } + + /// Try to update with another instance, return false if both instance + /// are not compatible. + pub fn try_update(&mut self, other: ChildInfo) -> bool { + match self { + OwnedChildInfo::Default(owned_child_trie) => owned_child_trie.try_update(other), + } + } + + /// Get `ChildInfo` reference to this owned child info. + pub fn as_ref(&self) -> ChildInfo { + match self { + OwnedChildInfo::Default(OwnedChildTrie { data }) + => ChildInfo::Default(ChildTrie { + data: data.as_slice(), + }), + } + } +} + +/// A child trie of default type. +/// Default is the same implementation as the top trie. +/// It share its trie node storage with any kind of key, +/// and its unique id needs to be collision free (eg strong +/// crypto hash). +#[derive(Clone, Copy)] +pub struct ChildTrie<'a> { + /// Data containing unique id. + /// Unique id must but unique and free of any possible key collision + /// (depending on its storage behavior). + data: &'a[u8], +} + +/// Owned version of default child trie `ChildTrie`. +#[derive(Debug, Clone)] +#[cfg_attr(feature = "std", derive(PartialEq, Eq, Hash, PartialOrd, Ord))] +pub struct OwnedChildTrie { + /// See `ChildTrie` reference field documentation. + data: Vec, +} + +impl OwnedChildTrie { + /// Try to update with another instance, return false if both instance + /// are not compatible. + fn try_update(&mut self, other: ChildInfo) -> bool { + match other { + ChildInfo::Default(other) => self.data[..] == other.data[..], + } + } +} diff --git a/primitives/test-primitives/Cargo.toml b/primitives/test-primitives/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..5c2f2dcc0a68e70c1ecdb5e8c8c24bf4c65199de --- /dev/null +++ b/primitives/test-primitives/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "sp-test-primitives" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +sp-application-crypto = { version = "2.0.0", default-features = false, path = "../application-crypto" } +codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } +sp-core = { version = "2.0.0", default-features = false, path = "../core" } +serde = { version = "1.0.101", optional = true, features = ["derive"] } +sp-runtime = { version = "2.0.0", default-features = false, path = "../runtime" } + +[features] +default = [ + "std", +] +std = [ + "sp-application-crypto/std", + "serde", +] diff --git a/test/utils/primitives/src/lib.rs b/primitives/test-primitives/src/lib.rs similarity index 74% rename from test/utils/primitives/src/lib.rs rename to primitives/test-primitives/src/lib.rs index d30b9eabf6fa8084a3cfcb8b34712ef76e4e2c0a..d95b9cb3e280d86cb9f7c30c54a6b2ed4fdd30e0 100644 --- a/test/utils/primitives/src/lib.rs +++ b/primitives/test-primitives/src/lib.rs @@ -14,17 +14,17 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! The Substrate test primitives to share +//! The Substrate test primitives to share #![cfg_attr(not(feature = "std"), no_std)] use codec::{Encode, Decode}; -use app_crypto::sr25519; -pub use app_crypto; +use sp_application_crypto::sr25519; +pub use sp_application_crypto; -pub use primitives::{hash::H256, RuntimeDebug}; -use sr_primitives::traits::{BlakeTwo256, Verify, Extrinsic as ExtrinsicT,}; +pub use sp_core::{hash::H256, RuntimeDebug}; +use sp_runtime::traits::{BlakeTwo256, Verify, Extrinsic as ExtrinsicT,}; /// Extrinsic for test-runtime. #[derive(Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug)] @@ -69,10 +69,19 @@ pub type BlockNumber = u64; /// Index of a transaction. pub type Index = u64; /// The item of a block digest. -pub type DigestItem = sr_primitives::generic::DigestItem; +pub type DigestItem = sp_runtime::generic::DigestItem; /// The digest of a block. -pub type Digest = sr_primitives::generic::Digest; +pub type Digest = sp_runtime::generic::Digest; /// A test block. -pub type Block = sr_primitives::generic::Block; +pub type Block = sp_runtime::generic::Block; /// A test block's header. -pub type Header = sr_primitives::generic::Header; +pub type Header = sp_runtime::generic::Header; + + +/// Changes trie configuration (optionally) used in tests. +pub fn changes_trie_config() -> sp_core::ChangesTrieConfiguration { + sp_core::ChangesTrieConfiguration { + digest_interval: 4, + digest_levels: 2, + } +} \ No newline at end of file diff --git a/primitives/timestamp/Cargo.toml b/primitives/timestamp/Cargo.toml index 013a0340eaf489332a4e42b97404cdeca57d492a..ee86d6e3bc97f02813e71c4d3ce0533c0ad35f0f 100644 --- a/primitives/timestamp/Cargo.toml +++ b/primitives/timestamp/Cargo.toml @@ -5,19 +5,19 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -sr-api = { path = "../sr-api", default-features = false } -rstd = { package = "sr-std", path = "../sr-std", default-features = false } -sr-primitives = { path = "../sr-primitives", default-features = false } +sp-api = { version = "2.0.0", default-features = false, path = "../api" } +sp-std = { version = "2.0.0", default-features = false, path = "../std" } +sp-runtime = { version = "2.0.0", default-features = false, path = "../runtime" } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -inherents = { package = "substrate-inherents", path = "../inherents", default-features = false } +sp-inherents = { version = "2.0.0", default-features = false, path = "../inherents" } impl-trait-for-tuples = "0.1.3" [features] default = [ "std" ] std = [ - "sr-api/std", - "rstd/std", - "sr-primitives/std", + "sp-api/std", + "sp-std/std", + "sp-runtime/std", "codec/std", - "inherents/std", + "sp-inherents/std", ] diff --git a/primitives/timestamp/src/lib.rs b/primitives/timestamp/src/lib.rs index 028f44f378e391a4caff5ff7a3d9aaa9dea2e6ab..9306e14ca8504bbf16a594a3a2059afe7c5dfdbc 100644 --- a/primitives/timestamp/src/lib.rs +++ b/primitives/timestamp/src/lib.rs @@ -22,10 +22,10 @@ use codec::Encode; #[cfg(feature = "std")] use codec::Decode; #[cfg(feature = "std")] -use inherents::ProvideInherentData; -use inherents::{InherentIdentifier, IsFatalError, InherentData}; +use sp_inherents::ProvideInherentData; +use sp_inherents::{InherentIdentifier, IsFatalError, InherentData}; -use sr_primitives::RuntimeString; +use sp_runtime::RuntimeString; /// The identifier for the `timestamp` inherent. pub const INHERENT_IDENTIFIER: InherentIdentifier = *b"timstap0"; @@ -33,7 +33,7 @@ pub const INHERENT_IDENTIFIER: InherentIdentifier = *b"timstap0"; pub type InherentType = u64; /// Errors that can occur while checking the timestamp inherent. -#[derive(Encode, sr_primitives::RuntimeDebug)] +#[derive(Encode, sp_runtime::RuntimeDebug)] #[cfg_attr(feature = "std", derive(Decode))] pub enum InherentError { /// The timestamp is valid in the future. @@ -67,11 +67,11 @@ impl InherentError { /// Auxiliary trait to extract timestamp inherent data. pub trait TimestampInherentData { /// Get timestamp inherent data. - fn timestamp_inherent_data(&self) -> Result; + fn timestamp_inherent_data(&self) -> Result; } impl TimestampInherentData for InherentData { - fn timestamp_inherent_data(&self) -> Result { + fn timestamp_inherent_data(&self) -> Result { self.get_data(&INHERENT_IDENTIFIER) .and_then(|r| r.ok_or_else(|| "Timestamp inherent data not found".into())) } @@ -89,7 +89,7 @@ impl ProvideInherentData for InherentDataProvider { fn provide_inherent_data( &self, inherent_data: &mut InherentData, - ) -> Result<(), inherents::Error> { + ) -> Result<(), sp_inherents::Error> { use std::time::SystemTime; let now = SystemTime::now(); diff --git a/primitives/transaction-pool/Cargo.toml b/primitives/transaction-pool/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..3a3e15e611af11f80cf669175bfe5a9e51e78831 --- /dev/null +++ b/primitives/transaction-pool/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "sp-transaction-pool" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +codec = { package = "parity-scale-codec", version = "1.0.0", optional = true } +derive_more = { version = "0.99.2", optional = true } +futures = { version = "0.3.1", optional = true } +log = { version = "0.4.8", optional = true } +serde = { version = "1.0.101", features = ["derive"], optional = true} +sp-api = { version = "2.0.0", default-features = false, path = "../api" } +sp-runtime = { version = "2.0.0", default-features = false, path = "../runtime" } + +[features] +default = [ "std" ] +std = [ + "codec", + "derive_more", + "futures", + "log", + "serde", + "sp-api/std", + "sp-runtime/std", +] diff --git a/primitives/transaction-pool/runtime-api/Cargo.toml b/primitives/transaction-pool/runtime-api/Cargo.toml deleted file mode 100644 index e002208502592b9c73bf9951bf66cd56c98e41ae..0000000000000000000000000000000000000000 --- a/primitives/transaction-pool/runtime-api/Cargo.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -name = "substrate-transaction-pool-runtime-api" -version = "2.0.0" -authors = ["Parity Technologies "] -edition = "2018" - -[dependencies] -primitives = { package = "substrate-primitives", path = "../../core", default-features = false } -sr-api = { path = "../../sr-api", default-features = false } -sr-primitives = { path = "../../sr-primitives", default-features = false } - -[features] -default = [ "std" ] -std = [ "sr-primitives/std", "primitives/std", "sr-api/std" ] diff --git a/primitives/transaction-pool/src/error.rs b/primitives/transaction-pool/src/error.rs new file mode 100644 index 0000000000000000000000000000000000000000..bf1bcf354d0a9a0285bcdc1b06b04297a4974c5a --- /dev/null +++ b/primitives/transaction-pool/src/error.rs @@ -0,0 +1,82 @@ +// Copyright 2018-2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Transaction pool errors. + +use sp_runtime::transaction_validity::{ + TransactionPriority as Priority, InvalidTransaction, UnknownTransaction, +}; + +/// Transaction pool result. +pub type Result = std::result::Result; + +/// Transaction pool error type. +#[derive(Debug, derive_more::Display, derive_more::From)] +pub enum Error { + /// Transaction is not verifiable yet, but might be in the future. + #[display(fmt="Unknown transaction validity: {:?}", _0)] + UnknownTransaction(UnknownTransaction), + /// Transaction is invalid. + #[display(fmt="Invalid transaction validity: {:?}", _0)] + InvalidTransaction(InvalidTransaction), + /// The transaction validity returned no "provides" tag. + /// + /// Such transactions are not accepted to the pool, since we use those tags + /// to define identity of transactions (occupance of the same "slot"). + #[display(fmt="The transaction does not provide any tags, so the pool can't identify it.")] + NoTagsProvided, + /// The transaction is temporarily banned. + #[display(fmt="Temporarily Banned")] + TemporarilyBanned, + /// The transaction is already in the pool. + #[display(fmt="[{:?}] Already imported", _0)] + AlreadyImported(Box), + /// The transaction cannot be imported cause it's a replacement and has too low priority. + #[display(fmt="Too low priority ({} > {})", old, new)] + TooLowPriority { + /// Transaction already in the pool. + old: Priority, + /// Transaction entering the pool. + new: Priority + }, + /// Deps cycle etected and we couldn't import transaction. + #[display(fmt="Cycle Detected")] + CycleDetected, + /// Transaction was dropped immediately after it got inserted. + #[display(fmt="Transaction couldn't enter the pool because of the limit.")] + ImmediatelyDropped, + /// Invalid block id. + InvalidBlockId(String), + /// The pool is not accepting future transactions. + #[display(fmt="The pool is not accepting future transactions")] + RejectedFutureTransaction, +} + +impl std::error::Error for Error {} + +/// Transaction pool error conversion. +pub trait IntoPoolError: std::error::Error + Send + Sized { + /// Try to extract original `Error` + /// + /// This implementation is optional and used only to + /// provide more descriptive error messages for end users + /// of RPC API. + fn into_pool_error(self) -> std::result::Result { Err(self) } +} + +impl IntoPoolError for Error { + fn into_pool_error(self) -> std::result::Result { Ok(self) } +} diff --git a/primitives/transaction-pool/src/lib.rs b/primitives/transaction-pool/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..29db338b627b7efefd2e820385f0eb5c68011f65 --- /dev/null +++ b/primitives/transaction-pool/src/lib.rs @@ -0,0 +1,33 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Transaction pool primitives types & Runtime API. + +#![warn(missing_docs)] +#![cfg_attr(not(feature = "std"), no_std)] + +pub mod runtime_api; +#[cfg(feature = "std")] +pub mod error; +#[cfg(feature = "std")] +mod pool; + +#[cfg(feature = "std")] +pub use pool::*; + +pub use sp_runtime::transaction_validity::{ + TransactionLongevity, TransactionPriority, TransactionTag, +}; diff --git a/primitives/transaction-pool/src/pool.rs b/primitives/transaction-pool/src/pool.rs new file mode 100644 index 0000000000000000000000000000000000000000..52a3282f8767d7ae0db7eac4258a1f1079189987 --- /dev/null +++ b/primitives/transaction-pool/src/pool.rs @@ -0,0 +1,356 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Transaction pool primitives types & Runtime API. + +use std::{ + collections::HashMap, + hash::Hash, + sync::Arc, +}; +use futures::{ + Future, Stream, + channel::mpsc, +}; +use serde::{Deserialize, Serialize}; +use sp_runtime::{ + generic::BlockId, + traits::{Block as BlockT, Member}, + transaction_validity::{ + TransactionLongevity, TransactionPriority, TransactionTag, + }, +}; + +/// Transaction pool status. +#[derive(Debug)] +pub struct PoolStatus { + /// Number of transactions in the ready queue. + pub ready: usize, + /// Sum of bytes of ready transaction encodings. + pub ready_bytes: usize, + /// Number of transactions in the future queue. + pub future: usize, + /// Sum of bytes of ready transaction encodings. + pub future_bytes: usize, +} + +impl PoolStatus { + /// Returns true if the are no transactions in the pool. + pub fn is_empty(&self) -> bool { + self.ready == 0 && self.future == 0 + } +} + +/// Possible transaction status events. +/// +/// This events are being emitted by `TransactionPool` watchers, +/// which are also exposed over RPC. +/// +/// The status events can be grouped based on their kinds as: +/// 1. Entering/Moving within the pool: +/// - `Future` +/// - `Ready` +/// 2. Inside `Ready` queue: +/// - `Broadcast` +/// 3. Leaving the pool: +/// - `InBlock` +/// - `Invalid` +/// - `Usurped` +/// - `Dropped` +/// +/// The events will always be received in the order described above, however +/// there might be cases where transactions alternate between `Future` and `Ready` +/// pool, and are `Broadcast` in the meantime. +/// +/// There is also only single event causing the transaction to leave the pool. +/// +/// Note that there are conditions that may cause transactions to reappear in the pool. +/// 1. Due to possible forks, the transaction that ends up being in included +/// in one block, may later re-enter the pool or be marked as invalid. +/// 2. Transaction `Dropped` at one point, may later re-enter the pool if some other +/// transactions are removed. +/// 3. `Invalid` transaction may become valid at some point in the future. +/// (Note that runtimes are encouraged to use `UnknownValidity` to inform the pool about +/// such case). +/// +/// However the user needs to re-subscribe to receive such notifications. +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub enum TransactionStatus { + /// Transaction is part of the future queue. + Future, + /// Transaction is part of the ready queue. + Ready, + /// The transaction has been broadcast to the given peers. + Broadcast(Vec), + /// Transaction has been included in block with given hash. + #[serde(rename = "finalized")] // See #4438 + InBlock(BlockHash), + /// Transaction has been replaced in the pool, by another transaction + /// that provides the same tags. (e.g. same (sender, nonce)). + Usurped(Hash), + /// Transaction has been dropped from the pool because of the limit. + Dropped, + /// Transaction is no longer valid in the current state. + Invalid, +} + +/// The stream of transaction events. +pub type TransactionStatusStream = dyn Stream> + Send + Unpin; + +/// The import notification event stream. +pub type ImportNotificationStream = mpsc::UnboundedReceiver<()>; + +/// Transaction hash type for a pool. +pub type TxHash